/* =========================================================================
   Home — Phase 4
   -------------------------------------------------------------------------
   Measured from the original at 1440 / 1200 / 900 / 375.

   The card images are the surprising part: Wix positions each one absolutely
   with its own hand-set left offset and width, as PERCENTAGES of the viewport.
   Those percentages are identical at 1440, 1200 and 900, and swap to a second
   set below 751px. They are not a grid, so they are reproduced per card rather
   than forced into one — see .card-media--* below.
   ========================================================================= */

/* =========================================================================
   4.1  Hero
   ========================================================================= */
/* The hero is exactly one viewport tall and the intro block is centred in it.
   Checked against the original at three viewport heights: the block's centre
   lands on 450 at 900px tall and on 406 at 812px tall — vh/2 every time. An
   earlier fixed padding-top only matched at the height it was measured at.

   The header is pinned and overlaps this section, so 100vh is the whole
   viewport, not the viewport minus the header. */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
}

/* The hero is pinned and everything below scrolls OVER it — measured: the
   original's hero sits at viewport top 0 at scrollY 1500, 3000 and 5000 while
   the cards travel up normally. Mobile does not do this (at 375 the hero
   scrolls away like anything else), so the pin starts at 751px.
   Sticky rather than fixed: the hero keeps its place in flow, so the page
   height and every measurement below it are unchanged. */
@media (min-width: 751px) {
  .hero {
    position: sticky;
    top: 0;
    z-index: 0;
  }
  /* Opaque and above, or the pinned hero shows through them. */
  .hero-shadow,
  .cards {
    position: relative;
    z-index: 1;
    background: var(--surface);
  }
}

/* Slideshow occupies the left half at desktop; hidden below 751px, which is
   what the original does. */
.hero__media {
  display: none;
}
@media (min-width: 751px) {
  .hero__media {
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    width: 50%;
    height: 100%;
    overflow: hidden;
  }
}

/* The slideshow is full-bleed 50vw, but the copy belongs to the page grid,
   which caps at 1600 and centres. Measured: at 1800 and 2200 the intro stays
   480px wide and starts at 60% of the capped 1600 grid (1060 and 1260), while
   a percentage of the viewport would have put it at 1080 and 1320.
   Wix says the same thing from the other side: container max-width 800 (half
   of 1600), stack 60% of it = 480. */
.hero__text {
  position: relative;
  z-index: 1;
  padding-inline: var(--gutter);
  width: 100%;
}
@media (min-width: 751px) {
  /* The cap goes on the hero, so the text's percentages resolve against a
     1600-wide content box. (Putting it on .hero__text as percentage padding
     does not work: percentage padding resolves against the PARENT's width,
     which left a 60px-wide column at 2200.) The slideshow is absolutely
     positioned, so its containing block is the padding box and it stays
     full-bleed 50vw regardless. */
  .hero { padding-inline: max(0px, calc((100% - var(--container-max)) / 2)); }
  .hero__text {
    margin-left: 60%;
    width: 30%;                /* 60% of the half-width column */
    max-width: 500px;          /* the site-wide cap; 30% of 1600 is 480 */
    padding-inline: 0;
  }
}

/* Stack gaps 12 and 20, measured. The old 24/8 summed to the same total, so
   the button landed correctly while the paragraph sat 12px too low. */
.hero__greeting {
  margin-bottom: 12px;
}
.hero__intro {
  margin-bottom: 20px;
}
.hero__intro strong { font-weight: var(--weight-bold); }

/* =========================================================================
   4.2 / 4.4  Slideshow
   -------------------------------------------------------------------------
   Crossfade between five slides. Caption sits bottom-left, Previous at the
   left edge vertically centred, Next at the bottom-right — all measured.
   ========================================================================= */
.slides {
  position: absolute;
  inset: 0;
}

.slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.5s var(--easing);   /* measured: cross-fade 0.5s */
}
.slide[aria-hidden="false"] { opacity: 1; }
/* A slide at opacity 0 is still clickable, and the last one in the stack sits
   on top: every caption click was opening Point of Sale. */
.slide[aria-hidden="true"] { pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .slide { transition: none; }
}

/* <picture> is an inline box with no height of its own, so height:100% on the
   img inside it resolved to auto and each slide rendered at its intrinsic size
   (720x742 instead of 720x900). The wrapper has to be told to fill first. */
.hero__media picture {
  display: block;
  width: 100%;
  height: 100%;
}

.slide__img {
  width: 100%;
  height: 100%;
  object-fit: cover;               /* "fill bounding box" in the original */
  display: block;
}

/* Two stacked lines in the page's own ink — not white, and no text-shadow.
   Measured at 1440x900: title box 36,812 (16/28, medium), subtitle directly
   under it at 36,840 (14px), the pair sitting 43px off the bottom. */
/* Insets are percentages of the media WIDTH in the original - 5% in from the
   side, 6% up from the bottom - so they grow with the viewport. At 1440 that
   is the 36px/43px this used to hardcode; at 2200 the original sits at 55/66
   and the fixed values were visibly tight. margin-bottom rather than bottom
   because percentage margins resolve against width, which is what Wix does. */
.slide__caption {
  position: absolute;
  left: 5%;
  bottom: 0;
  margin-bottom: 6%;
  color: var(--ink);
}
.slide__title {
  display: block;
  font-size: var(--step-body);
  line-height: var(--step-body-lh);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
}
.slide__sub {
  display: block;
  font-size: var(--step-small);
  line-height: var(--step-small-lh);
}

/* Only Next ships. The original has a Previous control too, but it is fully
   transparent at rest AND on hover — present, never visible — so Martin asked
   for it to go rather than be reproduced as an invisible thing to tab into.
   Every slide is still reachable: Next loops, and ArrowLeft works when focus
   is inside the slideshow. Next carries a grey wash that turns white on
   hover, over 0.2s. */
.slides__btn {
  position: absolute;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-strong);
  cursor: pointer;
  transition: background-color 0.2s var(--easing);
}
.slides__btn--next {
  right: 5%;
  bottom: 0;
  margin-bottom: 6%;
  background: rgba(134, 134, 134, .35);
}
.slides__btn--next:hover { background: rgba(255, 255, 255, .3); }

/* =========================================================================
   4.3  Project cards
   -------------------------------------------------------------------------
   Each tile is a ratio-locked container with its own pale fill, 16px corners
   and a 1px/2px/30% shadow. The artwork is centred inside it at its own
   measured size and never resizes the container — which is what makes the
   four stock-photo replacements safe to drop in later.

   Measured from the original at 1440:
     container  left 7.5%, width 42.5% (612px), ratio 544:730 (821px tall),
                96px below the section top, overflow clipped
     artwork    centred, sized per card, object-fit: contain
                (Amazon Business is the one photo, and it covers)
     text       centred on the section, stack gaps 4 / 16 / 20

   The same container at 900 is 382x513 — the ratio holds. Mobile drops to a
   full-width 327x221 band with the artwork centred in it.
   ========================================================================= */
.cards { padding-top: 0; padding-bottom: 0; }

/* ---- the divider under the hero -----------------------------------------
   White, 20px tall, full-bleed, with a 15px shadow that shows as a soft edge
   against the page. Measured: absent below 751px, and the gap above it is a
   share of the viewport width — 2% at tablet, 1.2% at desktop. That is what
   puts the first card band at 938 / 940 / 937 / 941 / 946 across 900 / 1000 /
   1440 / 1800 / 2200, which a fixed 38px only matched at one width. */
.hero-shadow { display: none; }
@media (min-width: 751px) {
  .hero-shadow {
    display: block;
    position: relative;
    z-index: 1;
    height: 20px;
    margin-top: 2%;
    background: var(--surface);
    box-shadow: 0 0 15px rgba(0, 0, 0, .3);
  }
}
@media (min-width: 1001px) {
  .hero-shadow { margin-top: 1.2%; }
}

.card-row { position: relative; }

.card-media {
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: var(--radius-tile);
  box-shadow: var(--shadow-tile);
}

/* The whole tile is a link to its project — the original wraps both the
   container and the artwork in one. Hovering it grows the artwork by 2% over
   0.2s, eased in and out; the container itself never changes, and it clips.
   The original animates 5% — 2% is Martin's call, logged in Appendix B. */
.card-media picture { display: block; }
.card-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  transition: transform 0.2s ease-in-out;
}
.card-media:hover img,
.card-media:focus-visible img {
  transform: scale(1.02);
}
@media (prefers-reduced-motion: reduce) {
  .card-media img { transition: none; }
  .card-media:hover img,
  .card-media:focus-visible img { transform: none; }
}
/* The one photograph in the set; it fills its box instead of fitting inside. */
.card-media--business img { object-fit: cover; }

.card-media--business { background: var(--tile-business); }
.card-media--blink    { background: var(--tile-blink); }
.card-media--design   { background: var(--tile-design); }
.card-media--trade    { background: var(--tile-trade); }
.card-media--pos      { background: var(--tile-pos); }

.card-text { padding-inline: var(--gutter); }

/* ---- mobile: under 751px. Stacked, centred, content flow. ----------------
   Measured: every section is 48px of padding, the 327x221 tile, a 24px gap,
   the text block, then 48px again. That accounts for all five section
   heights exactly (608 / 565 / 664 / 636 / 593 at 375px). */
@media (max-width: 750px) {
  /* Both text stacks cap at 500 here and centre in what is left — x=50 at
     600, x=100 at 700. The card copy centres on the original too; the hero
     copy does not (it stays against the gutter at x=24), so centring it is a
     deliberate change, logged in Appendix B. Below 548 the viewport is
     narrower than the cap and both simply sit at the gutter. */
  .card-text,
  .hero__text {
    max-width: calc(500px + var(--gutter) * 2);
    margin-inline: auto;
  }

  .card-row { padding-block: 48px; }
  .card-media {
    margin-inline: var(--gutter);
    margin-bottom: var(--space-md);   /* measured 24px */
    aspect-ratio: 327 / 221;
  }
  .card-media--business picture { width: 67.3%; aspect-ratio: 1 / 1; }
  .card-media--blink    picture { width: 57.5%; aspect-ratio: 188 / 220; }
  .card-media--design   picture { width: 58.4%; aspect-ratio: 1 / 1; }
  .card-media--trade    picture { width: 58.4%; aspect-ratio: 1 / 1; }
  .card-media--pos      picture { width: 67.3%; aspect-ratio: 1 / 1; }
}

/* ---- tablet and desktop ---------------------------------------------------
   The row is the page grid: full width up to 1600, then centred. Every
   percentage below resolves against THAT, not the viewport — at 1800 the
   original's section is x=100 w=1600, with the tile at 220 and the copy at
   1060. Against the viewport they would land at 135 and 1080.

   The tile stays in flow and its locked ratio drives the row's height, so the
   96px above and below it are the only vertical numbers here. That reproduces
   every measured band: 1013 at 1440, 705 at 900, 1105 at 1800 — all of which
   used to be hardcoded. */
@media (min-width: 751px) {
  .card-row {
    max-width: var(--container-max);
    margin-inline: auto;
    padding-block: 96px;
  }
  .card-media {
    margin-left: 7.5%;
    width: 42.5%;
    aspect-ratio: 544 / 730;         /* locked */
    margin-bottom: 0;
  }
  .card-text {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    margin-left: 60%;
    width: 30%;                /* 60% of the half-width column */
    max-width: 500px;          /* the site-wide cap; 30% of 1600 is 480 */
    padding-inline: 0;
  }

  /* Artwork widths are shares of the container (612px at 1440), with the
     display ratio each card was cropped to. */
  .card-media--business picture { width: 80.1%; aspect-ratio: 490 / 450; }
  .card-media--blink    picture { width: 100%;  aspect-ratio: 612 / 728; }
  .card-media--design   picture { width: 77.3%; aspect-ratio: 473 / 472; }
  .card-media--trade    picture { width: 69.9%; aspect-ratio: 428 / 538; }
  .card-media--pos      picture { width: 85.0%; aspect-ratio: 520 / 520; }
}

/* ---- tablet: 751-1000 ---- */
@media (min-width: 751px) and (max-width: 1000px) {
  /* Simple Trade is cropped square until desktop. */
  .card-media--trade picture { width: 70.1%; aspect-ratio: 1 / 1; }
  /* The one stack gap that changes with the breakpoint: 20px becomes 24px
     here, measured on all five cards. */
  .card-row__body { margin-bottom: var(--space-md); }
}

/* Stack gaps, confirmed by Martin from the original: 4 / 16 / 20. */
.card-row__eyebrow { margin-bottom: var(--space-2xs); }
.card-row__title {
  font-size: var(--step-section);
  line-height: var(--step-section-lh);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-section);
  margin-bottom: var(--space-sm);
}
.card-row__body { margin-bottom: 20px; }
