/* ==========================================================================
   KF Crafts — #build · "Built properly, layer by layer."
   Scroll-driven exploded view (js/layers.js). Three states:
     (none)      no JS / no WebGL: a plain, readable ordered list.
     .is-live    pinned stage, canvas, numbered dots, legend (desktop) or
                 caption card (phone).
     .is-static  prefers-reduced-motion: one still exploded frame + the list.
   Tokens come from site.css; fallbacks are inline so the file stands alone.
   ========================================================================== */

.build {
  --build-len: 180vh;            /* pinned scroll length — tune here only */
  --build-sky: #07090d;
  --build-pad-x: max(var(--gutter, 1rem), env(safe-area-inset-left));
  --build-pad-r: max(var(--gutter, 1rem), env(safe-area-inset-right));
  position: relative;
  background: var(--ink, #0a0a0a);
  overflow-x: clip;
}
@supports (height: 100svh) {
  .build { --build-len: 180svh; }
}
/* Phones read one caption card per layer: give them a little more runway (still within 200svh). */
@media (max-width: 899.98px) {
  .build { --build-len: 200vh; }
  @supports (height: 100svh) {
    .build { --build-len: 200svh; }
  }
}

/* ---------- Base: the accessible list (always in the DOM) ---------- */

.build__pin,
.build__stage { position: relative; }

.build__figure { display: none; }
.build__dots,
.build__leader { display: none; }

.build__overlay { padding-block: var(--section-pad, 6rem); }

.build__head {
  display: grid;
  gap: 1.25rem;
  max-width: 44rem;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line, rgba(216, 199, 156, 0.26));
}

.build__list {
  display: grid;
  gap: 0 var(--col-gap, 1.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.build__item {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  align-items: baseline;
  padding: 1.1rem 0 1.4rem;
  border-top: 1px solid var(--rule, rgba(244, 241, 234, 0.1));
}

.build__num {
  color: var(--champagne, #d8c79c);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
}

.build__name {
  color: var(--text-strong, rgba(244, 241, 234, 0.96));
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: 0.005em;
}

.build__copy {
  grid-column: 2;
  max-width: 34rem;
  margin-top: 0.5rem;
  color: var(--text, rgba(244, 241, 234, 0.82));
  font-size: 0.9375rem;
  font-weight: 300;
  line-height: 1.6;
}

.build__fig {
  color: var(--champagne, #d8c79c);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.build__end {
  display: grid;
  gap: 1.5rem;
  justify-items: start;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.build__final {
  max-width: 18ch;
  color: var(--text-strong, rgba(244, 241, 234, 0.96));
  font-size: clamp(2rem, 1.35rem + 2.6vw, 4rem);
  font-weight: 200;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

@media (min-width: 700px) {
  .build__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1100px) {
  .build__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- Canvas-backed states (shared) ---------- */

.build.is-live .build__figure,
.build.is-static .build__figure { display: block; }

.build__canvas {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1.1s var(--ease-out, ease-out);
}
.build.is-ready .build__canvas { opacity: 1; }

.build.is-live .build__dots,
.build.is-static .build__dots {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}

.build__dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  will-change: transform;
}
.build__dot span {
  position: absolute;
  left: -11px;
  top: -11px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--champagne, #d8c79c);
  border-radius: 50%;
  background: rgba(10, 10, 10, 0.72);
  color: var(--champagne, #d8c79c);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.35s ease, transform 0.45s var(--ease-out, ease-out), background-color 0.3s ease, color 0.3s ease;
}
.build__dot.is-on span { opacity: 1; transform: scale(1); }
.build__dot.is-active span {
  background: var(--champagne, #d8c79c);
  color: var(--ink, #0a0a0a);
  transform: scale(1.14);
}
.build__dot.is-active span::after {
  content: "";
  position: absolute;
  inset: -7px;
  border: 1px solid rgba(216, 199, 156, 0.5);
  border-radius: 50%;
  animation: build-ping 2.4s var(--ease-out, ease-out) infinite;
}
@keyframes build-ping {
  0% { opacity: 0.9; transform: scale(0.7); }
  70%, 100% { opacity: 0; transform: scale(1.35); }
}

.build__label {
  position: absolute;
  right: var(--build-pad-r);
  bottom: calc(0.9rem + env(safe-area-inset-bottom));
  z-index: 3;
  align-items: center;
  gap: 0.625rem;
  max-width: calc(100% - 2 * var(--gutter, 1rem));
  color: rgba(244, 241, 234, 0.8);
  font-size: 0.71875rem;
  line-height: 1.35;
  letter-spacing: 0.03em;
  text-align: right;
  display: flex;
  pointer-events: none;
}
.build__label::before {
  content: "";
  flex: none;
  width: 1.25rem;
  height: 1px;
  background: var(--champagne, #d8c79c);
}

/* ---------- Live: pinned stage ---------- */

.build.is-live .build__pin { height: var(--build-len); }

.build.is-live .build__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(120% 70% at 60% 62%, #111823 0%, rgba(17, 24, 35, 0) 70%),
    linear-gradient(to bottom, #05070b 0%, #0b1018 58%, #07080a 100%);
  background-color: var(--build-sky);
}

.build.is-live .build__figure {
  position: absolute;
  inset: 0;
}

/* Vignette: functional scrim under the copy, not decoration. */
.build.is-live .build__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(10, 10, 10, 0.7) 0%, rgba(10, 10, 10, 0) 24%),
    linear-gradient(to top, rgba(10, 10, 10, 0.8) 0%, rgba(10, 10, 10, 0) 34%),
    radial-gradient(140% 100% at 60% 50%, rgba(10, 10, 10, 0) 55%, rgba(10, 10, 10, 0.55) 100%);
}

.build.is-live .build__overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  padding: calc(var(--masthead-h, 100px) + 1rem) 0 calc(1rem + env(safe-area-inset-bottom));
  pointer-events: none;
}
.build.is-live .build__inner { position: relative; height: 100%; }

.build.is-live .build__head {
  margin: 0;
  gap: 0.875rem;
  padding-top: 1rem;
  transition: opacity 0.4s ease;
}
.build.is-live .build__title {
  font-size: clamp(1.75rem, 1.2rem + 1.9vw, 3.25rem);
  line-height: 1.06;
}

.build.is-live .build__end {
  position: absolute;
  left: var(--build-pad-x);
  right: var(--build-pad-r);
  bottom: 2.25rem;
  margin: 0;
  gap: 1.25rem;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.6s ease, transform 0.8s var(--ease-out, ease-out);
}
.build.is-live .build__end.is-on { opacity: 1; transform: none; }
.build.is-live .build__end .build__cta { pointer-events: none; }
.build.is-live .build__end.is-on .build__cta,
.build.is-live .build__end:focus-within .build__cta { pointer-events: auto; }
/* A keyboard user must never land on an invisible link. */
.build.is-live .build__end:focus-within { opacity: 1; transform: none; }

/* Desktop / tablet landscape: legend column on the left, leader line to the model. */
@media (min-width: 900px) {
  .build.is-live .build__head { max-width: 25rem; }

  /* Legibility scrim behind the legend column. */
  .build.is-live .build__stage::after {
    background:
      linear-gradient(to bottom, rgba(10, 10, 10, 0.7) 0%, rgba(10, 10, 10, 0) 24%),
      linear-gradient(to top, rgba(10, 10, 10, 0.8) 0%, rgba(10, 10, 10, 0) 34%),
      linear-gradient(to right, rgba(10, 10, 10, 0.72) 0%, rgba(10, 10, 10, 0.45) 26%, rgba(10, 10, 10, 0) 44%),
      radial-gradient(140% 100% at 60% 50%, rgba(10, 10, 10, 0) 55%, rgba(10, 10, 10, 0.55) 100%);
  }

  .build.is-live .build__list {
    display: block;
    width: min(24rem, 34vw);
    margin-top: clamp(1.25rem, 3.5vh, 2.5rem);
    transition: opacity 0.45s ease;
  }
  .build.is-live .build__item {
    grid-template-columns: 2.5rem minmax(0, 1fr);
    padding: 0.5rem 0;
    border-top-color: rgba(244, 241, 234, 0.08);
    transition: border-color 0.35s ease;
  }
  .build.is-live .build__num { color: rgba(216, 199, 156, 0.55); transition: color 0.35s ease; }
  .build.is-live .build__name {
    color: rgba(244, 241, 234, 0.55);
    font-size: 0.9375rem;
    transition: color 0.35s ease;
  }
  .build.is-live .build__copy {
    max-height: 0;
    margin-top: 0;
    overflow: hidden;
    opacity: 0;
    font-size: 0.875rem;
    transition: max-height 0.5s var(--ease-out, ease-out), opacity 0.35s ease, margin-top 0.5s var(--ease-out, ease-out);
  }
  .build.is-live .build__item.is-past .build__num { color: var(--champagne, #d8c79c); }
  .build.is-live .build__item.is-past .build__name { color: var(--text, rgba(244, 241, 234, 0.82)); }
  .build.is-live .build__item.is-active { border-top-color: var(--line-strong, rgba(216, 199, 156, 0.55)); }
  .build.is-live .build__item.is-active .build__num { color: var(--champagne, #d8c79c); }
  .build.is-live .build__item.is-active .build__name { color: var(--text-strong, rgba(244, 241, 234, 0.96)); }
  .build.is-live .build__item.is-active .build__copy {
    max-height: 11rem;
    margin-top: 0.4rem;
    opacity: 1;
  }

  .build.is-live .build__leader {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
    max-width: none;
    overflow: visible;
    pointer-events: none;
  }
  .build__leader path {
    fill: none;
    stroke: var(--champagne, #d8c79c);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  .build__leader.is-on path { opacity: 0.75; }

  /* The closing line sits in the left column, level with the lit building, not at the foot. */
  .build.is-live .build__end {
    top: 50%;
    right: auto;
    bottom: auto;
    max-width: 24rem;
    transform: translateY(calc(-50% + 12px));
  }
  .build.is-live .build__end.is-on,
  .build.is-live .build__end:focus-within { transform: translateY(-50%); }
}

/* Short desktop windows: keep the legend compact. */
@media (min-width: 900px) and (max-height: 760px) {
  .build.is-live .build__head .eyebrow { display: none; }
  .build.is-live .build__item { padding: 0.32rem 0; }
  .build.is-live .build__item.is-active .build__copy { max-height: 7.5rem; }
}

/* Phone / portrait tablet: caption card at the bottom, no leader lines. */
@media (max-width: 899.98px) {
  .build.is-live .build__list {
    position: absolute;
    left: var(--build-pad-x);
    right: var(--build-pad-r);
    bottom: 2.25rem;
    height: 0;
  }
  .build.is-live .build__item {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    grid-template-columns: 3.75rem minmax(0, 1fr);
    padding: 0.9rem 1rem 1rem;
    border: 0;
    border-top: 1px solid var(--line-strong, rgba(216, 199, 156, 0.55));
    background: rgba(10, 10, 10, 0.88); /* speed pass 26.09: no backdrop blur over the live 3D build */
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.35s ease, transform 0.5s var(--ease-out, ease-out);
  }
  .build.is-live .build__item.is-active { opacity: 1; transform: none; }
  .build.is-live .build__num::after {
    content: " / 09";
    color: var(--muted, #8a8a86);
  }
  .build.is-live .build__name { font-size: 1.0625rem; }
  .build.is-live .build__copy { font-size: 0.875rem; line-height: 1.55; }
  .build.is-live .build__final { font-size: clamp(2rem, 1.2rem + 4vw, 2.75rem); }
}

/* ---------- Static (reduced motion): one exploded still + the list ---------- */

.build.is-static .build__figure {
  position: relative;
  height: clamp(22rem, 70vh, 44rem);
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
  overflow: hidden;
  background: linear-gradient(to bottom, #05070b 0%, #0b1018 60%, #07080a 100%);
}
.build.is-static .build__label { right: 1rem; bottom: 0.9rem; }

/* ---------- Motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
  .build__dot span,
  .build.is-live .build__end,
  .build.is-live .build__head,
  .build.is-live .build__item,
  .build.is-live .build__copy,
  .build.is-live .build__canvas,
  .build.is-static .build__canvas { transition: none; }
  .build__dot.is-active span::after { animation: none; }
}

/* ==========================================================================
   Black and gold (26.09): only the 3D scene is daylight — a sunlit sky behind the
   model (js/layers.js lights it). Everything around it stays ink and champagne:
   ink scrims only where copy sits over the sky, dark dots and caption cards, and
   a close-up card (material + KF's own build photo) with hover / tap per layer.
   ========================================================================== */

.build { --build-sky: #cfdbe5; }

.build.is-live .build__stage {
  background: linear-gradient(to bottom, #7ea9d6 0%, #b8cfe2 48%, #dfe6e4 72%, #cfd9c9 100%);
  background-color: var(--build-sky);
}
.build.is-static .build__figure {
  background: linear-gradient(to bottom, #7ea9d6 0%, #b8cfe2 55%, #dfe6e4 100%);
}

/* Ink over the daylight, only where copy sits: the caption card and the closing line at the foot. */
.build.is-live .build__stage::after {
  background: linear-gradient(to top, rgba(10, 10, 10, 0.86) 0%, rgba(10, 10, 10, 0.5) 18%, rgba(10, 10, 10, 0) 34%);
}
/* Phones: the head carries its own ink, flowing down from the masthead — it fades out with the head
   (layers.js fades the head as the first layer arrives), so the sky is all day behind the layers. */
@media (max-width: 899.98px) {
  .build.is-live .build__head { position: relative; isolation: isolate; }
  .build.is-live .build__head::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: calc(-1 * (var(--masthead-h, 100px) + 1rem));
    bottom: -4.5rem;
    left: calc(-1 * var(--build-pad-x));
    right: calc(-1 * var(--build-pad-r));
    background: linear-gradient(to bottom, rgba(10, 10, 10, 0.92) 0%, rgba(10, 10, 10, 0.8) 55%, rgba(10, 10, 10, 0) 100%);
    pointer-events: none;
  }
}
@media (min-width: 900px) {
  /* Desktop: an ink column behind the legend (sized to the copy, not to the window), then the day. */
  .build.is-live .build__stage::after {
    background:
      linear-gradient(to bottom, rgba(10, 10, 10, 0.72) 0%, rgba(10, 10, 10, 0) 18%),
      linear-gradient(to top, rgba(10, 10, 10, 0.66) 0%, rgba(10, 10, 10, 0) 20%),
      linear-gradient(to right, rgba(10, 10, 10, 0.94) 0%, rgba(10, 10, 10, 0.88) calc(var(--build-pad-x) + 25rem), rgba(10, 10, 10, 0) calc(var(--build-pad-x) + 35rem));
  }
  /* Hover a layer: it becomes the one the camera shows. */
  .build.is-live .build__item { pointer-events: auto; cursor: zoom-in; }
  .build.is-live .build__item:hover .build__name,
  .build.is-live .build__item:focus-visible .build__name { color: var(--text-strong, rgba(244, 241, 234, 0.96)); }
  .build.is-live .build__item:hover .build__num { color: var(--champagne, #d8c79c); }
}
.build__item:focus-visible { outline: 2px solid var(--gold-hi, #e3ce92); outline-offset: 2px; }

/* Dots: ink with a champagne numeral over the sky (base rules above); tappable, with a 44px target. */
.build__dot span { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); }
.build.is-live .build__dot.is-on span,
.build.is-static .build__dot.is-on span { pointer-events: auto; cursor: zoom-in; }
.build__dot.is-on span::before {
  content: "";
  position: absolute;
  inset: -11px; /* a 44px target */
}

/* Phone caption card: ink glass (base rules above). Tap it for the close-up. */
@media (max-width: 899.98px) {
  .build.is-live .build__item.is-active { pointer-events: auto; cursor: zoom-in; }
}

/* ---------- Close-up card ---------- */

.build__lens { display: none; }
.build.is-live .build__lens,
.build.is-static .build__lens {
  position: absolute;
  z-index: 3;
  right: var(--build-pad-r);
  bottom: calc(2.6rem + env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas: "mat photo" "cap cap";
  align-items: end;
  gap: 0.6rem 0.75rem;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.6s var(--ease-out, ease-out);
  pointer-events: none;
}
.build.is-live .build__lens.is-on,
.build.is-static .build__lens.is-on { opacity: 1; transform: none; }
.build__lens-mat {
  grid-area: mat;
  display: none;
  width: 7.5rem;
  height: 7.5rem;
  overflow: hidden;
  border-radius: 50%;
  border: 1px solid var(--champagne);
  box-shadow: 0 0 0 5px rgba(10, 10, 10, 0.85), 0 16px 34px -14px rgba(0, 0, 0, 0.6);
}
.build__lens.has-mat .build__lens-mat { display: block; }
.build__lens-photo {
  grid-area: photo;
  position: relative;
  display: none;
  width: 11.5rem;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 0 0 5px rgba(10, 10, 10, 0.85), 0 16px 34px -14px rgba(0, 0, 0, 0.6);
}
.build__lens.has-photo .build__lens-photo { display: block; }
.build__lens img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}
.build__lens-tag {
  position: absolute;
  left: 0.4rem;
  bottom: 0.35rem;
  padding: 0.15rem 0.4rem;
  color: #f4f1ea;
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  background: rgba(10, 10, 10, 0.55);
  border-radius: 1px;
}
.build__lens-cap {
  grid-area: cap;
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0;
  color: var(--text);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.7), 0 1px 12px rgba(0, 0, 0, 0.55);
}
.build__lens-num { color: var(--champagne); font-variant-numeric: tabular-nums; }
.build__lens-name { color: var(--text-strong); }
.build__lens-note::before { content: "· "; color: var(--muted); }

/* Phones: a compact card top-right, under the masthead, clear of the caption card. */
@media (max-width: 899.98px) {
  .build.is-live .build__lens {
    top: calc(var(--masthead-h, 100px) + 0.75rem);
    bottom: auto;
    grid-template-columns: auto;
    grid-template-areas: "mat" "photo";
    justify-items: end;
    gap: 0.5rem;
  }
  .build__lens-mat { width: 4.75rem; height: 4.75rem; }
  .build__lens-photo { width: 7.5rem; }
  .build__lens-cap { display: none; }
}
.build.is-static .build__lens { right: 1rem; bottom: 2.4rem; }

@media (prefers-reduced-motion: reduce) {
  .build__lens { transition: none; }
}

/* Clear of the site's floating "Ask KF" button (bottom right). */
@media (min-width: 900px) {
  .build.is-live .build__lens { bottom: calc(5rem + env(safe-area-inset-bottom)); }
  .build.is-live .build__label { right: auto; left: var(--build-pad-x); flex-direction: row-reverse; text-align: left; }
}

/* ==========================================================================
   Round 3 (judge): real photographs lead, the drawing explains.
   ========================================================================== */

/* Each photographed layer carries KF's own build photo in its card (js/layers.js adds .build__photo). */
.build__photo {
  position: relative;
  display: block;
  grid-column: 1 / -1;
  aspect-ratio: 16 / 9;
  margin: 0 0 0.9rem;
  overflow: hidden;
  border-radius: 2px;
  background: var(--ink-2, #121110);
}
.build__photo img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}
.build__photo .build__lens-tag { left: 0.5rem; bottom: 0.45rem; }

@media (max-width: 899.98px) {
  .build.is-live .build__photo {
    max-height: 22svh;
    aspect-ratio: auto;
    height: 22svh;
    margin: -0.9rem -1rem 0.85rem;
    border-radius: 0;
  }
  /* The card has the photo; the corner keeps only the material. */
  .build.is-live .build__lens-photo { display: none !important; }
  .build__lens-mat { width: 4.25rem; height: 4.25rem; }
}

@media (min-width: 900px) {
  .build.is-live .build__photo { display: none; }
  /* Desktop close-up card: the build photo large, the material as a small disc on its corner. */
  .build.is-live .build__lens {
    grid-template-columns: auto;
    grid-template-areas: "photo" "cap";
    justify-items: end;
    gap: 0.7rem;
  }
  .build.is-live .build__lens-photo { width: clamp(17rem, 27vw, 27rem); }
  .build.is-live .build__lens.has-photo .build__lens-mat {
    position: absolute;
    top: -2.25rem;
    left: -2.25rem;
    z-index: 1;
    width: 5.5rem;
    height: 5.5rem;
  }
  .build.is-live .build__lens:not(.has-photo) .build__lens-mat { grid-area: photo; width: 10rem; height: 10rem; }
  .build.is-live .build__lens-cap { font-size: 0.8125rem; }
}

/* The drawing's honest mark: the site's small CGI tag, not a sentence. */
.build__label.cgi-mark {
  gap: 0;
  font-size: 0.5625rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(244, 241, 234, 0.64);
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.6), 0 1px 12px rgba(0, 0, 0, 0.45);
}
.build__label.cgi-mark::before { display: none; }
