/* ===========================================================================
   SERVICE DETAIL — Customer Acquisition & Customer Systems
   Every rule below is scoped to the `.sd` sections these two pages use, so
   nothing here can leak onto any other route. Default state (no JS, reduced
   motion, or `service.js` never loading) is fully visible and static; the
   `sd-js` class on <html> — added only when JS runs and motion is allowed —
   is what switches elements into their hidden-until-scrolled state.
   =========================================================================== */

.sd{ overflow-x: clip; }

/* ============================================================== 1. HERO */
.sd-hero__grid{ display: grid; gap: var(--s-8); }
.sd-hero__art{ order: -1; width: 100%; max-width: 15.5rem; margin-inline: auto; }
@media (min-width: 860px){
  .sd-hero__grid{ grid-template-columns: minmax(0,1fr) minmax(0,.86fr); align-items: center; gap: clamp(2.5rem, 1rem + 5vw, 6rem); }
  .sd-hero__art{ order: 0; max-width: none; margin-inline: 0; }
}

.sd-hero__title{ font-family: var(--font-display); font-weight: 700; font-optical-sizing: auto;
  letter-spacing: -.01em; line-height: .98; overflow-wrap: anywhere;
  font-size: clamp(2.35rem, 1.7rem + 3.6vw, 4.75rem);
  margin-block: var(--s-5) var(--s-6); max-width: 15ch; }
.sd-hero__lede{ max-width: 38ch; }

.sd-hero__art{ position: relative; }
.sd-hero__img{ display: block; width: 100%; height: auto; max-width: none; }
.sd-hero__svg{ position: absolute; inset: 0; width: 100%; height: 100%; }
.sd-field-line{ fill: none; stroke: var(--ink); stroke-opacity: .32; stroke-width: 1.6; stroke-dasharray: 2.5 7; stroke-linecap: round; }
.sd-drift{ transform-box: fill-box; }
.sd-drift--ink{ fill: var(--ink); }
.sd-drift--accent{ fill: var(--accent); }
/* a simpler loop on phones: fewer things drifting */
@media (max-width: 859px){ .sd-hero__svg circle.sd-drift:nth-of-type(4), .sd-hero__svg rect.sd-drift:nth-of-type(6) { display: none; } }
@media (prefers-reduced-motion: reduce){ .sd-drift{ display: none; } }

/* =========================================================== 2. ROUTE */
.sd-route-head{ max-width: 46rem; }
.sd-route-intro{ margin-block: var(--s-4) var(--s-5); max-width: 20ch; }
.sd-route-statement{ color: var(--ink-2); }

.sd-route{ position: relative; margin-top: clamp(2.75rem, 1.75rem + 3.5vw, 4.5rem); }
.sd-route__svg{ display: block; width: 100%; height: auto; margin-bottom: clamp(-1.75rem, -1rem - 2vw, -.75rem); }
.sd-route__path{ fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round; }
html.sd-js .sd-route__path{ stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1150ms var(--ease-out); }
html.sd-js .sd-route__path.in{ stroke-dashoffset: 0; }

.sd-route__stops{ display: flex; justify-content: space-between; gap: var(--s-6); list-style: none; margin: 0; padding: 0; }
.sd-stop{ display: grid; grid-template-columns: auto 1fr; align-items: center; gap: var(--s-2) var(--s-3); max-width: 15rem; }
.sd-stop__n{ grid-column: 2; color: var(--ink-2); }
.sd-stop__label{ grid-column: 2; font-family: var(--font-display); font-weight: 800; font-stretch: 108%;
  font-size: clamp(1.05rem, .95rem + .5vw, 1.3125rem); letter-spacing: -.02em; line-height: 1.15; }
.sd-stop__dot{ grid-row: 1 / span 2; position: relative; width: 15px; height: 15px; border-radius: 50%;
  border: 1.5px solid var(--ink); flex: none; }
.sd-stop__dot::after{ content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
html.sd-js .sd-stop__dot::after{ opacity: 0; transform: scale(.3); transition: opacity 480ms var(--ease-out), transform 480ms var(--ease-out); }
html.sd-js .sd-stop.in .sd-stop__dot::after{ opacity: 1; transform: none; }
html.sd-js .sd-stop__label, html.sd-js .sd-stop__n{ opacity: 0; transform: translateY(8px); transition: opacity 480ms var(--ease-out), transform 480ms var(--ease-out); }
html.sd-js .sd-stop.in .sd-stop__label, html.sd-js .sd-stop.in .sd-stop__n{ opacity: 1; transform: none; }
html.sd-js .sd-route__stops .sd-stop:nth-child(2) .sd-stop__dot::after,
html.sd-js .sd-route__stops .sd-stop:nth-child(2) .sd-stop__label,
html.sd-js .sd-route__stops .sd-stop:nth-child(2) .sd-stop__n{ transition-delay: 90ms; }
html.sd-js .sd-route__stops .sd-stop:nth-child(3) .sd-stop__dot::after,
html.sd-js .sd-route__stops .sd-stop:nth-child(3) .sd-stop__label,
html.sd-js .sd-route__stops .sd-stop:nth-child(3) .sd-stop__n{ transition-delay: 180ms; }

@media (max-width: 699px){
  .sd-route__svg{ display: none; }
  .sd-route__stops{ flex-direction: column; gap: var(--s-7); position: relative; padding-left: 1.9rem; }
  .sd-route__stops::before{ content: ""; position: absolute; left: 6px; top: 7px; bottom: 7px; width: 2px; background: var(--rule-strong); }
  .sd-stop{ position: relative; max-width: none; grid-template-columns: 1fr; }
  .sd-stop__dot{ position: absolute; left: -1.9rem; top: 0; }
  .sd-stop__n, .sd-stop__label{ grid-column: 1; }
}

@media (prefers-reduced-motion: reduce){
  .sd-route__path{ stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* ======================================================= 3. CAPABILITIES */
.sd-caps-head{ max-width: 40rem; }
.sd-caps-head .h2{ margin-top: var(--s-4); }

.sd-caps{ margin-top: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
.sd-cap{ border-bottom: 1px solid var(--rule-strong); }
.sd-cap:first-child{ border-top: 1px solid var(--ink); }
.sd-cap__summary{ display: grid; grid-template-columns: 3rem 1fr auto; align-items: center; gap: var(--s-3) var(--s-4);
  padding-block: var(--s-5); cursor: pointer; list-style: none; -webkit-tap-highlight-color: transparent; }
.sd-cap__summary::-webkit-details-marker{ display: none; }
.sd-cap__summary::marker{ content: ""; }
.sd-cap__n{ color: var(--ink-2); }
.sd-cap__t{ font-family: var(--font-display); font-weight: 800; font-stretch: 108%; font-size: var(--t-h3); letter-spacing: -.015em; }
.sd-cap__chev{ width: 11px; height: 7px; color: var(--ink); flex: none; transition: transform var(--dur-2) var(--ease); }
.sd-cap[open] .sd-cap__chev{ transform: rotate(180deg); }
.sd-cap__list{ display: grid; gap: var(--s-3); grid-column: 2 / -1; padding: 0 0 var(--s-6); margin: 0; list-style: none; }
.sd-cap__list li{ font-family: var(--font-mono); font-size: var(--t-mono); color: var(--ink-2); padding-left: var(--s-5); position: relative; }
.sd-cap__list li::before{ content: ""; position: absolute; left: 0; top: .6em; width: 8px; height: 1.5px; background: var(--ink); }

@media (min-width: 700px){
  .sd-caps{ display: grid; grid-template-columns: repeat(2, 1fr); border-top: 1px solid var(--ink); border-left: 1px solid var(--ink); }
  .sd-cap{ border: 0; border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
  .sd-cap__summary{ padding: var(--s-6) var(--s-6) var(--s-4); cursor: default; grid-template-columns: 2.75rem 1fr; }
  .sd-cap__chev{ display: none; }
  .sd-cap__list{ padding: 0 var(--s-6) var(--s-7); grid-column: 2 / -1; }
  /* forced open: the matrix reads as an index, not an accordion. Chrome
     wraps a closed <details>'s non-summary content in an internal
     ::details-content box set to `content-visibility: hidden; height: 0`;
     overriding the light-DOM child is not enough, the pseudo-element itself
     has to be reopened or the row collapses to the summary's height and the
     list paints outside its own cell. */
  .sd-cap:not([open])::details-content{ content-visibility: visible; block-size: auto; height: auto; }
  .sd-cap:not([open]) > .sd-cap__list{ display: grid; content-visibility: visible; }
}
@media (min-width: 1060px){ .sd-caps{ grid-template-columns: repeat(3, 1fr); } }

html.sd-js .sd-cap{ opacity: 0; transform: translateY(16px); transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out); }
html.sd-js .sd-cap.in{ opacity: 1; transform: none; }
html.sd-js .sd-cap:nth-child(1){ transition-delay: 0ms; } html.sd-js .sd-cap:nth-child(2){ transition-delay: 60ms; }
html.sd-js .sd-cap:nth-child(3){ transition-delay: 120ms; } html.sd-js .sd-cap:nth-child(4){ transition-delay: 180ms; }
html.sd-js .sd-cap:nth-child(5){ transition-delay: 240ms; } html.sd-js .sd-cap:nth-child(6){ transition-delay: 300ms; }
html.sd-js .sd-cap:nth-child(7){ transition-delay: 360ms; }
@media (max-width: 699px){ html.sd-js .sd-cap{ opacity: 1; transform: none; transition: none; } }

.sd-cap__summary:hover{ background: var(--hover); }
.sd-cap:focus-within .sd-cap__summary{ background: var(--hover); }

/* ============================================================ 4. CLOSING */
.sd-close__text{ position: relative; display: inline-block; }
.sd-close__trace{ display: block; width: min(100%, 26rem); height: .8rem; margin-top: var(--s-4); overflow: visible; }
.sd-close__trace path{ fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; }
html.sd-js .sd-close__trace path{ stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 900ms var(--ease-out); }
html.sd-js .sd-close__trace.in path{ stroke-dashoffset: 0; }

@media (prefers-reduced-motion: reduce){
  .sd-close__trace path{ stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* Belt and suspenders: if `sd-js` is somehow present without a matching
   IntersectionObserver ever resolving (e.g. the callback never fires because
   the element was already in view at load and some browser quirk skips the
   first tick), nothing above is allowed to stay invisible forever — the
   scroll-reveal targets keep a visible base state and only ever *add*
   motion, they never start from `display:none` or `visibility:hidden`. */

/* ============================================ v4.2 · after the site audit */
/* the kicker's "Services" is the way back up: a breadcrumb, not decoration */
.sd-crumb{ color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.sd-crumb:hover{ text-decoration-thickness: 2px; }

/* no lonely last card: a card alone on its row spans the row and lays its
   list out across it (Customer Systems has seven groups) */
@media (min-width: 700px) and (max-width: 1059px){
  .sd-cap:last-child:nth-child(odd){ grid-column: 1 / -1; }
}
@media (min-width: 1060px){
  .sd-caps:not(.sd-caps--2) > .sd-cap:last-child:nth-child(3n+1){ grid-column: 1 / -1; }
  .sd-caps:not(.sd-caps--2) > .sd-cap:last-child:nth-child(3n+1) .sd-cap__list{ grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--s-6); }
  .sd-caps--2{ grid-template-columns: repeat(2, 1fr); }
  .sd-caps--2 > .sd-cap:last-child:nth-child(odd){ grid-column: 1 / -1; }
}
html.sd-js .sd-cap:nth-child(8){ transition-delay: 420ms; }
/* Growth Partner's scope items are one sentence each: body copy, not a list */
.sd-caps--2 .sd-cap__list li{ font-family: var(--font-body); font-size: var(--t-small); padding-left: 0; }
.sd-caps--2 .sd-cap__list li::before{ display: none; }

/* ============================================ v4.4 · capability cards
   Smaller, and each group is a card: a white title strip with the number on
   an ink chip, the list on a pale wash of the band below it. */
.sd-caps{ display: grid; gap: var(--s-4); border: 0; }
.sd-cap, .sd-cap:first-child{ border: 1.5px solid var(--ink); background: rgba(255, 255, 255, .38); box-shadow: 4px 4px 0 0 rgba(30, 25, 25, .14); }
.sd-cap__summary{ grid-template-columns: auto 1fr auto; gap: var(--s-3); padding: var(--s-3) var(--s-4); background: var(--white); border-bottom: 1.5px solid var(--ink); }
.sd-cap:not([open]) .sd-cap__summary{ border-bottom-color: transparent; }
.sd-cap__summary:hover, .sd-cap:focus-within .sd-cap__summary{ background: var(--white); }
.sd-cap__n{ display: inline-grid; place-items: center; min-width: 2rem; height: 1.6rem; padding: 0 .35rem; background: var(--ink); color: var(--yellow); font-size: .6875rem; letter-spacing: .08em; }
.sd-cap__t{ font-size: 1.0625rem; line-height: 1.2; letter-spacing: -.01em; }
.sd-cap__list{ gap: var(--s-2); grid-column: 1 / -1; padding: var(--s-4) var(--s-4) var(--s-5); }
.sd-cap__list li{ font-size: .75rem; line-height: 1.5; color: var(--ink); padding-left: var(--s-4); }
.sd-cap__list li::before{ top: .75em; width: 6px; background: var(--orange); }
@media (min-width: 700px){
  .sd-caps{ grid-template-columns: repeat(2, 1fr); border: 0; align-items: stretch; }
  .sd-cap{ border: 1.5px solid var(--ink); }
  .sd-cap__summary{ padding: var(--s-3) var(--s-4); grid-template-columns: auto 1fr; border-bottom-color: var(--ink) !important; }
  .sd-cap__list{ padding: var(--s-4) var(--s-4) var(--s-5); grid-column: 1 / -1; }
}
@media (min-width: 1060px){ .sd-caps{ grid-template-columns: repeat(3, 1fr); gap: var(--s-5); } }
.sd-caps-head .h2{ font-size: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem); }
/* v4.4: the service scenes are larger drawings; the tall one is held to the
   hero's height instead of running past it */
.sd-hero__img{ max-height: min(34rem, 66vh); object-fit: contain; }
@media (max-width: 859px){ .sd-hero__art{ max-width: 17rem; } .sd-hero__img{ max-height: 15rem; } }

/* v4.5 (10a): "keeps moving" is held together by a non-breaking space in the
   string itself (service-detail.js), not by a blanket nowrap here — a CSS rule
   would also catch Customer Acquisition's 24-character phrase and clip it
   behind .sd{ overflow-x: clip } on phones. */

/* v4.5 (9b): the route draws slower, and a car rides the head of the line so
   01-02-03 reads as travel rather than a line appearing. The car shares the
   path data with .sd-route__path, so it is always exactly at the drawn head.
   Guarded by @supports: where motion path is unavailable the car is simply
   not drawn, and the road behaves as it did before. */
html.sd-js .sd-route__path{ transition: stroke-dashoffset 2600ms var(--ease-out); }

.sd-route__car{ display: none; }
@supports (offset-path: path("M0,0 L1,1")){
  .sd-route__car{
    display: block; color: var(--ink);
    offset-path: path("M20,50 C220,5 320,60 450,32 C580,4 680,60 880,20");
    offset-rotate: auto;
    offset-distance: 100%;
  }
  html.sd-js .sd-route__car{
    offset-distance: 0%; opacity: 0;
    transition: offset-distance 2600ms var(--ease-out), opacity 260ms linear;
  }
  html.sd-js .sd-route__path.in ~ .sd-route__car{ offset-distance: 100%; opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  /* service.js returns before adding sd-js when reduced motion is set, so the
     animated rules never attach on load. This covers the case where the
     preference changes afterwards: it has to match the specificity of
     html.sd-js .sd-route__car to win the cascade, which .sd-route__car alone
     does not. */
  html.sd-js .sd-route__car,
  html.sd-js .sd-route__path.in ~ .sd-route__car{
    offset-distance: 100%; opacity: 1; transition: none;
  }
  html.sd-js .sd-route__path{ transition: none; }
}

/* v4.5 (9a): the route headline kept the right half of the band empty, because
   .sd-route-head is capped at 46rem. It now shares a row with a scene. */
.sd-route-top{ display: grid; gap: var(--s-7); align-items: center; }
@media (min-width: 900px){
  .sd-route-top{ grid-template-columns: minmax(0, 46rem) minmax(0, 1fr); gap: var(--s-8); }
}
.sd-route-art{ margin: 0; }
.sd-route-art img{ display: block; width: 100%; height: auto; max-width: none; }
/* rt-systems was generated without a side gutter, so it gets one here */
/* v5.4: rt-systems became rt-robots (marks 7/9/10 replaced all three route
   illustrations). The 6% inset stays with the slot, not with the old art: it is
   there because this band's asset is the widest and shortest of the three. */
.sd-route-art--rt-robots img{ padding-inline: 6%; }
