/* ==========================================================================
   changemyprinters.co.uk — shared stylesheet
   Mobile-first. Change the palette in :root to rebrand the whole site.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Palette — TODO: confirm final brand colours */
  --navy: #1b2a4a;
  --navy-700: #24365c;
  --navy-300: #5a6b8c;
  --accent: #2fbf71;
  /* Darkened from #249657 (3.8:1 on white). This is the link-hover colour and
     the colour of text set on --accent-tint, so it has to clear 4.5:1 on
     both. Now 4.6:1. It also darkens the primary button's hover state,
     which only improves that button's white-on-green contrast. */
  --accent-dark: #0d7f40;
  --accent-tint: #e6f7ee;
  --off-white: #f7f8fa;
  --white: #ffffff;
  --charcoal: #22262b;
  --grey-600: #5c646e;
  /* Darkened from #8b939d, which scored 2.9:1 on white — below the 4.5:1
     AA minimum. Used for meta text, "optional" tags and idle step labels,
     all of which are real content, not decoration. Now 4.6:1. */
  --grey-400: #6a727c;
  --grey-200: #dfe3e8;
  --grey-100: #eef0f3;
  --warn: #b9411b;
  --warn-tint: #fdf0ec;

  /* Face shading for the hero's 3D mark. Tints of --navy, lit from above:
     top lightest, front mid, sides darkest. Every face is deliberately
     LIGHTER than the hero's own navy background — shade the front to --navy
     itself and the object dissolves into the backdrop. Kept as explicit
     values rather than color-mix() so an unsupported browser can't leave a
     face transparent. If you rebrand --navy, rebrand these with it. */
  --p3-top: #4a6699;
  --p3-front: #32497a;
  --p3-side: #24365c;
  --p3-slot: #16233d;

  /* Semantic aliases — use these in components */
  --bg: var(--off-white);
  --bg-raised: var(--white);
  --text: var(--charcoal);
  --text-muted: var(--grey-600);
  --border: var(--grey-200);
  --brand: var(--navy);
  --cta: var(--accent);

  /* Type */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;

  /* Spacing scale */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;

  /* Shape */
  --radius: 10px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 2px rgba(27, 42, 74, 0.06),
    0 1px 3px rgba(27, 42, 74, 0.08);
  --shadow-md: 0 4px 12px rgba(27, 42, 74, 0.08),
    0 2px 4px rgba(27, 42, 74, 0.06);
  --shadow-lg: 0 12px 32px rgba(27, 42, 74, 0.12),
    0 4px 8px rgba(27, 42, 74, 0.06);

  --wrap: 1120px;
  --wrap-narrow: 720px;
}

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

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

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  /* Safety net for long emails and URLs in prose on narrow screens. */
  overflow-wrap: break-word;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4 {
  color: var(--brand);
  line-height: 1.2;
  margin: 0 0 var(--s-4);
  font-weight: 700;
  letter-spacing: -0.015em;
}

h1 {
  font-size: clamp(2rem, 5.5vw, 3.15rem);
}
h2 {
  font-size: clamp(1.5rem, 3.6vw, 2.15rem);
}
h3 {
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
}
h4 {
  font-size: 1.05rem;
}

p {
  margin: 0 0 var(--s-4);
}

a {
  color: var(--navy);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--accent-dark);
}

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

ul,
ol {
  padding-left: 1.25rem;
}

li {
  margin-bottom: var(--s-2);
}

strong {
  font-weight: 650;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--s-6) 0;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  background: var(--grey-100);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

/* Visible focus for keyboard users everywhere */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--s-4);
  top: -4rem;
  z-index: 200;
  background: var(--white);
  color: var(--navy);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius);
  font-weight: 600;
  box-shadow: var(--shadow-md);
  transition: top 0.15s ease;
}

.skip-link:focus {
  top: var(--s-4);
}

/* --------------------------------------------------------------------------
   3. Layout helpers
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--s-4);
}

.wrap--narrow {
  max-width: var(--wrap-narrow);
}

.section {
  padding-block: var(--s-7);
}

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

.section--navy {
  background: var(--navy);
  color: #dde3ee;
}

.section--navy h2,
.section--navy h3 {
  color: var(--white);
}

@media (min-width: 768px) {
  .section {
    padding-block: var(--s-8);
  }
}

.lede {
  font-size: 1.1rem;
  color: var(--text-muted);
  max-width: 58ch;
}

.section-head {
  max-width: 62ch;
  margin-bottom: var(--s-6);
}

.text-center {
  text-align: center;
}

.center-block {
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  font: inherit;
  font-weight: 650;
  line-height: 1.2;
  padding: 0.85rem 1.5rem;
  min-height: 48px;
  border-radius: var(--radius);
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    transform 0.1s ease, color 0.15s ease;
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #06301b;
}

.btn--primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--white);
}

.btn--secondary {
  background: var(--white);
  border-color: var(--grey-200);
  color: var(--navy);
}

.btn--secondary:hover {
  border-color: var(--navy);
  color: var(--navy);
}

.btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.35);
  color: var(--white);
}

.btn--ghost:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: var(--white);
  color: var(--white);
}

.btn--block {
  width: 100%;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   5. Header & footer
   -------------------------------------------------------------------------- */
.site-header {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 60;
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 64px;
}

/* --- Brand lockup ------------------------------------------------------
   One inline SVG: .logo-icon (the printer) and .logo-wordmark (the type),
   as separate groups so either can be restyled or swapped alone. Every
   colour comes from the palette variables at the top of this file.

   The wordmark is live SVG text in the site font rather than outlined
   paths, so it inherits the palette and stays a single source of truth.
   Each <text> carries textLength + lengthAdjust, which pins the lockup to
   its designed width even if Inter hasn't loaded yet or is unavailable —
   without it, a fallback font would change the lockup's proportions.

   TODO: for exact brand fidelity, replace .logo-wordmark with outlined
   paths exported from the original logo artwork. The current type is
   Inter 800, which is close in spirit but is not the logo's own typeface.
   ----------------------------------------------------------------------- */
.logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex: none;
}

.logo-mark {
  display: block;
  height: 28px;
  width: auto;
}

.logo-mark .l-body {
  fill: var(--navy);
}

.logo-mark .l-panel {
  fill: var(--white);
  stroke: var(--navy);
  stroke-width: 3;
}

.logo-mark .l-dot {
  fill: var(--white);
}

.logo-mark .l-accent {
  fill: var(--accent);
}

.logo-mark .l-word {
  fill: var(--navy);
}

.logo-mark .l-word-accent {
  fill: var(--accent);
}

.logo-mark .l-type {
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: 36px;
  letter-spacing: -1.4px;
}

.logo-mark .l-tld {
  font-size: 23px;
  letter-spacing: -0.6px;
}

/* On navy, the printer body goes white and its panels take the background
   colour, so the mark reads as a clean inverse rather than a silhouette. */
.logo-mark--invert .l-body {
  fill: var(--white);
}

.logo-mark--invert .l-panel {
  fill: var(--navy);
  stroke: var(--white);
}

.logo-mark--invert .l-dot {
  fill: var(--navy);
}

.logo-mark--invert .l-word {
  fill: var(--white);
}

.site-footer .logo-mark {
  height: 30px;
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.nav__links {
  display: none;
  gap: var(--s-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__links a {
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 550;
  font-size: 0.95rem;
}

.nav__links a:hover,
.nav__links a[aria-current="page"] {
  color: var(--navy);
}

.nav .btn {
  padding: 0.55rem 1rem;
  min-height: 40px;
  font-size: 0.92rem;
}

@media (min-width: 720px) {
  .nav__links {
    display: flex;
  }
}

/* Drop the .co.uk suffix below 480px, where the lockup and the CTA start
   competing for the line. Measured with the suffix kept: 81px of clearance at
   480px, but only 31px at 430px and 22px at 421px, and by 400px the flex gap
   has floored at its 16px minimum. So the full lockup is only comfortable
   from roughly 450px up — 480px is the honest cut, and it matches the
   breakpoint the exploded-printer section already uses.

   Hiding the suffix alone would only blank the ink and reclaim no space, so
   the SVG also gets an explicit narrower width. preserveAspectRatio
   "xMinYMid slice" anchors the viewBox left and crops the surplus on the
   right: 148 / 24 crops at viewBox x≈395, just past the end of "printers". */
@media (max-width: 479px) {
  .site-header .logo-mark {
    width: 148px;
    height: 24px;
  }
  .site-header .logo-mark .l-tld {
    display: none;
  }
  .nav .btn {
    font-size: 0.85rem;
    padding: 0.5rem 0.8rem;
    white-space: nowrap;
  }
}

.site-footer {
  background: var(--navy);
  color: #b9c3d6;
  padding-block: var(--s-7) var(--s-5);
  font-size: 0.94rem;
}

.site-footer a {
  color: #dde3ee;
}

.site-footer a:hover {
  color: var(--white);
}

.footer-grid {
  display: grid;
  gap: var(--s-6);
  margin-bottom: var(--s-6);
}

@media (min-width: 720px) {
  .footer-grid {
    grid-template-columns: 1.6fr 1fr 1fr;
    gap: var(--s-7);
  }
}

.footer-grid h3 {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--white);
  margin-bottom: var(--s-3);
}

.footer-grid ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-grid li {
  margin-bottom: var(--s-2);
}

.footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  justify-content: space-between;
  font-size: 0.86rem;
  color: #9aa6bd;
}

/* Footer CTA band */
.cta-band {
  background: var(--navy);
  color: #dde3ee;
  text-align: center;
  padding-block: var(--s-7);
}

.cta-band h2 {
  color: var(--white);
}

.cta-band p {
  max-width: 52ch;
  margin-inline: auto;
  margin-bottom: var(--s-5);
}

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */
.hero {
  background: linear-gradient(170deg, var(--navy) 0%, #16233d 100%);
  color: #dde3ee;
  padding-block: var(--s-7) var(--s-8);
}

.hero h1 {
  color: var(--white);
  margin-bottom: var(--s-4);
  text-wrap: balance;
}

.hero__lede {
  font-size: 1.1rem;
  color: #c3cddf;
  max-width: 46ch;
  margin-bottom: var(--s-5);
}

.hero__grid {
  display: grid;
  gap: var(--s-6);
}

@media (min-width: 940px) {
  .hero__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-7);
    align-items: start;
  }
  .hero {
    padding-block: var(--s-8) var(--s-9);
  }
}

.hero__points {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-5);
}

.hero__points li {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  margin-bottom: var(--s-3);
  color: #c9d3e4;
}

.hero__points svg {
  flex: none;
  margin-top: 3px;
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   7b. Hero 3D mark
   The brand icon as a real 3D object, built from CSS 3D transforms only —
   no WebGL, no canvas, no library, nothing to download. Roughly 20 elements,
   animating transform and opacity exclusively, so it stays on the compositor.

   It sits in the dead space under the hero bullets: at >=940px the left
   column runs ~210px shorter than the widget beside it, so this fills that
   gap rather than making the hero taller. Below 940px the hero collapses to
   one column and anything added here would push the widget down the page,
   so it is not rendered at all.
   -------------------------------------------------------------------------- */
/* Shown at every width. On phones it is scaled down via --p3-scale and given
   a shorter box, so it reads as a hero graphic without pushing the enquiry
   widget far down the page. */
.hero__3d {
  display: block;
  height: 158px;
  margin-top: var(--s-4);
  /* Perspective lives on the outer box; everything inside shares it. */
  perspective: 620px;
  perspective-origin: 50% 44%;
  --p3-scale: 0.66;
}

@media (min-width: 620px) {
  .hero__3d {
    height: 190px;
    --p3-scale: 0.82;
  }
}

@media (min-width: 940px) {
  .hero__3d {
    height: 220px;
    margin-top: var(--s-5);
    perspective: 900px;
    perspective-origin: 48% 42%;
    --p3-scale: 1;
  }
}

.p3-scene {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

/* Two nested wrappers because a single element can only run one transform
   animation: the outer one bobs, the inner one turns. */
.p3-float {
  position: absolute;
  left: 50%;
  top: 50%;
  transform-style: preserve-3d;
  animation: p3-float 6.5s ease-in-out infinite alternate;
}

.p3-turn {
  transform-style: preserve-3d;
  animation: p3-turn 17s ease-in-out infinite alternate;
}

@keyframes p3-float {
  from {
    transform: translateY(8px);
  }
  to {
    transform: translateY(-10px);
  }
}

/* The `to` pose is deliberately the best-looking angle: the global
   reduced-motion rule collapses animations to their end state, so that is
   what a reduced-motion visitor is left looking at. */
@keyframes p3-turn {
  from {
    transform: rotateX(-17deg) rotateY(-24deg) scale3d(var(--p3-scale, 1), var(--p3-scale, 1), var(--p3-scale, 1));
  }
  to {
    transform: rotateX(-11deg) rotateY(16deg) scale3d(var(--p3-scale, 1), var(--p3-scale, 1), var(--p3-scale, 1));
  }
}

/* ---- boxes ---- */

/* A box is a zero-size origin point; the faces hang off its centre. Each
   instance sets --w / --h / --d (dimensions) and --y (vertical offset). */
.p3-box {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: translateY(var(--y, 0));
}

/* Faces are centred on the box origin with negative margins, NOT with a
   translate(-50%,-50%) inside the transform. That matters: transform-origin
   already defaults to the face's centre, so a centring translate would be
   applied a second time and rotated along with the face, pushing each wall
   out by half its own size. Layout does the centring; the transform then
   only rotates the face into its plane and pushes it out to the wall.

   Only four walls are drawn — the back and underside never rotate into view
   within the ±24° the rig turns through. */
.p3-box > span {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  border-radius: 3px;
}

.f-front {
  width: var(--w);
  height: var(--h);
  margin-left: calc(var(--w) / -2);
  margin-top: calc(var(--h) / -2);
  background: var(--p3-front);
  transform: translateZ(calc(var(--d) / 2));
}

.f-top {
  width: var(--w);
  height: var(--d);
  margin-left: calc(var(--w) / -2);
  margin-top: calc(var(--d) / -2);
  background: var(--p3-top);
  transform: rotateX(90deg) translateZ(calc(var(--h) / 2));
}

.f-left {
  width: var(--d);
  height: var(--h);
  margin-left: calc(var(--d) / -2);
  margin-top: calc(var(--h) / -2);
  background: var(--p3-side);
  transform: rotateY(-90deg) translateZ(calc(var(--w) / 2));
}

.f-right {
  width: var(--d);
  height: var(--h);
  margin-left: calc(var(--d) / -2);
  margin-top: calc(var(--h) / -2);
  background: var(--p3-side);
  transform: rotateY(90deg) translateZ(calc(var(--w) / 2));
}

/* ---- details on the front face ---- */

/* Same centring rule as the faces: margins, not a translate. */
.p3-slot {
  position: absolute;
  left: 0;
  top: 0;
  width: 128px;
  height: 7px;
  margin-left: -64px;
  margin-top: -3.5px;
  border-radius: 4px;
  background: var(--p3-slot);
  transform: translateZ(76px) translateY(-17px);
}

.p3-panel {
  position: absolute;
  left: 0;
  top: 0;
  width: 122px;
  height: 54px;
  margin-left: -61px;
  margin-top: -27px;
  border-radius: 7px;
  background: var(--white);
  display: grid;
  place-items: center;
  transform: translateZ(76px) translateY(13px);
  box-shadow: 0 2px 10px rgba(8, 14, 28, 0.35);
}

.p3-arrows {
  width: 36px;
  height: 36px;
  fill: var(--accent);
  animation: p3-spin 19s linear infinite;
}

@keyframes p3-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ---- sheet feeding out of the slot ---- */

.p3-paper {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  animation: p3-feed 8s ease-in-out infinite;
}

.p3-paper > span {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 104px;
  height: 64px;
  margin-left: -52px;
  margin-top: -32px;
  border-radius: 2px;
  background: linear-gradient(160deg, #ffffff, #dbe1ea);
  /* Laid flat, so its height reads as depth. */
  transform: rotateX(90deg);
  opacity: 0;
  animation: p3-feed-fade 8s ease-in-out infinite;
}

@keyframes p3-feed {
  0%,
  45% {
    transform: translateY(-14px) translateZ(46px);
  }
  70% {
    transform: translateY(-14px) translateZ(96px);
  }
  100% {
    transform: translateY(-14px) translateZ(116px);
  }
}

@keyframes p3-feed-fade {
  0%,
  45% {
    opacity: 0;
  }
  62%,
  82% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* ---- ground shadow ----
   Outside .p3-float on purpose: the shadow stays on the floor while the
   printer bobs above it, and only breathes in size and darkness. */
.p3-shadow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 230px;
  height: 56px;
  border-radius: 50%;
  background: radial-gradient(
    ellipse at center,
    rgba(4, 9, 20, 0.55),
    rgba(4, 9, 20, 0) 70%
  );
  transform: translate(-50%, -50%) translateY(calc(96px * var(--p3-scale, 1))) scaleY(0.42) scale(var(--p3-scale, 1));
  animation: p3-shadow 6.5s ease-in-out infinite alternate;
}

@keyframes p3-shadow {
  from {
    transform: translate(-50%, -50%) translateY(calc(96px * var(--p3-scale, 1))) scaleY(0.42) scale(calc(1.04 * var(--p3-scale, 1)));
    opacity: 0.9;
  }
  to {
    transform: translate(-50%, -50%) translateY(calc(96px * var(--p3-scale, 1))) scaleY(0.42) scale(calc(0.9 * var(--p3-scale, 1)));
    opacity: 0.6;
  }
}

/* --------------------------------------------------------------------------
   7. The "What am I paying?" widget
   -------------------------------------------------------------------------- */
.widget {
  background: var(--white);
  color: var(--text);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.widget__head {
  padding: var(--s-5) var(--s-5) var(--s-4);
  border-bottom: 1px solid var(--border);
}

.widget__head h2 {
  font-size: 1.3rem;
  margin-bottom: var(--s-1);
}

.widget__head p {
  margin: 0;
  font-size: 0.92rem;
  color: var(--text-muted);
}

.widget__body {
  padding: var(--s-5);
}

/* Step progress */
.steps {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  list-style: none;
  margin: 0 0 var(--s-5);
  padding: 0;
  font-size: 0.85rem;
  color: var(--grey-400);
}

.steps li {
  margin: 0;
}

.steps__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 600;
}

.steps__num {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--grey-100);
  color: var(--grey-600);
  font-size: 0.78rem;
  flex: none;
}

.steps__item[aria-current="step"] {
  color: var(--navy);
}

.steps__item[aria-current="step"] .steps__num {
  background: var(--accent);
  color: #06301b;
}

.steps__item[data-done="true"] .steps__num {
  background: var(--accent-tint);
  color: var(--accent-dark);
}

.steps__rule {
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* Fields */
.field {
  margin-bottom: var(--s-4);
}

.field__label,
.fieldset__legend {
  display: block;
  font-weight: 600;
  font-size: 0.94rem;
  color: var(--navy);
  margin-bottom: var(--s-2);
}

.field__hint {
  display: block;
  font-weight: 400;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: -2px;
  margin-bottom: var(--s-2);
}

.field__optional {
  font-weight: 400;
  color: var(--grey-400);
  font-size: 0.85em;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
select,
textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem; /* 16px stops iOS zooming on focus */
  color: var(--text);
  background: var(--white);
  border: 1.5px solid var(--grey-200);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  min-height: 48px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

textarea {
  min-height: 96px;
  resize: vertical;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--grey-400);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 191, 113, 0.18);
  outline: none;
}

select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath fill='none' stroke='%235c646e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  padding-right: 2.4rem;
}

/* Input with a £ or p adornment */
.input-group {
  display: flex;
  align-items: stretch;
}

.input-group__addon {
  display: grid;
  place-items: center;
  padding-inline: 0.85rem;
  background: var(--grey-100);
  border: 1.5px solid var(--grey-200);
  color: var(--text-muted);
  font-weight: 600;
  flex: none;
}

.input-group__addon--pre {
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
}

.input-group__addon--post {
  border-left: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* Addon on the left (e.g. "£"): square off the input's left corners. */
.input-group__addon--pre + input {
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* Addon on the right (e.g. "p"): the input leads, so square off its right. */
.input-group input:first-child {
  border-radius: var(--radius) 0 0 var(--radius);
}

/* Two-up field row */
.field-row {
  display: grid;
  gap: var(--s-4);
}

@media (min-width: 560px) {
  .field-row {
    grid-template-columns: 1fr 1fr;
  }
}

/* Segmented radio group (pages per month) */
.segmented {
  border: 0;
  padding: 0;
  margin: 0 0 var(--s-4);
}

.segmented__options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-2);
}

@media (min-width: 560px) {
  .segmented__options {
    grid-template-columns: repeat(4, 1fr);
  }
}

.segmented__option {
  position: relative;
}

.segmented__option input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.segmented__option span {
  display: grid;
  place-items: center;
  text-align: center;
  min-height: 48px;
  padding: var(--s-2);
  border: 1.5px solid var(--grey-200);
  border-radius: var(--radius);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-muted);
  transition: border-color 0.15s ease, background-color 0.15s ease,
    color 0.15s ease;
}

.segmented__option input:hover + span {
  border-color: var(--grey-400);
}

.segmented__option input:checked + span {
  border-color: var(--accent);
  background: var(--accent-tint);
  color: var(--accent-dark);
}

.segmented__option input:focus-visible + span {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Consent / checkbox */
.checkbox {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  font-size: 0.92rem;
  line-height: 1.5;
  cursor: pointer;
}

.checkbox input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--accent-dark);
  cursor: pointer;
}

/* Honeypot — hidden from people, visible to naive bots */
.hp-field {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Validation */
.field--error input,
.field--error select,
.field--error textarea {
  border-color: var(--warn);
}

.field__error {
  display: none;
  margin: var(--s-2) 0 0;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--warn);
}

.field--error .field__error {
  display: block;
}

.form-alert {
  display: none;
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius);
  border-left: 4px solid var(--warn);
  background: var(--warn-tint);
  color: #7d2d12;
  font-size: 0.92rem;
}

.form-alert[data-visible="true"] {
  display: block;
}

.form-alert p {
  margin: 0;
}

/* Widget steps visibility */
.widget__step[hidden] {
  display: none;
}

.widget__actions {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  margin-top: var(--s-5);
}

@media (min-width: 560px) {
  .widget__actions {
    flex-direction: row-reverse;
    align-items: center;
  }
  .widget__actions .btn--primary {
    flex: 1;
  }
}

.widget__footnote {
  margin: var(--s-4) 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.5;
}

/* Step 1 result panel */
.result {
  background: var(--accent-tint);
  border: 1px solid rgba(47, 191, 113, 0.35);
  border-radius: var(--radius);
  padding: var(--s-4);
  margin-bottom: var(--s-5);
}

.result__label {
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-dark);
  margin: 0 0 var(--s-1);
}

.result__figure {
  font-size: clamp(1.9rem, 6vw, 2.4rem);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.1;
  margin: 0 0 var(--s-2);
  letter-spacing: -0.02em;
}

.result__breakdown {
  list-style: none;
  margin: 0 0 var(--s-3);
  padding: 0;
  font-size: 0.9rem;
  color: var(--navy-700);
}

.result__breakdown li {
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-1) 0;
  border-bottom: 1px dashed rgba(36, 150, 87, 0.25);
  margin: 0;
}

.result__breakdown li:last-child {
  border-bottom: 0;
}

.result__breakdown dfn {
  font-style: normal;
}

.result__breakdown b {
  font-weight: 650;
  white-space: nowrap;
}

.result__message {
  margin: 0 0 var(--s-2);
  font-size: 0.96rem;
  color: var(--navy-700);
}

.result__caveat {
  margin: 0;
  font-size: 0.82rem;
  color: var(--grey-600);
}

/* --------------------------------------------------------------------------
   8. Trust strip
   -------------------------------------------------------------------------- */
.trust {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding-block: var(--s-5);
}

.trust__list {
  display: grid;
  gap: var(--s-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 640px) {
  .trust__list {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-5);
  }
}

.trust__item {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  margin: 0;
  font-size: 0.93rem;
  color: var(--text-muted);
  line-height: 1.45;
}

.trust__item svg {
  flex: none;
  color: var(--accent-dark);
  margin-top: 2px;
}

.trust__item b {
  display: block;
  color: var(--navy);
  font-weight: 650;
}

/* --------------------------------------------------------------------------
   9. Scroll-driven exploded printer
   -------------------------------------------------------------------------- */
.explode {
  position: relative;
  background: var(--off-white);
}

/* The tall scroll track. Height is what gives us room to scrub. */
.explode__track {
  position: relative;
  height: 280vh;
}

.explode__sticky {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: grid;
  align-content: center;
  padding-block: var(--s-6);
  overflow: hidden;
}

.explode__intro {
  text-align: center;
  max-width: 56ch;
  margin: 0 auto var(--s-5);
}

.explode__intro p {
  color: var(--text-muted);
  margin-bottom: 0;
}

.explode__stage {
  position: relative;
  width: 100%;
  /* The whole sticky block has to fit inside one viewport or the pin breaks,
     so the diagram is capped by viewport height as well as width. The SVG is
     680x600, i.e. ~0.88 tall per unit wide. */
  max-width: min(640px, 66vh);
  margin-inline: auto;
}

.printer-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Parts are moved only with transform — never layout properties. */
.printer-svg .part {
  will-change: transform;
}

.printer-svg .part-label {
  opacity: 0;
  will-change: opacity, transform;
}

.printer-svg .part-label rect {
  fill: var(--white);
  stroke: var(--grey-200);
}

.printer-svg .part-label .label-title {
  fill: var(--navy);
  font-size: 13px;
  font-weight: 700;
}

.printer-svg .part-label .label-body {
  fill: var(--grey-600);
  font-size: 11.5px;
}

.printer-svg .leader {
  stroke: var(--grey-400);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

/* Flat illustration palette — all driven by the site variables. */
.printer-svg .p-shell {
  fill: var(--navy);
}
.printer-svg .p-shell-mid {
  fill: var(--navy-700);
}
.printer-svg .p-shell-light {
  fill: var(--navy-300);
}
.printer-svg .p-accent {
  fill: var(--accent);
}
.printer-svg .p-accent-soft {
  fill: var(--accent-tint);
}
.printer-svg .p-paper {
  fill: var(--off-white);
}
.printer-svg .p-glass {
  fill: #c9d3e4;
}
.printer-svg .p-line {
  fill: none;
  stroke: var(--navy-300);
  stroke-width: 2;
  stroke-linecap: round;
}

/* Compact static mode (<480px): the SVG zooms to the exploded printer column
   and the captions are read from the HTML list underneath instead, where they
   can reflow and stay legible. */
.explode__captions {
  list-style: none;
  margin: var(--s-5) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}

.explode__captions li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
  margin: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s-3) var(--s-4);
}

.explode__captions b {
  grid-column: 2;
  color: var(--navy);
  font-weight: 650;
  font-size: 0.95rem;
}

.explode__captions span {
  grid-column: 2;
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.explode__captions .cap-num {
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent-tint);
  color: var(--accent-dark);
  font-size: 0.8rem;
  font-weight: 700;
}

/* On wide screens the captions live inside the SVG, so the HTML list is
   hidden visually but kept in the accessibility tree — the SVG is exposed
   as a single image, so this list is how screen readers get the detail. */
.explode:not([data-compact="true"]) .explode__captions {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.explode[data-compact="true"] .printer-svg .part-label {
  display: none;
}

.explode__hint {
  text-align: center;
  font-size: 0.85rem;
  color: var(--grey-400);
  margin: var(--s-4) 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
}

.explode__hint svg {
  animation: nudge 1.8s ease-in-out infinite;
}

@keyframes nudge {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(4px);
  }
}

/* Static fallback: small screens and reduced-motion users get the
   fully-exploded diagram with no scroll trickery at all. */
.explode[data-mode="static"] .explode__track,
.explode[data-compact="true"] .explode__track {
  height: auto;
}

.explode[data-compact="true"] .explode__sticky {
  position: static;
  min-height: 0;
}

.explode[data-mode="static"] .explode__sticky {
  position: static;
  min-height: 0;
}

/* Nothing is pinned in static mode, so the diagram can use its full width. */
.explode[data-mode="static"] .explode__stage {
  max-width: 640px;
}

.explode[data-mode="static"] .explode__hint {
  display: none;
}

.explode[data-mode="static"] .printer-svg .part-label {
  opacity: 1;
}

/* Compact (<480px): the diagram pins near the top and the caption cards scroll
   up underneath it, each fading in as its part separates. The SVG needs an
   explicit height because JS interpolates its viewBox as it explodes — with
   height:auto that would resize the element on every frame and shift the page. */
.explode[data-compact="true"] .explode__stage {
  max-width: 100%;
  position: sticky;
  top: 76px;
  z-index: 1;
}

.explode[data-compact="true"] .printer-svg {
  width: 100%;
  height: 48vh;
  max-height: 380px;
}

/* Reduced motion: nothing is pinned and nothing interpolates, so the fixed
   height above is not only unnecessary, it is harmful. The exploded column is
   224x576 — tall and narrow — so forcing it into a short, wide box fits it by
   height and leaves it rendering about 132px wide, stranded in the middle of
   the screen with the parts crushed together. Let it take its natural height
   and constrain the width instead, which is how a static diagram wants to be
   read anyway. */
.explode[data-mode="static"][data-compact="true"] .explode__stage {
  position: static;
  max-width: 190px;
  margin-inline: auto;
}

.explode[data-mode="static"][data-compact="true"] .printer-svg {
  height: auto;
  max-height: none;
}

.explode[data-compact="true"] .explode__captions li {
  will-change: opacity, transform;
}

/* --------------------------------------------------------------------------
   10. Cards, steps, FAQ
   -------------------------------------------------------------------------- */
.card-grid {
  display: grid;
  gap: var(--s-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 720px) {
  .card-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .card-grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }
}

.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  margin: 0;
  box-shadow: var(--shadow-sm);
}

.card h3 {
  margin-bottom: var(--s-2);
}

.card p:last-child {
  margin-bottom: 0;
}

.card__num {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent-dark);
  font-weight: 700;
  font-size: 1.05rem;
  margin-bottom: var(--s-3);
}

.card__icon {
  color: var(--accent-dark);
  margin-bottom: var(--s-3);
  display: block;
}

/* Blog cards */
.post-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
  margin: 0;
}

.post-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.post-card__thumb {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--navy);
}

.post-card__thumb svg {
  display: block;
  width: 100%;
  height: 100%;
}

.post-card__body {
  padding: var(--s-5);
  display: flex;
  flex-direction: column;
  flex: 1;
}

.post-card__body :is(h2, h3) {
  font-size: 1.15rem;
  margin-bottom: var(--s-2);
}

.post-card__body :is(h2, h3) a {
  text-decoration: none;
  color: var(--navy);
}

.post-card__body :is(h2, h3) a:hover {
  text-decoration: underline;
  color: var(--accent-dark);
}

.post-card__body p {
  color: var(--text-muted);
  font-size: 0.95rem;
  flex: 1;
}

.post-meta {
  font-size: 0.82rem;
  color: var(--grey-400);
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
}

.post-meta__dot::before {
  content: "·";
  margin-right: var(--s-2);
}

/* FAQ — details/summary, no JS required */
.faq {
  max-width: var(--wrap-narrow);
}

.faq__item {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: var(--s-3);
  overflow: hidden;
}

.faq__item summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  font-weight: 650;
  color: var(--navy);
  cursor: pointer;
  list-style: none;
  min-height: 56px;
}

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

.faq__item summary::after {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--grey-400);
  border-bottom: 2px solid var(--grey-400);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.18s ease;
}

.faq__item[open] summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

.faq__item summary:hover {
  background: var(--grey-100);
}

.faq__answer {
  padding: 0 var(--s-4) var(--s-4);
  color: var(--text-muted);
}

.faq__answer p:last-child {
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   11. Prose (blog posts, legal pages)
   -------------------------------------------------------------------------- */
.prose {
  max-width: 68ch;
}

.prose h2 {
  margin-top: var(--s-7);
  font-size: clamp(1.35rem, 3vw, 1.7rem);
}

.prose h3 {
  margin-top: var(--s-6);
}

.prose > :first-child {
  margin-top: 0;
}

.prose ul,
.prose ol {
  margin-bottom: var(--s-4);
}

.prose li {
  padding-left: var(--s-1);
}

.prose blockquote {
  margin: var(--s-5) 0;
  padding: var(--s-4) var(--s-5);
  border-left: 4px solid var(--accent);
  background: var(--white);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--navy-700);
  font-size: 1.02rem;
}

.prose blockquote p:last-child {
  margin-bottom: 0;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--s-5);
  font-size: 0.94rem;
  background: var(--white);
}

.prose th,
.prose td {
  text-align: left;
  padding: var(--s-3);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.prose th {
  color: var(--navy);
  font-weight: 650;
  background: var(--grey-100);
}

.table-scroll {
  overflow-x: auto;
  margin-bottom: var(--s-5);
  -webkit-overflow-scrolling: touch;
}

.table-scroll table {
  margin-bottom: 0;
  min-width: 480px;
}

.callout {
  background: var(--white);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--s-4) var(--s-5);
  margin: var(--s-5) 0;
}

.callout h3 {
  margin-top: 0;
  font-size: 1.05rem;
}

.callout p:last-child {
  margin-bottom: 0;
}

/* Page header for interior pages */
.page-head {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding-block: var(--s-6);
}

.page-head h1 {
  margin-bottom: var(--s-3);
}

.page-head .lede {
  margin-bottom: 0;
}

.breadcrumb {
  font-size: 0.86rem;
  color: var(--text-muted);
  margin-bottom: var(--s-3);
}

.breadcrumb a {
  color: var(--text-muted);
}

.breadcrumb ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.breadcrumb li {
  margin: 0;
}

.breadcrumb li + li::before {
  content: "/";
  margin-right: var(--s-2);
  color: var(--grey-400);
}

/* --------------------------------------------------------------------------
   11b. Touch target sizing
   Navigation links default to the height of their text — around 16-19px, which
   is a small thing to hit on a phone. These give the site's *navigational*
   links a ~44px tap area.

   Deliberately NOT applied to inline links inside body copy: padding those
   would break the line rhythm of a paragraph, and a link sitting in a sentence
   is understood to be text-sized. This targets menus, footers, breadcrumbs and
   standalone link lists only.
   -------------------------------------------------------------------------- */
.logo {
  padding-block: 10px;
}

.footer-grid li {
  margin-bottom: 0;
}

.footer-grid ul a,
.footer-grid p a {
  display: inline-block;
  padding-block: 0.78rem;
}

.footer-grid p a {
  padding-block: 0.6rem;
}

.breadcrumb a {
  display: inline-block;
  padding-block: 0.7rem;
}

/* Standalone link lists (the 404 page's suggestions) */
.link-list {
  list-style: none;
  padding: 0;
  display: inline-block;
  text-align: left;
}

.link-list li {
  margin-bottom: 0;
}

.link-list a {
  display: inline-block;
  padding-block: 0.6rem;
}

/* --------------------------------------------------------------------------
   12. Cookie banner
   -------------------------------------------------------------------------- */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  background: var(--white);
  border-top: 1px solid var(--border);
  box-shadow: 0 -6px 24px rgba(27, 42, 74, 0.12);
  padding: var(--s-4);
  /* Keep clear of iOS home indicator */
  padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
  transform: translateY(110%);
  transition: transform 0.25s ease;
}

.cookie-banner[data-visible="true"] {
  transform: translateY(0);
}

.cookie-banner__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  display: grid;
  gap: var(--s-3);
}

@media (min-width: 860px) {
  .cookie-banner__inner {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--s-5);
  }
}

.cookie-banner p {
  margin: 0;
  font-size: 0.88rem;
  color: var(--text-muted);
  line-height: 1.5;
}

.cookie-banner h2 {
  font-size: 0.98rem;
  margin-bottom: var(--s-1);
}

.cookie-banner__actions {
  display: flex;
  gap: var(--s-3);
}

.cookie-banner__actions .btn {
  flex: 1;
  padding: 0.6rem 1.1rem;
  min-height: 44px;
  font-size: 0.92rem;
  white-space: nowrap;
}

@media (min-width: 860px) {
  .cookie-banner__actions .btn {
    flex: none;
  }
}

/* --------------------------------------------------------------------------
   13. Thanks / 404 centred pages
   -------------------------------------------------------------------------- */
.centred-page {
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: var(--s-8);
  min-height: 58vh;
}

.centred-page__inner {
  max-width: 56ch;
}

.centred-page__icon {
  color: var(--accent);
  margin-bottom: var(--s-4);
}

.centred-page .btn {
  margin-top: var(--s-3);
}

/* --------------------------------------------------------------------------
   14. Print
   -------------------------------------------------------------------------- */
@media print {
  .site-header,
  .site-footer,
  .cookie-banner,
  .cta-band,
  .explode {
    display: none !important;
  }
  body {
    background: #fff;
  }
}
