/* ==========================================================================
   builder.css — styles used only by builder.html
   ========================================================================== */

/* Hero --------------------------------------------------------------------
   Full-bleed. The illustration is laid out in Figma pixels on a 1286-wide
   stage; --u is the length of one Figma pixel, so the whole scene scales
   with the viewport. Objects are placed from the centre line (x = 643). */
.hero {
  container-type: inline-size;
  position: relative;
  overflow: clip;
  background: linear-gradient(to bottom, rgba(180, 232, 148, .27), rgba(236, 239, 244, 0));
}
.hero__scene {
  --u: calc(min(100cqw, 1286px) / 1286);
  position: relative;
  height: calc(1334 * var(--u));
  /* space between the header and the top of the scene, as in Figma */
  margin-top: calc(45 * var(--u));
  /* keeps a picked-up object's z-index inside the scene, under the header */
  isolation: isolate;
}
/* 24px above the header in Figma, shrinking with the screen */
.hero__header { position: relative; z-index: 2; padding-top: clamp(8px, 1.87vw, 24px); }
.hero__desk {
  position: absolute;
  inset-inline: 0;
  top: calc(662 * var(--u));
  height: max(1px, calc(2 * var(--u)));
  background: var(--desk);
}
.hero__obj {
  position: absolute;
  left: calc(50% + (var(--x) - 643) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(var(--w) * var(--u));
  max-width: none;
  height: auto;
}
/* The plants hug the edges of the screen, however wide it is. */
.hero__plant { left: auto; }
.hero__plant--left { left: 0; }
.hero__plant--right { right: 0; }

.hero__stand-shadow,
.hero__stand,
.hero__neck { height: calc(var(--h) * var(--u)); }
.hero__stand-shadow { border-radius: 999px; background: linear-gradient(to bottom, #50c091, #7cb991); }
.hero__stand { border-radius: 999px; background: linear-gradient(to bottom, #50c091, #d7f594); }
.hero__neck {
  border-radius: calc(12 * var(--u));
  background: linear-gradient(to bottom, var(--grad-deep), var(--grad-light) 92.5%);
}

/* isolate: keeps the screen's z-index inside the monitor, so the character
   sitting on top can dangle its feet over the bezel */
.hero__monitor { height: calc(394 * var(--u)); isolation: isolate; }
.hero__monitor::before,
.hero__monitor::after {
  content: "";
  position: absolute;
  width: calc(707 * var(--u));
  border-radius: calc(14 * var(--u));
}
.hero__monitor::before {            /* side of the monitor */
  left: calc(8 * var(--u));
  top: 0;
  height: calc(394 * var(--u));
  background: #82c271;
}
.hero__monitor::after {             /* bezel */
  left: 0;
  top: 0;
  height: calc(384 * var(--u));
  background: linear-gradient(to bottom, var(--grad-deep), var(--grad-light) 92.5%);
}
.hero__screen {
  position: absolute;
  z-index: 1;
  left: calc(20 * var(--u));
  top: calc(20 * var(--u));
  width: calc(667 * var(--u));
  height: calc(344 * var(--u));
  border-radius: calc(12 * var(--u));
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The headline lives on the monitor, so it scales with the scene instead of
   using a type token. It is the one deliberate exception to the type scale. */
.hero__title {
  display: flex;
  flex-direction: column;
  gap: calc(16 * var(--u));
  font-family: var(--font-display);
  font-weight: 800;
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-size: calc(48 * var(--u));
  line-height: 1;
  letter-spacing: -.04em;
  color: var(--green-900);
  white-space: nowrap;
}
.hero__line { display: flex; align-items: center; gap: calc(12 * var(--u)); }
.hero__pair { display: flex; align-items: center; gap: calc(8 * var(--u)); }
.hero__icon { width: 1em; height: 1em; flex: none; }

/* The sleeping cat: three "z"s drift up from its head, one after another.
   Taken from the Figma Motion timeline (one cycle is 2.725s; each z follows
   the same path, a third of a cycle apart). */
.hero__cat > img:first-child { display: block; width: 100%; height: auto; }
.hero__z {
  position: absolute;
  left: calc(60 * var(--u));
  top: calc(5.75 * var(--u));
  width: calc(var(--w) * var(--u));
  max-width: none;
  height: auto;
  opacity: 0;
  pointer-events: none;
  animation: cat-z 2.725s linear infinite;
}
.hero__z--2 { animation-delay: -1.8167s; }
.hero__z--3 { animation-delay: -.9083s; }
@keyframes cat-z {
  0% { translate: calc(0 * var(--u)) calc(7 * var(--u)); scale: 0.82; opacity: 0; }
  4.17% { translate: calc(1.011 * var(--u)) calc(5 * var(--u)); scale: 0.832; opacity: 0.158; }
  8.33% { translate: calc(2.018 * var(--u)) calc(3 * var(--u)); scale: 0.845; opacity: 0.533; }
  12.5% { translate: calc(3.015 * var(--u)) calc(1 * var(--u)); scale: 0.857; opacity: 0.887; }
  16.67% { translate: calc(4 * var(--u)) calc(-1 * var(--u)); scale: 0.87; opacity: 1; }
  20.83% { translate: calc(4.968 * var(--u)) calc(-3 * var(--u)); scale: 0.882; opacity: 1; }
  25% { translate: calc(5.914 * var(--u)) calc(-5 * var(--u)); scale: 0.895; opacity: 1; }
  29.17% { translate: calc(6.837 * var(--u)) calc(-7 * var(--u)); scale: 0.907; opacity: 1; }
  33.33% { translate: calc(7.732 * var(--u)) calc(-9 * var(--u)); scale: 0.92; opacity: 1; }
  37.5% { translate: calc(8.598 * var(--u)) calc(-11 * var(--u)); scale: 0.932; opacity: 1; }
  41.67% { translate: calc(9.432 * var(--u)) calc(-13 * var(--u)); scale: 0.945; opacity: 1; }
  45.83% { translate: calc(10.233 * var(--u)) calc(-15 * var(--u)); scale: 0.957; opacity: 1; }
  50% { translate: calc(11 * var(--u)) calc(-17 * var(--u)); scale: 0.97; opacity: 1; }
  54.17% { translate: calc(11.733 * var(--u)) calc(-19 * var(--u)); scale: 0.982; opacity: 1; }
  58.33% { translate: calc(12.432 * var(--u)) calc(-21 * var(--u)); scale: 0.995; opacity: 1; }
  62.5% { translate: calc(13.098 * var(--u)) calc(-23 * var(--u)); scale: 1.007; opacity: 1; }
  66.67% { translate: calc(13.732 * var(--u)) calc(-25 * var(--u)); scale: 1.02; opacity: 1; }
  70.83% { translate: calc(14.337 * var(--u)) calc(-27 * var(--u)); scale: 1.032; opacity: 0.981; }
  75% { translate: calc(14.914 * var(--u)) calc(-29 * var(--u)); scale: 1.045; opacity: 0.887; }
  79.17% { translate: calc(15.468 * var(--u)) calc(-31 * var(--u)); scale: 1.057; opacity: 0.728; }
  83.33% { translate: calc(16 * var(--u)) calc(-33 * var(--u)); scale: 1.07; opacity: 0.533; }
  87.5% { translate: calc(16.515 * var(--u)) calc(-35 * var(--u)); scale: 1.083; opacity: 0.332; }
  91.67% { translate: calc(17.018 * var(--u)) calc(-37 * var(--u)); scale: 1.095; opacity: 0.158; }
  95.83% { translate: calc(17.511 * var(--u)) calc(-39 * var(--u)); scale: 1.107; opacity: 0.041; }
  100% { translate: calc(18 * var(--u)) calc(-41 * var(--u)); scale: 1.12; opacity: 0; }
}

/* Draggable illustrations ---------------------------------------------------
   Anything in the scene with data-drag can be picked up and put down anywhere
   in the hero. js/parallax.js writes --dx / --dy in Figma pixels, so a moved
   object keeps its place when the scene scales. Parallax (--py) still adds on
   top. Positions are not saved: a reload puts everything back. */
.hero__obj[data-drag] {
  translate:
    calc(var(--bx, 0px) + var(--dx, 0) * var(--u))
    calc(var(--py, 0px) + var(--dy, 0) * var(--u));
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  transition: scale .2s ease;
}
@media (hover: hover) {
  .hero__obj[data-drag]:hover { scale: .9; }
}
.hero__obj[data-drag].is-dragging { scale: .9; cursor: grabbing; }

@container (max-width: 759px) {
  /* Phones: zoom in on the desk so the headline stays readable. */
  .hero__scene { --u: calc(100cqw / 860); }
  .hero__plant--left { translate: -58% var(--py, 0px); }
  .hero__plant--right { translate: 58% var(--py, 0px); }
}

/* Intro card -------------------------------------------------------------- */
.intro { position: relative; padding-top: clamp(16px, 3.2vw, 31px); }
/* Two pins hold the card up: 40px in from the left, 42px in from the right. */
.intro__pin {
  position: absolute;
  top: 0;
  right: clamp(20px, 4.4vw, 42px);
  width: clamp(40px, 6.8vw, 65px);
  z-index: 1;
}
.intro__pin--left { right: auto; left: clamp(20px, 4.2vw, 40px); }
.intro__frame {
  padding: clamp(36px, 6.7vw, 64px) clamp(8px, 1.25vw, 12px) clamp(8px, 1.25vw, 12px);
  border-radius: clamp(28px, 4.2vw, 40px);
  background: linear-gradient(to bottom, var(--grad-light), var(--grad-deep) 92.5%);
}
.intro__body {
  display: flex;
  flex-direction: column;
  gap: 19px;
  padding: clamp(20px, 3.4vw, 32px);
  border-radius: clamp(22px, 3.4vw, 32px);
  background: var(--surface);
}

/* Work -------------------------------------------------------------------- */
.work-list {
  display: flex;
  flex-direction: column;
  gap: var(--section-gap);
  margin-top: var(--section-gap);
}
.work { display: flex; flex-direction: column; gap: 24px; }
.work--roomy { gap: 32px; }
.work__head { display: flex; flex-direction: column; gap: 6px; }
.work__head--olive .eyebrow { color: var(--olive-800); }

/* An animated scene in a work card (the HAL 9000 loop, a Figma Motion timeline
   played as a Lottie). It works like the footer: the stage is a box with the
   scene's aspect ratio (883 x 460), holding a still of the first frame.
   js/parallax.js adds the Lottie's <svg> and marks the stage .is-playing; if
   it never does, or the visitor prefers reduced motion, the still stays. */
.scene { overflow: hidden; overflow: clip; }
.scene__stage { position: relative; width: 100%; aspect-ratio: 883 / 460; }
.scene__poster,
.scene__stage > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
}
.scene__stage.is-playing .scene__poster { visibility: hidden; }

.demo { display: grid; grid-template-columns: 478fr 470fr; gap: 12px; }
.demo__media,
.demo__copy {
  border-radius: 24px;
  padding: clamp(24px, 4.2vw, 40px) clamp(20px, 3.4vw, 32px);
  background: linear-gradient(to bottom, var(--card), rgba(242, 252, 233, 0));
}
.demo__media { display: flex; align-items: center; justify-content: center; }
.demo__screen {
  display: block;
  width: min(100%, calc(var(--w, 260) * 1px));
  height: auto;
  background: #1a100c;
  border: 4px solid rgba(0, 0, 0, .11);
  border-radius: 20px;
  box-shadow: 0 -4px 64px rgba(0, 0, 0, .2);
}
.demo__copy { display: flex; flex-direction: column; gap: clamp(24px, 4.9vw, 47px); }
.demo__block { display: flex; flex-direction: column; gap: 8px; }

@media (max-width: 719px) {
  .demo { grid-template-columns: 1fr; }
  /* Phones: zoom in on the middle of the scene (589 of its 883 design pixels
     are visible), so the device and its label stay readable. */
  .scene__stage { width: 150%; margin-left: -25%; }
}
