/* Extracted from the page's inline <style> block.
   The site's Content-Security-Policy is style-src 'self', which blocks
   inline styles outright. Same rules, same order, now served as a file. */

/* The header carries the four standard links only. A "Register your
   interest" pill sat here at first and the banner route ran straight
   through it, and it pointed at the section directly below anyway. */

/* ====================================================================
   PAGE BANNER
   Same three ground layers as the homepage hero, recomposed so the two
   are recognisably related without being the same picture. 0 KB.
   ==================================================================== */

.page-banner {
  position: relative;
  display: flex;
  min-height: 400px;
  align-items: center;
  overflow: hidden;
  padding: calc(var(--header-h) + 34px) clamp(22px, 5vw, 82px) 54px;
  color: var(--white);
  background:
    radial-gradient(900px 520px at 16% 88%, rgba(215, 25, 32, 0.17), transparent 62%),
    radial-gradient(760px 480px at 88% 8%, rgba(255, 255, 255, 0.05), transparent 62%),
    linear-gradient(157deg, #191d22 0%, #121519 46%, #0b0d0f 100%);
}

.page-banner::before {
  position: absolute;
  z-index: 0;
  inset: 0;
  content: "";
  background-image: radial-gradient(rgba(255, 255, 255, 0.16) 1px, transparent 1.4px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(68deg, transparent 30%, #000 60%, transparent 96%);
  mask-image: linear-gradient(68deg, transparent 30%, #000 60%, transparent 96%);
  opacity: 0.5;
}

.page-banner__mark {
  position: absolute;
  z-index: 0;
  top: 74px;
  right: -150px;
  width: min(38vw, 520px);
  height: auto;
  opacity: 0.06;
}

.page-banner__content {
  position: relative;
  z-index: 3;
  width: min(680px, 60vw);
}

.page-banner__crumb {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px;
  color: var(--red-on-dark);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.115em;
  text-transform: uppercase;
}

.page-banner__crumb a {
  color: inherit;
  border-bottom: 1px solid rgba(255, 77, 84, 0.4);
  text-decoration: none;
}

.page-banner__crumb a:hover,
.page-banner__crumb a:focus-visible {
  border-bottom-color: currentColor;
}

.page-banner__crumb span[aria-hidden] {
  color: rgba(255, 255, 255, 0.34);
}

/* One step below the homepage hero's 50px, so the homepage keeps the top
   of the hierarchy while this still reads as a page headline. */
.page-banner h1 {
  max-width: 17ch;
  margin: 0;
  font-size: clamp(32px, 3.1vw, 46px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.07;
  text-wrap: balance;
}

.page-banner__intro {
  max-width: 52ch;
  margin: 22px 0 0;
  color: var(--body-on-ink);
  font-size: clamp(16px, 1.05vw, 18px);
  line-height: 1.62;
}

/* --- The banner route ------------------------------------------------ */

/* The drawing area starts below the header, not at the top of the banner.
   Full-bleed, the entering segment ran straight through the navigation
   links at desktop widths. Offsetting the region is robust at every
   width, where nudging the path sideways would only miss the links until
   the nav wrapped or a label changed. */
.page-banner__route {
  position: absolute;
  z-index: 1;
  top: var(--header-h);
  left: 0;
  width: 100%;
  height: calc(100% - var(--header-h));
  pointer-events: none;
}

.route-path {
  fill: none;
  stroke: var(--red);
  stroke-width: var(--route-width);
  stroke-linecap: round;
}

.route-path--track {
  opacity: 0.13;
}

.page-banner__route .route-path--live {
  stroke-dasharray: 800;
  stroke-dashoffset: 800;
  animation: banner-draw 1500ms cubic-bezier(0.22, 0.61, 0.36, 1) 220ms forwards;
}

@keyframes banner-draw {
  to {
    stroke-dashoffset: 0;
  }
}

.route-node {
  position: absolute;
  z-index: 2;
  width: 20px;
  height: 20px;
  border: var(--route-width) solid var(--red);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

/* Node positions are percentages of the banner, but the route now only
   covers the part below the header, so the same fraction is taken of
   that shorter box to keep the node sitting on the line. */
.page-banner__node {
  top: calc(var(--header-h) + (100% - var(--header-h)) * 0.575);
  left: 59.7%;
  background: #121519;
  opacity: 0;
  animation: node-in 400ms ease 1250ms forwards;
}

@keyframes node-in {
  to {
    opacity: 1;
  }
}

/* ====================================================================
   THE PAGE RAIL
   ==================================================================== */

.route-flow {
  /* Where the line stops, measured up from the bottom of the flow, so
     the rail ends exactly on the terminal node instead of running past
     it. The last section here is the form, so this clears it. */
  --end-stop: 150px;

  position: relative;
}

.route-flow__connector {
  position: absolute;
  z-index: 4;
  top: 0;
  left: 0;
  width: 100%;
  height: 130px;
  pointer-events: none;
}

.route-flow__connector .route-path--live {
  stroke-dasharray: 620;
  stroke-dashoffset: 620;
  animation: banner-draw 900ms cubic-bezier(0.22, 0.61, 0.36, 1) 1450ms forwards;
}

.route-flow__rail,
.route-flow__rail-track {
  position: absolute;
  z-index: 4;
  top: 126px;
  right: 5%;
  bottom: var(--end-stop);
  width: var(--route-width);
  border-radius: 2px;
  background: var(--red);
  transform: translateX(50%);
  pointer-events: none;
}

.route-flow__rail-track {
  opacity: 0.13;
}

/* Scroll-linked drawing with no JavaScript, using a scroll-driven
   animation. Everything is drawn and visible by default; the animated
   state is opted into only where the browser supports it. */
@supports (animation-timeline: scroll()) {
  .route-flow__rail {
    transform-origin: top;
    scale: 1 0;
    animation: rail-draw linear forwards;
    animation-timeline: scroll(root block);
    animation-range: 20% 86%;
  }

  @keyframes rail-draw {
    to {
      scale: 1 1;
    }
  }
}

.route-flow__node {
  z-index: 5;
  right: 5%;
  background: var(--paper);
  transform: translate(50%, -50%);
}

.route-flow__node--turn {
  top: 0;
}

/* translateY(+50%) so the node's centre lands exactly on --end-stop. */
.route-flow__node--end {
  bottom: var(--end-stop);
  background: var(--white);
  transform: translate(50%, 50%);
}

@media (max-width: 860px) {
  .page-banner__route,
  .page-banner__node,
  .route-flow__connector,
  .route-flow__rail,
  .route-flow__rail-track,
  .route-flow__node {
    opacity: 0.5;
  }
}

@media (max-width: 720px) {
  .page-banner {
    min-height: 0;
  }

  .page-banner__content {
    width: 100%;
  }

  .page-banner__route,
  .page-banner__mark,
  .route-flow__connector,
  .route-flow__rail,
  .route-flow__rail-track,
  .route-node {
    display: none;
  }
}

/* ====================================================================
   CONTENT
   Copy is PROVISIONAL and not signed off.
   ==================================================================== */

.mock-section {
  position: relative;
  padding: 84px clamp(22px, 5vw, 82px);
  background: var(--paper);
}

.mock-section--white {
  background: var(--white);
}

.mock-section--lede {
  padding-top: 96px;
}

.mock-lede {
  max-width: 62ch;
  margin: 0;
  color: var(--body-on-paper);
  font-size: clamp(17px, 1.2vw, 20px);
  line-height: 1.66;
}

.mock-section h2 {
  max-width: 20ch;
  margin: 0 0 42px;
  font-size: clamp(27px, 2.6vw, 38px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.14;
}

.mock-grid {
  display: grid;
  max-width: 1180px;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Hover lift, matching the homepage service rows. Uses `translate`
   rather than `transform`, because the reveal animation's settled state
   sets `transform` and the two would otherwise fight. */
.mock-card {
  padding: 30px 28px 34px;
  border: 1px solid transparent;
  background: transparent;
  translate: 0 0;
  transition:
    translate 260ms ease,
    box-shadow 260ms ease,
    background-color 260ms ease,
    border-color 260ms ease;
}

.mock-card:hover,
.mock-card:focus-within {
  border-color: var(--line);
  background: var(--white);
  box-shadow:
    0 2px 6px rgba(17, 19, 22, 0.05),
    0 18px 38px rgba(17, 19, 22, 0.09);
  translate: 0 -5px;
}

.mock-section--white .mock-card:hover,
.mock-section--white .mock-card:focus-within {
  background: var(--paper);
}

.mock-card:hover .mock-card__number,
.mock-card:focus-within .mock-card__number {
  color: var(--red-text);
}

.mock-card h3 {
  margin: 18px 0 10px;
  font-size: clamp(19px, 1.5vw, 23px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.mock-card p {
  margin: 0;
  color: var(--body-on-paper);
  font-size: 16px;
  line-height: 1.64;
}

.mock-card__number {
  display: block;
  color: var(--muted-number);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.115em;
  transition: color 260ms ease;
}

.mock-card__rule {
  display: block;
  width: 34px;
  height: 3px;
  margin-top: 12px;
  background: var(--red);
  transform-origin: left;
}

/* --- The two-column block with the photograph ------------------------ */

.mock-split {
  display: grid;
  max-width: 1180px;
  align-items: center;
  gap: clamp(34px, 5vw, 74px);
  grid-template-columns: 1fr;
}

@media (min-width: 921px) {
  .mock-split {
    grid-template-columns: 1fr minmax(280px, 420px);
  }
}

.mock-split h2 {
  margin-bottom: 22px;
}

.mock-figure {
  position: relative;
  margin: 0;
}

.mock-figure img {
  display: block;
  width: 100%;
  height: auto;
}

/* A red bracket on the corner, tying the photograph to the route rather
   than letting it sit as a foreign object on the page. */
.mock-figure::after {
  position: absolute;
  z-index: 2;
  bottom: -14px;
  left: -14px;
  width: 96px;
  height: 96px;
  border-bottom: var(--route-width) solid var(--red);
  border-left: var(--route-width) solid var(--red);
  content: "";
}

/* --- The numbered steps ---------------------------------------------- */

.mock-steps {
  display: grid;
  gap: 30px;
  max-width: 54ch;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.mock-steps li {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 20px;
  align-items: start;
}

.mock-steps li::before {
  display: flex;
  width: 46px;
  height: 46px;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--red);
  border-radius: 50%;
  color: var(--red-text);
  content: counter(step, decimal-leading-zero);
  counter-increment: step;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.05em;
}

.mock-steps h3 {
  margin: 11px 0 8px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.mock-steps p {
  margin: 0;
  color: var(--body-on-paper);
  font-size: 16px;
  line-height: 1.64;
}

.mock-section--white .mock-steps p {
  color: var(--body-on-white);
}

/* ====================================================================
   THE REGISTRATION FORM
   Uses the same .contact-form and .success hooks as the homepage, so
   script.js validates it and shows the confirmation panel. It is not
   connected to anything.
   ==================================================================== */

.register {
  position: relative;
  padding: 84px clamp(22px, 5vw, 82px) 150px;
  background: var(--white);
}

.register__inner {
  max-width: 760px;
}

.register h2 {
  max-width: 22ch;
  margin: 0 0 16px;
  font-size: clamp(27px, 2.6vw, 38px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.14;
}

.register__intro {
  max-width: 58ch;
  margin: 0 0 34px;
  color: var(--body-on-white);
  font-size: clamp(15px, 1vw, 17px);
  line-height: 1.7;
}

.register .contact-form {
  display: grid;
  gap: 20px 26px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.register .field--wide,
.register .form-notice,
.register .form-foot,
.register .field--consent,
.register .register__collection {
  grid-column: 1 / -1;
}

/* The collection notice sits directly above the consent box, which is
   where it has to be: at the point of collection, not on another page. */
.register__collection {
  margin: 6px 0 0;
  padding: 16px 18px;
  border-left: 3px solid var(--line);
  background: var(--paper);
  color: var(--body-on-paper);
  font-size: 13px;
  line-height: 1.6;
}

.register__collection a {
  color: var(--red-text);
  text-underline-offset: 3px;
}

/* The select is not covered by the shared .field rules, which only reach
   input and textarea. Matched to them here rather than changing the
   shared file. */
.field select {
  width: 100%;
  height: 48px;
  padding: 0 2px;
  border: 0;
  border-bottom: 1px solid #9a9ca0;
  border-radius: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  font-size: 16px;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.field select:focus {
  border-color: var(--red);
  box-shadow: 0 2px 0 var(--red);
}

.field__hint {
  margin: 0;
  color: var(--body-on-white);
  font-size: 13px;
  line-height: 1.55;
}

.field--consent {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 12px;
  align-items: start;
}

.field--consent input {
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--red);
}

.field--consent label {
  color: var(--body-on-white);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.6;
}

/* The error sits under the label, not under the 22px tick column. */
.field__error--consent {
  grid-column: 2;
  margin-top: 6px;
}

.field--consent input[aria-invalid="true"] {
  outline: 2px solid var(--red-dark);
  outline-offset: 2px;
}

.register__resume {
  margin: 26px 0 0;
  padding: 18px 20px;
  border: 1px dashed var(--line);
  color: var(--body-on-white);
  font-size: 14px;
  line-height: 1.62;
}

.register__resume strong {
  color: var(--ink);
}

/* ====================================================================
   ENTRANCE MOTION
   Note the direction of the @supports: content is visible by default and
   the hidden starting state is opted into only where it can actually
   run.
   ==================================================================== */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-rise] {
      opacity: 0;
      translate: 0 22px;
      animation: rise 620ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
      animation-timeline: view();
      animation-range: entry 8% cover 26%;
    }

    .mock-card__rule {
      scale: 0 1;
      animation: rule-grow 520ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
      animation-timeline: view();
      animation-range: entry 12% cover 30%;
    }

    .mock-figure img {
      opacity: 0;
      scale: 1.05;
      animation: figure-settle 900ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
      animation-timeline: view();
      animation-range: entry 4% cover 34%;
    }

    .mock-figure::after {
      opacity: 0;
      animation: node-in 500ms ease forwards;
      animation-timeline: view();
      animation-range: entry 30% cover 46%;
    }
  }
}

@keyframes rise {
  to {
    opacity: 1;
    translate: 0 0;
  }
}

@keyframes rule-grow {
  to {
    scale: 1 1;
  }
}

@keyframes figure-settle {
  to {
    opacity: 1;
    scale: 1;
  }
}

.mock-card:nth-child(2) {
  animation-delay: 90ms;
}

.mock-card:nth-child(3) {
  animation-delay: 180ms;
}

/* ====================================================================
   REDUCED MOTION — everything drawn, settled and still.
   ==================================================================== */

@media (prefers-reduced-motion: reduce) {
  .page-banner__route .route-path--live,
  .route-flow__connector .route-path--live {
    stroke-dashoffset: 0;
    animation: none;
  }

  .page-banner__node,
  .mock-figure::after {
    opacity: 1;
    animation: none;
  }

  .route-flow__rail {
    scale: 1 1;
    animation: none;
  }

  [data-rise],
  .mock-figure img {
    opacity: 1;
    translate: 0 0;
    scale: 1;
    animation: none;
  }

  .mock-card__rule {
    scale: 1 1;
    animation: none;
  }

  .mock-card:hover,
  .mock-card:focus-within {
    translate: 0 0;
  }
}

/* ====================================================================
   MOCKUP FLAG — not part of the design
   ==================================================================== */

.mock-flag {
  margin: 0;
  padding: 11px clamp(22px, 5vw, 82px);
  border-top: 2px solid #b58900;
  background: #3a2c00;
  color: #ffd97a;
  font-size: 13px;
  line-height: 1.5;
}

.mock-flag code {
  color: #ffe9b0;
  font-size: 12px;
}
