@font-face{font-family:"Manrope Variable";src:url("assets/xn7gYHE41ni1AdIRggexSg.woff2") format("woff2");font-style:normal;font-weight:200 800;font-display:swap}
@font-face{font-family:Manrope;src:url("assets/xn7gYHE41ni1AdIRggexSg.woff2") format("woff2");font-style:normal;font-weight:300 800;font-display:swap}

.home-candidate{--ink:#000;--muted:rgba(0,0,0,.7);--soft:rgba(0,0,0,.5);--blue:#015dd3;--green:#49cc31;--motion-accordion:900ms;--ease-out-expo:cubic-bezier(.16, 1, .3, 1);--motion-roll:200ms;--ease-roll:cubic-bezier(.12, .23, .5, 1);box-sizing:border-box;margin:0;background:#fff;color:var(--ink);font-family:Manrope,sans-serif;font-size:16px;font-weight:500;line-height:1.4;overflow-x:hidden}
.home-candidate *{box-sizing:border-box}
.home-candidate a{color:inherit;text-decoration:none}
.home-candidate :where(h1,h2,p,ul){margin:0}
.home-candidate a:focus-visible,.home-candidate button:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
/* overflow-x:clip so a section still parked at its pre-reveal translateX(30px) cannot
   widen documentElement.scrollWidth. clip (not hidden) keeps this from becoming a
   scroll container, which would break position:sticky/fixed descendants. */
.home-candidate main{display:flex;flex-direction:column;align-items:flex-start;gap:200px;width:100%;padding:160px 80px 240px;background:#fff;position:relative;z-index:2;overflow-x:clip}
.content-wide{width:100%}
.surface{width:100%}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

/* Entrance reveal — CSS owns the pre-animation state and nothing else. The states
   are scoped under the JS-added .js-home-motion root class, so without JS every
   target is visible. PortfolioMotion's WAAPI runtime plays the motion and adds
   .is-visible, which doubles as the settled state after a teardown, so a target is
   never left at opacity 0. */
.js-home-motion .home-candidate [data-home-reveal="section"]:not(.is-visible){opacity:0;transform:translate3d(30px,0,0)}
.js-home-motion .home-candidate [data-home-reveal="card"]:not(.is-visible){opacity:0;transform:translate3d(0,30px,0)}
/* Two layered effects, matching Framer:
   - block level : Scroll Animation enter, Offset 50 X
   - per line    : Text Effect, Offset 30 X + opacity 0, 500ms, bezier(0,.46,.56,1),
                   delay 0.2s per visual line
   The block itself never fades — its words carry the opacity — so it is held at
   .001 only until home-motion.js has split it. */
.js-home-motion .home-candidate [data-home-reveal="title"]:not(.is-visible){opacity:.001}
.js-home-motion .home-candidate [data-home-reveal="cta"]:not(.is-visible){opacity:0;transform:translate3d(50px,0,0)}
/* inline-block so the Offset 30 X from the Framer text effect can actually apply —
   transforms are ignored on inline boxes. Words still wrap at the spaces between
   them, which are left as their own text nodes. */
.hero-word{display:inline-block}
.hero-word-group{display:inline-block;white-space:nowrap}

.hero{display:flex;flex-direction:column;align-items:flex-start;gap:32px;max-width:1180px;height:625.5625px}
.hero-kicker{width:100%;font-family:"Manrope Variable",sans-serif;font-size:30px;font-weight:400;font-variation-settings:"wght" 500;line-height:1.3}
/* direct child only, so the per-word spans home.js injects cannot re-match it */
.hero-kicker>span{font-size:32px;line-height:1.3}
.hero h1{width:100%;font-family:"Manrope Variable",sans-serif;font-size:64px;font-weight:400;font-variation-settings:"wght" 500;line-height:1.2;letter-spacing:normal}
.hero h1 em{color:var(--green);font-style:normal}
.hero h1 strong{color:var(--blue);font-weight:400}
.hero .hero-outcome{width:100%;color:var(--muted);font-size:32px;font-weight:500;line-height:1.3}
/* class-based, not positional: the per-word spans change the child index */
.hero-outcome .hl-1{color:#0e62d4}
.hero-outcome .hl-2{color:#005ed3}
.hero .hero-location{width:100%;color:var(--muted);font-size:24px;font-weight:700;line-height:1.4}
.hero .portfolio-pill-button--inverse{margin-top:18px}

.eyebrow{font-size:16px;font-weight:500;line-height:22.4px}
.what-bring{display:grid;grid-template-columns:20% 1fr;align-items:start;gap:16px;width:100%;height:100.78125px}
.what-bring ul{padding:0;list-style-position:inside;color:var(--muted);font-size:24px;font-weight:500;line-height:33.6px}

.projects{--portfolio-project-card-copy-gap:30px;--portfolio-project-card-meta-gap:20px;--portfolio-project-card-title-gap:8px;--portfolio-project-card-title-letter-spacing:normal;--portfolio-project-card-client-color:var(--muted);display:flex;flex-direction:column;align-items:stretch;gap:50px;height:2160.78125px;overflow:hidden}
.projects .portfolio-project-card__meta{align-items:center}
.project-feature .project-media{height:703.203125px}
.project-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:40px;row-gap:50px}

.roles{position:relative;height:345.21875px;padding-bottom:40px;overflow:visible}
.roles>div{width:calc(100% - 180.484375px)}
.roles>div+div{margin-top:20px}
.roles h2,.services h2,.about h2{font-size:40px;font-weight:500;line-height:56px;letter-spacing:normal}
.roles>div h2{width:fit-content}
.roles p{margin-top:10px;color:var(--soft);font-size:16px;font-weight:500;line-height:22.4px}
.roles .portfolio-pill-button{position:absolute;right:0;top:0}

/* min-height (not height) so open rows can grow the list and the section, the way
   the reference does: 334.40625 -> 426.8125 (one row) -> 519.21875 (two rows). */
.services{display:flex;flex-direction:column;align-items:flex-start;gap:24px;min-height:334.40625px;overflow:visible}
.services>.eyebrow{width:100%}
.service-list{width:100%;min-height:288px}
/* Grid-row disclosure: the panel track goes 0fr <-> 1fr, so nothing measures or
   transitions a height and the open row sizes itself at every width. Collapsing
   only exists under .js-home-motion — the document's own state is every row open,
   which is what makes the copy readable without JavaScript. */
.services article{position:relative;display:grid;grid-template-rows:auto auto;width:100%;overflow:hidden;box-shadow:rgb(217,217,217) 0 1px 0 0}
.js-home-motion .services article{grid-template-rows:auto 0fr;transition:grid-template-rows var(--motion-accordion) var(--ease-out-expo)}
.js-home-motion .services article.is-open{grid-template-rows:auto 1fr}
.services article h2{width:100%}
.service-toggle{display:flex;align-items:center;width:100%;height:96px;margin:0;padding:0 72px 0 0;border:0;background:none;color:inherit;font:inherit;letter-spacing:inherit;text-align:left;cursor:pointer}
/* the row is exactly 96px with overflow:hidden, so the shared +3px outline offset
   would be clipped away; inset the ring instead. Needs to outspecify
   `.home-candidate button:focus-visible`. */
.home-candidate .service-toggle:focus-visible{outline:2px solid var(--blue);outline-offset:-4px}
.service-arrow{position:absolute;right:0;top:24px;display:grid;place-items:center;width:48px;height:48px}
.service-arrow svg{display:block;width:24px;height:24px;fill:#000;transition:transform .35s ease}
.service-toggle[aria-expanded="true"] .service-arrow svg{transform:rotate(180deg)}
/* overflow:hidden zeroes the 0fr track's automatic minimum, but only for content —
   padding on the panel itself would still floor the collapsed track, so the 2px of
   lead-in and 40px of trailing space sit on the copy. They put the settled open row
   on the reference's 188.40625px at 1440 (96 + 2 + 50.40625 + 40). */
.service-panel{min-width:0;min-height:0;width:calc(100% - 72px);overflow:hidden}
.services article p{padding:2px 0 40px;color:var(--muted);font-size:18px;font-weight:600;line-height:25.2px}

.about{position:relative;display:grid;grid-template-columns:20% 64%;align-items:start;gap:16px;height:288.78125px;overflow:visible}
.about>div{width:100%}
.about div p{margin-top:20px;color:var(--muted);font-size:24px;font-weight:500;line-height:33.6px}
.about .portfolio-pill-button{position:absolute;right:0;top:0}

.clients{display:flex;flex-direction:column;align-items:flex-start;gap:40px;height:605.59375px;overflow:hidden}
.client-logos{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));grid-template-rows:repeat(2,200px);gap:0;width:100%;height:400px;overflow:hidden}
.client-logos img{place-self:center;display:block;border-radius:0;object-fit:cover;object-position:center}
.client-logos img:nth-child(1){width:185px;height:61px}
.client-logos img:nth-child(2){width:191px;height:63px}
.client-logos img:nth-child(3){width:236px;height:78px}
.client-logos img:nth-child(4){width:210px;height:69px}
.client-logos img:nth-child(5){width:204px;height:67px}
.client-logos img:nth-child(6){width:208px;height:68px}
.client-logos img:nth-child(7),.client-logos img:nth-child(8){width:222px;height:73px}
.client-logos img:nth-child(9){width:344px;height:113px;max-width:none}
.client-logos img:nth-child(10){width:216px;height:71px}
.client-copy{display:flex;flex-direction:column;gap:20px;width:60%;height:165.59375px;overflow:hidden}
.client-copy h2{font-size:32px;font-weight:700;line-height:44.8px}
.client-copy p{color:rgba(0,0,0,.5);font-size:20px;font-weight:500;line-height:28px}

/* ---------------------------------------------------------------------------
   The reference has four tiers, switching at 1440 / 1100 / 768. Everything that
   is common to all three narrower tiers lives here; the three blocks below carry
   only what is specific to one band. Measured against dist/index.html at
   height 900, DPR 1.
   --------------------------------------------------------------------------- */
@media (max-width:1439.98px){
  /* The reference's hero headline is two lines at 1280 — the hard break is a
     >=1440 device only. The clients paragraph has no hard break on the reference
     at any width; below 1100 keeping it would force a spurious third line. */
  .desktop-break{display:none}
  /* Single-column card grid: the reference's rows are equal (grid-auto-rows
     minmax(0,1fr), so every row takes the tallest card) and 40px apart, not the
     50px that separates the feature card from the grid. */
  .project-grid{row-gap:40px;grid-auto-rows:minmax(0,1fr)}
  /* roles / about: below 1440 the CTA leaves its absolute slot on the right and
     rejoins the flow under the content, 88px (roles) / 48px (about) below it. */
  .roles{padding-bottom:0}
  .roles>div{width:100%}
  /* display:flex (not the inline-flex the pill rests at) so the margin below the
     copy is a plain block margin, not a line-box offset that would round. */
  .roles .portfolio-pill-button,.about .portfolio-pill-button{display:flex;width:fit-content;position:static}
  .roles .portfolio-pill-button{margin-top:88px}
  .about{padding-bottom:0}
  .about .portfolio-pill-button{margin-top:48px}
}

@media (min-width:768px) and (max-width:1439.98px){
  /* main drops to a 64px gutter here, but the header does not — the reference's
     Desktop and Tablet header variants both stay on 24px/80px down to 768. */
  .home-candidate main{gap:120px;padding:160px 64px 160px}
  .hero{height:auto}
  .hero h1{font-size:50px}
  .what-bring{height:auto}
  .projects,.roles,.services,.about,.clients{height:auto;min-height:0}
  .projects{overflow:visible}
  .project-grid{grid-template-columns:1fr}
  /* two-column about keeps its 16px column gap but no row gap — the CTA's own
     48px margin is the whole distance from the copy above it. */
  .about{grid-template-columns:20% 1fr;column-gap:16px;row-gap:0}
  .about .portfolio-pill-button{grid-column:2;justify-self:start}
  .about div p{font-size:22px;line-height:30.8px}
  .client-logos{grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:repeat(4,150px);height:auto}
  .client-copy{width:60%;height:auto}
  .client-logos img:nth-child(1){width:160px;height:51px}
  .client-logos img:nth-child(2){width:149px;height:53px}
  .client-logos img:nth-child(3){width:191px;height:68px}
  .client-logos img:nth-child(4){width:179px;height:59px}
  .client-logos img:nth-child(5){width:186px;height:57px}
  .client-logos img:nth-child(6){width:165px;height:58px}
  .client-logos img:nth-child(7){width:179px;height:63px}
  .client-logos img:nth-child(8){width:180px;height:63px}
  .client-logos img:nth-child(9){width:301px;height:103px}
  .client-logos img:nth-child(10){width:173px;height:61px}
}

/* 1100-1439: desktop type scale, tablet gutter. The feature card's media is the
   only thing that separates this band from 768-1099. */
@media (min-width:1100px) and (max-width:1439.98px){
  .project-feature .project-media{height:473.203125px}
}

/* 768-1099: the reference steps its type down a notch here — hero location,
   card titles, section headings, the clients headline and the footer headline. */
@media (min-width:768px) and (max-width:1099.98px){
  /* kicker tablet wrap: the reference's glyph boxes render this line fractionally
     wider, which pushes the trailing period onto a fourth line. */
  .hero-kicker{max-inline-size:97%}
  .hero .hero-location{font-size:22px;line-height:30.8px}
  .project-feature .project-media{height:476px}
  .projects{--portfolio-project-card-title-size:22px;--portfolio-project-card-title-line-height:30.8px}
  .roles h2,.services h2,.about h2{font-size:32px;line-height:44.8px}
  .client-copy h2{font-size:26px;line-height:36.4px}
}

@media (max-width:767.98px){
  .home-candidate main{gap:80px;padding:120px 16px 160px}
  .hero{gap:32px;width:100%;height:auto}
  .hero-kicker{font-size:23px}
  .hero-kicker span{font-size:24px}
  .hero h1{font-size:35px;line-height:1.2}
  .hero .hero-outcome{font-size:24px}
  .hero .hero-location{font-size:14px}
  /* four 32px stack gaps + this margin = the reference's 144px of hero spacing
     below 768 (it is 146px at and above 768). */
  .hero .portfolio-pill-button--inverse{margin-top:16px}
  .what-bring{display:grid;grid-template-columns:1fr;gap:16px;height:auto}
  .what-bring ul{font-size:18px;line-height:25.2px}
  .projects{gap:50px;height:auto;padding-top:0;overflow:visible}
  .project-grid{grid-template-columns:1fr}
  .projects{--portfolio-project-card-title-size:20px;--portfolio-project-card-title-line-height:28px}
  .roles{height:auto}
  .roles>div+div{margin-top:20px}
  .roles h2,.services h2{font-size:26px;line-height:36.4px}
  .about h2{font-size:20px;line-height:28px}
  .services{height:auto;min-height:0;gap:16px}
  .service-list{height:auto;min-height:0}
  .about{display:block;height:auto}
  .about .eyebrow{margin-bottom:16px}
  .about div p{font-size:14px;line-height:19.6px}
  .clients{height:auto;gap:40px;overflow:visible}
  .client-logos{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(5,80px);height:auto}
  /* the reference keeps logos-then-copy at every width — no reorder below 768 */
  .client-copy{width:100%;height:auto}
  .client-copy h2{font-size:20px;line-height:28px}
  .client-copy p{color:var(--muted);font-size:14px;line-height:19.6px}
  .client-logos img:nth-child(1){width:108px;height:21px}
  .client-logos img:nth-child(2){width:114px;height:23px}
  .client-logos img:nth-child(3){width:159px;height:38px}
  .client-logos img:nth-child(4){width:133px;height:29px}
  .client-logos img:nth-child(5){width:127px;height:27px}
  .client-logos img:nth-child(6){width:131px;height:28px}
  .client-logos img:nth-child(7),.client-logos img:nth-child(8){width:145px;height:33px}
  .client-logos img:nth-child(9){width:267px;height:73px}
  .client-logos img:nth-child(10){width:139px;height:31px}
}

@media (prefers-reduced-motion:reduce){
  /* No Lenis (the shared controller stops it), no parallax, no spatial reveal. */
  /* Every reveal target settles visible in every state combination. home-motion.js
     reveals them outright and never splits the hero, so the .hero-word rule is the
     belt-and-braces case. */
  .js-home-motion .home-candidate [data-home-reveal="section"]:not(.is-visible),
  .js-home-motion .home-candidate [data-home-reveal="card"]:not(.is-visible),
  .js-home-motion .home-candidate [data-home-reveal="title"]:not(.is-visible),
  .js-home-motion .home-candidate [data-home-reveal="cta"]:not(.is-visible),
  .home-candidate .hero-word{opacity:1;transform:none;transition:none}
  /* The accordion keeps working, it just switches instantly. */
  .js-home-motion .services article,.service-arrow svg{transition:none}
}
