/*==============================================================================
  CSIGNAL PAGES
  ----------------------------------------------------------------------------
  Everything for /work/ and the case studies under /work/<slug>/. Split out of
  csignal-skin.css so two people can work on the rebrand at once: that file was
  being edited by two sessions, which silently duplicated it end to end once
  already. csignal-skin.css keeps the site-wide layer (type, header, buttons,
  footer, the homepage and the legal pages); this file keeps the page-specific
  layer and is loaded after it.

  Load order on those pages:
      style.css / our-work.css / case-study.css
      csignal-skin.css      site-wide
      csignal-pages.css     this file
  Everything here is scoped to body.cs-skin like the skin, so it cannot leak.
==============================================================================*/

/*==============================================================================
  WORK PAGE
  ----------------------------------------------------------------------------
  Sections 15 to 19 skin /work/v2.php. Everything here is scoped to
  body.cs-skin like the rest of the file, and every family except
  .featured-project and .industry-filters also appears on /about/, /contact/
  and the service template, so this is the shared work paying forward.

  NOTE ON font-family: the sweep in section 1 is a scoped universal carrying
  !important, so ANY font override below must carry !important too. A
  non-important declaration cannot beat an important one at any specificity.
==============================================================================*/

/*------------------------------------------------------------------------------
  15. Work: hero
------------------------------------------------------------------------------*/

body.cs-skin .intro {
  background-color: var(--ink);
  position: relative;
}

/* The teal-into-violet blur was off-palette on both counts. */
/* The blur behind the nav. Hidden on /work/ by the rule below, but services.css
   styles the same element as .intro.intro-services .intro__gradient at 0,3,0,
   which outranks a plain body.cs-skin .intro__gradient at 0,2,0, so it kept
   painting on /services/. Matching its shape settles it. Off-palette anyway:
   the gradient runs teal into violet and the palette has no gradients. */
body.cs-skin .intro__gradient,
body.cs-skin .intro.intro-services .intro__gradient { display: none !important; }

/* --- Hero decoration --------------------------------------------------------
   Two shapes, one accent, both bleeding off an edge, both drawn by cs_shape()
   from /csignal/assets/shapes.php rather than pasted in, so the geometry stays
   in sync with the brand source.

   Three shapes. It was five, matching the homepage, and five was too many
   here: the homepage hangs its set around a card deck that occupies the middle
   of the frame, so there is somewhere for a shape to sit. This hero has copy
   on the left and a card plus a marquee on the right and nothing in between,
   so Spike and Ask ended up floating over the logos and over the lede rather
   than bleeding off anything. Both are gone.

   Store off the right, Leak off the right, the Signal burst off the left, and
   Spike cropped by the testimonial card rather than by a page edge, which is
   the other legitimate crop: it emerges from behind the card instead of
   floating next to it.

   THIS IS THE HOMEPAGE'S SHAPE, same values as .cs-deco--store in
   csignal-hero.css: Store at 820px in #173023, top 90px, right -220px, no
   float. There it sits behind the recommendation deck; here it sits behind
   the testimonial card, which is the same job.

   IT IS NOT CUT OFF AT THE BOTTOM. Two things had to change for that. The
   hero clips on the x axis only, so the shape runs off the right edge and
   continues down past the hero instead of being sliced at its bottom border.
   And .results-strip gives up its background: the section paints after the
   hero, so an opaque background there would have covered the part of the
   shape that runs underneath it and the shape would have looked cut off
   anyway. body.cs-skin is already ink, so a transparent band changes nothing
   except letting the shape through. Exactly what happens behind the logo
   marquee on the homepage.

   1. Ghost. Store at 820px in #173023, running off the right edge and
      continuing below the hero behind the stat cards.

   2. Accents. Leak in blue off the right edge, Spike in coral behind the
      card, the Signal burst in Deep Violet off the left. 64px to 132px:
      punctuation, not furniture.

   Two shapes is the limit for a single composition, so nothing else goes here.
   Neither is rotated: these are cut from a grid, not scattered.

   WHY THESE ARE CHILDREN OF .intro AND NOT OF .container-fluid: the container
   is width-capped and centred, so a shape inside it would stop at the content
   edge instead of running off the page. Anchored to the section, the section
   box is the frame and overflow: clip does the cropping.

   overflow: clip on BOTH axes, and this is the fix for the dark stripe under
   the stat cards. Letting the ghost run past the hero on the y axis does not
   put it behind the sections below, it puts it in front of them: .cs-herodeco
   is positioned, and positioned content paints above in-flow block content
   whatever the source order. So the part hanging below the hero landed on top
   of .featured-projects and read as a slab across the page. Giving each
   following section its own z-index would be an endless game, one section at a
   time, so the shape is contained instead: clipped by the hero on all four
   sides. It bleeds off the right as before and stops cleanly at the fold.

   clip, not hidden. hidden would make .intro a scroll container.

   The accents float on cs-float, the homepage's own keyframe out of
   csignal-hero.css, which this page already loads. Reused rather than
   redeclared: @keyframes resolve by source order, not specificity, so a second
   cs-float here would quietly beat the original everywhere. It carries --rot,
   so a shape's resting angle rides along with the float instead of fighting
   it. Durations and delays are staggered per shape so the group never pulses
   in time. The ghost does not move, exactly as on the homepage.
------------------------------------------------------------------------------*/

body.cs-skin .intro { overflow: clip; }

body.cs-skin .cs-herodeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-herodeco__s { position: absolute; display: block; }
body.cs-skin .cs-herodeco__s svg { display: block; }
body.cs-skin .cs-herodeco__in {
  display: block;
  animation: cs-float 8s ease-in-out infinite;
}

/* Pinned by both edges rather than sized in pixels. The right column starts
   at 3/5 of the inner width, which is about 59% of the section once the
   container's own padding is counted, and the marquee is the full width of
   that column. A left edge at 46% therefore sits outside it at every viewport,
   so the label and the logos are always inside the shape. A fixed 820px could
   only ever be right at one window width, which is why the logos were hanging
   off its left edge.

   SIZED BY HEIGHT, ANCHORED RIGHT. This is the only arrangement that cannot
   be cut off, and it is worth writing down why the others could not work.

   Store is square. The hero is a little over 500px tall and the section is
   nearly 1900px wide, so the distance from the left edge of the marquee (60%,
   where the right column starts) to the right edge of the page is around
   760px, while the hero has barely 450px of height to give. A square shape
   asked to span that width is therefore always about 300px taller than the
   space it lives in, and something has to give: either it overruns the hero,
   or it gets clipped. Driving it from width produced the first, then the
   second, then a slab across .featured-projects when the overrun was allowed
   to escape.

   So height drives it instead. Pinned top and bottom with clearance at each
   end, the shape is always shorter than the hero and can never be cut by it,
   and width follows the square. Anchored to the right, the overhang bleeds off
   that edge, which is the one crop a shape is supposed to have.

   THE TRADE-OFF, stated plainly: the left edge now lands where the height puts
   it, roughly three quarters across, so the first logo or two in the marquee
   sit to the left of the shape rather than on it. Getting both would mean
   letting the shape run down past the hero and behind the stat cards, which is
   possible but needs the two sections below to be given their own stacking
   layers and the results band made transparent again. That is a different
   build, not a tweak to this one.

   2. Accents. Leak off the right edge, the Signal burst off the left. 64px
      and 128px: punctuation, not furniture.

   Two shapes is the limit for a single composition, so nothing else goes here.
   Neither is rotated: these are cut from a grid, not scattered.

   WHY THESE ARE CHILDREN OF .intro AND NOT OF .container-fluid: the container
   is width-capped and centred, so a shape inside it would stop at the content
   edge instead of running off the page. Anchored to the section, the section
   box is the frame and overflow: clip does the cropping.

   overflow: clip on BOTH axes, and this is the fix for the dark stripe under
   the stat cards. Letting the ghost run past the hero on the y axis does not
   put it behind the sections below, it puts it in front of them: .cs-herodeco
   is positioned, and positioned content paints above in-flow block content
   whatever the source order. So the part hanging below the hero landed on top
   of .featured-projects and read as a slab across the page. Giving each
   following section its own z-index would be an endless game, one section at a
   time, so the shape is contained instead: clipped by the hero on all four
   sides. It bleeds off the right as before and stops cleanly at the fold.

   clip, not hidden. hidden would make .intro a scroll container.

   The accents float on cs-float, the homepage's own keyframe out of
   csignal-hero.css, which this page already loads. Reused rather than
   redeclared: @keyframes resolve by source order, not specificity, so a second
   cs-float here would quietly beat the original everywhere. It carries --rot,
   so a shape's resting angle rides along with the float instead of fighting
   it. Durations and delays are staggered per shape so the group never pulses
   in time. The ghost does not move, exactly as on the homepage.
------------------------------------------------------------------------------*/

body.cs-skin .intro { overflow: clip; }

body.cs-skin .cs-herodeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-herodeco__s { position: absolute; display: block; }
body.cs-skin .cs-herodeco__s svg { display: block; }
body.cs-skin .cs-herodeco__in {
  display: block;
  animation: cs-float 8s ease-in-out infinite;
}

/* Pinned by both edges rather than sized in pixels. The right column starts
   at 3/5 of the inner width, which is about 59% of the section once the
   container's own padding is counted, and the marquee is the full width of
   that column. A left edge at 46% therefore sits outside it at every viewport,
   so the label and the logos are always inside the shape. A fixed 820px could
   only ever be right at one window width, which is why the logos were hanging
   off its left edge.

   The left edge sits at 60%, which is where the right hero column begins and
   therefore exactly where the label and the logos start. Aligning the shape to
   the column rather than to a pixel figure means the marquee starts on the
   shape at every window width. Store is square, so width drives height: the
   svg runs at width 100% with height auto and stays in proportion, and the
   hero's clip takes whatever hangs below. */
/* Target: the left edge falls about halfway across the testimonial card, the
   right edge is the only one that crops, and the top and bottom are never cut.

   The card is max-width 480px, right-aligned in its column, so its midpoint
   sits roughly 320px in from the right edge of the section. Store is square,
   so a shape hung off the right edge puts its left edge at width minus
   overhang: 780 - 340 = 440px in, a little past the card's midpoint. Those two
   numbers are the whole control. To resize, move both and keep the difference
   in the 320 to 440 range.

   max-height is the guard: height is whichever is smaller, 560px or the hero
   minus 80px, so on a short hero the shape shrinks rather than being clipped.
   It can never be cut top or bottom. Centred on the hero's midline. */
body.cs-skin .cs-herodeco__s--ghost {
  top: 50%;
  right: -340px;
  width: 780px;
  height: 780px;
  max-height: calc(100% - 40px);
  transform: translateY(-50%);
}

/* The box is sized, the svg fills it. Not width:auto on the svg: this span is
   absolutely positioned with no left, so it is shrink-to-fit, and an svg with
   an auto width inside a shrink-to-fit box resolves to zero. That is what made
   the shape disappear. preserveAspectRatio is on by default, so if the
   max-height cap bites, Store shrinks inside the box and stays square rather
   than stretching. */
body.cs-skin .cs-herodeco__s--ghost svg {
  width: 100%;
  height: 100%;
}

body.cs-skin .cs-herodeco__s--leak { top: 48%;    right: -56px; }
body.cs-skin .cs-herodeco__s--mark { bottom: 26%; left: -24px; }

/* Spike, coming out from behind the top left corner of the testimonial card.
   The card is max-width 480px and right-aligned in its column, so its left
   edge sits a little over 560px in from the right of the section. Anchoring
   the shape at 540 puts most of it behind the card with its stepped corner
   showing past that edge, and the top offset lets it break the card's top
   line. It is behind because .intro .container-fluid carries z-index 1 and the
   decoration sits at 0. */
body.cs-skin .cs-herodeco__s--spike {
  top: 6px;
  right: 490px;
  /* cs-float reads --rot for the resting angle, so the tilt rides with the
     drift rather than being overwritten by it. Inherited down to the animated
     inner span. */
  --rot: 14deg;
}

/* Stillness keeps the resting angles; only the drift stops. */
@media (prefers-reduced-motion: reduce) {
  body.cs-skin .cs-herodeco__in {
    animation: none;
    transform: rotate(var(--rot, 0deg));
  }
}

/* Everything goes below 1280. The hero is a single column there, so the
   accents lose the gutter they sit in and the marquee runs the full width,
   which no shape anchored to the right can contain. */
@media (max-width: 1279px) {
  body.cs-skin .cs-herodeco { display: none; }
}

body.cs-skin .intro .container-fluid { position: relative; z-index: 1; }

/* The H1 is "Our work", an eyebrow sitting above the H2 that does the real
   talking. Same treatment as .cs-eyebrow on the homepage. */
/* --- The eyebrow, one component ---------------------------------------------
   /work/, /services/ and the 31 case studies all open with a small label above
   the headline, and all three were drawing it differently: the first two in
   the body face at 0.14em, the case studies in mono at 0.08em. They are the
   same thing, so they get the same rule, and it is the Metric role from the
   guidelines: mono, uppercase, lime.

   THE SERVICES SELECTOR IS NOT REDUNDANT. services.css styles this element as
   .intro.intro-services .intro__subheading, which is 0,3,0 and outranks a
   plain body.cs-skin h1.intro__subheading at 0,2,1, so the services eyebrow
   kept its Season Serif at clamp(1.125rem, 2vw, 2rem) and ignored everything
   here except the properties services.css does not declare. That is why it
   came out a different size and face from the one on /work/. Matching its
   shape at 0,4,0 is what actually settles it. */

body.cs-skin h1.intro__subheading,
body.cs-skin .intro.intro-services .intro__subheading,
body.cs-skin .case-study-hero__subheading {
  font-family: var(--cs-mono) !important;
  font-size: 12px !important;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--lime) !important;
  /* services.css sets margin-bottom:2rem on the same 0,3,0 selector, so the
     gap belongs to this rule too or the services eyebrow floats off its
     headline while /work/ sits tight. */
  margin-bottom: 0.4rem !important;
}


body.cs-skin .intro__heading { color: var(--on-ink); }

/* --- Hero rhythm -------------------------------------------------------------
   The stack arrived spaced for a 24px lede. Now that the lede is 17px the gaps
   read as holes, so every knob in the column comes down together: the label to
   the headline, the headline to the lede, and the section's own padding top
   and bottom. Nothing moves horizontally and nothing reflows; the fold just
   sits higher. */

/* margin-bottom now lives on the shared eyebrow rule above. */

body.cs-skin .intro__left { gap: 0.75rem; }

@media (min-width: 1280px) {
  body.cs-skin .intro__left { gap: 0.875rem; }
}

body.cs-skin .intro.section {
  padding-top: 1.5rem;
  padding-bottom: 0.5rem;
}

@media (min-width: 1024px) {
  body.cs-skin .intro.section {
    padding-top: 2rem;
    padding-bottom: 0.75rem;
  }
}

/* --- Hero rhythm, second pass -----------------------------------------------
   The gap left under the lede is not padding. Above 1280 the hero is two
   columns, the right one is the taller of the two (card, then the marquee),
   and it sets the row height. The left column is top-aligned inside that row,
   so whatever the right column has spare falls underneath the lede.

   Section padding can only give back what it holds, so the rest comes off the
   right column's own height: the marquee loses its top margin and half its
   label gap, and the card loses a little padding. Roughly 50px off the right
   column is roughly 50px off the gap under the left one. */

body.cs-skin .work-logos {
  margin-top: 0;
  padding-top: 1rem;
}

body.cs-skin .work-logos__label { margin-bottom: 0.75rem; }

body.cs-skin .hero-testimonial { padding: 1.25rem 1.375rem !important; }

/* The left column is bottom-aligned against the taller right column, which
   parks the heading and lede low and opens the gap under them. Top-aligned,
   the two columns start together and the slack falls to the bottom of the
   section where the padding above already accounts for it. */
body.cs-skin .intro__inner { align-items: start; }

/* And the band below closes up by the same amount. */
body.cs-skin .results-strip { padding-top: 0; padding-bottom: 2.5rem; }

@media (min-width: 1024px) {
  body.cs-skin .results-strip { padding-bottom: 3rem; }
}
/* our-work.css sets this at clamp(18px, 2vw, 24px), which is a second headline
   rather than a lede. The display line is doing the shouting; this reads. */
body.cs-skin .intro__description {
  color: var(--on-ink-muted);
  font-size: clamp(15px, 1.2vw, 17px);
  line-height: 1.6;
  max-width: 62ch;
}

/* The 111SKIN card.
   ----------------------------------------------------------------------------
   It arrived as a translucent grey panel with a hairline, which is the generic
   glass card every site has and the one thing the palette rules forbid: flat
   and saturated, no gradients, nothing translucent.

   It is now the same object as .cs-reco on /csignal/ and in the homepage hero
   deck: a paper card on ink, 22px radius, the quote carrying the Heading role
   in the display face and the attribution carrying the Metric role in mono.
   Surface, radius and text colour live in style attributes and are set in the
   copy; the faces have to be set here because the sweep in section 1 is
   !important and nothing inline can beat it. */
body.cs-skin .hero-testimonial p {
  font-family: var(--cs-display) !important;
}

body.cs-skin .hero-testimonial span {
  font-family: var(--cs-mono) !important;
}

/* A thicker lime edge on hover, drawn as a ring rather than a fatter border.
   Growing border-width would change the box and shift the card's contents by a
   pixel or two; a box-shadow spread sits outside the box and costs no layout.
   1px border plus a 2px ring reads as a 3px edge. */
body.cs-skin .hero-testimonial {
  transition: border-color 0.2s ease, box-shadow 0.2s ease !important;
}

body.cs-skin .hero-testimonial:hover {
  border-color: var(--lime) !important;
  box-shadow: 0 0 0 3px var(--lime);
}

/* The ring was being sliced down its right side. .intro__right carries
   overflow: hidden, the card is margin-left: auto so its right edge sits flush
   against that column's edge, and a box-shadow spread is overflow like any
   other. The marquee below already clips itself twice over, on .work-logos and
   again on .work-logos__track-wrap, so this column does not need to. */
body.cs-skin .intro__right { overflow: visible; }

body.cs-skin .hero-testimonial img { border-radius: 50%; }

body.cs-skin .work-logos__label {
  font-family: var(--cs-mono) !important;
  color: var(--on-ink-muted);
}

/*------------------------------------------------------------------------------
  16. Work: results strip
  Four counters. Display face and lime for the numbers, the Metric role for
  the labels under them.
------------------------------------------------------------------------------*/

/* Ink, and positioned.
   ----------------------------------------------------------------------------
   This band was briefly transparent so the Store could run down behind it. It
   could not: .cs-herodeco is a positioned element, and positioned content
   paints above in-flow block content whatever the source order, so the shape
   came down OVER the stat cards and clipped the fourth one. Opaque again, with
   its own stacking layer, so nothing from the hero can reach it. The Store now
   ends cleanly at the fold instead. */
body.cs-skin .results-strip {
  background-color: var(--ink);
  color: var(--on-ink);
  position: relative;
  z-index: 1;
}

body.cs-skin .results-strip__stat-number {
  font-family: var(--cs-display) !important;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--ink);
  /* The page sets this at 2.5rem rising to 3rem, sized for a full-width row.
     A quarter of half a band is about 165px, and "£300m+" at 3rem overflows
     it. This is the homepage's own step, which tops out at 1.75rem, nudged up
     because these are the page's headline numbers rather than a footnote. */
  font-size: clamp(1.5rem, 2.2vw, 2rem);
}

body.cs-skin .results-strip__stat-label {
  font-family: var(--cs-mono) !important;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-paper-muted);
  margin: 0.6rem 0 0;
}

/* --- The stats as cards ------------------------------------------------------
   The same component and the same 12s cycle as .about-charle__stat on the
   homepage: one card lit at a time, three seconds each, negative delays of
   0s / -9s / -6s / -3s so nothing is lit twice and nothing is all-lit on load,
   and the flick between states is 1.5% of the loop rather than a fade.

   The colours are the homepage's, with one hex nudged. There it runs
   #EDF0E6 -> #0E1C16, but #0E1C16 is exactly the colour of this section, so a
   lit card would vanish into the band and read as a gap in the row. The lit
   state is #1B3226 instead: still ink, still clearly the dark card, but a
   shade raised off the ground it sits on.

   New keyframe names. @keyframes resolve by source order, not specificity, so
   cs-stat-bg and friends must not be redeclared.

   The page's own block sets this row to flex at 768 and grid at mobile. Cards
   want equal widths, so it is a grid at every width here. */

body.cs-skin .results-strip__stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

@media (min-width: 768px) {
  body.cs-skin .results-strip__stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
  }
}

/* Half the band, not all of it. On the homepage this row lives inside
   .about-charle__left, which is 3 of 5 grid columns, so the cards are narrow
   and sit against the left edge with the section breathing to their right.
   Same proportion here: the row is capped at half and the Explore Services
   button keeps the right. */
@media (min-width: 1024px) {
  body.cs-skin .results-strip__stats {
    flex: 0 1 50%;
    max-width: 50%;
  }
}

body.cs-skin .results-strip__stat {
  background: #EDF0E6;
  border-radius: 14px;
  padding: 18px 16px 16px;
  animation: cs-wstat-bg 12s linear infinite;
  animation-delay: var(--d, 0s);
}

body.cs-skin .results-strip__stat:nth-child(1) { --d: 0s; }
body.cs-skin .results-strip__stat:nth-child(2) { --d: -9s; }
body.cs-skin .results-strip__stat:nth-child(3) { --d: -6s; }
body.cs-skin .results-strip__stat:nth-child(4) { --d: -3s; }

body.cs-skin .results-strip__stat .results-strip__stat-number {
  animation: cs-wstat-num 12s linear infinite;
  animation-delay: var(--d, 0s);
}

body.cs-skin .results-strip__stat .results-strip__stat-label {
  animation: cs-wstat-lbl 12s linear infinite;
  animation-delay: var(--d, 0s);
}

@keyframes cs-wstat-bg {
  0%, 25%      { background: #1B3226; }
  26.5%, 98.5% { background: #EDF0E6; }
  100%         { background: #1B3226; }
}

@keyframes cs-wstat-num {
  0%, 25%      { color: #D3F502; }
  26.5%, 98.5% { color: #0E1C16; }
  100%         { color: #D3F502; }
}

@keyframes cs-wstat-lbl {
  0%, 25%      { color: rgba(243, 245, 238, 0.62); }
  26.5%, 98.5% { color: rgba(14, 28, 22, 0.62); }
  100%         { color: rgba(243, 245, 238, 0.62); }
}

/* Hover takeover, as on the homepage. !important is load-bearing: a running
   animation outranks normal author declarations, and !important is the one
   level that beats it even while paused. The hovered card is written as a
   descendant of the hovered row so it reaches 0,4,0 and outranks the
   quieten-everything rule at 0,3,0. */
body.cs-skin .results-strip__stat,
body.cs-skin .results-strip__stat-number,
body.cs-skin .results-strip__stat-label {
  transition: background 0.18s ease-out, color 0.18s ease-out;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat {
  animation-play-state: paused;
  background: #EDF0E6 !important;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat-number {
  animation-play-state: paused;
  color: #0E1C16 !important;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat-label {
  animation-play-state: paused;
  color: rgba(14, 28, 22, 0.62) !important;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat:hover {
  background: #1B3226 !important;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat:hover .results-strip__stat-number {
  color: #D3F502 !important;
}

body.cs-skin .results-strip__stats:hover .results-strip__stat:hover .results-strip__stat-label {
  color: rgba(243, 245, 238, 0.62) !important;
}

/* Stillness: card three stays lit, as on the homepage. */
@media (prefers-reduced-motion: reduce) {
  body.cs-skin .results-strip__stat,
  body.cs-skin .results-strip__stat-number,
  body.cs-skin .results-strip__stat-label { animation: none; }

  body.cs-skin .results-strip__stat-number { color: var(--ink); }
  body.cs-skin .results-strip__stat-label { color: var(--on-paper-muted); }
  body.cs-skin .results-strip__stat:nth-child(3) { background: #1B3226; }
  body.cs-skin .results-strip__stat:nth-child(3) .results-strip__stat-number { color: var(--lime); }
  body.cs-skin .results-strip__stat:nth-child(3) .results-strip__stat-label { color: rgba(243, 245, 238, 0.62); }
}

/* This one is white-on-black in the page's own block. */
body.cs-skin .results-strip .btn-black {
  background: var(--lime);
  color: var(--ink);
}

body.cs-skin .results-strip .btn-white:hover,
body.cs-skin .results-strip .btn-black:hover { background: #E2FF3A; color: var(--ink); }

/*------------------------------------------------------------------------------
  17. Work: project cards, and the stat pill as a CSignal chip
  ----------------------------------------------------------------------------
  Every card already carries a number with its metric attached, which is the
  product's own grammar. Rendering them as the recommendation chip from
  /csignal/ is the single most on-brand change on this page.
------------------------------------------------------------------------------*/

body.cs-skin .work-list.section,
body.cs-skin .featured-projects { background-color: var(--ink); }

body.cs-skin .project__stat-pill,
body.cs-skin .featured-project__stat,
body.cs-skin .featured-project__pill {
  /* Ink chip, lime number, which is how .cs-reco__conf works on /csignal/: a
     chip in a tint with the value coloured, not a solid block of accent.
     Solid lime was wrong on two counts. There are 22 of these on screen at
     once, and a highlighter that marks everything marks nothing, so lime lost
     its scarcity. And they sit on photography we do not control, where lime
     against the red Candy Kittens and Billionaire Boys Club shots clashed
     badly. Ink is legible on any image, and the value is set in paper rather
     than lime so the chip stays quiet: lime is now spent only on the headline
     highlight and the stat cards, where it has something to mark. */
  background: var(--ink);
  color: var(--paper);
  /* The frosted grey pill goes: the chip is a flat colour, per the palette
     rule that there are no gradients and nothing translucent. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  font-family: var(--cs-mono) !important;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
}

/* Paper band, not ink. --on-ink resolves to paper, so the link was paper on
   paper and the title disappeared. */
body.cs-skin .project__title a { color: var(--on-paper); }

/* index.css sets the title at 18px/500 and the meta line at 15px. Three points
   apart at the same weight is not a hierarchy, and 500 on the display face
   reads as a body string rather than a card title. The title takes the weight
   the display face is drawn for, the meta line drops and goes to the metric
   role, and the gap tightens so the two read as one block. */
body.cs-skin .project__title {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
}

body.cs-skin .project__type {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.25;
}

body.cs-skin .project__text { gap: 0.3rem; }

/* --- .project belongs to TWO components -------------------------------------
   The homepage carousel (.projects) sits on a paper band and the work grid
   (.work-list) sits on ink, and both use these same class names. The rules
   above are written for paper, which is right for the carousel and turns the
   19 titles on this page into paper on ink, invisible. Everything colour
   related for the work grid is therefore scoped under .work-list, which
   outranks the unscoped rules without touching them.

   If a third component ever picks up .project, scope it the same way rather
   than editing the shared rules. */

body.cs-skin .work-list .project__title,
body.cs-skin .work-list .project__title a { color: var(--on-ink); }

body.cs-skin .work-list .project__title a:hover { color: var(--lime); }

body.cs-skin .work-list .project__type { color: var(--on-ink-muted); }

body.cs-skin .work-list .project__thumbnail {
  background: var(--ink-2);
  border: 1px solid var(--line-on-ink);
}
body.cs-skin .project__title a:hover { color: var(--lime); }
body.cs-skin .project__type { color: var(--on-paper-muted); }

/* Was #f8f8f8, which reads as a hole punched in the ink. Same trap as the
   RNLI logo in the homepage marquee: give the box a surface, not a knockout. */
body.cs-skin .project__thumbnail {
  background: var(--paper-2);
  border: 0;
}

body.cs-skin .featured-project__overlay {
  background: linear-gradient(to top, rgba(14, 28, 22, 0.92) 0%, rgba(14, 28, 22, 0) 100%);
}

body.cs-skin .featured-project__name { color: var(--on-ink); }
body.cs-skin .featured-project__type { color: var(--on-ink-muted); }

/* Explore Services moved out of the results band and into the head of the
   featured row, sitting top right above the third card. The page's own block
   still styles .results-strip__cta as a column that becomes a row at 768, so
   all this needs is the right alignment and a little air under it. The button
   keeps its colours from its style attribute, which is why nothing here
   restates them. */
body.cs-skin .featured-projects .results-strip__cta {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 0.75rem;
}

/* Explore Services hovers exactly like .cs-btn--outline on /csignal/ and the
   homepage: the hairline and the label both go lime, the fill stays empty.
   !important throughout because the button's resting colours live in a style
   attribute, and inline beats a normal author rule at any specificity. */
body.cs-skin .featured-projects .results-strip__cta .btn {
  transition: color 0.12s ease-out, border-color 0.12s ease-out !important;
}

body.cs-skin .featured-projects .results-strip__cta .btn:hover {
  background: transparent !important;
  border-color: var(--lime) !important;
  color: var(--lime) !important;
}

/* The featured row was starting a long way down the page. Three things were
   stacked on top of each other: 3rem under the results band, 3rem of padding
   on top of this section, and the CTA's own margin. All three come down and
   the row lifts by about 90px. The bottom padding is untouched, so the spacing
   into the grid below is unchanged. */
body.cs-skin .featured-projects { padding-top: 1rem; }

@media (min-width: 1024px) {
  body.cs-skin .featured-projects { padding-top: 1.25rem; }
}

body.cs-skin .results-strip { padding-bottom: 1.5rem; }

@media (min-width: 1024px) {
  body.cs-skin .results-strip { padding-bottom: 1.75rem; }
}

/* --- Two shapes behind the featured row --------------------------------------
   Medium, and cropped by the outer two thumbnails rather than by a page edge,
   which is the same crop the Spike uses behind the testimonial card. Violet
   poking left from behind Cambridge Satchel, coral poking right from behind
   Billionaire Boys Club. They sit in the gutters, so nothing lands on an image.

   The grid needs its own stacking layer. The decoration is positioned and the
   cards are not, and positioned content paints above in-flow content whatever
   the source order, so without this the shapes would sit ON the thumbnails
   instead of behind them. Same trap that put a slab over this section earlier.

   overflow: clip keeps them inside the section: they are anchored near its
   edges and must not reappear over the rows above or below. */

body.cs-skin .featured-projects {
  position: relative;
  overflow: clip;
}

body.cs-skin .featured-projects__grid {
  position: relative;
  z-index: 1;
}

body.cs-skin .cs-fpdeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-fpdeco__s { position: absolute; display: block; }
body.cs-skin .cs-fpdeco__s svg { display: block; }

body.cs-skin .cs-fpdeco__s--l { left: 8px;  bottom: 96px; }
body.cs-skin .cs-fpdeco__s--r { right: 8px; bottom: 210px; }

/* The gutters they sit in only exist at desktop widths. */
@media (max-width: 1279px) {
  body.cs-skin .cs-fpdeco { display: none; }
}

/* --- Small shapes behind the project grids -----------------------------------
   Six in total, three per grid, 82px to 122px.

   BUILT FOR A GRID THAT MOVES. The industry filters hide and show cards and
   clone the featured projects in and out, so the grid reflows and the section
   changes height on every click. Nothing here is attached to a card or to a
   card's position. Each shape is anchored to the SECTION: left or right edge in
   px so it always sits in the gutter, and a PERCENTAGE down the section so it
   keeps its place proportionally when the section gets shorter or taller. The
   decoration also lives outside .container, and the filter script only ever
   touches .work-list__inner and its children, so it cannot be reordered,
   cloned or removed by a filter.

   The grid takes its own stacking layer for the usual reason: the shapes are
   positioned and the cards are not, so without it they would paint on top of
   the thumbnails. overflow: clip keeps them inside their own section however
   short a filter makes it. */

body.cs-skin .work-list.section {
  position: relative;
  overflow: clip;
}

body.cs-skin .work-list__inner {
  position: relative;
  z-index: 1;
}

body.cs-skin .cs-wldeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-wldeco__s { position: absolute; display: block; }
body.cs-skin .cs-wldeco__s svg { display: block; }

/* Pulled in off the section edge: at left:6px the leak was being sliced by
   the section's overflow-x clip, so only a squared-off block showed and the
   notch that makes it a leak was lost. */
body.cs-skin .cs-wldeco__s--a { left: 34px; top: 20%; }
body.cs-skin .cs-wldeco__s--b { right: 10px; top: 44%; }
body.cs-skin .cs-wldeco__s--c { left: 4px;  bottom: 20%; }

body.cs-skin .cs-wldeco__s--d { right: 8px; top: 22%; }
body.cs-skin .cs-wldeco__s--e { left: 6px;  top: 55%; }
body.cs-skin .cs-wldeco__s--f { right: 6px; bottom: 16%; }

/* No gutters to hide in below 1280. */
@media (max-width: 1279px) {
  body.cs-skin .cs-wldeco { display: none; }
}

body.cs-skin .see-more-cta { background-color: var(--ink); }
body.cs-skin .see-more-cta__link { color: var(--on-ink-muted); }
body.cs-skin .see-more-cta__link:hover { color: var(--lime); }

/*------------------------------------------------------------------------------
  18. Work: industry filters and the team CTA
  The two light bands on the page. Paper, not white.
------------------------------------------------------------------------------*/

body.cs-skin .industry-filters { background-color: var(--paper); }

body.cs-skin .industry-filters__subheading {
  font-family: var(--cs-mono) !important;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-paper-muted);
}

body.cs-skin .industry-filters__heading { color: var(--on-paper); }

body.cs-skin .industry-filters__link {
  font-family: var(--cs-body) !important;
  border-color: var(--line-on-paper);
  color: var(--on-paper);
}

/* Lime on paper is close to invisible, so the active chip stays ink and lime
   does the hover. Same call as the light sections in section 4. */
body.cs-skin .industry-filters__link:hover {
  background: transparent;
  color: var(--on-paper);
  border-color: var(--ink);
}

body.cs-skin .industry-filters__link.active {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

body.cs-skin .team-cta { background-color: var(--paper-2); }

body.cs-skin .team-cta__subtitle {
  font-family: var(--cs-mono) !important;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-paper-muted);
}

body.cs-skin .team-cta__heading { color: var(--on-paper); }
body.cs-skin .team-cta__description { color: var(--on-paper-muted); }
body.cs-skin .team-cta__image img { border-radius: 14px; }

/* testimonial.php and experts.php are shared includes and cannot be edited,
   so both are handled from here. The experts button keeps its arrow in the
   markup; hiding it and reclaiming the 3rem style.css reserves for it is the
   same result as stripping it from a page we own. */
body.cs-skin .testimonial { background-color: var(--ink); }
body.cs-skin .testimonial__heading { color: var(--on-ink); }
/*------------------------------------------------------------------------------
  19. The stepped edge
  ----------------------------------------------------------------------------
  Two flat colours meeting on an irregular cut seam. The guidelines call it the
  one deliberate act of resistance in the system and it exists nowhere else on
  the site yet.

  Drawn as a ::before on the LOWER section, filled with the colour of the
  section above, rather than by clipping a section: clipping a section would
  cut its content too. Steps are 11% to 17% wide and run across five depths,
  because regular steps read as a graphic pattern and irregular steps read as
  something torn.

  Twice on the page, no more, per the rule. Both seams sit where ink meets
  paper; a seam between two ink sections would be invisible.
------------------------------------------------------------------------------*/

body.cs-skin .industry-filters,
body.cs-skin #grid-bottom { position: relative; }

body.cs-skin .industry-filters::before,
body.cs-skin #grid-bottom::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 34px;
  pointer-events: none;
  z-index: 1;
}

/* Ink above, paper below. */
body.cs-skin .industry-filters::before {
  background: var(--ink);
  clip-path: polygon(
    0 0, 100% 0,
    100% 41%, 88% 41%, 88% 74%, 72% 74%, 72% 23%,
    61% 23%, 61% 62%, 45% 62%, 45% 100%, 32% 100%,
    32% 47%, 17% 47%, 17% 81%, 0 81%
  );
}

/* Paper-2 above, ink below. A different cut, or the two seams read as a
   repeat rather than as two tears. */
body.cs-skin #grid-bottom::before {
  background: var(--paper-2);
  clip-path: polygon(
    0 0, 100% 0,
    100% 68%, 85% 68%, 85% 29%, 73% 29%, 73% 84%,
    57% 84%, 57% 38%, 46% 38%, 46% 96%, 30% 96%,
    30% 52%, 19% 52%, 19% 26%, 0 26%
  );
}

/*------------------------------------------------------------------------------
  21. Case studies
  ----------------------------------------------------------------------------
  One section for all 31 pages under /work/<slug>/. They share case-study.css
  and carry no inline styles, no style attributes and no Season declarations of
  their own, so everything is done here and each page's v2.php only differs in
  its head.

  The page is already black on white text. What changes is ink instead of
  black, the type roles, the brief list as chips, the quote as the paper card,
  and decoration in the hero.
------------------------------------------------------------------------------*/

body.cs-skin.case-study-page,
body.cs-skin .case-study-hero,
body.cs-skin .case-study-brief,
body.cs-skin .case-study-text,
body.cs-skin .case-study-images,
body.cs-skin .case-study-image,
body.cs-skin .case-study-image-grid,
body.cs-skin .case-study-quote { background-color: var(--ink); }

/* --- Hero -------------------------------------------------------------------
   The eyebrow above the H1 takes the Metric role, the same treatment the
   "OUR WORK" label gets on the index. */
/* The two teal-into-violet blurs go. case-study.css paints them as ::before
   and ::after on the hero, and they are off-palette on both counts: the
   palette is flat and saturated with no gradients at all, and neither colour
   is in it. The Store ghost and the two accents do that job now. */
body.cs-skin .case-study-hero::before,
body.cs-skin .case-study-hero::after { display: none; }

body.cs-skin .case-study-hero { position: relative; overflow: clip; }
body.cs-skin .case-study-hero > .container { position: relative; z-index: 1; }

body.cs-skin .case-study-hero__subheading {
  font-family: var(--cs-mono) !important;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lime);
}

body.cs-skin .case-study-hero__heading {
  color: var(--on-ink);
  letter-spacing: -0.03em;
  line-height: 0.98;
}

body.cs-skin .case-study-hero__description { color: var(--on-ink-muted); }

/* Same construction as the hero on the index: sized by height so it can never
   be cut top or bottom, anchored right so the only crop is the bleed. */
body.cs-skin .cs-csdeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-csdeco__s { position: absolute; display: block; }
body.cs-skin .cs-csdeco__s svg { display: block; }

body.cs-skin .cs-csdeco__s--ghost {
  top: 50%;
  right: -260px;
  width: 620px;
  height: 620px;
  max-height: calc(100% - 40px);
  transform: translateY(-50%);
}

body.cs-skin .cs-csdeco__s--ghost svg { width: 100%; height: 100%; }

body.cs-skin .cs-csdeco__s--a { top: 14%;    left: -46px; }
body.cs-skin .cs-csdeco__s--b { bottom: 20%; right: 1%; }

/* Coral, cropped by the right edge of the screen. The ghost sits inside the
   frame on that side, so this is the one shape that actually runs off it. */
body.cs-skin .cs-csdeco__s--c { top: 34%; right: -56px; }

/* Spark, on the headline's shoulder.
   ----------------------------------------------------------------------------
   It was a free-floating shape in the decoration layer, positioned as a
   percentage of the section. That could not work: the hero section contains
   the full-bleed image as well as the copy, so it is several times taller than
   the text block, and any percentage lands somewhere unrelated to the words.
   The heading is also centred, so where its first line starts depends on the
   title's length and differs on all 31 pages.

   So the mark goes INSIDE the h1, as an inline-block before the text. It then
   travels with the heading at every width and on every title, and the centring
   accounts for it. aria-hidden and no text content, so the heading still reads
   exactly as it did to a screen reader and to Google. */
body.cs-skin .cs-h1spark {
  display: inline-block;
  vertical-align: 0.42em;
  margin-right: 0.3em;
  line-height: 0;
}

body.cs-skin .cs-h1spark svg { display: block; }

@media (max-width: 767px) {
  body.cs-skin .cs-h1spark { display: none; }
}

@media (max-width: 1279px) {
  body.cs-skin .cs-csdeco { display: none; }
}

/* --- Brief ------------------------------------------------------------------
   The strongest CSignal moment on the page. Industry, Project and Technology
   are a specification, and a specification set in 18px prose reads as a
   paragraph. As chips it reads as data, which is what it is. */

body.cs-skin .case-study-brief__heading { color: var(--on-ink); letter-spacing: -0.03em; }
body.cs-skin .case-study-brief__description { color: var(--on-ink-muted); }

/* h4, so the display face is asserted on it with !important by the sweep in
   section 1. Switching a heading to the mono role needs !important back. */
/* --- The spec panel ---------------------------------------------------------
   Rebuilt for density. It was running to nearly 1400px for eleven short
   strings: an 11px label, then a 1.5rem flex gap, then case-study.css's own
   margins on the subheading and on list-to-subheading, then 18px values with
   loose leading. Four different spacing rules stacked between every pair of
   lines.

   One rule now owns each gap. The flex gap goes to zero and the groups carry
   their own bottom margin, so label-to-value is 6px, line-to-line is the
   leading, and group-to-group is 22px with a hairline to mark it. The label
   drops to 10px and the values to 14px, which is where they should have been:
   this is a spec list beside the prose, not a second column of body copy. */

/* --- Shapes behind the spec panel -------------------------------------------
   z-index: -1 on its own did not work, and the reason is worth writing down.
   A negative z-index child drops to the back of the nearest STACKING CONTEXT,
   not to the back of its parent. .case-study-brief__right opened no context,
   so the shapes fell all the way behind the section's own ink background and
   vanished completely.

   So the panel opens a context with isolation: isolate, and gives up its
   background to a pseudo-element. Inside that context the order is:
     -2  the shapes
     -1  the paper card, drawn by ::before
      0  the text, in flow above both
   Both layers are negative, which keeps them under the in-flow copy; a
   positioned z-index 0 background would have painted OVER the text instead.
   Nothing clips, so the part of each shape beyond the card's edge shows. */

body.cs-skin .cs-briefdeco {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
}

body.cs-skin .cs-briefdeco__s { position: absolute; display: block; }
body.cs-skin .cs-briefdeco__s svg { display: block; }

body.cs-skin .cs-briefdeco__s--l { top: 14%;    left: -58px; }
body.cs-skin .cs-briefdeco__s--r { bottom: 16%; right: -52px; }
body.cs-skin .cs-briefdeco__s--t { top: -46px;  right: 24%; }
/* Tucked into the bottom left corner and turned onto the diagonal. It was
   centred under the card and hanging straight down, where the Signal burst's
   tapered point reads as something other than a logo. Cornered and angled, it
   reads as a mark coming out from behind the card. The rotation is overridden
   here rather than in 31 pages of inline markup. */
body.cs-skin .cs-briefdeco__s--b { bottom: 4px; left: -62px; }
body.cs-skin .cs-briefdeco__s--b .cs-herodeco__in { --rot: 46deg; }

@media (max-width: 1023px) {
  body.cs-skin .cs-briefdeco { display: none; }
}

/* --- The brief grid ---------------------------------------------------------
   case-study.css lays this out as six equal columns with a 5rem gutter, so the
   panel is a strict fraction of the row and keeps shrinking with the viewport.
   Between about 1024 and 1400 it narrows to the point where single terms wrap
   onto two lines, which is what makes a spec list look broken.

   Auto columns with a floor instead: the prose takes what is left and the
   panel is held between 300px and 360px, which fits the longest term on this
   template on one line. The gutter comes down to 3rem where the room is
   tightest and goes back to 5rem once there is space for it. */

@media (min-width: 1024px) {
  body.cs-skin .case-study-brief__inner {
    grid-template-columns: minmax(0, 1fr) clamp(300px, 26vw, 360px);
    gap: 3rem;
  }

  body.cs-skin .case-study-brief__left,
  body.cs-skin .case-study-brief__right { grid-column: auto; }
}

@media (min-width: 1440px) {
  body.cs-skin .case-study-brief__inner { gap: 5rem; }
}

body.cs-skin .case-study-brief__right {
  /* Paper, not a dark panel. It was #1A1B1E out of case-study.css, a neutral
     near-black that belongs to no palette and read as grey against the green
     ground. A paper card on ink is the system's own object: the same one the
     111SKIN card, the quote and .cs-reco on /csignal/ all use, and it gives
     the spec list the contrast it was missing. */
  background: transparent;
  border-radius: 20px;
  gap: 0;
  padding: 26px 24px;
  position: relative;
  isolation: isolate;
}

/* The card itself. A pseudo-element rather than the panel's background, so the
   shapes have a layer to sit under. */
body.cs-skin .case-study-brief__right::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper);
  border-radius: 20px;
}

body.cs-skin .case-study-brief__subheading {
  font-family: var(--cs-mono) !important;
  font-size: 10px !important;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #55665C;
  margin: 0 0 6px;
}

body.cs-skin .case-study-brief__list {
  list-style: none;
  padding: 0;
  margin: 0 0 22px;
}

body.cs-skin .case-study-brief__list:last-child { margin-bottom: 0; }

/* case-study.css adds its own top margin here at 0,2,0. */
body.cs-skin .case-study-brief__list + .case-study-brief__subheading {
  margin-top: 0;
  padding-top: 22px;
  border-top: 1px solid rgba(14, 28, 22, 0.12);
}

body.cs-skin .case-study-brief__list-item {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}

body.cs-skin .case-study-brief__list-item a {
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  box-shadow: inset 0 -2px 0 var(--lime);
  transition: background 0.12s ease-out, box-shadow 0.12s ease-out;
}

/* Lime as a text colour on paper is close to invisible, so the link fills
   instead of recolouring. Same flip the legal pages use. */
body.cs-skin .case-study-brief__list-item a:hover {
  background: var(--lime);
  box-shadow: inset 0 -0.35em 0 var(--lime), 0 0 0 3px var(--lime);
}



/* --- Body copy --------------------------------------------------------------
   Links inside the prose take the same underline-to-fill flip the legal pages
   use, which is the only lime in the running text. */

body.cs-skin .case-study-text__heading { color: var(--on-ink); letter-spacing: -0.03em; }
body.cs-skin .case-study-text__description { color: var(--on-ink-muted); }

body.cs-skin .case-study-text__description a {
  color: var(--on-ink);
  font-weight: 600;
  text-decoration: none;
  box-shadow: inset 0 -2px 0 var(--lime);
  transition: color 0.12s ease-out, box-shadow 0.12s ease-out;
}

body.cs-skin .case-study-text__description a:hover {
  color: var(--lime);
  box-shadow: inset 0 -2px 0 transparent;
}

/* --- Imagery ----------------------------------------------------------------
   14px, the same radius the feature blocks use in section 8. */
/* One radius, on the container, which clips. case-study.css already rounds
   .case-study-image__image (20px, 50px above 1024) and rounding the img as
   well left the container's larger corner showing as a dark crescent behind
   each one. The img goes square and the box does the clipping. */
body.cs-skin .case-study-image__image,
body.cs-skin .case-study-images__image {
  border-radius: 14px;
  overflow: hidden;
}

body.cs-skin .case-study-image__image img,
body.cs-skin .case-study-images__image img,
body.cs-skin .case-study-image-grid img { border-radius: 0; }

/* --- Quote ------------------------------------------------------------------
   Five of the 31 carry one. It becomes the same object as the 111SKIN card on
   the index and .cs-reco on /csignal/: a paper card on ink, the quote in the
   display face, the attribution in the Metric role. */

body.cs-skin .case-study-quote__inner {
  background: var(--paper);
  border-radius: 22px;
  padding: clamp(24px, 3vw, 44px);
}

body.cs-skin .case-study-quote__quote-text {
  font-family: var(--cs-display) !important;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.12;
  color: var(--ink);
}

body.cs-skin .case-study-quote__quote-author {
  font-family: var(--cs-mono) !important;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #55665C;
}

body.cs-skin .case-study-quote__quote-author-title {
  font-family: var(--cs-mono) !important;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8FA096;
}

/* No stepped edge here. The index carries two, and the seam needs two flat
   colours meeting across a full-bleed join to read as a tear; inside a padded
   section it was just decoration. */


/* --- Shapes through the body ------------------------------------------------
   One per .case-study-text section, cycled through four variants so no two in
   a row repeat a shape, a colour, an angle or a side. Same sizes as the hero,
   122px to 140px.

   Anchored to the section and bleeding off the page edge, never sitting inside
   the measure. The container takes its own stacking layer because the
   decoration is positioned and the copy is not; overflow-x: clip crops the
   bleed without turning the section into a scroll container or slicing the
   shape top and bottom. */

body.cs-skin .case-study-text {
  position: relative;
  overflow-x: clip;
}

body.cs-skin .case-study-text > .container { position: relative; z-index: 1; }

body.cs-skin .cs-txdeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-txdeco__s { position: absolute; display: block; }
body.cs-skin .cs-txdeco__s svg { display: block; }

body.cs-skin .cs-txdeco--a .cs-txdeco__s { top: 18%;    left: -48px; }
body.cs-skin .cs-txdeco--b .cs-txdeco__s { bottom: 20%; right: -40px; }
body.cs-skin .cs-txdeco--c .cs-txdeco__s { top: 30%;    right: -52px; }
body.cs-skin .cs-txdeco--d .cs-txdeco__s { bottom: 14%; left: -44px; }

@media (max-width: 1023px) {
  body.cs-skin .cs-txdeco { display: none; }
}


/* --- Result cards -----------------------------------------------------------
   Eight of the 31 carry a .case-study-stats band. The cards were #1a1b1e, the
   same neutral near-black the spec panel used, with white numbers. They are
   paper now with ink numbers: the same object as the spec panel, the quote and
   the 111SKIN card, and the one place on these pages where a hard number is
   the subject.

   Each card gets a shape behind it, cycled through four so no two in a row
   repeat. Same stacking trick as the spec panel: the card opens a context with
   isolation, gives up its background to a pseudo-element at -1, and the shape
   sits at -2 under it. A plain negative z-index would drop the shape behind
   the section's own background and it would never be seen. */

body.cs-skin .case-study-stats { background-color: var(--ink); }

body.cs-skin .case-study-stats__heading,
body.cs-skin .case-study-stats__subheading { color: var(--on-ink); }

body.cs-skin .case-study-stats__item {
  background-color: transparent;
  border-radius: 20px;
  position: relative;
  isolation: isolate;
  overflow: visible;
}

body.cs-skin .case-study-stats__item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper);
  border-radius: 20px;
}

body.cs-skin .case-study-stats__item-title { color: #55665C; }

body.cs-skin .case-study-stats__item-value {
  font-family: var(--cs-display) !important;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--ink);
}

body.cs-skin .cs-stdeco {
  position: absolute;
  display: block;
  z-index: -2;
  pointer-events: none;
}

body.cs-skin .cs-stdeco svg { display: block; }

body.cs-skin .cs-stdeco--a { top: -38px;    right: 12%; }
body.cs-skin .cs-stdeco--b { bottom: -34px; left: 14%; }
body.cs-skin .cs-stdeco--c { top: 18%;      right: -44px; }
body.cs-skin .cs-stdeco--d { bottom: 12%;   left: -40px; }

@media (max-width: 1023px) {
  body.cs-skin .cs-stdeco { display: none; }
}


/* --- Services intro ---------------------------------------------------------
   The right column (the Shopify partner lockup and the standfirst) sat a long
   way down: services.css gives .intro-services 9rem of section padding and a
   1.5rem column gap, and the column is top-aligned against a much taller left
   column. Padding comes down to match the rest of the v2 pages and the column
   starts at the top of the row rather than drifting. */

body.cs-skin .intro.intro-services {
  padding-top: 2rem;
  padding-bottom: 2rem;
}

body.cs-skin .intro.intro-services .intro__inner { align-items: start; }

body.cs-skin .intro.intro-services .intro__right {
  gap: 1.25rem;
  margin-top: 0;
}

body.cs-skin .intro.intro-services .intro__description { margin-top: 0; }

/* --- Hairline off the section image -----------------------------------------
   .image__inner picks up a border from the ink-on-ink rules further up, and on
   a full-bleed photograph a 1px olive edge reads as a rendering artefact
   rather than a frame. */
body.cs-skin .image__inner,
body.cs-skin .image__image,
body.cs-skin .image__inner img { border: 0 !important; box-shadow: none !important; }


/* --- Under the people band --------------------------------------------------
   style.css pads .people heavily at the bottom and the section that follows
   pads again at the top, so the two stack into a hole with nothing in it. Both
   come down; nothing else about either section moves. */

body.cs-skin .people { padding-bottom: 3rem; }

@media (min-width: 1024px) {
  body.cs-skin .people { padding-bottom: 4.5rem; }
}

body.cs-skin .people + .section,
body.cs-skin .people + section { padding-top: 3.5rem; }


/* --- The eyebrow above a section heading ------------------------------------
   .partners__subtitle and its siblings carry a large bottom margin from
   style.css, which on a light band leaves the label stranded a long way above
   the headline it belongs to. Same treatment the hero eyebrow got. */

body.cs-skin .partners__subtitle,
body.cs-skin .services__subtitle,
body.cs-skin .service-faqs__subtitle,
body.cs-skin .feature__subheading { margin-bottom: 0.5rem !important; }

/* --- Shapes through the services feature blocks -----------------------------
   One per .feature section, cycled through four so no two in a row share a
   shape, colour, angle or side. 116px to 146px, the same range the case study
   body uses. Anchored to the section and bleeding off the page edge, never
   inside the measure; the container takes its own stacking layer because the
   decoration is positioned and the copy is not. */

body.cs-skin .feature {
  position: relative;
  overflow-x: clip;
}

body.cs-skin .feature > .container,
body.cs-skin .feature > .container-fluid { position: relative; z-index: 1; }

body.cs-skin .cs-ftdeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-ftdeco__s { position: absolute; display: block; }
body.cs-skin .cs-ftdeco__s svg { display: block; }

body.cs-skin .cs-ftdeco--a .cs-ftdeco__s { top: 12%;    left: -52px; }
body.cs-skin .cs-ftdeco--b .cs-ftdeco__s { bottom: 16%; right: -44px; }
body.cs-skin .cs-ftdeco--c .cs-ftdeco__s { top: 26%;    right: -56px; }
body.cs-skin .cs-ftdeco--d .cs-ftdeco__s { bottom: 10%; left: -48px; }

/* Mobile keeps the shapes. They were hidden below 1023px on the assumption
   that a shape tuned for a wide page would either overflow or land on the
   copy at phone width -- but .feature already has overflow-x: clip, so the
   bleed is cropped rather than scrollable. Scaled down and pulled tighter to
   the edges instead, with transform-origin on the anchored side so the crop
   stays proportional rather than dragging the shape back into the measure. */
@media (max-width: 1023px) {
  body.cs-skin .cs-ftdeco__s { transform: scale(0.58); }

  body.cs-skin .cs-ftdeco--a .cs-ftdeco__s {
    top: 2%; bottom: auto; left: -30px; right: auto;
    transform-origin: left center;
  }
  body.cs-skin .cs-ftdeco--b .cs-ftdeco__s {
    bottom: 4%; top: auto; right: -26px; left: auto;
    transform-origin: right center;
  }
  body.cs-skin .cs-ftdeco--c .cs-ftdeco__s {
    top: 3%; bottom: auto; right: -30px; left: auto;
    transform-origin: right center;
  }
  body.cs-skin .cs-ftdeco--d .cs-ftdeco__s {
    bottom: 3%; top: auto; left: -26px; right: auto;
    transform-origin: left center;
  }
}


/* --- The case study link on the testimonial ---------------------------------
   The yellow box is the browser's own focus ring landing on a link inside a
   dark photograph, not a style of ours. Replaced with the skin's focus
   treatment: a lime ring with an offset, shown only for keyboard focus, so a
   mouse click leaves no box behind but tab order stays visible. */

body.cs-skin .testimonial__play:focus { outline: none; }

body.cs-skin .testimonial__play:focus-visible {
  outline: 2px solid var(--lime);
  outline-offset: 4px;
  border-radius: 6px;
}

body.cs-skin .testimonial__play:hover { color: var(--lime); }


/* --- The services band ------------------------------------------------------
   A paper band with nothing behind it reads flat, so it gets the taupe slab
   treatment from /csignal/: one oversized Store a half-step darker than the
   paper, bleeding off the right and the bottom. It is depth, not decoration,
   which is why it is a tint of the ground rather than an accent, and why it is
   the only large shape on a light band.

   Two medium accents keep it from being just a shadow: coral off the left,
   violet off the right. Both cropped by a page edge like everywhere else.

   The container takes its own layer because the decoration is positioned and
   the list is not. overflow-x: clip crops the bleed without slicing the slab
   top and bottom. */

/* .service-faqs, NOT .services. The <section class="services section"> in this
   page is commented out in the markup: the visible paper band with the SEO /
   CRO / Design / Email accordion is .service-faqs. The decoration was being
   injected into the commented-out section, so it never rendered at all. */
body.cs-skin .service-faqs {
  position: relative;
  overflow-x: clip;
}

body.cs-skin .service-faqs > .container,
body.cs-skin .service-faqs > .container-fluid { position: relative; z-index: 1; }

body.cs-skin .cs-svdeco {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-svdeco__s { position: absolute; display: block; }
body.cs-skin .cs-svdeco__s svg { display: block; }

body.cs-skin .cs-svdeco__s--slab { top: 40px; right: -120px; }
body.cs-skin .cs-svdeco__s--a    { top: 70px; left: 28px; }
body.cs-skin .cs-svdeco__s--b    { bottom: 70px; right: 60px; }

/* Same reasoning as the feature shapes. --a moves off the left edge as well
   as down: at 28px it sat on top of the "Our Services" heading, which is
   tolerable beside a wide heading and not at phone width. */
@media (max-width: 1023px) {
  body.cs-skin .cs-svdeco__s { transform: scale(0.6); }

  body.cs-skin .cs-svdeco__s--a {
    top: 24px; left: -34px;
    transform-origin: left center;
  }
  body.cs-skin .cs-svdeco__s--b {
    bottom: 40px; right: -28px;
    transform-origin: right center;
  }
}


/* --- The services hero, its own set -----------------------------------------
   /work/ and /services/ share the .intro markup, so services was inheriting
   /work/'s shapes verbatim: the same Store ghost in the same corner with the
   same three accents. Two pages that read as the same picture.

   A different cast and a different composition. Ask instead of Store for the
   ghost, so the silhouette differs at a glance. Proof and Path for two of the
   accents, neither of which appears anywhere else on the site, plus a violet
   Spark. Both stroked line shapes, which also gives this hero a lighter
   texture than /work/'s solid blocks.

   The composition is mirrored too: /work/ hangs its ghost off the right and
   crowds the lower left; this one anchors bottom left and works up the right.
   Nothing sits inside the measure. */

body.cs-skin .cs-svhero {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

body.cs-skin .cs-svhero__s { position: absolute; display: block; }
body.cs-skin .cs-svhero__s svg { display: block; }

body.cs-skin .cs-svhero__s--ghost { bottom: -180px; left: -240px; }
body.cs-skin .cs-svhero__s--b { bottom: 12%; right: -48px; }

@media (max-width: 1279px) {
  body.cs-skin .cs-svhero { display: none; }
}


/* --- The Spark on "grow" ----------------------------------------------------
   Inside the h2, immediately after the word, for the same reason the case
   study Spark sits inside its h1: the hero section is far taller than the
   headline and the line breaks move with the viewport, so any percentage
   anchored to the section lands somewhere unrelated to the word at most
   widths. Inline, it travels with "grow" wherever that word ends up.

   Raised onto the word's top right shoulder and turned clockwise so it reads
   as thrown off the end of it rather than parked beside it. aria-hidden with
   no text content, so the heading is unchanged to a reader and to Google. */

/* The mark is anchored to the heading box, not to the word. Tying it to "grow"
   with nowrap made the pair an unbreakable unit, which pushed "grow" onto the
   second line and left a gap behind it: the fix moved the fault rather than
   removing it. Out of flow it cannot influence the wrap at all, and it lands on
   the top-right shoulder of the first line at every width. */
body.cs-skin .intro.intro-services .intro__heading { position: relative; }

body.cs-skin .cs-h2grow { position: static; }

body.cs-skin .cs-h2spark {
  position: absolute;
  top: -0.30em;
  right: -0.10em;
  line-height: 0;
  pointer-events: none;
  /* Clockwise, so it reads as thrown off the line rather than parked on it. */
  transform: rotate(48deg);
}

body.cs-skin .cs-h2spark svg { display: block; }

@media (max-width: 767px) {
  body.cs-skin .cs-h2spark { display: none; }
}


/* --- The band behind the nav ------------------------------------------------
   style.css gives the header a blurred, semi-transparent backdrop. Over a dark
   hero that reads as a grey-blue gradient sitting behind the nav, which is the
   frosted-glass look the skin explicitly replaced with flat ink everywhere
   else. The blur and any background image go; the header keeps whatever flat
   colour section 2 of the skin gives it. */

body.cs-skin .header-container,
body.cs-skin .header-container::before,
body.cs-skin .header,
body.cs-skin .header::before {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  background-image: none !important;
}


/* --- The last of the blurs, and why the services shapes were invisible -------
   .services__bg-one and .service-faqs__bg-one are two more teal-into-violet
   blurred discs out of style.css, same family as .intro__gradient. Off-palette
   on both counts, and .services__bg-one was doing real damage: it is an
   absolutely positioned 949px element that sits AFTER the decoration in source
   order, so with both at z-index auto it painted straight over the taupe slab
   and the two accents. The shapes were rendering the whole time and being
   covered by a blur.

   Both blurs go, and the decoration takes an explicit layer so nothing later
   in the section can bury it again: blur 0, shapes 1, content 2. */

body.cs-skin .services__bg-one,
body.cs-skin .service-faqs__bg-one,
body.cs-skin .looking__gradient { display: none !important; }

body.cs-skin .cs-svdeco { z-index: 2; }

body.cs-skin .service-faqs > .container,
body.cs-skin .service-faqs > .container-fluid { z-index: 3; }


/* Percentages were the wrong anchor here: .services is a tall section and a
   percentage from its top lands well below the visible band. Fixed offsets
   from the section's own edges instead, and the slab is a real step off the
   paper rather than the 4% tint it was, which read as nothing at all. */

/* --- The gradient behind the nav on /services/ ------------------------------
   Not the header at all. service.css paints the PAGE BODY with two old-brand
   radial glows over black:

     .service-page { background: radial-gradient(... rgba(0,180,240,.14)),
                                 radial-gradient(... rgba(160,79,244,.16)), #000 }

   Both ellipses are centred around 320-420px down at 65-75% across, so their
   top edge sits directly behind the fixed header and reads as a teal-violet
   wash there. Killing backdrop-filter on the header could never touch it,
   which is why the band survived every previous attempt. .service-page is
   0,1,0; this is 0,2,0 and resets the whole shorthand, images included -- a
   background-color alone would leave the two gradient layers painting. */
body.cs-skin.service-page { background: var(--ink) !important; }

@media (max-width: 1023px) {
  body.cs-skin.service-page { background: var(--ink) !important; }
}


/* --- CSignal attribution on /work/ -------------------------------------------
   The badge is the homepage lockup reused, so it reads as the same mark rather
   than a new one; it only needs its own spacing here because the work hero
   stacks it under the lede instead of placing it in a side column. */
body.cs-skin .cs-kicker-hit--work { margin-top: 22px; }

/* The line under the results strip. Small and quiet on purpose: it is a source
   note, not a claim, and it should not compete with the four figures above it. */
/* The page's own block turns .results-strip__inner into a nowrap flex row at
   1024, so a 100% basis on the source line could not move to a new line -- it
   just shrank the cards next to it. Wrapping is what actually puts it under. */
/* row-gap 0 because the page's own 3rem gap applies between wrapped rows too,
   which put a huge void between the cards and the source line below them.
   The line's own margin is the only spacing it needs. */
body.cs-skin .results-strip__inner { flex-wrap: wrap; row-gap: 0; }

body.cs-skin .cs-statsrc {
  flex: 0 0 100%;
  width: 100%;
  order: 9;
  margin: 14px 0 0;
  font-family: var(--cs-mono) !important;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(243, 245, 238, 0.42);
}

body.cs-skin .cs-statsrc a { color: var(--lime); text-decoration: none; }
body.cs-skin .cs-statsrc a:hover { text-decoration: underline; }

@media screen and (max-width: 767px) {
  body.cs-skin .cs-statsrc { font-size: 10px; }
}
