@import url("https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Next:wght@400;700&family=Unbounded:wght@600;800&display=swap");
@view-transition{navigation:auto}
:root{--ink:#170F3A;--indigo:#3A25A8;--paper:#F8F6FF;--pink:#F0388C;--amber:#FFC53D;--mint:#37D9A0;--sky:#4FC3F7}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--ink);font:1.05rem/1.6 "Atkinson Hyperlegible Next",system-ui,sans-serif;overflow-x:hidden}
.wrap{max-width:70rem;margin:0 auto;padding:0 1.25rem;position:relative}
h1,h2,h3,.brand,.tick{font-family:Unbounded,system-ui,sans-serif;line-height:1.15;margin:0}
h1{font-size:clamp(1.9rem,5.4vw,4rem);font-weight:800;letter-spacing:-.02em;max-width:20ch}
h2{font-size:clamp(1.5rem,3.4vw,2.3rem);font-weight:800}
h3{font-size:1.2rem;font-weight:600}
p{margin:0 0 1rem;max-width:60ch}
a{color:inherit}
:focus-visible{outline:3px solid var(--pink);outline-offset:3px}
.skip{position:absolute;left:-999px}.skip:focus{left:1rem;top:1rem;z-index:99;background:var(--ink);color:#fff;padding:.5rem 1rem}

.hd{position:sticky;top:0;z-index:20;background:rgba(248,246,255,.85);backdrop-filter:blur(12px)}
.hd .wrap{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem 1rem;padding-block:.7rem}
.brand{display:flex;align-items:center;gap:.6rem;font-size:.95rem;font-weight:800;text-decoration:none}
.brand b{display:grid;place-items:center;width:2.2rem;height:2.2rem;border-radius:.7rem;background:var(--pink);color:#fff;font-size:.75rem;transition:transform .4s cubic-bezier(.3,1.6,.5,1)}
.brand:hover b{transform:rotate(-14deg) scale(1.15)}
nav{display:flex;flex-wrap:wrap;gap:.2rem}
nav a{padding:.4rem .85rem;border-radius:99px;font-weight:700;font-size:.95rem;text-decoration:none;transition:background .25s,transform .25s}
nav a:hover{background:var(--amber);transform:translateY(-2px)}
nav a[aria-current]{background:var(--ink);color:#fff}

.hero{position:relative;overflow:hidden;color:#fff;background:linear-gradient(135deg,var(--indigo),var(--ink));padding:clamp(3.5rem,9vw,6.5rem) 0 clamp(3rem,6vw,4.5rem)}
.hero.sm{padding:clamp(3rem,7vw,5rem) 0}
.hero.pint{background:linear-gradient(135deg,#FF8A1F,var(--amber));color:var(--ink)}
.hero.nz{background:linear-gradient(135deg,#0B7A4B,var(--mint));color:var(--ink)}
.hero.hire{background:linear-gradient(135deg,var(--pink),var(--indigo))}
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(26rem circle at var(--mx,70%) var(--my,20%),rgba(255,255,255,.2),transparent 60%)}
.blob{position:absolute;border-radius:50%;filter:blur(70px);opacity:.55;animation:float 11s ease-in-out infinite alternate}
.b1{width:22rem;height:22rem;background:var(--pink);top:-6rem;right:-4rem}
.b2{width:18rem;height:18rem;background:var(--sky);bottom:-6rem;left:25%;animation-delay:-4s}
.b3{width:13rem;height:13rem;background:var(--amber);top:35%;right:28%;opacity:.35;animation-delay:-7s}
@keyframes float{to{transform:translate(-3rem,2.5rem) scale(1.18)}}
.words span{display:inline-block;opacity:0;transform:translateY(60%) rotate(4deg);animation:up .7s calc(var(--i)*70ms + .1s) cubic-bezier(.2,.8,.2,1) forwards}
@keyframes up{to{opacity:1;transform:none}}
.lead{font-size:1.2rem;max-width:40rem;margin-top:1.5rem}
.acts{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:1.75rem}
.btn{position:relative;overflow:hidden;display:inline-block;padding:.8rem 1.4rem;border-radius:99px;background:var(--pink);color:#fff;font-weight:700;text-decoration:none;transition:transform .25s cubic-bezier(.3,1.6,.5,1),box-shadow .25s}
.btn::after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.5) 50%,transparent 70%);transform:translateX(-120%);transition:transform .6s}
.btn:hover{transform:translateY(-3px) scale(1.05);box-shadow:0 .7rem 1.4rem rgba(23,15,58,.25)}
.btn:hover::after{transform:translateX(120%)}
.btn.alt{background:none;box-shadow:inset 0 0 0 2px currentColor}
.btn.dark{background:var(--ink)}
.more{font-weight:700;text-decoration:none;background:linear-gradient(var(--pink),var(--pink)) 0 100%/100% 3px no-repeat;padding-bottom:2px;transition:background-size .3s}
.more:hover{background-size:100% 100%;color:#fff}

.route{list-style:none;margin:clamp(2.5rem,6vw,4rem) 0 0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:2rem;position:relative}
.route::before{content:"";position:absolute;left:0;right:0;top:.55rem;border-top:4px dotted var(--amber);transform-origin:left;animation:draw 1.6s .5s cubic-bezier(.6,0,.2,1) both}
.route li{position:relative;padding-top:2.4rem}
.route li::before{content:"";position:absolute;top:0;left:0;width:1.3rem;height:1.3rem;border-radius:50%;background:radial-gradient(var(--indigo) 0 30%,var(--amber) 32%);animation:pop .5s cubic-bezier(.3,1.8,.5,1) both}
.route li:nth-child(1)::before{animation-delay:.5s}.route li:nth-child(2)::before{animation-delay:1.3s}.route li:nth-child(3)::before{animation-delay:2.1s}
.route h3{margin-bottom:.35rem}.route p{margin:0;font-size:1rem;opacity:.9}
@keyframes draw{from{transform:scaleX(0)}}@keyframes drawy{from{transform:scaleY(0)}}@keyframes pop{from{opacity:0;transform:scale(.2)}}

.tick{overflow:hidden;background:var(--amber);padding:.9rem 0;font-size:1rem;font-weight:800}
.tick div{display:flex;width:max-content;animation:tick 30s linear infinite}
.tick span{margin-right:2.5rem}.tick span:nth-child(3n+2){color:var(--pink)}.tick span:nth-child(3n){color:var(--indigo)}
.tick:hover div{animation-play-state:paused}
@keyframes tick{to{transform:translateX(-50%)}}

section{padding:clamp(3rem,7vw,5rem) 0}
.soft{background:#EAE4FF}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1.25rem;margin:2rem 0}
.card,.mini{border-radius:1.25rem;padding:1.5rem;background:#fff;transition:transform .25s ease,box-shadow .3s}
.card:hover,.mini:hover{box-shadow:0 1rem 2rem rgba(58,37,168,.18)}
.mini:nth-child(4n+1){background:#FFD3E6}.mini:nth-child(4n+2){background:#CDEEFF}.mini:nth-child(4n+3){background:#CCF5E4}.mini:nth-child(4n){background:#FFEDBB}
.mini h3,.card h3{margin-bottom:.5rem}.mini p,.card p{margin:0 0 .6rem;font-size:1rem}
.tilt{transform:perspective(800px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg))}
.panel{display:grid;grid-template-columns:1fr 1fr;gap:2rem;align-items:center;margin-top:1.5rem;padding:clamp(1.5rem,4vw,3rem);border-radius:2rem;overflow:hidden}
.panel.pint{background:var(--amber)}.panel.nz{background:var(--mint)}
.art{aspect-ratio:4/3;border-radius:1.25rem;background:rgba(255,255,255,.45);color:var(--ink)}
.art svg{width:100%;height:100%;display:block}
.art path{fill:none;stroke:currentColor;stroke-width:3;stroke-dasharray:1 9;stroke-linecap:round;animation:march 1.2s linear infinite}
.art circle{fill:var(--pink);transform-box:fill-box;transform-origin:center;animation:bob 1.6s ease-in-out infinite alternate}
.art circle:nth-of-type(2){animation-delay:-.5s;fill:var(--indigo)}.art circle:nth-of-type(3){animation-delay:-1s}
@keyframes march{to{stroke-dashoffset:-20}}@keyframes bob{to{transform:translateY(-8px) scale(1.15)}}
.tags{display:flex;flex-wrap:wrap;gap:.4rem;margin:.5rem 0 1.25rem;padding:0;list-style:none}
.tags li{border-radius:99px;padding:.1rem .8rem;font-size:.9rem;font-weight:700;color:#fff;background:var(--ink);transition:transform .25s cubic-bezier(.3,1.8,.5,1)}
.tags li:nth-child(4n+1){background:var(--pink)}.tags li:nth-child(4n+2){background:var(--indigo)}.tags li:nth-child(4n+3){background:#0B7A4B}
.tags li:hover{transform:translateY(-3px) rotate(-3deg)}
.steps{counter-reset:s;list-style:none;padding:0;margin:2rem 0 0;display:grid;gap:1rem}
.steps li{counter-increment:s;display:flex;gap:1rem;align-items:flex-start;padding:1rem 1.25rem;background:#fff;border-radius:1rem}
.steps li::before{content:counter(s);flex:none;display:grid;place-items:center;width:2.2rem;height:2.2rem;border-radius:50%;background:var(--pink);color:#fff;font:800 .95rem Unbounded,sans-serif}
.steps h3{font-size:1.05rem;margin-bottom:.15rem}.steps p{margin:0}
.band{background:var(--pink);color:#fff}.band .btn{background:var(--ink)}
.ph{border:3px dashed currentColor;border-radius:1.25rem;padding:1.5rem;margin-top:1rem;opacity:.75}
.back{display:inline-block;margin-bottom:1.5rem;font-weight:700}

.ft{background:var(--ink);color:#fff;padding:4rem 0 2rem}
.mail{display:inline-block;margin:.75rem 0 1rem;font:800 clamp(1.1rem,4vw,2rem) Unbounded,sans-serif;overflow-wrap:anywhere;text-decoration:none;background:linear-gradient(var(--amber),var(--amber)) 0 100%/0 4px no-repeat;transition:background-size .4s}
.mail:hover{background-size:100% 4px}
.ft p a{margin-right:1.25rem}.ft small{opacity:.7}

.js .rv{opacity:0;translate:0 32px;transition:opacity .7s,translate .7s cubic-bezier(.2,.8,.2,1)}
.js .rv.in{opacity:1;translate:0 0}
.grid>.rv:nth-child(2){transition-delay:.1s}.grid>.rv:nth-child(3){transition-delay:.2s}.grid>.rv:nth-child(4){transition-delay:.3s}

@media (max-width:44rem){
.panel{grid-template-columns:1fr}
.route{grid-template-columns:1fr;gap:1.5rem;padding-left:2.2rem}
.route::before{left:.6rem;right:auto;top:.6rem;bottom:.6rem;border-top:0;border-left:4px dotted var(--amber);transform-origin:top;animation-name:drawy}
.route li{padding:0}.route li::before{left:-2.2rem;top:.15rem}
}
@media (prefers-reduced-motion:reduce){
*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
.words span,.js .rv{opacity:1;transform:none;translate:none}
}

.shots {
  position: relative;
  height: 64rem;
  margin-top: 2rem;
}

/* ─────────────────────────────
   Photos
   ───────────────────────────── */

.shot {
  position: absolute;
  width: 220px;
  margin: 0;
  padding: .45rem .45rem .7rem;

  background: #fff;

  box-shadow:
    0 .4rem .8rem rgba(23,15,58,.12),
    0 1.25rem 2rem rgba(23,15,58,.12);

  cursor: pointer;
  z-index: 1;

  transition:
    transform .4s cubic-bezier(.2,1.4,.3,1),
    box-shadow .3s ease;
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: .12rem;
}

.shot figcaption {
  margin: .55rem .1rem 0;
  font-size: .8rem;
  line-height: 1.25;
  font-weight: 700;
}


/* ─────────────────────────────
   Scattered / overlapping layout
   ───────────────────────────── */

/* 01 — top left */
.shot-1 {
  left: 5%;
  top: 2rem;
  transform: rotate(-6deg);
  z-index: 3;
}

/* 02 — central */
.shot-2 {
  left: 27%;
  top: 0;
  width: 240px;
  transform: rotate(4deg);
  z-index: 2;
}

/* 03 — top right */
.shot-3 {
  left: 50%;
  top: 10rem;
  transform: rotate(-3deg);
  z-index: 4;
}

/* 04 — tucked into the middle/right */
.shot-4 {
  left: 66%;
  top: 27rem;
  width: 205px;
  transform: rotate(6deg);
  z-index: 5;
}

/* 05 — lower left */
.shot-5 {
  left: 9%;
  top: 30rem;
  transform: rotate(3deg);
  z-index: 4;
}

/* 06 — lower middle */
.shot-6 {
  left: 43%;
  top: 40rem;
  transform: rotate(-5deg);
  z-index: 3;
}

/* 07 — upper right, overlapping the main cluster */
.shot-7 {
  left: 70%;
  top: 2rem;
  transform: rotate(15deg);
  z-index: 3;
}


/* ─────────────────────────────
   Pick up a photo
   ───────────────────────────── */

.shot:hover {
  z-index: 100;

  transform:
    translateY(-1rem)
    scale(1.13)
    rotate(0deg);

  box-shadow:
    0 1rem 1.5rem rgba(23,15,58,.16),
    0 2.5rem 4rem rgba(23,15,58,.25);
}


/* ─────────────────────────────
   Little background accents
   ───────────────────────────── */

.shots::before {
  content: "";
  position: absolute;

  width: 12rem;
  height: 12rem;

  left: 35%;
  top: 30rem;

  border-radius: 50%;

  background: var(--pink);
  opacity: .06;

  filter: blur(30px);

  pointer-events: none;
}

.shots::after {
  content: "";
  position: absolute;

  width: 14rem;
  height: 14rem;

  right: 8%;
  bottom: 3rem;

  border-radius: 50%;

  background: var(--sky);
  opacity: .05;

  filter: blur(30px);

  pointer-events: none;
}


/* ─────────────────────────────
   Tablet
   ───────────────────────────── */

@media (max-width: 60rem) {

  .shots {
    height: 55rem;
  }

  .shot {
    width: 190px;
  }

  .shot-1 {
    left: 2%;
    top: 1rem;
  }

  .shot-2 {
    left: 25%;
    top: 7rem;
    width: 210px;
  }

  .shot-3 {
    left: 54%;
    top: 0;
  }

  .shot-4 {
    left: 66%;
    top: 24rem;
    width: 180px;
  }

  .shot-5 {
    left: 7%;
    top: 42rem;
  }

  .shot-6 {
    left: 43%;
    top: 48rem;
  }

  .shot-7 {
    left: 69%;
    top: 3rem;
  }

  .shot:hover {
    transform:
      translateY(-.75rem)
      scale(1.09)
      rotate(0deg);
  }
}


/* ─────────────────────────────
   Mobile
   ───────────────────────────── */

@media (max-width: 44rem) {

  .shots {
    height: 66rem;
    margin-top: 1.5rem;
  }

  .shot {
    width: 145px;
    padding: .35rem .35rem .55rem;
  }

  .shot figcaption {
    font-size: .7rem;
  }

  .shot-1 {
    left: 0;
    top: 0;
    transform: rotate(-5deg);
  }

  .shot-2 {
    left: 38%;
    top: 5rem;
    width: 165px;
    transform: rotate(4deg);
  }

  .shot-3 {
    left: 9%;
    top: 22rem;
    transform: rotate(3deg);
  }

  .shot-4 {
    left: 54%;
    top: 28rem;
    width: 140px;
    transform: rotate(-5deg);
  }

  .shot-5 {
    left: 1%;
    top: 43rem;
    transform: rotate(-3deg);
  }

  .shot-6 {
    left: 43%;
    top: 51rem;
    transform: rotate(5deg);
  }

  /* 07 — added to the upper/middle cluster */
  .shot-7 {
    left: 54%;
    top: 17rem;
    width: 140px;
    transform: rotate(8deg);
    z-index: 6;
  }

  .shot:hover {
    transform:
      translateY(-.5rem)
      scale(1.08)
      rotate(0deg);
  }
}


/* ─────────────────────────────
   Very small phones
   ───────────────────────────── */

@media (max-width: 25rem) {

  .shots {
    height: 68rem;
  }

  .shot {
    width: 135px;
  }

  .shot-1 {
    left: 0;
    top: 0;
  }

  .shot-2 {
    left: 39%;
    top: 4rem;
    width: 150px;
  }

  .shot-3 {
    left: 5%;
    top: 24rem;
  }

  .shot-4 {
    left: 52%;
    top: 29rem;
    width: 130px;
  }

  .shot-5 {
    left: 0;
    top: 45rem;
  }

  .shot-6 {
    left: 42%;
    top: 52rem;
  }

  .shot-7 {
    left: 51%;
    top: 18rem;
    width: 130px;
  }
}


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

  .shot:hover {
    transform: none;
  }
}



/* ─────────────────────────────
   Route maps (home page project panels)
   Append to assets/css/style.css
   ───────────────────────────── */

.routemap{aspect-ratio:4/3;border-radius:1.25rem;overflow:hidden;background:rgba(255,255,255,.55);color:var(--ink)}
.routemap svg{display:block;width:100%;height:100%}

/* dotted route: a white halo underneath keeps the dots readable on any map */
.routemap .halo,.routemap .line{fill:none;stroke-linecap:round;stroke-dasharray:1 15;animation:rm-march 1.6s linear infinite}
.routemap .halo{stroke:#fff;stroke-width:10;opacity:.9}
.routemap .line{stroke:var(--ink);stroke-width:5}

/* markers hover gently, each one out of step with the last (--i is set in JS) */
.routemap .bob{animation:rm-bob 1.6s calc(var(--i,0) * -.4s) ease-in-out infinite alternate}

/* map pin (NZ) */
.routemap .pin{fill:var(--pink);stroke:var(--ink);stroke-width:2.5;stroke-linejoin:round}
.routemap .pin-dot{fill:#fff}
.routemap .shadow{fill:var(--ink);opacity:.22}

@keyframes rm-march{to{stroke-dashoffset:-32}}
@keyframes rm-bob{to{transform:translateY(-6px)}}

/* ─────────────────────────────
   Flowing polaroid scatter (small projects page)
   Append to assets/css/style.css, after the existing .shot rules.

   Same polaroids as .shots on the PintRunner page, but they sit in the
   page flow and wrap by themselves, so any number of screenshots (and
   any image height) works without hand-placing each one.
   ───────────────────────────── */

.shots-flow {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;          /* each polaroid keeps its own height */
  margin-top: 2rem;
  padding: 1rem 0 3rem;
}

.shots-flow .shot {
  position: relative;               /* in the flow, not pinned to a spot */
  flex: none;
  width: calc(var(--w, 1) * 220px);
  margin: 0 -.35rem 1.5rem;         /* negative side margins make neighbours overlap */
  top: var(--y, 0);                 /* vertical scatter */
  transform: rotate(var(--r, 0deg));
  z-index: var(--z, 1);
}

.shots-flow .shot:hover {
  z-index: 100;
  transform: translateY(-1rem) scale(1.13) rotate(0deg);
}


/* ─────────────────────────────
   Per-photo scatter:
   --r rotation, --y vertical nudge, --w size multiplier, --z stacking
   Later photos sit on top. Captions are left-aligned, so the part a
   neighbour covers is the spare space at the right-hand end.
   Add another line if you add more photos.
   ───────────────────────────── */

.shots-flow .shot:nth-child(1)  { --r: -6deg; --y: 1.5rem; --w: 1;    --z: 1; }
.shots-flow .shot:nth-child(2)  { --r:  4deg; --y: 0;      --w: 1.08; --z: 2; }
.shots-flow .shot:nth-child(3)  { --r: -3deg; --y: 2rem;   --w: 1;    --z: 3; }
.shots-flow .shot:nth-child(4)  { --r:  6deg; --y: .5rem;  --w: .94;  --z: 4; }
.shots-flow .shot:nth-child(5)  { --r: -5deg; --y: 1.5rem; --w: 1.04; --z: 5; }
.shots-flow .shot:nth-child(6)  { --r:  3deg; --y: 0;      --w: 1;    --z: 6; }
.shots-flow .shot:nth-child(7)  { --r: -5deg; --y: 2rem;   --w: 1.06; --z: 7; }
.shots-flow .shot:nth-child(8)  { --r:  5deg; --y: .5rem;  --w: .96;  --z: 8; }
.shots-flow .shot:nth-child(9)  { --r: -3deg; --y: 1.5rem; --w: 1;    --z: 9; }
.shots-flow .shot:nth-child(10) { --r:  7deg; --y: 0;      --w: 1.02; --z: 10; }


/* ─────────────────────────────
   Little background accents
   ───────────────────────────── */

.shots-flow::before,
.shots-flow::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(30px);
  pointer-events: none;
}

.shots-flow::before {
  width: 12rem;
  height: 12rem;
  left: 30%;
  top: 20%;
  background: var(--pink);
  opacity: .06;
}

.shots-flow::after {
  width: 14rem;
  height: 14rem;
  right: 8%;
  bottom: 10%;
  background: var(--sky);
  opacity: .05;
}


/* ─────────────────────────────
   Hover animation fix (also fixes the PintRunner page)
   .js .rv sets its own `transition`, which replaces the polaroid's
   transform/box-shadow transition, so the "pick up" snapped instead of
   easing. This keeps the reveal fade and the hover ease together.
   ───────────────────────────── */

.js .shot.rv {
  transition:
    opacity .7s,
    translate .7s cubic-bezier(.2,.8,.2,1),
    transform .4s cubic-bezier(.2,1.4,.3,1),
    box-shadow .3s ease;
}


/* ─────────────────────────────
   Tablet
   ───────────────────────────── */

@media (max-width: 60rem) {
  .shots-flow .shot {
    width: calc(var(--w, 1) * 190px);
  }

  .shots-flow .shot:hover {
    transform: translateY(-.75rem) scale(1.09) rotate(0deg);
  }
}


/* ─────────────────────────────
   Mobile
   ───────────────────────────── */

@media (max-width: 44rem) {
  .shots-flow {
    margin-top: 1.5rem;
    padding-bottom: 2.5rem;
  }

  .shots-flow .shot {
    width: calc(var(--w, 1) * 155px);
    margin: 0 -.3rem 1.25rem;
  }

  .shots-flow .shot:hover {
    transform: translateY(-.5rem) scale(1.08) rotate(0deg);
  }
}


/* ─────────────────────────────
   Very small phones
   ───────────────────────────── */

@media (max-width: 25rem) {
  .shots-flow .shot {
    width: calc(var(--w, 1) * 140px);
  }
}


@media (prefers-reduced-motion: reduce) {
  .shots-flow .shot:hover {
    transform: rotate(var(--r, 0deg));
  }
}