/* ==========================================================================
   Structured PM Ltd · components
   Reads tokens.css and base.css. Declares no raw values of its own except
   where a value is structural rather than design (scrollbar width, z-index).

   Shared by all seven pages. Nothing here may be copied into a page.
   ========================================================================== */

/* --- Skip link ---------------------------------------------------------- */

.spm-skip {
  position: absolute;
  left: var(--spm-space-4);
  top: calc(var(--spm-space-4) * -6);
  z-index: 100;
  padding: var(--spm-space-3) var(--spm-space-6);
  background: var(--spm-navy);
  color: var(--spm-on-navy);
  border-radius: var(--spm-radius);
  text-decoration: none;
  transition: top var(--spm-duration-fast) var(--spm-ease);
}

.spm-skip:focus { top: var(--spm-space-4); }


/* --- Header -------------------------------------------------------------
   Wordmark left, links, one orange button. Structured PM is the wordmark
   because the parent always outranks the programme. */

.spm-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--spm-light);
  border-bottom: 1px solid var(--spm-rule);
}

.spm-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spm-space-6);
  min-height: 72px;
}

.spm-wordmark {
  font-family: var(--spm-font-display);
  font-size: var(--spm-size-h3);
  text-transform: uppercase;
  letter-spacing: var(--spm-tracking-display);
  color: var(--spm-navy);
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
}

.spm-wordmark small {
  display: block;
  font-family: var(--spm-font-mono);
  font-size: 9px;
  letter-spacing: var(--spm-tracking-label);
  color: var(--spm-ink-50);
  margin-top: 3px;
}

.spm-nav { display: flex; align-items: center; gap: var(--spm-space-6); }

.spm-nav__links {
  display: flex;
  align-items: center;
  gap: var(--spm-space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.spm-nav__links a {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-ink-70);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--spm-target);
}

.spm-nav__links a:hover,
.spm-nav__links a[aria-current='page'] {
  color: var(--spm-navy);
  text-decoration: underline;
  text-underline-offset: 6px;
}

.spm-nav__toggle {
  display: none;
  min-height: var(--spm-target);
  min-width: var(--spm-target);
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--spm-rule-strong);
  border-radius: var(--spm-radius);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-navy);
  cursor: pointer;
  padding-inline: var(--spm-space-3);
}

/* Mobile is the primary layout, so the stacked header is the default and the
   row is the enhancement. Below 900px the links collapse behind a toggle. */
@media (max-width: 899px) {
  .spm-nav__toggle { display: inline-flex; }

  .spm-nav__links {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--spm-space-4) var(--spm-gutter) var(--spm-space-6);
    background: var(--spm-light);
    border-bottom: 1px solid var(--spm-rule);
  }

  .spm-nav__links[data-open='true'] { display: flex; }

  .spm-nav__links li + li { border-top: 1px solid var(--spm-rule); }

  .spm-header__inner { position: relative; }

  .spm-header__cta { padding-inline: var(--spm-space-4); }
}

/* On a narrow phone the wordmark, the menu toggle and a full length button
   do not fit on one row, so the button moves inside the menu. */
@media (max-width: 539px) {
  .spm-header__cta { display: none; }
  .spm-nav__links .spm-header__cta--menu {
    display: inline-flex;
    margin-top: var(--spm-space-4);
  }
}

@media (min-width: 540px) {
  .spm-nav__links .spm-header__cta--menu { display: none; }
}


/* --- Hero ---------------------------------------------------------------
   Full bleed navy. Hero imagery is Home only. The image slot below is empty
   by design until a real photograph exists, because the brand rule is real
   photography or nothing. */

.spm-hero { padding-block: var(--spm-section); }

.spm-hero__grid {
  display: grid;
  gap: var(--spm-space-12);
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 900px) {
  .spm-hero__grid { grid-template-columns: 7fr 5fr; }
}

.spm-hero__title { margin-top: var(--spm-space-4); }

.spm-hero__sub { margin-top: var(--spm-space-6); }

.spm-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spm-space-6);
  margin-top: var(--spm-space-12);
}

/* Sits under the hero actions on the navy ground, so it takes the muted
   on-navy ink rather than the light-ground one. */
.spm-hero__note {
  margin-top: var(--spm-space-4);
  color: var(--spm-on-navy-70);
}

/* Image slot. Holds its space so the layout does not shift when a real
   photograph is dropped in. */
.spm-hero__media {
  aspect-ratio: 4 / 5;
  border: 1px solid var(--spm-rule-on-navy);
  border-radius: var(--spm-radius);
  display: flex;
  align-items: flex-end;
  padding: var(--spm-space-6);
}

.spm-hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: var(--spm-radius);
}

@media (max-width: 899px) {
  .spm-hero__media { display: none; }
}


/* --- Section heads ------------------------------------------------------ */

.spm-sechead { margin-bottom: var(--spm-space-12); }
.spm-sechead h2 { margin-top: var(--spm-space-4); }
.spm-sechead p { margin-top: var(--spm-space-6); }


/* --- Problem columns ---------------------------------------------------- */

.spm-problem { border-top: 1px solid var(--spm-rule); padding-top: var(--spm-space-8); }
.spm-problem h3 {
  font-size: var(--spm-size-h3);
  line-height: var(--spm-leading-tight);
}
.spm-problem p { margin-top: var(--spm-space-4); color: var(--spm-ink-70); }


/* --- Two for one diagram ------------------------------------------------ */

.spm-twofer {
  display: grid;
  gap: var(--spm-space-4);
  grid-template-columns: 1fr;
}

@media (min-width: 600px) {
  .spm-twofer { grid-template-columns: 1fr 1fr; }
}

.spm-twofer__cell {
  background: var(--spm-paper);
  border: 1px solid var(--spm-rule);
  border-top: 2px solid var(--spm-navy);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-6);
}

.spm-twofer__cell ul {
  list-style: none;
  margin: var(--spm-space-4) 0 0;
  padding: 0;
  font-size: var(--spm-size-small);
  color: var(--spm-ink-70);
}

.spm-twofer__cell li { padding-block: var(--spm-space-2); }
.spm-twofer__cell li + li { border-top: 1px solid var(--spm-rule); }

.spm-twofer__from {
  grid-column: 1 / -1;
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-ink-50);
  text-align: center;
  padding-top: var(--spm-space-3);
}


/* --- Ten steps strip ----------------------------------------------------
   Horizontal and scrollable on mobile, grid once there is room. */

.spm-steps {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 78%;
  gap: var(--spm-space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--spm-space-6);
  margin-inline: calc(var(--spm-gutter) * -1);
  padding-inline: var(--spm-gutter);
  -webkit-overflow-scrolling: touch;
}

@media (min-width: 600px) { .spm-steps { grid-auto-columns: 40%; } }

@media (min-width: 900px) {
  .spm-steps {
    grid-auto-flow: row;
    grid-template-columns: repeat(5, 1fr);
    grid-auto-columns: auto;
    overflow-x: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}

.spm-step {
  scroll-snap-align: start;
  display: block;
  background: var(--spm-paper);
  border: 1px solid var(--spm-rule);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-6);
  text-decoration: none;
  min-height: 132px;
  transition: border-color var(--spm-duration-fast) var(--spm-ease);
}

.spm-step:hover, .spm-step:focus-visible { border-color: var(--spm-navy); }

.spm-step__no {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  color: var(--spm-ink-50);
}

.spm-step__name {
  display: block;
  margin-top: var(--spm-space-3);
  font-family: var(--spm-font-display);
  font-size: var(--spm-size-h3);
  line-height: var(--spm-leading-tight);
  letter-spacing: var(--spm-tracking-display);
  text-transform: uppercase;
  color: var(--spm-navy);
}

.spm-steps__hint {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-ink-50);
  margin-top: var(--spm-space-4);
}

@media (min-width: 900px) { .spm-steps__hint { display: none; } }


/* --- Proof strip -------------------------------------------------------- */

.spm-proof {
  display: grid;
  gap: var(--spm-space-6);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  border-top: 1px solid var(--spm-rule-on-navy);
  border-bottom: 1px solid var(--spm-rule-on-navy);
  padding-block: var(--spm-space-8);
}

.spm-proof__item strong {
  display: block;
  font-family: var(--spm-font-display);
  font-size: var(--spm-size-h3);
  letter-spacing: var(--spm-tracking-display);
  text-transform: uppercase;
  font-weight: var(--spm-weight-regular);
}


/* --- Quotes -------------------------------------------------------------
   Client words, carried verbatim. */

.spm-quote {
  background: var(--spm-paper);
  border: 1px solid var(--spm-rule);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-8);
  display: flex;
  flex-direction: column;
}

.spm-quote blockquote {
  margin: 0;
  font-size: var(--spm-size-lead);
  font-weight: var(--spm-weight-medium);
  line-height: var(--spm-leading-lead);
}

.spm-quote p { margin-top: var(--spm-space-4); color: var(--spm-ink-70); font-size: var(--spm-size-small); flex: 1; }

.spm-quote figcaption {
  margin-top: var(--spm-space-6);
  padding-top: var(--spm-space-4);
  border-top: 1px solid var(--spm-rule);
}


/* --- Closing call to action ---------------------------------------------
   The brand doc calls this an orange band, and the colour rule says orange
   is never a background. The rule wins: navy panel, orange rule above the
   action, orange button. */

.spm-cta { text-align: center; }
.spm-cta hr { margin-inline: auto; }
.spm-cta h2 { margin-top: var(--spm-space-6); }
.spm-cta p { margin: var(--spm-space-6) auto 0; }
.spm-cta .spm-btn { margin-top: var(--spm-space-12); }

/* Two actions in the closing block. The container carries the top margin so
   the buttons do not each take one and stagger. */
.spm-cta .spm-route__actions {
  justify-content: center;
  margin-top: var(--spm-space-12);
}
.spm-cta .spm-route__actions .spm-btn { margin-top: 0; }


/* --- Footer ------------------------------------------------------------- */

/* The closing call to action is navy on every page and so is the footer, so
   without this rule the two run together as one slab. A hairline is enough:
   they are meant to read as related, just not as the same block. */
.spm-footer {
  padding-block: var(--spm-space-16) var(--spm-space-12);
  border-top: var(--spm-border-on-navy);
}

.spm-footer__grid {
  display: grid;
  gap: var(--spm-space-12);
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .spm-footer__grid { grid-template-columns: 2fr 1fr 1fr; }
}

.spm-footer ul { list-style: none; margin: var(--spm-space-4) 0 0; padding: 0; }
.spm-footer li { padding-block: var(--spm-space-1); }

.spm-footer a {
  color: var(--spm-on-navy-70);
  text-decoration: none;
  font-size: var(--spm-size-small);
  display: inline-flex;
  align-items: center;
  min-height: var(--spm-space-8);
}

.spm-footer a:hover { color: var(--spm-on-navy); text-decoration: underline; text-underline-offset: 4px; }

.spm-footer__legal {
  margin-top: var(--spm-space-12);
  padding-top: var(--spm-space-6);
  border-top: 1px solid var(--spm-rule-on-navy);
  font-size: var(--spm-size-small);
  color: var(--spm-on-navy-50);
}

.spm-footer__legal p { max-width: none; }

/* The claim line. It sits above the registration details rather than among
   them, because it is the opposite of boilerplate: it is the first proof a
   visitor gets that the rules were read rather than copied.

   Lime, not orange. The orange rule reserves that for the primary action of
   the viewport, and on a page whose footer already carries a call to action
   this is a link, not the action. */
.spm-footer__claim {
  margin-bottom: var(--spm-space-4);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-fine);
  letter-spacing: 0.04em;
}

/* .spm-footer a already sets a size at (0,2,0), so setting it on the paragraph
   alone loses. Two-class form here to match it, and this block is later. */
.spm-footer__claim a {
  font-size: var(--spm-size-fine);
  color: var(--spm-on-navy-80);
  text-decoration: none;
  border-bottom: 1px solid var(--spm-rule-on-navy);
  padding-bottom: 2px;
  transition: color var(--spm-duration-fast), border-color var(--spm-duration-fast);
}

.spm-footer__claim a:hover,
.spm-footer__claim a:focus-visible {
  color: var(--spm-lime);
  border-color: var(--spm-lime);
}




/* --- Tiles, what you get ------------------------------------------------ */

.spm-tile {
  border-top: 2px solid var(--spm-lime);
  padding-top: var(--spm-space-6);
}

.spm-tile h4 { margin-bottom: var(--spm-space-3); }
.spm-tile p { color: var(--spm-ink-70); font-size: var(--spm-size-small); }


/* --- Step list, expandable ----------------------------------------------
   Native details and summary, so it opens with scripting off. */

.spm-steplist { border-top: 1px solid var(--spm-rule); }

/* Column headers. The approved block set the ladder as a real table, and the
   headers are most of why it reads as a price structure rather than a list.
   Hidden below 600px, where the price column moves under the name. */
.spm-steplist__head {
  display: none;
  gap: var(--spm-space-4);
  padding-block: var(--spm-space-2);
  border-bottom: 1px solid var(--spm-rule);
}

@media (min-width: 600px) { .spm-steplist__head { display: flex; } }

.spm-steplist__head span { color: var(--spm-ink-50); }
.spm-steplist__head span:nth-child(1) { flex: 0 0 64px; }
.spm-steplist__head span:nth-child(2) { flex: 1 1 auto; }
.spm-steplist__head span:nth-child(3) { flex: 0 0 auto; text-align: right; }

.spm-steplist details { border-bottom: 1px solid var(--spm-rule); }

/* Rows are deliberately tight. Padding is space-3, and min-height carries the
   48px tap target rather than padding doing it, so the row is as dense as it
   can be without shrinking the target. */
.spm-steplist summary {
  display: flex;
  align-items: baseline;
  gap: var(--spm-space-4);
  padding-block: var(--spm-space-3);
  min-height: var(--spm-target);
  cursor: pointer;
  list-style: none;
  transition: background var(--spm-duration-fast);
}

.spm-steplist summary:hover { background: var(--spm-orange-tint); }

.spm-steplist summary::-webkit-details-marker { display: none; }

.spm-steplist summary::after {
  content: '+';
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-fine);
  color: var(--spm-ink-50);
  flex: 0 0 16px;
  text-align: right;
}

.spm-steplist details[open] summary::after { content: '\2013'; }

/* Orange, as in the approved block, but the darkened text form. The brand
   orange measures 3.07:1 on this ground and fails at 11px. See
   --spm-orange-ink. If this ladder is ever moved onto a navy ground the
   colour must switch back to --spm-orange, which passes there and does not
   pass here. */
.spm-steplist__no {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  color: var(--spm-orange-ink);
  flex: 0 0 64px;
}

.spm-steplist__name {
  font-family: var(--spm-font-display);
  font-weight: var(--spm-weight-display);
  font-size: var(--spm-size-h3);
  line-height: var(--spm-leading-tight);
  letter-spacing: var(--spm-tracking-display);
  text-transform: uppercase;
  color: var(--spm-navy);
  flex: 1 1 auto;
}

.spm-steplist__price {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-fine);
  font-variant-numeric: tabular-nums;
  color: var(--spm-ink-70);
  flex: 0 0 auto;
  padding-left: var(--spm-space-4);
  white-space: nowrap;
}

/* Free is a lime chip, not a price. Navy on lime is 11.47:1. */
.spm-steplist__price--free {
  background: var(--spm-lime);
  color: var(--spm-on-lime);
  padding: 3px 8px;
  border-radius: var(--spm-radius);
}

.spm-steplist__body {
  padding: 0 0 var(--spm-space-6) 64px;
  max-width: var(--spm-measure);
}

/* On a phone the 64px reference column and the price column together leave
   the name too narrow, so short names like "Data mapping" wrapped to two
   lines. The reference shrinks to the width of its two digits and the name
   drops a step on the type scale. */
@media (max-width: 599px) {
  .spm-steplist__body { padding-left: 0; }
  .spm-steplist summary { gap: var(--spm-space-3); }
  .spm-steplist__no { flex: 0 0 20px; letter-spacing: 0.06em; }
  .spm-steplist__name { font-size: var(--spm-size-lead); }
  .spm-steplist__price { padding-left: var(--spm-space-3); }
}

.spm-steplist__body .spm-label { margin-bottom: var(--spm-space-2); }

/* Total row, the tfoot of the approved table. */
.spm-steplist__total {
  display: flex;
  gap: var(--spm-space-4);
  padding-block: var(--spm-space-4);
  border-top: 2px solid var(--spm-rule-strong);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-fine);
  letter-spacing: var(--spm-tracking-button);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.spm-steplist__total span:first-child { flex: 1 1 auto; padding-left: 64px; }
.spm-steplist__total span:last-child  { flex: 0 0 auto; }

@media (max-width: 599px) {
  .spm-steplist__total span:first-child { padding-left: 0; }
}


/* --- Routes ------------------------------------------------------------- */

.spm-routes {
  display: grid;
  gap: var(--spm-space-6);
  grid-template-columns: 1fr;
}

@media (min-width: 860px) { .spm-routes { grid-template-columns: 1fr 1fr; } }

/* The card is the raised navy surface. It only exists inside a navy panel,
   which is why every colour below comes from the inverted set. The 1px
   border is not decoration: the surface sits 1.24:1 off the ground, which is
   not enough of a lift to define an edge on its own. */
.spm-route {
  background: var(--spm-surface);
  border: var(--spm-border-on-navy);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-8);
  display: flex;
  flex-direction: column;
}

@media (min-width: 900px) { .spm-route { padding: var(--spm-space-12); } }

.spm-route .spm-label { color: var(--spm-lime); margin-bottom: var(--spm-space-3); }

.spm-route h3, .spm-route h4 { color: var(--spm-on-navy); }

/* The price is the largest thing in the card and it carries its own footnote
   in body type, so the number stays a number and the terms stay readable. */
.spm-route .spm-route__price {
  font-family: var(--spm-font-display);
  font-weight: var(--spm-weight-display);
  font-size: var(--spm-size-price);
  line-height: 1;
  letter-spacing: var(--spm-tracking-display);
  color: var(--spm-paper);
  margin-top: var(--spm-space-4);
}

.spm-route .spm-route__price span {
  display: block;
  margin-top: var(--spm-space-2);
  font-family: var(--spm-font-body);
  font-weight: var(--spm-weight-regular);
  font-size: var(--spm-size-small);
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--spm-on-navy-70);
}

.spm-route .spm-route__pitch {
  margin-top: var(--spm-space-6);
  color: var(--spm-on-navy-80);
}

.spm-route ul {
  list-style: none;
  margin: var(--spm-space-6) 0 0;
  padding: 0;
  flex: 1;
}

/* A short lime dash rather than a bullet or a tick. It is the one place the
   lime appears at body scale, and it is what makes the card read as StepWise
   from across the room. */
.spm-route li {
  position: relative;
  padding-left: 22px;
  margin-bottom: var(--spm-space-3);
  font-size: var(--spm-size-small);
  line-height: 1.6;
  color: var(--spm-on-navy-80);
}

.spm-route li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 11px;
  width: 8px;
  height: 2px;
  background: var(--spm-lime);
}

.spm-route__foot { margin-top: auto; padding-top: var(--spm-space-8); }

.spm-route__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spm-space-3);
}

/* Done for you. Sits below the two routes on the same navy ground, separated
   by a rule rather than a card, because it is not a third route. */
.spm-dfy {
  margin-top: var(--spm-space-16);
  padding-top: var(--spm-space-8);
  border-top: var(--spm-border-on-navy);
  display: flex;
  flex-wrap: wrap;
  gap: var(--spm-space-6);
  align-items: flex-start;
  justify-content: space-between;
}

.spm-dfy .spm-label { color: var(--spm-lime); }
.spm-dfy p { color: var(--spm-on-navy-80); }

.spm-panel-navy .spm-vat {
  margin-top: var(--spm-space-8);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-on-navy-50);
}

.spm-route .spm-route__note {
  margin-top: var(--spm-space-3);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-on-navy-50);
}


/* --- In and out --------------------------------------------------------- */

.spm-inout ul { list-style: none; margin: var(--spm-space-4) 0 0; padding: 0; }

.spm-inout li {
  padding-block: var(--spm-space-3);
  border-top: 1px solid var(--spm-rule);
  font-size: var(--spm-size-small);
}

/* The figure inside a summary card. Mono and tabular so the two cards line
   up against each other rather than drifting. */
.spm-pricelead {
  margin-top: var(--spm-space-3);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-lead);
  font-variant-numeric: tabular-nums;
  color: var(--spm-navy);
}


/* --- Objections --------------------------------------------------------- */

.spm-faq { border-top: 1px solid var(--spm-rule); }

.spm-faq details { border-bottom: 1px solid var(--spm-rule); }

.spm-faq summary {
  display: flex;
  gap: var(--spm-space-6);
  align-items: center;
  padding-block: var(--spm-space-6);
  min-height: var(--spm-target);
  cursor: pointer;
  list-style: none;
  font-size: var(--spm-size-lead);
  font-weight: var(--spm-weight-medium);
}

.spm-faq summary::-webkit-details-marker { display: none; }

.spm-faq summary::after {
  content: '+';
  margin-left: auto;
  font-family: var(--spm-font-mono);
  color: var(--spm-ink-50);
  flex-shrink: 0;
}

.spm-faq details[open] summary::after { content: '\2013'; }

.spm-faq__body { padding-bottom: var(--spm-space-8); }


/* --- Sign up modal ------------------------------------------------------
   Free account only. There is no checkout anywhere on this site, so this
   form never mentions payment and never shows bank details. */

.spm-modal {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: none;
  background: rgba(5, 10, 48, 0.72);
  padding: var(--spm-space-6);
  overflow-y: auto;
}

.spm-modal[data-open='true'] { display: block; }

.spm-modal__panel {
  background: var(--spm-light);
  border-radius: var(--spm-radius);
  max-width: 620px;
  margin: var(--spm-space-12) auto;
  padding: var(--spm-space-12) var(--spm-space-8);
}

.spm-modal__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--spm-space-6);
  margin-bottom: var(--spm-space-8);
}

.spm-modal__close {
  background: none;
  border: 1px solid var(--spm-rule-strong);
  border-radius: var(--spm-radius);
  min-height: var(--spm-target);
  min-width: var(--spm-target);
  cursor: pointer;
  font-family: var(--spm-font-mono);
  color: var(--spm-navy);
  flex-shrink: 0;
}

.spm-formgrid {
  display: grid;
  gap: var(--spm-space-6);
  grid-template-columns: 1fr;
}

@media (min-width: 600px) { .spm-formgrid { grid-template-columns: 1fr 1fr; } }

.spm-formgrid .spm-field { margin-bottom: 0; }
.spm-formgrid .spm-field--wide { grid-column: 1 / -1; }

.spm-consentbox {
  margin-top: var(--spm-space-8);
  padding: var(--spm-space-6);
  background: var(--spm-paper);
  border: 1px solid var(--spm-rule);
  border-radius: var(--spm-radius);
}

.spm-check {
  display: flex;
  gap: var(--spm-space-3);
  align-items: flex-start;
  font-size: var(--spm-size-small);
}

.spm-check + .spm-check { margin-top: var(--spm-space-4); }

.spm-check input { margin-top: 5px; flex-shrink: 0; width: 18px; height: 18px; }

/* Error text is navy, with an orange rule as the second cue. Orange type at
   14px measures 4.39:1 on the light ground this sits on, which is under the
   4.5:1 line, and an error message is the last thing that should be hard to
   read. Navy measures 17.79:1 and the rule carries the signal. */
.spm-formstatus {
  margin-top: var(--spm-space-4);
  padding-left: var(--spm-space-4);
  border-left: 2px solid var(--spm-orange);
  font-size: var(--spm-size-small);
  color: var(--spm-navy);
}

.spm-formstatus:empty { display: none; }


/* --- Checkout: order summary and payment method -------------------------
   Both appear only when the modal is opened for a paid item. Neither uses
   orange: the submit button is the one action in this viewport, and the
   summary and the radios are information, not something to press. */
.spm-order {
  display: flex;
  gap: var(--spm-space-4);
  align-items: baseline;
  margin-top: var(--spm-space-6);
  padding-block: var(--spm-space-4);
  border-top: 2px solid var(--spm-rule-strong);
  border-bottom: 1px solid var(--spm-rule);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-fine);
  letter-spacing: var(--spm-tracking-button);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--spm-navy);
}

.spm-order__item  { flex: 1 1 auto; }
.spm-order__price { flex: 0 0 auto; font-weight: var(--spm-weight-semibold); }

/* .spm-paymethods, .spm-paymethod and .spm-banknote were removed on
   27 August 2026 with the bank transfer option they styled. There is one
   payment method now, so the modal states it rather than offering a choice
   of one. Nothing else on the site carries these classes. */

[hidden] { display: none !important; }


/* --- Roadmap stages and step cards -------------------------------------
   The roadmap page is the only page that carries the full deliverable list,
   so its job is scanning, not selling. It is built as a ruled ledger for the
   same reason the price ladder is: a run of ruled rows reads as a sequence
   without needing a decorative spine to say so.

   The four stages alternate ground, light then navy then light then navy, so
   a long page has rhythm and navy stays a surface rather than becoming the
   page. Every rule below therefore has to work on both grounds. Where a value
   differs it is set once here and once under .spm-panel-navy, never inline.

   No prices appear on this page. Prices live on stepwise.html and nowhere
   else, so there is one place for a figure to be wrong.                    */

.spm-stage + .spm-stage { margin-top: var(--spm-space-16); }

.spm-stage__head {
  max-width: var(--spm-measure);
  margin-bottom: var(--spm-space-12);
}

.spm-stage__head h2 { margin-top: var(--spm-space-3); }
.spm-stage__head p  { margin-top: var(--spm-space-4); }

/* The list of steps in a stage. Top rule closes the ledger at the head; each
   card carries its own bottom rule. */
.spm-stepblock { border-top: 1px solid var(--spm-rule); }
.spm-panel-navy .spm-stepblock { border-top-color: var(--spm-rule-on-navy); }

/* Single column below 760px. The reference sits above the name there rather
   than beside it, because a rail wide enough for the numeral leaves the name
   too narrow to hold on one line at 390px. */
.spm-stepcard {
  display: grid;
  gap: var(--spm-space-3);
  padding-block: var(--spm-space-8);
  border-bottom: 1px solid var(--spm-rule);
}

.spm-panel-navy .spm-stepcard { border-bottom-color: var(--spm-rule-on-navy); }

@media (min-width: 760px) {
  .spm-stepcard {
    grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--spm-space-8);
    padding-block: var(--spm-space-12);
  }
}

/* Mono, because it is a reference and not a heading. It is deliberately quiet:
   the orange rule allows one orange element per viewport and reserves it for
   actions, so ten orange numerals down a page is not available. The step name
   in display type is the thing that carries. */
.spm-stepcard__no {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-h3);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--spm-ink-50);
}

.spm-panel-navy .spm-stepcard__no { color: var(--spm-on-navy-50); }

.spm-stepcard__name { margin: 0; }

.spm-stepcard .spm-stepcard__purpose {
  margin-top: var(--spm-space-3);
  font-size: var(--spm-size-small);
  color: var(--spm-ink-70);
  max-width: var(--spm-measure);
}

.spm-panel-navy .spm-stepcard .spm-stepcard__purpose { color: var(--spm-on-navy-70); }

/* What the step leaves behind. Dashes rather than bullets, to match the route
   cards. Lime carries the dash on navy; on the light ground lime measures
   1.42:1 and disappears. The light form uses ink-50, not the rule token: a
   rule at 0.24 alpha composites to 1.62:1 on this ground, which next to an
   11:1 lime dash on the navy stages reads as a broken marker rather than a
   quiet one. Same device, two grounds, one place each. */
.spm-stepcard__out { margin: 0; }

/* Single column, the grid gap that separates the reference from the name is
   too tight to also separate the name block from the deliverables. Only the
   second join needs the extra space, so it is added here rather than by
   widening the gap for both. */
@media (max-width: 759px) {
  .spm-stepcard__out { margin-top: var(--spm-space-4); }
}

.spm-stepcard__out ul {
  list-style: none;
  margin: var(--spm-space-4) 0 0;
  padding: 0;
}

.spm-stepcard__out li {
  position: relative;
  padding-left: var(--spm-space-6);
  padding-block: var(--spm-space-2);
  font-size: var(--spm-size-small);
  line-height: 1.5;
}

.spm-stepcard__out li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18px;
  width: 8px;
  height: 2px;
  background: var(--spm-ink-50);
}

.spm-panel-navy .spm-stepcard__out li::before { background: var(--spm-lime); }

/* Step zero sits outside the four stages because it is free and because it is
   the only step that ends in a decision rather than a document. */
/* The heading is an h2 because it is the only heading in its section, but the
   display-2 size that carries a full-width section head is too large inside a
   bordered card. Sized down one step, not marked down one level. */
.spm-stepzero h2 { font-size: var(--spm-size-h2); }

.spm-stepzero {
  border: var(--spm-border);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-8);
}

@media (min-width: 900px) { .spm-stepzero { padding: var(--spm-space-12); } }

.spm-stepzero__flag {
  display: inline-block;
  margin-bottom: var(--spm-space-4);
  padding: var(--spm-space-1) var(--spm-space-3);
  background: var(--spm-lime);
  color: var(--spm-on-lime);
  border-radius: var(--spm-radius);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  font-weight: var(--spm-weight-medium);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
}

@media (min-width: 760px) {
  .spm-stepzero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--spm-space-12);
    align-items: start;
  }
}

.spm-stepzero__grid > * + * { margin-top: var(--spm-space-8); }

@media (min-width: 760px) {
  .spm-stepzero__grid > * + * { margin-top: 0; }
}

/* The tally. Three figures generated from the page itself, so they cannot
   drift from the list above them. */
.spm-tally {
  display: grid;
  gap: var(--spm-space-8);
  margin-top: var(--spm-space-12);
}

@media (min-width: 700px) {
  .spm-tally { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.spm-tally__item {
  padding-top: var(--spm-space-6);
  border-top: var(--spm-border-on-navy);
}

.spm-tally__no {
  display: block;
  font-family: var(--spm-font-display);
  font-weight: var(--spm-weight-display);
  font-size: var(--spm-size-display-2);
  line-height: 1;
  letter-spacing: var(--spm-tracking-display);
  color: var(--spm-paper);
}

.spm-tally .spm-tally__label {
  margin-top: var(--spm-space-3);
  font-size: var(--spm-size-small);
  color: var(--spm-on-navy-70);
}


/* --- Contact ------------------------------------------------------------
   The primary action on this site is booking a call, so the booking block
   comes first in the source and sits first on a narrow screen. The form is
   the alternative for people who would rather write, not the headline.     */

.spm-contact {
  display: grid;
  gap: var(--spm-space-12);
}

@media (min-width: 900px) {
  .spm-contact {
    grid-template-columns: minmax(0, 4fr) minmax(0, 5fr);
    gap: var(--spm-space-16);
    align-items: start;
  }
}

/* Navy booking block. The one raised surface on this page, so it takes the
   rule border that every raised navy surface needs. */
.spm-booking {
  background: var(--spm-navy);
  border: var(--spm-border-on-navy);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-8);
}

@media (min-width: 900px) { .spm-booking { padding: var(--spm-space-12); } }

.spm-booking h2, .spm-booking h3 { color: var(--spm-on-navy); }
.spm-booking .spm-label { color: var(--spm-lime); }
.spm-booking p { color: var(--spm-on-navy-80); }

.spm-booking ul { list-style: none; margin: var(--spm-space-6) 0 0; padding: 0; }

.spm-booking li {
  position: relative;
  padding-left: var(--spm-space-6);
  padding-block: var(--spm-space-2);
  font-size: var(--spm-size-small);
  color: var(--spm-on-navy-80);
}

.spm-booking li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 15px;
  width: 8px;
  height: 2px;
  background: var(--spm-lime);
}

/* Direct details. A definition list, because that is what it is. */
.spm-reach { margin-top: var(--spm-space-12); }

.spm-reach dl { margin: 0; }

.spm-reach div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spm-space-2) var(--spm-space-4);
  justify-content: space-between;
  padding-block: var(--spm-space-4);
  border-top: 1px solid var(--spm-rule);
}

.spm-reach dt {
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-ink-50);
}

.spm-reach dd { margin: 0; font-size: var(--spm-size-small); text-align: right; }

/* The email address is the longest value and it only just fits beside its
   label at 390px. Below that the row wraps, and a wrapped value that is still
   right-aligned reads as a mistake, so narrow screens stack instead. */
@media (max-width: 420px) {
  .spm-reach div { display: block; }
  .spm-reach dd { text-align: left; margin-top: var(--spm-space-1); }
}

/* The form card. Paper on the light ground, so the fields have something to
   sit against: an input is also paper, and paper on paper has no edge. */
.spm-formcard {
  background: var(--spm-paper);
  border: var(--spm-border);
  border-radius: var(--spm-radius);
  padding: var(--spm-space-8);
}

@media (min-width: 900px) { .spm-formcard { padding: var(--spm-space-12); } }

@media (min-width: 560px) {
  .spm-formcard .spm-formgrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 var(--spm-space-6);
  }
  .spm-formcard .spm-field--wide { grid-column: 1 / -1; }
}

/* Sent state. Replaces the form rather than covering it, so a screen reader
   is not left inside a form that is no longer there. */
.spm-sent {
  border-left: 3px solid var(--spm-lime);
  padding-left: var(--spm-space-6);
}

.spm-sent[hidden] { display: none; }

/* Status line. Only ever shows a real outcome: this form does not report
   success until the request has actually succeeded. */
.spm-formstatus--error {
  color: var(--spm-orange-ink);
  font-weight: var(--spm-weight-medium);
}


/* --- Legal pages --------------------------------------------------------
   Privacy, terms and cookies. Long reading documents, so the measure is the
   constraint that matters and the contents list is the navigation.

   The content on these pages is carried across word for word. Nothing here
   changes wording; it only changes how the wording is set.                */

.spm-legal { display: grid; gap: var(--spm-space-12); }

/* A grid item defaults to min-width:auto, so it refuses to shrink below its
   content. The lawful-basis table sets a 560px min-width so its columns stay
   readable, and without this the whole grid inherited that width and pushed
   the page sideways at 390px. min-width:0 lets the item shrink so the table
   scrolls inside its own wrapper, which is the behaviour .spm-tablewrap was
   written for. */
.spm-legal > * { min-width: 0; }

@media (min-width: 900px) {
  .spm-legal {
    grid-template-columns: 220px minmax(0, 1fr);
    gap: var(--spm-space-16);
    align-items: start;
  }
}

/* Contents. Sticky on desktop only: a sticky block on a short viewport eats
   the reading area it is supposed to help with. */
@media (min-width: 900px) {
  .spm-legal__toc { position: sticky; top: var(--spm-space-16); }
}

.spm-legal__toc ol {
  list-style: none;
  margin: var(--spm-space-4) 0 0;
  padding: 0;
  counter-reset: toc;
}

.spm-legal__toc li { counter-increment: toc; }

.spm-legal__toc a {
  display: flex;
  gap: var(--spm-space-3);
  padding-block: var(--spm-space-2);
  font-size: var(--spm-size-small);
  color: var(--spm-ink-70);
  text-decoration: none;
  border-bottom: 1px solid var(--spm-rule);
}

.spm-legal__toc a::before {
  content: counter(toc, decimal-leading-zero);
  flex: 0 0 20px;
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  color: var(--spm-ink-50);
}

.spm-legal__toc a:hover { color: var(--spm-navy); background: var(--spm-orange-tint); }

/* Sections. scroll-margin keeps a heading clear of the fixed header when it
   is jumped to from the contents list. */
.spm-legal__section { scroll-margin-top: var(--spm-space-24); }

.spm-legal__section + .spm-legal__section { margin-top: var(--spm-space-16); }

.spm-legal__section h2 {
  font-size: var(--spm-size-h3);
  display: flex;
  gap: var(--spm-space-4);
  align-items: baseline;
  padding-bottom: var(--spm-space-4);
  border-bottom: 1px solid var(--spm-rule);
}

.spm-legal__section h2 span {
  flex: 0 0 auto;
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  letter-spacing: var(--spm-tracking-label);
  color: var(--spm-ink-50);
}

.spm-legal__section > p,
.spm-legal__section > ol,
.spm-legal__section > ul { margin-top: var(--spm-space-4); max-width: var(--spm-measure); }

.spm-legal__section ul,
.spm-legal__section ol { padding-left: var(--spm-space-6); }

.spm-legal__section li { padding-block: var(--spm-space-2); }

.spm-legal__section a { color: var(--spm-navy); }

/* Tables in legal copy are wide by nature. The wrapper scrolls, never the
   page, and the header row repeats the mono label treatment. */
.spm-tablewrap {
  margin-top: var(--spm-space-6);
  overflow-x: auto;
  border: var(--spm-border);
  border-radius: var(--spm-radius);
}

.spm-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: var(--spm-size-small);
}

.spm-table th {
  text-align: left;
  padding: var(--spm-space-3) var(--spm-space-4);
  background: var(--spm-light);
  border-bottom: 1px solid var(--spm-rule-strong);
  font-family: var(--spm-font-mono);
  font-size: var(--spm-size-label);
  font-weight: var(--spm-weight-medium);
  letter-spacing: var(--spm-tracking-label);
  text-transform: uppercase;
  color: var(--spm-ink-70);
}

.spm-table td {
  padding: var(--spm-space-4);
  border-bottom: 1px solid var(--spm-rule);
  vertical-align: top;
}

.spm-table tr:last-child td { border-bottom: 0; }

/* Document metadata: last updated, ICO registration. */
.spm-docmeta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spm-space-3) var(--spm-space-8);
  margin-top: var(--spm-space-8);
}

.spm-docmeta span { color: var(--spm-on-navy-70); }
