/* company.html — Why / What / Focus as a stepped pair.

   This was a scroll-driven sticky stack first, and it did not work. Scroll
   could be made to pick the right photo, but a sticky figure holds still
   while the copy moves past it — that is what sticky means — so the two
   never appeared to travel together. Stepping through with arrows or a
   click changes both on the same event, which is the only way they stay
   locked.

   The clip mask still carries the copy's meaning: 16 loose squares for
   "the information is there but it's scattered", 6 interlocking blocks for
   "we connect what you already have", 2 clean panels for "one clear
   picture". */

.co-stack {
  padding: var(--section-pad) 0;
}

.co-stack__inner {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}

.co-stack__visual {
  grid-column: 2;
  grid-row: 1;
}

.co-stack__body {
  grid-column: 1;
  grid-row: 1;
}

/* ---- the three headings -------------------------------------------- */

.co-stack__item + .co-stack__item {
  border-top: 1px solid var(--gray-200);
}

.co-stack__item h2 {
  margin: 0;
}

.co-stack__trigger {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  width: 100%;
  padding: 1.35rem 0;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}

.co-stack__num {
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gray-500);
  transition: color 320ms var(--ease-out);
}

.co-stack__name {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--gray-500);
  transition: color 320ms var(--ease-out);
}

/* Inactive is --gray-500 (#767676) rather than a lowered opacity: opacity
   .55 over --gray-700 blends to roughly #949494, 3.04:1 on white, which
   fails AA. #767676 measures 4.54:1 and clears it at any size. */
.co-stack__item.is-active .co-stack__num { color: var(--brand); }
.co-stack__item.is-active .co-stack__name { color: var(--gray-900); }

.co-stack__trigger:hover .co-stack__name { color: var(--gray-900); }

/* ---- the panels ----------------------------------------------------- */

.co-stack__panel p {
  margin: 0;
  padding-bottom: 1.6rem;
  max-width: 40em;
  font-size: 1.025rem;
  line-height: 1.75;
  color: var(--gray-700);
}

/* Collapsed states are gated behind .js-reveal, the flag reveal-init.js
   sets before first paint. Without scripting every panel stays open and the
   section reads as three ordinary paragraphs — which is also what crawlers
   get. --panel-h is measured per panel by company-stack.js; the fallback
   only has to be large enough not to clip mid-transition. */
.js-reveal .co-stack__panel {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 420ms var(--ease-out),
              opacity 260ms var(--ease-out);
}

.js-reveal .co-stack__panel.is-open {
  max-height: var(--panel-h, 40rem);
  opacity: 1;
}

/* ---- arrows --------------------------------------------------------- */

/* Revealed by script. Without it there is nothing to step through, so a
   pair of dead buttons would only mislead. */
.co-stack__controls {
  display: flex;
  gap: 0.75rem;
  margin-top: 2rem;
}

.co-stack__controls[hidden] { display: none; }

.co-stack__arrow {
  width: 3rem;
  height: 3rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--gray-300);
  border-radius: 50%;
  background: none;
  font-size: 1.1rem;
  color: var(--gray-700);
  cursor: pointer;
  transition: border-color 200ms var(--ease-out),
              color 200ms var(--ease-out),
              background-color 200ms var(--ease-out);
}

.co-stack__arrow:hover {
  border-color: var(--gray-900);
  color: var(--gray-900);
}

.co-stack__arrow[disabled] {
  opacity: 0.35;
  cursor: default;
}

.co-stack__arrow[disabled]:hover {
  border-color: var(--gray-300);
  color: var(--gray-700);
}

/* ---- the masked figure ---------------------------------------------- */

.co-stack__figure {
  margin: 0;
  width: 100%;
}

.co-stack__svg {
  display: block;
  width: 100%;
  max-width: 460px;
  height: auto;
  margin-inline: auto;
}

/* Three frames are present at once; only the shown one renders. The default
   is hidden with the first frame marked in the markup, so without JS the
   page still paints exactly one photo rather than none. */
.co-stack__frame { display: none; }
.co-stack__frame.is-shown { display: block; }

/* Each clip piece scales about its own centre. transform-box:fill-box is
   what makes "centre" mean the rect's own box rather than the viewBox
   origin — verified in-browser via hit-testing before this was written,
   which is why no animation library is needed here. */
/* --in-dur is written per clip by the script: fewer, larger pieces get a
   shorter one. Two big panels scaling over the same 620ms as sixteen small
   squares reads as slower, because there is far less happening on screen
   for the same stretch of time. The fallback is the sixteen-piece value. */
.co-stack__svg clipPath rect {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(1);
  transition: transform var(--in-dur, 620ms) cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--in-delay, 0s);
}

.co-stack__svg.is-out clipPath rect {
  transform: scale(0);
  transition: transform 380ms cubic-bezier(0.7, 0, 0.84, 0);
  transition-delay: var(--out-delay, 0s);
}

/* ---- narrow screens ------------------------------------------------- */

@media (max-width: 900px) {
  .co-stack__inner {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  /* Figure first: on a phone the picture is the thing that changes, and it
     should be in view when the heading beneath it is tapped. */
  .co-stack__visual,
  .co-stack__body {
    grid-column: 1;
    grid-row: auto;
  }

  .co-stack__svg {
    max-width: 380px;
  }
}

/* ---- reduced motion -------------------------------------------------- */

/* No re-assembly and no height animation. The mask holds its shape and the
   figure crossfades, so the step is still legible without anything moving. */
@media (prefers-reduced-motion: reduce) {
  .co-stack__svg clipPath rect,
  .co-stack__svg.is-out clipPath rect {
    transform: scale(1);
    transition: none;
  }

  .co-stack__svg {
    transition: opacity 180ms linear;
  }

  .co-stack__svg.is-out {
    opacity: 0;
  }

  .js-reveal .co-stack__panel {
    transition: opacity 180ms linear;
  }

  .co-stack__num,
  .co-stack__name {
    transition: none;
  }
}
