@charset "UTF-8";
/* ==========================================================================
   Arrow Point, Leyland
   Built from Figma frame "Desktop - 1" (1440 × 3671).
   Type scale, colour and geometry taken from assets/css/figma-export.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand palette (named per the Figma colour styles) */
  --ap-black:   #0D0728;
  --ap-blue:    #1D6DFD;
  --ap-blue-2:  #91C3FF;
  --ap-lime:    #CBFF95;
  --white:      #FFFFFF;

  /* Type scale — every size is line-height 1.2 in the source design */
  --fs-display: clamp(1.75rem, 2.78vw, 2.5rem);   /* 40px */
  --fs-lead:    clamp(1.375rem, 2.08vw, 1.875rem); /* 30px */
  --fs-lg:      clamp(1.0625rem, 1.39vw, 1.25rem); /* 20px */
  --fs-base:    clamp(0.9375rem, 1.11vw, 1rem);    /* 16px */
  --fs-xs:      0.75rem;                           /* 12px */

  --lh: 1.2;

  /* Cap for the PLACE / SPACE / PEOPLE columns only. Everything else runs
     full-bleed on its gutter. Figma proportions are against 1440 and scaled up. */
  --canvas: 1620px;
  --gutter: clamp(1.25rem, 4.86vw, 4.375rem); /* 70px at 1440 */

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  /* Long, soft deceleration — no overshoot, nothing springy */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* --------------------------------------------------------------------------
   2. Reset / base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: 'Silka', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  font-weight: 300;
  font-size: var(--fs-base);
  line-height: var(--lh);
  color: var(--ap-black);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, p, figure { margin: 0; }

img, svg { display: block; max-width: 100%; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--ap-lime);
  outline-offset: 3px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. Button — 256 × 45, fully rounded (border-radius 200px in Figma)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16rem;   /* 256px */
  min-height: 2.8125rem; /* 45px */
  padding: 0.625rem 1.75rem;
  border-radius: 200px;
  box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25);
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: var(--lh);
  text-decoration: none;
  transition: background-color 0.25s var(--ease),
              color 0.25s var(--ease),
              transform 0.25s var(--ease);
}

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--dark {
  background: var(--ap-black);
  color: var(--white);
}
.btn--dark:hover {
  background: var(--ap-lime);
  color: var(--ap-black);
}

.btn--lime {
  background: var(--ap-lime);
  color: var(--ap-black);
}
.btn--lime:hover { background: var(--white); }

/* --------------------------------------------------------------------------
   4. Hero — Figma 0 → 971
   The aerial render already carries the blue geometric overlay; the gradient
   sits behind it so ultra-wide viewports never show bare background.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  /* Full screen height. svh = the *small* viewport, so on mobile the hero still
     fits when the browser's address bar is expanded. min- not fixed height, so
     a short window grows the hero rather than clipping the content. */
  min-height: 100vh; /* fallback for browsers without svh */
  min-height: 100svh;
  padding: 3.875rem var(--gutter) 2.8125rem; /* 62px top / 45px bottom */
  text-align: center;
  color: var(--white);
  background-color: var(--ap-black);
  background-image: url('../images/hero.jpg'),
                    linear-gradient(243.6deg, #0D0728 0.04%, #1D6DFD 66.33%, #91C3FF 99.96%);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

.hero__logo {
  width: min(28.83rem, 60%); /* 461px at 1440 */
  height: auto;
  margin-inline: auto;
}

.hero__title {
  /* Wide enough to hold "...Logistics Units" on one line before the break */
  max-width: 56rem;
  margin: 2.75rem auto 0; /* 44px below the logo */
  font-size: var(--fs-display);
  font-weight: 300;
  line-height: var(--lh);
}

/* The unit sizes carry the message — bold against the light headline */
.hero__title strong {
  font-weight: 700;
}

.hero__completion {
  margin-top: 1.375rem; /* 22px */
  font-size: var(--fs-lead);
  font-weight: 600;
}

.hero__cta { margin-top: 2.6875rem; } /* 43px */

/* Postcode + what3words, pinned to the foot of the hero */
.hero__location {
  margin-top: auto;
  padding-top: 3rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 2.8125rem; /* 45px between the two halves */
  font-size: var(--fs-base);
  letter-spacing: 0.05em;
}

.hero__postcode { font-weight: 700; }
.hero__w3w { font-weight: 300; }

a.hero__w3w {
  text-decoration: none;
  transition: color 0.25s var(--ease);
}
a.hero__w3w:hover { color: var(--ap-lime); }

/* --------------------------------------------------------------------------
   5. Connect — Figma 971 → 1512 (white fading up from #91C3FF)
   -------------------------------------------------------------------------- */
.connect {
  position: relative;
  z-index: 2;
  padding: 2.625rem 0 0; /* heading sits 42px into the section */
  background: linear-gradient(0deg, #91C3FF -45.29%, #FFFFFF 60.91%);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}

.connect__title {
  /* 560px of text + the gutter padding, which border-box counts in max-width */
  max-width: 50rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
  font-size: var(--fs-display);
  font-weight: 300;
  line-height: var(--lh);
  text-align: center;
}

/* The three pillars sit inboard of the left-hand column graphic, which is why
   the block is deliberately off-centre (325px left / 193px right at 1440). */
.pillars {
  display: grid;
  grid-template-columns: 1.17fr 1fr 1fr;
  /* Capped to the design canvas — the padding below is a % of this box, so
     without the cap the columns keep spreading past 1440 and run under the
     decorative columns. */
  max-width: var(--canvas);
  margin: 3.125rem auto 0; /* columns begin at 1159px, 50px under the heading */
  /* % padding resolves against the containing block, not this capped box, so
     each side is clamped — the 1440 values (325 / 144) scaled to the 1620 cap. */
  padding: 0 min(10%, 10.125rem) 0 min(22.57%, 22.85rem);
}

.pillar {
  position: relative;
  padding: 0 1.5rem 2.1875rem 0.75rem;
  border-left: 1px solid var(--ap-blue);
}

/* The "+" marks sit in the gutter, left of dividers 2 and 3 */
.pillar + .pillar::before {
  content: '';
  position: absolute;
  top: 0;
  left: -1.5625rem; /* 25px */
  width: 1.25rem;
  height: 1.25rem;
  background: url('../ui/ui_icon+.svg') no-repeat center / contain;
}

.pillar__icon {
  width: 4.75rem;  /* 76px */
  height: 4.75rem;
  margin-bottom: 1.375rem;
}

.pillar__label {
  margin-bottom: 0.4375rem; /* copy starts at 1287 */
  font-size: var(--fs-lg);
  font-weight: 300;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.pillar__copy {
  font-size: var(--fs-base);
  font-weight: 300;
  line-height: var(--lh);
}

/* --- Decorative blue columns, overlapping the section boundaries ----------
   Anchored to the viewport edges rather than the 1440 canvas, so on wide
   screens they move outboard with the window and stay clear of the copy. */
.stage-columns {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.stage-columns img {
  position: absolute;
  width: min(17.57%, 15.8125rem); /* tracks the canvas, caps at 253px */
  filter: drop-shadow(0 5px 10px rgba(0, 0, 0, 0.2));
}

/* Offsets are measured from the top of .connect (Figma y=971) and expressed in
   vw so they track the canvas, then freeze once the 1440 design width is hit.
   Percentages can't be used here — they'd resolve against the section's own
   height, which varies with how the body copy wraps. */

/* Figma: top 519, 253 × 660 — rises 452px into the hero.
   The artwork is 756 × 1663, so this box stretches it ~1.19× as the design does. */
.stage-columns .col-right {
  right: 3.125rem; /* 50px off the window edge */
  top: max(-31.39vw, -28.25rem); /* -452px */
  aspect-ratio: 253 / 660;
}

/* Figma: top 1169, 253 × 514 — drops 171px over the location map */
.stage-columns .col-left {
  left: 3.125rem; /* 50px off the window edge */
  top: min(13.75vw, 12.375rem); /* 198px */
  aspect-ratio: 253 / 514;
}

/* --------------------------------------------------------------------------
   6. Location map — Figma 1512 → 2376
   -------------------------------------------------------------------------- */
.location {
  position: relative;
  z-index: 1;
  /* Explicit width is load-bearing: with aspect-ratio + min-height and an auto
     width, the browser resolves the width back out of the height and the
     section grows wider than the viewport. */
  width: 100%;
  aspect-ratio: 1440 / 864;
  min-height: 22rem;
  background: var(--ap-black) url('../images/occupier-map.jpg') no-repeat center / cover;
}

/* --------------------------------------------------------------------------
   7. Development render — Figma 2396, 1400 × 782, 20px radius
   -------------------------------------------------------------------------- */
.render {
  padding: 1.25rem; /* 20px frame on all sides, full-bleed */
  background: var(--white);
}

.render img {
  width: 100%;
  height: auto;
  border-radius: 1.25rem;
}

/* --------------------------------------------------------------------------
   8. Footer — Figma 3198 → 3671
   -------------------------------------------------------------------------- */
.site-footer {
  padding: 3.5rem var(--gutter) 3.875rem; /* 56 / 62 top and bottom */
  color: var(--white);
  background: var(--ap-black);
}

.footer__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2rem;
}

.footer__title {
  font-size: var(--fs-display);
  font-weight: 300;
  line-height: var(--lh);
}

.footer__body {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 2.5rem 2rem;
  margin-top: 2.75rem;
}

/* --- Joint agents --------------------------------------------------------- */
.agent {
  display: grid;
  grid-template-columns: 8.625rem 1fr; /* 138px logo column */
  gap: 0 1.9375rem;
}

.agent__logo {
  grid-row: 1 / span 2;
  width: 100%;
  height: auto;
  align-self: start;
  margin-top: 0.25rem;
}

.agent__contact { font-style: normal; }
.agent__contact + .agent__contact { margin-top: 2rem; } /* 91px row pitch */

.agent__name {
  font-weight: 700;
  font-size: var(--fs-base);
}

.agent__contact a {
  display: block;
  font-weight: 300;
  text-decoration: none;
  transition: color 0.25s var(--ease);
}
.agent__contact a:hover { color: var(--ap-lime); }

/* --- Developer lockup ----------------------------------------------------- */
.developer {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 1.25rem;
  text-align: right;
}

.developer__label {
  font-size: var(--fs-base);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.developer__marks {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.developer__marks img { height: 2.75rem; width: auto; }

.developer__rule {
  width: 1px;
  height: 2.75rem;
  background: rgba(255, 255, 255, 0.35);
}

/* Stand-in for the missing Caddick mark — see the note in index.html */
.developer__caddick {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
}

/* --- Legal ---------------------------------------------------------------- */
.legal {
  margin-top: 3rem;
  font-size: var(--fs-xs);
  font-weight: 300;
  line-height: 1.2;
  color: rgba(255, 255, 255, 0.75);
}

.legal a {
  font-weight: 700;
  color: var(--white);
  text-decoration: none;
}
.legal a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   9. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  .pillars { padding-inline: var(--gutter); grid-template-columns: repeat(3, 1fr); }
  .footer__body { grid-template-columns: 1fr 1fr; }
  .developer {
    grid-column: 1 / -1;
    align-items: flex-start;
    text-align: left;
  }
}

@media (max-width: 1023px) {
  /* The blue columns are sized to the 1440 canvas; below it they crowd the copy. */
  .stage-columns { display: none; }
}

@media (max-width: 860px) {
  /* Stacked, the columns no longer run to the section edge, so the gradient
     needs its own foot before the location map starts. */
  .connect { padding-bottom: 3.5rem; }

  .pillars {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    margin-top: 3.5rem;
  }
  .pillar { padding-bottom: 0; }

  /* The "+" joins are still the divider between one pillar and the next — they
     just move from the side gutter into the vertical gap, centred on the rule. */
  .pillar + .pillar::before {
    top: -1.875rem;
    left: -0.625rem;
  }

  .pillar__copy { max-width: 38em; } /* keep a readable measure once stacked */

  .footer__body { grid-template-columns: 1fr; }
  .agent { grid-template-columns: 7.5rem 1fr; }
}

@media (max-width: 620px) {
  :root { --fs-display: 1.75rem; --fs-lead: 1.375rem; }

  .hero { padding-top: 2.5rem; }
  .hero__logo { width: min(20rem, 80%); }
  .hero__title { margin-top: 2rem; }
  .hero__cta { margin-top: 2rem; }
  .hero__location { gap: 0.375rem; flex-direction: column; }

  .btn { min-width: 0; width: 100%; max-width: 20rem; }

  /* Match the artwork's own ratio so the occupier labels aren't cropped away.
     min-height must go too, or it would crop the ratio straight back off. */
  .location { aspect-ratio: 2048 / 1448; min-height: 0; }
  .render { padding: 0.75rem; }
  .render img { border-radius: 0.75rem; }

  .agent { grid-template-columns: 1fr; gap: 1.25rem; }
  .agent__logo { grid-row: auto; width: 7.5rem; }
}

/* --------------------------------------------------------------------------
   10. Motion

   Hidden states live behind BOTH `.js` and a no-preference motion query, so
   with JS off — or reduced motion on — nothing is ever hidden in the first
   place and the page renders exactly as it does without this section.
   -------------------------------------------------------------------------- */
@keyframes ap-rise {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {

  /* --- On load: the hero resolves from the logo down ---------------------- */
  .js .hero__logo,
  .js .hero__title,
  .js .hero__completion,
  .js .hero__cta,
  .js .hero__location {
    animation: ap-rise 1s var(--ease-out) both;
  }

  .js .hero__logo       { animation-delay: 0.15s; }
  .js .hero__title      { animation-delay: 0.35s; }
  .js .hero__completion { animation-delay: 0.50s; }
  .js .hero__cta        { animation-delay: 0.65s; }
  .js .hero__location   { animation-delay: 0.85s; }

  /* --- On scroll: each block fades up as a whole ------------------------- */
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 1s var(--ease-out),
                transform 1s var(--ease-out);
  }

  .js [data-reveal].is-visible {
    opacity: 1;
    transform: none;
  }

  /* Full-bleed panels just fade — sliding something this large reads as a jolt */
  .js .location[data-reveal],
  .js .render[data-reveal] {
    transform: none;
    transition-duration: 1.3s;
  }

  /* Side by side, PLACE / SPACE / PEOPLE cross into view at the same moment,
     so a small delay per block makes them land one after another. */
  .js .pillar:nth-child(1) { transition-delay: 0s; }
  .js .pillar:nth-child(2) { transition-delay: 0.15s; }
  .js .pillar:nth-child(3) { transition-delay: 0.30s; }

  /* Stacked, each block crosses the fold on its own, so the same delay would
     just read as lag. Stagger belongs to the side-by-side layout only. */
  @media (max-width: 860px) {
    .js .pillar:nth-child(2),
    .js .pillar:nth-child(3) { transition-delay: 0s; }
  }

  .js .footer__body { transition-delay: 0.12s; }
  .js .legal        { transition-delay: 0.24s; }

  /* Both columns are parked off-canvas while hidden, so an observer on the
     element itself would never intersect — JS reveals them instead. The right
     one waits for the first scroll (it's on screen at load, so animating it
     immediately would play before anyone is looking), the left one arrives
     with the columns block it sits beside. */
  .js .col-left,
  .js .col-right {
    opacity: 0;
    transition: opacity 1.9s var(--ease-out),
                transform 1.9s var(--ease-out);
  }

  .js .col-left  { transform: translateX(-120%); }
  .js .col-right { transform: translateX(120%); }

  .js .col-left.is-visible,
  .js .col-right.is-visible {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   11. Preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:hover { transform: none; }
}
