/* Shell components added for the site rebuild: the Industries dropdown, the
   expanded footer and the cookie consent dialog. These sit alongside the purged
   Webflow stylesheet and reuse its design tokens, so the visual language is
   unchanged. */

/* --- skip link ---------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background-color: var(--neutral--100);
  color: var(--conundrum-blue-accent);
  border: 1px solid var(--conundrum-blue-accent);
  border-radius: 10px;
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
}

.skip-link:focus {
  left: 16px;
  top: 16px;
}

/* --- primary navigation: Industries dropdown ----------------------------- */

.nav-dropdown {
  position: relative;
  display: flex;
  align-items: center;
}

.nav-dropdown__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  padding: 0;
  color: var(--neutral--700);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
}

.nav-dropdown__toggle::after {
  content: "";
  width: 0.4em;
  height: 0.4em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
  transition: transform 0.2s ease;
}

.nav-dropdown.is-open .nav-dropdown__toggle::after {
  transform: translateY(0.1em) rotate(-135deg);
}

.nav-dropdown__toggle:hover,
.nav-dropdown__toggle:focus-visible {
  color: var(--conundrum-blue-accent);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* The collapsed menu is the state the page first paints in: the markup ships
   the list with a hidden attribute and the toggle is visible from the start,
   so site-nav.js changes no layout and the header does not move on load. The
   no-script fallback in no-js.css puts the list back in flow. */
.nav-dropdown__menu {
  position: absolute;
  display: block;
  top: calc(100% + 12px);
  left: 0;
  z-index: 40;
  min-width: 260px;
  margin: 0;
  padding: 8px;
  list-style: none;
  background-color: var(--neutral--100);
  border: 1px solid var(--neutral--200);
  border-radius: 12px;
  box-shadow: 0 16px 32px var(--general--shadow-01);
}

.nav-dropdown__menu[hidden] {
  display: none;
}

.nav-dropdown__menu a {
  display: block;
  border-radius: 8px;
  padding: 10px 12px;
  white-space: normal;
}

.nav-dropdown__menu a:hover,
.nav-dropdown__menu a:focus-visible {
  background-color: var(--system--blue-100);
  text-decoration: none;
}

.nav-cta {
  border: 1px solid var(--conundrum-blue-accent);
  border-radius: 10px;
  padding: 10px 18px;
  color: var(--conundrum-blue-accent);
  white-space: nowrap;
}

.primary-navigation a.nav-cta:hover,
.primary-navigation a.nav-cta:focus-visible {
  background-color: var(--conundrum-blue-accent);
  color: var(--neutral--100);
  text-decoration: none;
}

@media screen and (max-width: 767px) {
  .nav-dropdown__toggle {
    font-size: 12px;
  }

  .nav-dropdown__menu {
    left: auto;
    right: 0;
  }

  .nav-cta {
    padding: 8px 14px;
  }
}

/* --- footer -------------------------------------------------------------- */

/* Two rows: where to go, then who we are. The company name appears once, in
   the registration line that company law requires anyway, and the wordmark is
   left to the header at the top of the same page. */
/* One rule marks where the page ends. Inside it the two lines sit close
   together, because they are the same thought: the links, then who is behind
   them. */
.site-footer {
  border-top: 1px solid var(--neutral--200);
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px 32px;
  padding-top: 20px;
  padding-bottom: 6px;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 32px;
  padding-bottom: 20px;
}

/* The theme indents every list item by 8px and spaces it by 8 below. In the
   footer that pushed the links out of line with the registration sentence
   under them, which is the one thing they have to line up with. */
.footer-links li,
.footer-legal li {
  margin-bottom: 0;
  padding-left: 0;
}

.footer-details {
  margin: 0;
  color: var(--neutral--500);
  font-size: 0.8125rem;
  line-height: 1.6;
  font-style: normal;
}

.footer-details a {
  color: var(--neutral--600);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-details a:hover,
.footer-details a:focus-visible {
  color: var(--conundrum-blue-accent);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin: 0;
  padding: 0;
  list-style: none;
  align-content: flex-start;
}

.footer-links a,
.footer-links button {
  border: 0;
  background: none;
  padding: 0;
  color: var(--neutral--600);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
}

.footer-links a:hover,
.footer-links a:focus-visible,
.footer-links button:hover,
.footer-links button:focus-visible {
  color: var(--conundrum-blue-accent);
  text-decoration: underline;
  text-underline-offset: 4px;
}

@media screen and (max-width: 767px) {
  .footer-top {
    grid-template-columns: 1fr;
    gap: 24px;
    padding-top: 32px;
  }
}

/* --- cookie consent ------------------------------------------------------ */

.consent {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 90;
  background-color: var(--neutral--100);
  border: 1px solid var(--neutral--200);
  border-radius: 16px;
  box-shadow: 0 24px 48px var(--general--shadow-01);
}

.consent__inner {
  max-width: 880px;
  margin: 0 auto;
  padding: 24px;
}

.consent__title {
  margin: 0 0 8px;
  color: var(--neutral--700);
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.3;
}

.consent__text {
  margin: 0;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.consent__link {
  color: var(--conundrum-blue-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.consent__options {
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
}

.consent__option {
  border: 1px solid var(--neutral--200);
  border-radius: 12px;
  padding: 12px 14px;
}

.consent__option-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
}

.consent__option-copy {
  display: block;
}

.consent__checkbox {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex: none;
  accent-color: var(--conundrum-blue-accent);
}

.consent__option-name {
  display: block;
  color: var(--neutral--700);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
}

.consent__option-note {
  display: block;
  margin-top: 2px;
  color: var(--neutral--600);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.consent__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 20px;
}

/* Accept and Reject are deliberately identical in size, weight and colour:
   rejecting must be no harder than accepting. */
.consent__button {
  flex: 1 1 180px;
  border: 1px solid var(--conundrum-blue-accent);
  border-radius: 10px;
  background-color: var(--neutral--100);
  padding: 14px 20px;
  color: var(--conundrum-blue-accent);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.111em;
  text-align: center;
  cursor: pointer;
  transition:
    border-color 0.3s,
    background-color 0.3s,
    color 0.3s;
}

.consent__button:hover,
.consent__button:focus-visible {
  background-color: var(--conundrum-blue-accent);
  color: var(--neutral--100);
}

.consent__button--quiet {
  border-color: var(--neutral--300);
  color: var(--neutral--600);
}

.consent__button--quiet:hover,
.consent__button--quiet:focus-visible {
  border-color: var(--neutral--600);
  background-color: var(--neutral--200);
  color: var(--neutral--700);
}

@media screen and (max-width: 560px) {
  .consent__button {
    flex-basis: 100%;
  }
}

/* --- page scaffolding ---------------------------------------------------- */

.page-notice {
  border: 1px dashed var(--neutral--300);
  border-radius: 16px;
  padding: 24px;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* --- content utilities -------------------------------------------------- */

.inner-container._800px {
  max-width: 800px;
}

.mg-top-32px {
  margin-top: 32px;
}

.text-200 {
  font-size: 1rem;
  line-height: 1.6;
}

/* Long-form pages: legal text, page narrative, case studies. */
.prose p {
  margin-bottom: 16px;
  color: var(--neutral--600);
  line-height: 1.7;
}

.prose ul,
.prose ol {
  margin-bottom: 20px;
  padding-left: 22px;
  color: var(--neutral--600);
  line-height: 1.7;
}

.prose li {
  margin-bottom: 10px;
}

.prose h2 {
  margin-top: 48px;
  margin-bottom: 12px;
}

.prose h3 {
  margin-top: 32px;
  margin-bottom: 8px;
}

.prose a {
  color: var(--conundrum-blue-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* A button that has to read as a link because it sits inside a sentence. */
.link-button {
  border: 0;
  background: none;
  padding: 0;
  color: var(--conundrum-blue-accent);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.link-button:hover,
.link-button:focus-visible {
  color: var(--neutral--700);
}

/* --- cards and grids ----------------------------------------------------- */

.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
}

.tile {
  border: 1px solid var(--neutral--200);
  border-radius: 16px;
  padding: 28px;
  background-color: var(--neutral--100);
}

.tile h3 {
  margin-top: 0;
  margin-bottom: 10px;
  color: var(--neutral--700);
  font-size: 1.125rem;
  line-height: 1.35;
}

.tile p {
  margin-bottom: 0;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  line-height: 1.65;
}

.tile p + p {
  margin-top: 12px;
}

/* --- data tables --------------------------------------------------------- */

.data-table-wrap {
  overflow-x: auto;
  margin-bottom: 24px;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.data-table caption {
  margin-bottom: 10px;
  color: var(--neutral--600);
  font-size: 0.875rem;
  text-align: left;
}

.data-table th,
.data-table td {
  border-bottom: 1px solid var(--neutral--200);
  padding: 12px 14px;
  color: var(--neutral--600);
  text-align: left;
  vertical-align: top;
  line-height: 1.55;
}

.data-table th {
  color: var(--neutral--700);
  font-weight: 600;
  white-space: nowrap;
}

/* --- pending evidence ---------------------------------------------------- */

/* Where a figure cannot be published until its claims register row is
   substantiated, the page says so rather than quietly omitting the result. */
/* --- forms on light pages ------------------------------------------------ */

/* The existing .input styling was authored for the dark contact panel on the
   home page. These pages are light, so the form gets its own scope rather
   than overriding those rules. */

.page-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.page-form .field-full {
  grid-column: 1 / -1;
}

.page-form label {
  display: block;
  margin-bottom: 6px;
  color: var(--neutral--700);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.4;
}

.page-form .field-hint {
  display: block;
  margin-top: 6px;
  color: var(--neutral--500);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.5;
}

.page-form input[type="text"],
.page-form input[type="email"],
.page-form input[type="tel"],
.page-form select,
.page-form textarea {
  width: 100%;
  border: 1px solid var(--neutral--300);
  border-radius: 10px;
  background-color: var(--neutral--100);
  padding: 14px 16px;
  color: var(--neutral--700);
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.4;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}

.page-form textarea {
  min-height: 140px;
  resize: vertical;
}

.page-form input:focus,
.page-form select:focus,
.page-form textarea:focus {
  border-color: var(--conundrum-blue-accent);
  box-shadow: 0 0 0 3px var(--system--blue-100);
  outline: none;
}

.page-form .required-mark {
  color: var(--system--red-400);
}

/* Shown in place of a submission when the build carries no Web3Forms access
   key, so the reader is told what to do instead of being handed the endpoint's
   own error page. homepage-runtime.js adds it; normally it never exists. */
.form-unavailable {
  grid-column: 1 / -1;
  margin: 0;
  border: 1px solid var(--system--red-400);
  border-radius: 12px;
  padding: 14px 16px;
  background-color: var(--neutral--100);
  color: var(--neutral--700);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.form-unavailable:focus-visible {
  outline: 2px solid var(--conundrum-blue-accent);
  outline-offset: 2px;
}

.page-form fieldset {
  border: 1px solid var(--neutral--200);
  border-radius: 12px;
  margin: 0;
  padding: 16px 18px;
}

.page-form legend {
  padding: 0 6px;
  color: var(--neutral--700);
  font-size: 0.9375rem;
  font-weight: 500;
}

.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px 20px;
  margin-top: 8px;
}

.check-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.check-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  flex: none;
  accent-color: var(--conundrum-blue-accent);
}

.check-row label,
.check-row span {
  margin: 0;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.5;
}

.form-footnote {
  color: var(--neutral--500);
  font-size: 0.875rem;
  line-height: 1.6;
}

/* Web3Forms' honeypot: present for bots, never shown or focusable. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-success {
  display: none;
  border: 1px solid var(--system--green-200);
  border-radius: 14px;
  background-color: var(--system--green-100);
  padding: 24px;
  color: var(--neutral--700);
  line-height: 1.6;
}

.form-error {
  display: none;
  border: 1px solid var(--system--red-200);
  border-radius: 14px;
  padding: 20px;
  color: var(--neutral--700);
  line-height: 1.6;
}

@media screen and (max-width: 600px) {
  .page-form {
    grid-template-columns: 1fr;
  }
}

/* The hero's secondary action is a link, not a second button: the filled
   button style was authored for dark panels and outranks the primary here. */
.hero-secondary-link {
  display: inline-block;
  margin-left: 24px;
  color: var(--conundrum-blue-accent);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 4px;
}

.hero-secondary-link:hover,
.hero-secondary-link:focus-visible {
  color: var(--neutral--700);
}

@media screen and (max-width: 560px) {
  .hero-secondary-link {
    display: block;
    margin: 20px 0 0;
  }
}

/* The exported logo strip carries a 74px right margin on top of a 1218px
   minimum width, which together exceed the container and clip the last logo.
   The margin served a layout that no longer exists. */
.logo-strip-row.logo-strip-large {
  margin-right: 0;
}

/* --- header and logo behaviour ------------------------------------------ */

/* The exported theme lifts the logo 3px on hover. On a sticky header that
   reads as the logo jumping under the pointer, so it is removed. */
.header-logo-link,
.footer-logo-wrapper {
  transition: opacity 0.2s;
}

.header-logo-link:hover,
.footer-logo-wrapper:hover {
  transform: none;
  opacity: 0.75;
}

/* The header sticks at top:-20px and carries no stacking context, so sections
   that establish their own (the logo strip sets z-index:1) paint over it as
   they scroll past, which reads as flickering. Pin it at the top and put it
   above the page. */
.header-wrapper {
  top: 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
}

/* --- engagement milestones ----------------------------------------------- */

/* A horizontal run of milestones across the full page width, rather than four
   stacked cards in an 800px column. */
.milestones {
  counter-reset: milestone;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 32px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.milestone {
  position: relative;
  padding-top: 60px;
}

.milestone::before {
  counter-increment: milestone;
  content: counter(milestone);
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: var(--conundrum-blue-accent);
  color: var(--neutral--100);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 40px;
  text-align: center;
}

/* The rule joining one milestone to the next. */
.milestone::after {
  content: "";
  position: absolute;
  top: 19px;
  left: 52px;
  right: -32px;
  height: 2px;
  background-color: var(--neutral--200);
}

.milestone:last-child::after {
  display: none;
}

.milestone h3 {
  margin: 0 0 8px;
  color: var(--neutral--700);
  font-size: 1.0625rem;
  line-height: 1.35;
}

.milestone p {
  margin: 0;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  line-height: 1.65;
}

@media screen and (max-width: 991px) {
  .milestones {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px 40px;
  }

  /* With two per row the connector would run off the end of each row. */
  .milestone::after {
    display: none;
  }
}

@media screen and (max-width: 560px) {
  .milestones {
    grid-template-columns: 1fr;
    gap: 28px;
  }
}

/* --- card link alignment -------------------------------------------------- */

/* Cards in a row have different amounts of copy, so their trailing links land
   at different heights unless the card is a column that pushes them down. */
.tile {
  display: flex;
  flex-direction: column;
}

/* Push a trailing link to the foot of the card so links align across a row.
   Only a link: on a card that ends in ordinary copy this would open a gap
   under the heading instead. */
.tile > p:last-child:has(a) {
  margin-top: auto;
}

.tile p + p {
  padding-top: 12px;
}

/* The exported header pads 32px above the nav row and 10px below. That was
   balanced only while the header sat at top:-20px and scrolled 20px of the
   top padding out of view. Now that it is pinned at top:0 the full 32px
   shows, which drops the row low in the bar and leaves the bordered call to
   action almost touching the bottom edge. Even padding restores it. */
.header-wrapper {
  padding-top: 20px;
  padding-bottom: 20px;
}

/* The logo link keeps a 4px bottom margin from the theme, which lifts the
   wordmark 2px above the optical centre of the row it shares. */
.header-logo-link {
  margin-bottom: 0;
}

/* Raise the frame without moving the label. The box is shifted up with
   position, which keeps it out of the flex layout so nothing else in the
   header moves, and the padding is rebalanced by the same 5px to push the
   text back down inside the box. Net effect: the border sits 5px higher, the
   label stays on the same line as the navigation text beside it. The two
   paddings still sum to 20px, so the box height and the header are unchanged. */
.nav-cta {
  /* The only number to change when the frame needs nudging. Positive lifts
     the border; the three declarations below stay in step automatically. */
  --frame-lift: 2px;

  position: relative;
  top: calc(-1 * var(--frame-lift));
  padding-top: calc(10px + var(--frame-lift));
  padding-bottom: calc(10px - var(--frame-lift));
}

/* --- call-to-action consistency ------------------------------------------ */

/* The header button reads as part of the menu rather than as a body call to
   action: same black label as the links beside it, no underline. The blue
   frame is what marks it out. */
.primary-navigation a.nav-cta {
  color: var(--neutral--700);
  text-decoration: none;
}

/* Underline the call-to-action labels in the page body, so the bordered
   buttons and the plain hero link read as one family. Declared after the
   theme's own text-decoration: none, which it would otherwise win on equal
   specificity. */
.btn-primary,
.btn-secondary {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.btn-primary:hover,
.btn-primary:focus-visible,
.btn-secondary:hover,
.btn-secondary:focus-visible {
  text-decoration: underline;
}

/* The theme lifts buttons 3px on hover, which reads as the button jumping out
   from under the pointer. The colour change alone is the hover signal. */
.btn-primary:hover,
.btn-primary:focus-visible,
.btn-secondary:hover,
.btn-secondary:focus-visible {
  transform: none;
}

/* --- text beside an image ------------------------------------------------ */

/* Copy on the left, supporting image on the right, collapsing to one column
   before the text column gets too narrow to read comfortably.

   The row starts both columns at the top, so the page heading always sits the
   same distance below the breadcrumbs. Centring the row instead pushed the
   heading down by half of whatever the illustration was taller than the copy,
   which varied with the length of the copy: 14px on one page and 86px on
   another, and most of all on Contact, which has the fewest words. */
.split-media {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 56px;
  align-items: start;
}

/* The illustration keeps the optical centring the row gave up. */
.split-media__figure {
  align-self: center;
}

/* The case studies hub pads its own 80px where every other breadcrumbed page
   gets 60 from the section inside it, which left its heading sitting lower
   than the rest. The 100px below it is its own and stays. */
.case-studies-hub {
  padding-top: 60px;
}

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

.split-media__figure {
  margin: 0;
}

.split-media__figure img {
  display: block;
  width: 100%;
  height: auto;
}

@media screen and (max-width: 991px) {
  .split-media {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  /* Below the breakpoint the illustration is decorative rather than
     supporting, so it gives way to the copy instead of pushing it down. */
  .split-media__figure {
    max-width: 480px;
  }
}

/* Result headline on a case study card, read before the title. */
.case-result {
  margin: 0 0 8px;
  color: var(--conundrum-blue-accent);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Two per row rather than as many as fit: four case study cards across a wide
   screen leaves each column too narrow for its own headline. */
.tile-grid--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media screen and (max-width: 767px) {
  .tile-grid--two {
    grid-template-columns: 1fr;
  }
}

/* Tables run wider than the prose column they sit beside: a four-column
   results table does not fit 800px without scrolling sideways. */
.inner-container._1040px {
  max-width: 1040px;
}

/* Row headers were set not to wrap, which is what pushed the results table
   past its container in the first place. */
.data-table th {
  white-space: normal;
}

/* Below this width a four-column numeric table cannot fit whatever is done to
   it, so each row becomes a small block and every value carries the column
   name it lost. No sideways scrolling at any width. */
@media screen and (max-width: 720px) {
  .data-table--stack,
  .data-table--stack tbody,
  .data-table--stack tr,
  .data-table--stack th,
  .data-table--stack td {
    display: block;
    width: 100%;
  }

  .data-table--stack thead {
    display: none;
  }

  .data-table--stack tr {
    border: 1px solid var(--neutral--200);
    border-radius: 12px;
    margin-bottom: 14px;
    padding: 14px 16px;
  }

  .data-table--stack th,
  .data-table--stack td {
    border: 0;
    padding: 4px 0;
  }

  .data-table--stack th[scope="row"] {
    color: var(--neutral--700);
    font-size: 1rem;
    padding-bottom: 8px;
  }

  .data-table--stack td::before {
    content: attr(data-label);
    display: block;
    color: var(--neutral--500);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
}

/* --- case study card imagery --------------------------------------------- */

/* The image bleeds to the card edges, so it sits outside the card's padding.
   Same 1280/628 crop the old site used for its case study thumbnails. */
.tile {
  overflow: hidden;
}

.tile__media {
  display: block;
  margin: -28px -28px 20px;
}

.tile__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1280 / 628;
  object-fit: cover;
}

@media screen and (max-width: 767px) {
  .tile__media {
    margin: -28px -28px 18px;
  }
}

/* --- platform feature cards ---------------------------------------------- */

/* The exported card draws a divider under its heading that was switched off
   by an id-scoped rule on the old home page. That rule went with the section,
   so the card carries its own. */
.platform-card .border-line-item.v2 {
  border: 0;
}

.platform-card {
  border-radius: 24px;
}

.platform-card .image-style.v1 {
  display: block;
  width: 100%;
  height: auto;
}

/* Compact the platform tour. The exported card was built for a full-width
   feature section, so at half width its 38px heading and 20px stacked margins
   left the block far taller than it needs to be. */
.platform-card {
  padding: 14px;
}

.platform-card h3.display-4 {
  margin-top: 16px;
  font-size: 1.75rem;
  line-height: 1.25;
  /* The theme tracks .display-4 at a fixed -3px, drawn for 38px type. At this
     size that is a tenth of the em and the letters run together, so tracking
     is set relative to the font size instead of in pixels. */
  letter-spacing: -0.01em;
}

.platform-card .border-line-item.v2 {
  margin-top: 10px;
  margin-bottom: 12px;
}

.platform-card .border-line-item.v2 p {
  margin-bottom: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
}

.platform-card .features-grid-2-col {
  grid-column-gap: 8px;
  grid-row-gap: 8px;
}

/* The theme gives these property pills a translucent grey fill, which reads as
   a smudge rather than a tag; they take a tint of the accent instead.

   The box also sat two pixels low against its label. It is lifted with
   position/top and the vertical padding is rebalanced by the same two pixels,
   so the background moves and the text stays exactly where it was. */
.platform-card .badge-primary.tiny {
  position: relative;
  top: -2px;
  padding: 8px 12px 4px;
  border-color: #dbe3f8;
  background-color: #eef2fc;
  color: var(--conundrum-blue-accent);
  font-size: 0.8125rem;
}

.business-ai-grid-2-col {
  grid-column-gap: 32px;
  grid-row-gap: 28px;
}

/* The exported card reserves a 23.5rem minimum for its text row
   (grid-template-rows: minmax(1.5rem,auto) minmax(23.5rem,1fr) auto auto),
   which is why tightening the type changed nothing: the row held its floor
   regardless. Let both rows size to their content. The selector matches the
   theme's specificity so it actually wins. */
.grid-1-column.business-ai-grid-1-col.v2.blur-backdrop.padding-1rem.platform-card {
  grid-template-rows: auto auto;
  padding: 14px;
}

/* Six cards split 4 and 2 under auto-fit, which reads as a broken row.
   Three across gives two even rows. */
.tile-grid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media screen and (max-width: 991px) {
  .tile-grid--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media screen and (max-width: 600px) {
  .tile-grid--three {
    grid-template-columns: 1fr;
  }
}

/* --- card treatment ------------------------------------------------------- */
/* Modelled on the old site's Crushing / Grinding / Flotation / Cement cards:
   a blue heading, accent-blue top and bottom edges, and a soft drop shadow.
   On the old site the blue edges marked the selected tab and the card slid
   3px sideways on hover; here they are the permanent resting state and there
   is no hover response at all. The owner asked for cards that do not change
   under the pointer, so this rule has no :hover counterpart and no transition
   — do not add one.

   This applies to .tile only. The platform tour cards were given the same
   surface and the owner rejected it: those cards are meant to sit straight on
   the wave backdrop with no border, shadow or card background, as they do on
   the old site. Do not fold .platform-card back into these selectors. */
.tile {
  border: 1px solid var(--neutral--200);
  border-top-color: var(--conundrum-blue-accent);
  border-bottom-color: var(--conundrum-blue-accent);
  background-color: var(--neutral--100);
  box-shadow: 0 2px 6px 0 var(--general--shadow-06);
}

.tile h3 {
  color: var(--conundrum-blue-accent);
}

/* --- proof bar ------------------------------------------------------------ */
/* Home section 2 in the specification: three or four measured figures, each
   linked to the case study it comes from. The heading is for screen readers
   and the page outline; on screen the figures speak for themselves. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* It closes the hero, so it carries more of the weight than a rule of figures
   would: each column leads with the plant from the case study behind it. */
.proof-bar {
  margin-top: 8px;
  margin-bottom: 8px;
}

/* The illustrations are dense pipework and turn to mush much below this, so
   88px is a floor rather than a preference. They are served at twice that. */
.proof-bar__icon {
  display: block;
  width: auto;
  height: 88px;
  margin-bottom: 14px;
}

.proof-bar__list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px 32px;
  margin: 0;
  padding: 28px 0;
  border-top: 1px solid var(--neutral--200);
  border-bottom: 1px solid var(--neutral--200);
  list-style: none;
}

.proof-bar__list a {
  display: block;
  color: inherit;
  text-decoration: none;
}

.proof-bar__figure {
  display: block;
  color: var(--conundrum-blue-accent);
  font-size: 1.75rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* Each figure is a link to the case study behind it, and has to read as one
   standing still rather than only under the pointer. The label is underlined
   at rest and the whole item turns accent blue on hover. */
.proof-bar__label {
  display: block;
  margin-top: 6px;
  color: var(--neutral--600);
  font-size: 0.9375rem;
  line-height: 1.5;
  text-decoration: underline;
  text-decoration-color: var(--neutral--300);
  text-underline-offset: 4px;
}

.proof-bar__label::after {
  content: " \2192";
  color: var(--conundrum-blue-accent);
  text-decoration: none;
}

.proof-bar__list a:hover .proof-bar__label,
.proof-bar__list a:focus-visible .proof-bar__label {
  color: var(--conundrum-blue-accent);
  text-decoration-color: var(--conundrum-blue-accent);
}

@media screen and (max-width: 991px) {
  .proof-bar__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px 32px;
  }
}

@media screen and (max-width: 479px) {
  .proof-bar__list {
    grid-template-columns: 1fr;
  }
}

/* --- linked cards --------------------------------------------------------- */
/* One approach everywhere: the whole card is the link. The heading anchor is
   the only interactive element and its stretched ::after covers the card, so
   each card still holds exactly one link rather than a heading link and a
   duplicate "read more" underneath it. Keyboard focus lands on that anchor
   and is shown on the card. Nothing moves or changes colour on hover, per the
   card treatment above. */
.tile--link {
  position: relative;
}

.tile--link :is(h2, h3) a {
  color: inherit;
  text-decoration: none;
}

.tile--link :is(h2, h3) a::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* A card that is a link has to look like one under the pointer. The response
   is colour only -- a faint accent wash and an underline on the heading --
   because nothing on this site moves, lifts or resizes on hover. */
.tile--link {
  transition:
    background-color 0.2s,
    box-shadow 0.2s;
}

/* The blue edges thicken with an inset shadow rather than a wider border, so
   the card does not reflow by the two pixels it would gain -- nothing on this
   site moves under the pointer. The lines are drawn on an overlay rather than
   on the card itself because the case study cards bleed an image to the top
   edge, and an inset shadow on the card would paint underneath it. */
.tile--link::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  transition: box-shadow 0.2s;
}

.tile--link:hover,
.tile--link:focus-within {
  background-color: #f6f8fe;
  box-shadow: 0 2px 10px 0 var(--general--shadow-05);
}

.tile--link:hover::before,
.tile--link:focus-within::before {
  box-shadow:
    inset 0 2px 0 0 var(--conundrum-blue-accent),
    inset 0 -2px 0 0 var(--conundrum-blue-accent);
}

.tile--link:focus-within {
  outline: 2px solid var(--conundrum-blue-accent);
  outline-offset: 3px;
}

.tile--link :is(h2, h3) a:focus-visible {
  outline: none;
}

/* The theme fills the logo slider with 40% white. That was invisible against
   the wireframe terrain the hero used to carry; on the plain wash behind it
   now, it reads as a pale panel floating over the section, so it is cleared. */
.logo-strip-row .w-slider {
  background-color: transparent;
}

/* --- card with an icon ---------------------------------------------------- */
/* The industry cards lead with the material rather than the plant: the object
   sits to the left of the heading and the copy runs beside it. The icon is
   decorative, because the heading names the industry. */
.tile--icon {
  flex-direction: row;
  align-items: flex-start;
  gap: 20px;
}

.tile__icon {
  flex: 0 0 auto;
  width: 84px;
  height: auto;
}

.tile--icon .tile__body {
  min-width: 0;
}

.tile--icon .tile__body > *:last-child {
  margin-bottom: 0;
}

@media screen and (max-width: 479px) {
  .tile--icon {
    gap: 14px;
  }

  .tile__icon {
    width: 60px;
  }
}

/* --- page background motifs ----------------------------------------------- */
/* Faint wireframe illustrations that drift through a section and out again as
   the page scrolls. Ten of them, so a reader moving through the site rarely
   meets the same one twice, and no page carries one motif in two places.

   All are pinned with background-attachment: fixed, which is what produces the
   drift, and all sit under a white veil heavy enough that the copy never has to
   compete. No script is involved, so they work on every page rather than only
   the three that load the home page runtime.

   The artwork arrives in lilac and cyan and is recoloured into the accent on
   the way in, so the whole site reads in one hue. It is rasterised rather than
   served as SVG: a pinned background is repainted on every scroll frame, and
   re-rasterising several hundred vector polylines each time made scrolling
   stutter. Raster also softens the lines, which is how the earlier motifs
   looked.

   The files are encoded losslessly. At this strength the darkest line is only
   ten levels below white, and lossy WebP was introducing errors of up to
   twelve, so the artefacts were larger than the picture. Magnified by a large
   monitor they showed as a chewed mesh. */

/* Every motif is laid out the same way: covering the viewport, centred, and
   fixed, so a section shows whatever part of the motif it happens to span.
   Anything sized to contain and anchored to an edge reads as a band along that
   edge of the window instead, and a short section then catches a sliver of it
   and looks as though it carries no background at all. The home page hero is
   the one place that framing is wanted, and it keeps its own rule, in the
   page. */

.bg-wave-ridge {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-wave-ridge.9bd2403d4b9f.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, cover;
  background-attachment: scroll, fixed;
}

.bg-wave-crossing {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-wave-crossing.fac3a84f25a6.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, cover;
  background-attachment: scroll, fixed;
}

.bg-wave-crest {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-wave-crest.b87fbf8ee462.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, cover;
  background-attachment: scroll, fixed;
}

.bg-bubbles-chain {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-bubbles-chain.1d10c3ae6fef.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, contain;
  background-attachment: scroll, fixed;
}

.bg-bubbles-arch {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-bubbles-arch.83583b96405e.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, contain;
  background-attachment: scroll, fixed;
}

.bg-bubbles-scattered {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-bubbles-scattered.977ef5b006eb.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, contain;
  background-attachment: scroll, fixed;
}

.bg-bubbles-clusters {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-bubbles-clusters.b684aa653217.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, contain;
  background-attachment: scroll, fixed;
}

.bg-bubbles-stream {
  background-image: linear-gradient(
      180deg,
      #fff 0%,
      rgba(255, 255, 255, 0) 14%,
      rgba(255, 255, 255, 0) 86%,
      #fff 100%
    ),
    url("/assets/images/bg-bubbles-stream.a4a78349eb0c.webp");
  background-position: 0 0, 50% 50%;
  background-repeat: repeat, no-repeat;
  background-size: auto, contain;
  background-attachment: scroll, fixed;
}


/* --- closing call to action ----------------------------------------------- */
/* The theme splits this panel into "text | button" and only stacks it below
   768px, so at every width in between the heading wraps to three or four lines
   while the button keeps a column of its own. Laying it out as a wrapping flex
   row makes it answer to the space it actually has rather than to a
   breakpoint: the button sits beside the text while both fit and drops
   underneath when they do not. */
.grid-2-columns.cta-grid-2-col.v1 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px 40px;
}

/* The basis is the width the heading needs to stay on one line. Set lower and
   the two sit side by side while the heading wraps, which is the state this is
   meant to avoid. */
.cta-grid-2-col.v1 > .inner-container {
  flex: 1 1 42rem;
  min-width: 0;
}

.cta-grid-2-col.v1 > .btn-primary {
  flex: 0 0 auto;
}

/* --- value list ----------------------------------------------------------- */
/* Each item opens on the claim and then explains it. The lead takes the accent
   blue so the five claims can be read on their own, without the explanations
   underneath them. Scoped to this list: bold elsewhere on the site is emphasis
   inside a sentence, not a heading for one. */
.value-list strong {
  color: var(--conundrum-blue-accent);
}

/* A proof bar inside a page section rather than closing the hero: it needs
   room above it, and two figures should share the width rather than sit in the
   first two of four columns. */
.proof-bar--inline {
  margin-top: 32px;
  margin-bottom: 0;
}

.proof-bar__list--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media screen and (max-width: 600px) {
  .proof-bar__list--two {
    grid-template-columns: 1fr;
  }
}

/* --- footer: legal links and the social icon ------------------------------ */
/* The legal pages are a different kind of link from the rest of the footer, so
   they sit on their own row beneath the copyright line rather than competing
   with Platform and Case studies. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-legal a {
  color: var(--neutral--500);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-decoration: none;
}

.footer-legal a:hover,
.footer-legal a:focus-visible {
  color: var(--conundrum-blue-accent);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* The mark carries the meaning, so the link is labelled rather than captioned. */
/* The mark has no baseline of its own, so flex centring leaves it sitting a
   little high against the words beside it. Nudged down to match them; a
   relative offset, so nothing around it moves. */
.footer-icon-link {
  display: inline-flex;
  align-items: center;
  position: relative;
  top: 2px;
  color: var(--neutral--600);
}

.footer-icon-link:hover,
.footer-icon-link:focus-visible {
  color: var(--conundrum-blue-accent);
}

/* --- proof bar on a narrow screen ----------------------------------------- */
/* Stacked in one column the illustration reads as a stray thumbnail above the
   figure. Set it beside the pair instead, so it is clearly the picture that
   belongs to that number. Only the lists that have one are touched. */
@media screen and (max-width: 600px) {
  .proof-bar__list a:has(.proof-bar__icon) {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 16px;
    align-items: center;
  }

  .proof-bar__list a:has(.proof-bar__icon) .proof-bar__icon {
    grid-row: 1 / 3;
    height: 72px;
    margin-bottom: 0;
  }

  .proof-bar__list a:has(.proof-bar__icon) .proof-bar__figure {
    align-self: end;
  }

  .proof-bar__list a:has(.proof-bar__icon) .proof-bar__label {
    align-self: start;
    margin-top: 2px;
  }
}
