/* Commune – Featured Case Studies
   Reference frames: desktop 1440x925, mobile 570x1031 (pixel-matched to mockups)
   Fonts + colours are variables below for easy swapping. */

.ccs{
  --ccs-font-display:'Anton',Impact,'Arial Narrow',sans-serif;
  --ccs-font-body:'Outfit','Helvetica Neue',Arial,sans-serif;
  --ccs-ink:#121212;          /* section background */
  --ccs-cream:#F8F6F0;        /* big headline colour */
  --ccs-paper:#F8F6F0;        /* unfilled progress bar */
  --ccs-white:#F8F6F0;
  --ccs-title-size:clamp(52px,7.65vw,120px);
  --ccs-num-size:clamp(56px,8.4vw,132px);
  --ccs-intro-hold:300vh;     /* extra scroll the intro card holds full-screen */
  --ccs-delay-rest:.4s;       /* wait before the clip-masked elements wipe in */
}

/* full-bleed even inside a constrained content column */
.ccs{position:relative;width:100vw;margin-left:calc(50% - 50vw);background:var(--ccs-ink);color:var(--ccs-white);font-family:var(--ccs-font-body)}
.ccs{z-index:9999}
.ccs:has( .show-header ){z-index:0}
.ccs,.ccs *,.ccs *::before,.ccs *::after{box-sizing:border-box;margin:0;padding:0}
/* Theme content styles hit h2/p/ul/figure by element name — (0,1,1) — which beats
   the single-class reset above and drags absolutely-positioned boxes off their mark.
   Every offset in this file lives in top/left/right/bottom, so margins stay flat. */
.ccs .ccs-el,.ccs .ccs-head,.ccs .ccs-bars,.ccs .ccs-intro-text{margin:0!important}

/* ---------- intro: cream title card that floods to the orange logo wall ---------- */
/* pin scaffold: the card sticks full-screen for --ccs-intro-hold of extra scroll,
   which is also what gives the bar wipe -> flood -> text flip room to finish */
.ccs-intro-track{position:relative;z-index:1}
.ccs.ccs-js .ccs-intro-track{height:calc(100vh + var(--ccs-intro-hold));height:calc(100svh + var(--ccs-intro-hold))}
.ccs.ccs-js .ccs-intro{position:sticky;top:0}

.ccs-intro{position:relative;z-index:1;height:100vh;height:100svh;background:#F4F0E7;display:flex;align-items:center;justify-content:center;overflow:hidden}
.ccs-intro-flood{position:absolute;inset:0;background:#F3660C;opacity:0;will-change:clip-path}
.ccs-intro-wall{position:absolute;inset:0;display:flex;opacity:0;will-change:opacity}
.ccs-intro-col{flex:1;background-repeat:repeat-y;background-size:100% auto;background-position:50% 0;will-change:background-position}
.ccs-intro-text{position:relative;z-index:2;text-align:center;font-family:var(--ccs-font-display);font-weight:400;text-transform:uppercase;color:#121212;line-height:1;transition:color .35s ease}
.ccs-intro-l1{display:block;line-height:.7!important;font-size: min(9.4rem, calc((100vw - 40px) / 6.5));letter-spacing:.01em;opacity:0;transform:translateY(30px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}
.ccs-intro-l2{display:block;margin-top:.1em;font-size: min(9.4rem, calc((100vw - 40px) / 6.5));letter-spacing:.01em}
.ccs-intro-l2 em{font-style:normal;display:inline-block;position:relative;padding:.09em .18em .13em}
.ccs-intro-bar{position:absolute;top:0;left:0;right:0;bottom:0;background:#F3660C;-webkit-clip-path:inset(0 100% 0 0);clip-path:inset(0 100% 0 0);transition:clip-path .9s cubic-bezier(.77,0,.18,1),-webkit-clip-path .9s cubic-bezier(.77,0,.18,1),opacity .5s ease}
.ccs-intro-l2t{position:relative;z-index:1;display:inline-block;opacity:0;transform:translateY(30px);transition:opacity .7s ease .18s,transform .7s cubic-bezier(.22,.61,.36,1) .18s}
.ccs-intro.is-in .ccs-intro-l1{opacity:1;transform:none}
.ccs-intro.is-in .ccs-intro-l2t{opacity:1;transform:none}
.ccs-intro.is-bar .ccs-intro-bar{-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0)}
.ccs-intro.is-flooded .ccs-intro-text{color:#F4F0E7}
/* flood owns the frame: drop the bar so the logo strips run behind the words */
.ccs-intro.is-bar-out .ccs-intro-bar{opacity:0}

/* pin scaffold: N slides x 2 viewport-scrolls each, +1 for the pinned screen itself */
.ccs.ccs-js .ccs-track{height:calc((var(--ccs-count)*2 + 1)*100vh);z-index:1;}
.ccs-pin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
.ccs:not(.ccs-js) .ccs-slide:not(:first-child){display:none}

/* ---------- static header ---------- */
.ccs-head{position:absolute;z-index:6;top:9.3vh;right:64px;display:flex;align-items:center;gap:10px;font-family:var(--ccs-font-body);font-weight:700;font-size:15px;letter-spacing:.01em}
.ccs-head svg{width:17px;height:17px}

/* ---------- slides ---------- */
.ccs-slides{position:absolute;inset:0}
.ccs-slide{position:absolute;inset:0;pointer-events:none}
.ccs-slide.is-active{pointer-events:auto;z-index:2}
.ccs-slide.is-leaving{z-index:1}

/* media panel */
.ccs-media{position:absolute;z-index:1;left:31.8vw;top:15vh;width:36.3vw;height:70vh;overflow:hidden;background:#121212;transform: translateZ(0);isolation: isolate;-webkit-mask-image: -webkit-radial-gradient(white, #121212);mask-image: -webkit-radial-gradient(white, #121212)}
.ccs-tilt,.ccs-para{position:absolute;inset:0;will-change:transform;overflow:hidden}
.ccs-media img,.ccs-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background: transparent}

/* type + meta */
.ccs-kicker{position:absolute;z-index:3;left:5.85vw;top:22.5vh;font-family:var(--ccs-font-body);font-weight:700;font-size:15px;letter-spacing:.04em;text-transform:uppercase}
.ccs-title{position:absolute;z-index:3;left:5.85vw;top:26.5vh;width:52vw;max-width: 700px;font-family:var(--global-heading-font-family);font-weight:400;line-height: .95 !important;padding-top: 8px !important;font-size:120px;line-height:.95;letter-spacing:.01em;text-transform:uppercase;color:var(--ccs-cream)}
.ccs-tags{padding:0!important;position:absolute;z-index:3;left:5.85vw;bottom:14.6vh;list-style:none;font-family:var(--ccs-font-body);font-weight:600;font-size:19px;line-height:1.6}
.ccs-num{position:absolute;z-index:3;right:0;top:34.3vh;width:200px;padding-top: 24px;padding-right:10px;height: 140px;min-height: 120px;background:var(--ccs-accent);display:flex;align-items:center;justify-content:center}
.ccs-num span{font-family:var(--global-heading-font-family);font-size:120px;line-height:1;color:var(--ccs-ink);letter-spacing:.02em}
.ccs-desc{position:absolute;z-index:3;left:72.6vw;top:57vh;width:26vw;font-family:var(--ccs-font-body);font-weight:400;font-size:16px;line-height:1.55;color:#EDEDED}
.ccs-plus{display:block;font-size:15px;margin-bottom:4px}
.ccs-cta{position:absolute;z-index:3;left:72.4vw;bottom:15vh;display:inline-flex;align-items:center;gap:12px;padding:9px 18px;border:1px solid var(--ccs-white);color:var(--ccs-white);font-family:var(--ccs-font-body);font-weight:500;font-size:15px;text-decoration:none;transition:background .25s ease,color .25s ease}
.ccs-cta svg{width:12px;height:12px;color:var(--ccs-accent)}
.ccs-cta:hover{background:var(--ccs-accent);color:var(--ccs-ink)}
.ccs-cta:focus, .ccs-cta:active {color:white;}
.ccs-cta:hover svg{color:#121212;}

/* ---------- progress bars ---------- */
.ccs-bars{position:absolute;z-index:5;left:5.85vw;right:64px;bottom:5.2vh;display:flex;gap:24px}
.ccs-bar{position:relative;flex:1;height:12px;background:var(--ccs-paper);overflow:hidden}
.ccs-bar i{position:absolute;inset:0;background:var(--ccs-bar-c);transform:scaleX(0);transform-origin:left center}

/* ---------- enter / leave animation (clip wipe bottom -> top, no fade) ---------- */
/* Deliberately no opacity and no transform: every element reveals by clip-path
   alone, which leaves transform free for the centred mobile offsets below. */
.ccs.ccs-js .ccs-el{clip-path:inset(100% 0 0 0);-webkit-clip-path:inset(100% 0 0 0);transition:clip-path .7s cubic-bezier(.77,0,.18,1),-webkit-clip-path .7s cubic-bezier(.77,0,.18,1)}
.ccs.ccs-js .ccs-slide.is-active .ccs-el{clip-path:inset(0 0 0 0);-webkit-clip-path:inset(0 0 0 0)}
.ccs.ccs-js .ccs-slide.is-leaving .ccs-el{clip-path:inset(0 0 100% 0);-webkit-clip-path:inset(0 0 100% 0)}

/* scrolling up mirrors it, so the wipe always travels with the scroll.
   is-active/is-leaving outrank these on specificity, so order is irrelevant. */
.ccs.ccs-js[data-dir="up"] .ccs-el{clip-path:inset(0 0 100% 0);-webkit-clip-path:inset(0 0 100% 0)}
.ccs.ccs-js[data-dir="up"] .ccs-slide.is-leaving .ccs-el{clip-path:inset(100% 0 0 0);-webkit-clip-path:inset(100% 0 0 0)}

/* The outgoing slide has no delay, so it starts leaving immediately while the incoming
   clip-masked elements wait — that wait is the gap between case studies. */
.ccs.ccs-js .ccs-slide.is-active .ccs-el{transition-delay:var(--ccs-delay-rest)}

/* The media panel is the one exception: it fades rather than wiping, leads with no
   delay of its own, and the img/video inside holds still while it runs (no scale).
   clip-path needs !important because the [data-dir] rules above are more specific and
   would otherwise re-clip the panel on scroll-up. The explicit transition-delay:0s is
   needed too — the .ccs-el rule above is more specific than this rule's shorthand. */
.ccs.ccs-js .ccs-media{clip-path:none!important;-webkit-clip-path:none!important;opacity:0;transition:opacity .95s ease}
.ccs.ccs-js .ccs-slide.is-active .ccs-media{opacity:1;transition-delay:0s}

/* ---------- mobile (<=768px), reference 570x1031 ----------
   1u = one px of the mockup, so every number below is measured straight off it.
   Offsets are anchored to the centre of the viewport (mockup centre 285,515.5) and
   never use vh, so the composition holds its exact proportions at any screen height
   and centres itself, letting spare height fall away above and below.

   Reading the numbers: an x offset of -255 is a left edge at 285-255 = mockup x 30;
   a y offset of +313 is a top edge at 515.5+313 = mockup y 828. Right/bottom-anchored
   boxes count in from the far edge instead: right 260 puts the right edge at
   285+260 = 545, i.e. 25 in from the frame's right side. */
@media (max-width:768px){
  .ccs{
    --ccs-intro-hold:70vh;
    /* min() caps the unit so the full 1031u composition always fits the height */
    --ccs-u:min(calc(100vw / 570),calc(100vh / 1031));
    /* Whole-composition nudge: left by nx, up by ny, to keep the right-hand boxes
       off the edge once the frame is width-fit and 570u lands exactly on 100vw.
       Left/top-anchored boxes subtract these; right/bottom-anchored ones add them,
       since those measure inward from the far edge. */
    --ccs-nx:4px;
    --ccs-ny:4px;
  }
  /* custom properties get no per-declaration fallback, so svh needs @supports */
  @supports (height:100svh){
    .ccs{--ccs-u:min(calc(100vw / 570),calc(100svh / 1031))}
  }

  .ccs-head{top:calc(50% - var(--ccs-u) * 226 - var(--ccs-ny));right:calc(50% - var(--ccs-u) * 260 + var(--ccs-nx));writing-mode:vertical-rl;font-size:calc(var(--ccs-u) * 17);gap:calc(var(--ccs-u) * 11)}
  .ccs-head svg{display:none}

  .ccs-kicker{left:calc(50% - var(--ccs-u) * 255 - var(--ccs-nx));top:calc(50% - var(--ccs-u) * 446 - var(--ccs-ny));font-size:calc(var(--ccs-u) * 16)}
  /* 300u is narrow enough to wrap a two-word title after the first word, as the
     mockup does, and still clears the number block that starts at mockup x 455 */
  .ccs-title{left:calc(50% - var(--ccs-u) * 255 - var(--ccs-nx));top:calc(50% - var(--ccs-u) * 400 - var(--ccs-ny));width:calc(var(--ccs-u) * 400);max-width:none;font-size:calc(var(--ccs-u) * 64);line-height:1}
  /* 170 + 115 = 285 = half the frame, so the block stays flush to the right edge */
  .ccs-num{left:calc(50% + var(--ccs-u) * 170 - var(--ccs-nx));right:auto;top:calc(50% - var(--ccs-u) * 359 - var(--ccs-ny));width:calc(var(--ccs-u) * 115);height:calc(var(--ccs-u) * 100);min-height:0;padding-top:calc(var(--ccs-u) * 11)}
  .ccs-num span{font-size:calc(var(--ccs-u) * 62)}

  .ccs-media{left:calc(50% - var(--ccs-u) * 203 - var(--ccs-nx));top:calc(50% - var(--ccs-u) * 228 - var(--ccs-ny));width:calc(var(--ccs-u) * 405);height:calc(var(--ccs-u) * 499)}

  .ccs-bars{left:calc(50% - var(--ccs-u) * 252 - var(--ccs-nx));right:auto;top:calc(50% - var(--ccs-u) * 228 - var(--ccs-ny));bottom:auto;height:calc(var(--ccs-u) * 499);width:calc(var(--ccs-u) * 13);flex-direction:column;gap:calc(var(--ccs-u) * 12)}
  .ccs-bar{height:auto;width:calc(var(--ccs-u) * 13)}
  .ccs-bar i{transform:scaleY(0);transform-origin:center top}

  /* -255 lines the tags up with the kicker and title above them */
  .ccs-tags{left:calc(50% - var(--ccs-u) * 255 - var(--ccs-nx));top:calc(50% + var(--ccs-u) * 313 - var(--ccs-ny));bottom:auto;font-size:calc(var(--ccs-u) * 19);line-height:1.6}
  .ccs-desc{left:calc(50% + var(--ccs-u) * 23 - var(--ccs-nx));top:calc(50% + var(--ccs-u) * 310 - var(--ccs-ny));width:calc(var(--ccs-u) * 245);max-width:none;font-size:calc(var(--ccs-u) * 17) !important;line-height:1.45}
  .ccs-cta{left:auto;right:calc(50% - var(--ccs-u) * 260 + var(--ccs-nx));top:auto;bottom:calc(50% - var(--ccs-u) * 510 + var(--ccs-ny));font-size:calc(var(--ccs-u) * 21);gap:calc(var(--ccs-u) * 14);padding:calc(var(--ccs-u) * 5) calc(var(--ccs-u) * 25) calc(var(--ccs-u) * 8)}
  .ccs-cta svg{width:calc(var(--ccs-u) * 14);height:calc(var(--ccs-u) * 14)}
  .ccs-plus{font-size:calc(var(--ccs-u) * 16);margin-bottom:calc(var(--ccs-u) * 5)!important;translate:0 calc(var(--ccs-u) * 5)}
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  /* nothing animates during the hold, so don't make people scroll through it */
  .ccs{--ccs-intro-hold:0px}

  .ccs-intro-l1,.ccs-intro-l2t{opacity:1;transform:none;transition:none}
  .ccs-intro-bar{clip-path:none!important;-webkit-clip-path:none!important;transition:none}
  .ccs-intro-flood{display:none}
  .ccs.ccs-js .ccs-el,.ccs-bar i{transition:none!important}
  /* releases both reveal mechanisms: the clip wipe and the num/cta fade */
  .ccs.ccs-js .ccs-el{opacity:1!important;transform:none;clip-path:none!important;-webkit-clip-path:none!important}
  .ccs-tilt,.ccs-para{transform:none!important}
}



/*Text reveal animation*/

    .reveal-type .rt-unit {
    transition: opacity 0.08s linear;
    will-change: opacity;
  }
  /* keep words from breaking awkwardly mid-word when using char mode */
  .reveal-type .rt-word { display: inline-block; white-space: nowrap; }
 
  @media (prefers-reduced-motion: reduce) {
    .reveal-type .rt-unit { opacity: 1 !important; transition: none; }
  }