/* =========================
   CORE SERVICES — one pillar per row, on carbon-2
   Each pillar pairs its text (5 columns) with the project's own drawings,
   redrawn as SVG models (7 columns). The sides alternate: models left on the
   first pillar, right on the next. No cells, no boxes: the models stand on
   the section ground like the hero lamp.
   Everything builds as it comes into view (js/build.js adds .is-built to
   each [data-build] block, and drops it once the block is off screen so it
   builds again next time): the models assemble, and the text slides in
   towards them while its rules draw out from their side.
========================= */

.services {
  padding-block: var(--section);
  overflow-x: clip; /* text waiting to build sits 2.5rem towards the edge */
  --ground: var(--carbon-2);
  background: var(--carbon-2);
  color: var(--ink-inverse);
}

.services__head {
  padding-bottom: clamp(3.5rem, 2rem + 4vw, 6.5rem);
}

.services__title {
  grid-column: 1 / -1;
}

/* ---------- Pillar: models on one side, text on the other ---------- */
.pillar {
  --dir: 1;            /* the side the text sits on: 1 right, -1 left */
  --line-from: left;   /* rules draw out from the models' side */
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: center;
  padding-inline: var(--margin);
}

.pillar + .pillar {
  margin-top: clamp(5rem, 2rem + 7vw, 10rem);
}

.pillar__text {
  grid-column: 8 / -1;
  grid-row: 1;
  padding-left: clamp(0rem, -1rem + 2.5vw, 2.5rem);
}

.pillar__models,
.pillar__statement {
  grid-column: 1 / 8;
  grid-row: 1;
}

.pillar:nth-child(even) {
  --dir: -1;
  --line-from: right;
}

.pillar:nth-child(even) .pillar__text {
  grid-column: 1 / 6;
  padding-left: 0;
  padding-right: clamp(0rem, -1rem + 2.5vw, 2.5rem);
}

.pillar:nth-child(even) :is(.pillar__models, .pillar__statement) {
  grid-column: 6 / -1;
}

.pillar__title {
  max-width: 14em;
  font-size: clamp(1.75rem, 1rem + 1.7vw, 2.75rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.pillar__list {
  position: relative;
  margin-top: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
}

/* Rules are pseudo-elements so they can draw out (scaleX) as the text builds */
.pillar__list li,
.pillar__list::after {
  position: relative;
}

.pillar__list li {
  padding-block: 0.85em;
  font-size: clamp(1.0625rem, 0.95rem + 0.45vw, 1.375rem);
  line-height: 1.3;
}

.pillar__list li::before,
.pillar__list::after {
  content: "";
  display: block;
  height: 1px;
  background: var(--rule-dark);
  transform-origin: var(--line-from);
}

.pillar__list li::before {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

/* Two models side by side, the wide drawing first; one model takes the whole side */
.pillar__models {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: clamp(1.5rem, 1rem + 2vw, 3rem);
  align-items: end;
}

.pillar__models--single {
  grid-template-columns: 1fr;
}

.pillar__figure {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.pillar__figure figcaption {
  font-size: var(--step-small);
  color: var(--ink-inverse-soft);
}

/* IP & Innovation: no drawing, the one item set as the display line */
.pillar__statement {
  align-self: end;
}

.pillar__list--display {
  margin-top: 0;
}

.pillar__list--display li {
  padding-block: 1.25rem 0;
  font-size: var(--step-head);
  line-height: 1;
  letter-spacing: -0.03em;
}

.pillar__list--display::after {
  display: none;
}

/* ---------- Model drawings ---------- */
.model {
  display: block;
  width: 100%;
  height: auto;
}

.model :is(path, ellipse, circle) {
  stroke: var(--ink-inverse);
  stroke-width: 1.2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.model .fill-top { fill: var(--rule-dark); }
.model .fill-body { fill: var(--carbon-3); }
.model .fill-face { fill: var(--carbon-2); }
.model .fill-dark { fill: var(--carbon); }
.model .fill-board { fill: #1c2023; }
.model .fill-bezel { fill: var(--rule-dark); }
.model .fill-metal { fill: var(--ink-inverse-soft); }
.model .fill-part { fill: #4a4f55; }
.model .fill-part-side { fill: #3a3e43; }
.model .fill-part-shade { fill: #2f3338; }
.model .fill-guide { fill: rgba(242, 241, 237, 0.1); stroke: var(--ink-inverse-soft); }
.model .fill-glass { fill: rgba(242, 241, 237, 0.05); }
.model .fill-hatch { fill: url(#mold-hatch); }
.model .fill-none { fill: none; }
.model .line-soft { stroke: #5a5e63; }
.model .line-dim { stroke: #5a5e63; stroke-width: 1; }
.model .line-amber { fill: none; stroke: var(--amber); stroke-width: 1; }
.model .line-axis { stroke-dasharray: 14 4 3 4; }
.model .line-grid { stroke: var(--rule-dark); stroke-width: 1; }
.model .line-cutoff { stroke-width: 2; }
.model .line-sketch { stroke-dasharray: 6 5; }
.model .line-star { opacity: 0.5; }
.model .line-guide { fill: none; stroke: var(--rule-dark); stroke-width: 12; stroke-linecap: round; }
.model .line-guide-sm { fill: none; stroke: var(--rule-dark); stroke-width: 4; stroke-linecap: round; }
.model .line-led { fill: none; stroke: var(--ink-inverse); stroke-width: 3; stroke-linecap: round; }
.model .line-led-amber { fill: none; stroke: var(--amber); stroke-width: 3; stroke-linecap: round; }
.model .fill-white { fill: var(--ink-inverse); stroke: none; }
.model .fill-block { fill: var(--carbon-3); stroke: #3a3e43; }
.model .fill-lake { fill: rgba(242, 241, 237, 0.06); stroke: #5a5e63; }
.model .line-road { fill: none; stroke: var(--rule-dark); stroke-width: 9; stroke-linecap: round; }
.model .line-lane { fill: none; stroke: #3a3e43; stroke-width: 1; stroke-dasharray: 6 8; }
.model .line-river { fill: none; stroke: rgba(242, 241, 237, 0.16); stroke-width: 6; stroke-linecap: round; }
.model .line-ring { fill: none; stroke: var(--amber); stroke-width: 1.5; }
.model .line-ring--far { opacity: 0.45; }
.model .line-handle { stroke-width: 2.5; stroke-linecap: round; }
.model .line-glint { stroke-width: 2; stroke-linecap: round; opacity: 0.5; }
.model :is(.fill-amber, .fill-beam, .no-stroke) { stroke: none; }
.model .fill-amber { fill: var(--amber); }

/* FEA colour scale for the CAE plot, cool to hot (the one place these colours appear) */
.model :is(.fea-0, .fea-1, .fea-2, .fea-3, .fea-4, .fea-5, .fea-6, .fea-7, .fea-8) { stroke: none; }
.model .fea-0 { fill: #1d3a9e; }
.model .fea-1 { fill: #1f62d6; }
.model .fea-2 { fill: #1b9be0; }
.model .fea-3 { fill: #1cc4c0; }
.model .fea-4 { fill: #3fcf6b; }
.model .fea-5 { fill: #a9dc34; }
.model .fea-6 { fill: #f2c92b; }
.model .fea-7 { fill: #f28a22; }
.model .fea-8 { fill: #e0412b; }
.model .hatch { stroke: var(--rule-dark); stroke-width: 2; vector-effect: none; }

/* ---------- Models build on view (js/build.js toggles .is-built) ----------
   Resting state (no script, reduced motion): every model assembled.
   Before it builds, each part sits at its --from transform and --o opacity;
   .is-built moves it home after its --d delay. Leaving the view drops
   .is-built and the parts snap back (no transition), ready to build again.
   The data-conversion drawing's 2D trace is the one piece that goes the
   other way: shown flat first, it tilts into the ground plane and fades. */
.model__trace {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .motion .model__part {
    transform-box: var(--box, view-box);
    transform-origin: var(--origin, 0 0);
    transform: var(--from, none);
    opacity: var(--o, 0);
  }

  .motion .is-built .model__part {
    transform: none;
    opacity: 1;
    transition:
      transform var(--t, 1.1s) var(--ease) var(--d, 0s),
      opacity 0.6s var(--ease) var(--d, 0s);
  }

  .motion .model__trace {
    transform-origin: var(--origin);
    transform: var(--from);
    opacity: 1;
  }

  /* A part that keeps moving once built: the wind turbine rotor turns slowly */
  .motion .is-built .model__spin {
    animation: model-spin 14s linear infinite;
  }

  .motion .is-built .model__trace {
    transform: none;
    opacity: 0;
    transition:
      transform 1s var(--ease) var(--d, 0s),
      opacity 0.7s var(--ease) calc(var(--d, 0s) + 1.6s);
  }
}

/* ---------- Text builds on view ----------
   Title, then each line in turn, sliding towards the models; each rule
   draws out from the models' side; captions follow once the drawings settle. */
.pillar__title { --delay: 0s; }
.pillar__list li:nth-child(1) { --delay: 0.18s; }
.pillar__list li:nth-child(2) { --delay: 0.26s; }
.pillar__list li:nth-child(3) { --delay: 0.34s; }
.pillar__list li:nth-child(4) { --delay: 0.42s; }
.pillar__list::after { --delay: 0.5s; }

@media (prefers-reduced-motion: no-preference) {
  .motion [data-build] :is(.pillar__title, .pillar__list li) {
    opacity: 0;
    transform: translate3d(calc(var(--dir) * 2.5rem), 0, 0);
  }

  .motion [data-build] .pillar__list li::before,
  .motion [data-build] .pillar__list::after {
    transform: scaleX(0);
  }

  .motion [data-build] figcaption {
    opacity: 0;
  }

  .motion .is-built :is(.pillar__title, .pillar__list li) {
    opacity: 1;
    transform: none;
    transition:
      opacity 0.7s var(--ease) var(--delay),
      transform 1s var(--ease) var(--delay);
  }

  .motion .is-built .pillar__list li::before,
  .motion .is-built .pillar__list::after {
    transform: none;
    transition: transform 1.1s var(--ease) calc(var(--delay) + 0.1s);
  }

  .motion .is-built figcaption {
    opacity: 1;
    transition: opacity 0.7s var(--ease) 1.6s;
  }
}

/* ---------- Narrow screens: stacked, text first, then the models ---------- */
@media (max-width: 960px) {
  .pillar,
  .pillar:nth-child(even) {
    --dir: 1;
    --line-from: left;
  }

  .pillar__text,
  .pillar:nth-child(even) .pillar__text,
  .pillar__models,
  .pillar__statement,
  .pillar:nth-child(even) :is(.pillar__models, .pillar__statement) {
    grid-column: 1 / -1;
    grid-row: auto;
    padding-inline: 0;
  }

  .pillar__models,
  .pillar__statement {
    margin-top: clamp(2rem, 1rem + 3vw, 3rem);
  }
}

@media (max-width: 640px) {
  .pillar__models {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .model {
    max-height: 22rem;
  }
}

@keyframes model-spin {
  to { transform: rotate(360deg); }
}
