/*
Theme Name: Provintell
Theme URI: https://provintell.com
Author: Provintell Technologies
Description: Custom theme for Provintell — a dark, high-tech MSSP marketing site. Hand-coded, no page builder. Ships CODERED VTA advisories as a custom post type with structured severity, CVE and CVSS fields.
Version: 1.0.0
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: Proprietary
Text Domain: provintell
*/

/* ==========================================================================
   1. Design tokens
   ========================================================================== */

:root {
  /* ------------------------------------------------------------------------
     Light theme, sampled from the live provintell.com: white page, #333 body
     text, #1E73BE brand blue, #1C2654 navy for headings.

     The token NAMES are unchanged so every existing rule keeps working. Only
     the values flip. --cyan is now the brand blue, because it was the accent
     token used across arrows, ticks and eyebrows and cyan is illegible on
     white; red is kept for CodeRed branding and severity, where it means
     something, rather than as general UI accent.
     --------------------------------------------------------------------- */

  /* Surfaces */
  --void: #ffffff;
  --base: #f4f7fb;
  --surface: #ffffff;
  --raised: #eef3f9;
  --line: #d8e0ea;

  /* Text */
  --ink: #1c2654;
  --ink-dim: #4d566e;
  --ink-faint: #5f6879;

  /* Brand */
  --red: #d81830;
  --red-hot: #c4142a;

  /* Primary accent. Named --cyan for continuity with the rules that use it. */
  --cyan: #1e73be;

  /* Provintell blue. On white the brand value is legible as-is, so display
     type and body accent share one value. */
  --blue: #1e73be;
  --blue-ink: #175d99;
  /* Header bar and the accents that sit on it. The gradient is lifted
     verbatim from the provintell.com banner, so the two read as one brand. */
  --navy: #001861;
  --navy-deep: #070a2c;
  --header-bg: linear-gradient(348deg, #070a2c 0%, #001861 80%);
  --on-navy: rgba(255, 255, 255, 0.74);
  --on-navy-lit: #7ab8ee;

  /* Severity. Darkened from the dark-theme set so each clears 4.5:1 on white. */
  --sev-critical: #c4142a;
  --sev-high: #b8520a;
  --sev-medium: #8a6100;
  --sev-low: #1e73be;

  /* Dark panels keep the original ink, restored by .on-dark below. */
  --d-void: #04060e;
  --d-base: #070a16;
  --d-surface: var(--surface);
  --d-line: #1e2740;
  --d-ink: #e8ecf6;
  --d-ink-dim: #9aa4bd;
  --d-ink-faint: #7581a5;
  --d-accent: #22d3ee;

  --font-display: "Space Grotesk", system-ui, -apple-system, sans-serif;
  --font-sans: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;

  --wrap: 1200px;
  --radius: 14px;
  --header-h: 72px;
}

/* ==========================================================================
   2. Reset & base
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  scroll-behavior: smooth;
  overflow-x: clip;
  color-scheme: dark;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  background: var(--void);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: clip;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

::selection {
  background: var(--red);
  color: #fff;
}

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 3px;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 24px;
}

.mono {
  font-family: var(--font-mono);
}

/* Screen-reader-only, for skip links and labels */
.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link:focus {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 999;
  width: auto;
  height: auto;
  clip: auto;
  padding: 12px 18px;
  background: var(--red);
  color: #fff;
  border-radius: 8px;
}

/* ==========================================================================
   3. Motion — progressive enhancement only
   Content is never hidden by default, so crawlers and screen readers always
   see it. This is the deliberate fix for the old Elementor site, whose
   sections rendered as empty text.
   ========================================================================== */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      animation: reveal-in linear both;
      animation-timeline: view();
      /* Measured on the element entering, not on how tall it is. The old
         cover-based range scaled with element height, so a short card low on
         the page could still be part-way through its fade once it came to
         rest, which read as washed-out text. */
      animation-range: entry 0% entry 40%;
    }
  }
}

@keyframes reveal-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes radar {
  to {
    transform: rotate(360deg);
  }
}

@keyframes drift {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(0, -22px, 0) scale(1.06);
  }
}

@keyframes pulse-ring {
  0% {
    box-shadow: 0 0 0 0 rgba(34, 211, 238, 0.5);
  }
  70% {
    box-shadow: 0 0 0 7px rgba(34, 211, 238, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(34, 211, 238, 0);
  }
}

@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ==========================================================================
   4. Decorative backgrounds
   ========================================================================== */

.grid-field {
  background-image:
    linear-gradient(to right, rgba(120, 140, 190, 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(120, 140, 190, 0.07) 1px, transparent 1px);
  background-size: 64px 64px;
}

.glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
  pointer-events: none;
}

.rule-glow {
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(225, 29, 52, 0.55),
    rgba(34, 211, 238, 0.35),
    transparent
  );
}

/* ==========================================================================
   5. Buttons & shared bits
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 24px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  transition:
    background-color 0.2s,
    border-color 0.2s,
    box-shadow 0.2s,
    color 0.2s;
}

.btn-primary {
  /* Transparent border, not none: keeps the box the same height as .btn-ghost
     so the two sit level when they share a row. */
  border: 1px solid transparent;
  background: var(--red);
  color: #fff;
}

.btn-primary:hover {
  background: var(--red-hot);
  box-shadow: 0 10px 30px -10px rgba(225, 29, 52, 0.6);
}

.btn-ghost {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
}

.btn-ghost:hover {
  border-color: var(--cyan);
  background: var(--raised);
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--red);
}

.eyebrow::before {
  content: "";
  width: 24px;
  height: 1px;
  background: var(--red);
}

.section-head {
  max-width: 640px;
}

.section-head h2 {
  margin-top: 20px;
  font-size: clamp(1.75rem, 4vw, 2.75rem);
}

.section-head p {
  margin-top: 20px;
  font-size: 17px;
  color: var(--ink-dim);
}

.section {
  padding-block: clamp(64px, 10vw, 128px);
}

/* Step marker inside the CyberSOC section: the two views are one thing now,
   so each gets a numbered label rather than a heading of its own. */
.cyber-step {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 18px;
  padding-top: clamp(24px, 4vw, 44px);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The spine. Two stations on one instrument, not two dashboards stacked. */
.cyber-step {
  position: relative;
}

.cyber-step::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 0;
  height: calc(clamp(24px, 4vw, 44px) - 4px);
  width: 1px;
  background: repeating-linear-gradient(
    to bottom,
    var(--red) 0 4px,
    transparent 4px 9px
  );
}

.cyber-step span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  background: var(--red);
  color: #fff;
  font-size: 10px;
  letter-spacing: 0.06em;
}

/* ---- Malaysia panel ------------------------------------------------------
   One country pulled out of everything above it. Dark, because it is the
   block that should stop a local reader, and because a second white card
   would have disappeared into the run of them. */

.my-panel {
  --void: #04102f;
  --base: #061638;
  --surface: rgba(255, 255, 255, 0.05);
  --raised: rgba(255, 255, 255, 0.09);
  --line: rgba(255, 255, 255, 0.16);
  --ink: #fff;
  --ink-dim: rgba(255, 255, 255, 0.82);
  --ink-faint: rgba(255, 255, 255, 0.62);
  /* The plugin resolves --c-red through var(--red), so the accents have to be
     retuned here as well or they fall back to the light-theme red and land at
     3.1:1 on the navy. */
  --red: #ff7186;
  --red-hot: #ff8f9c;
  --blue: #6fb3f2;
  --cyan: #6fb3f2;

  --c-ink: #fff;
  --c-dim: rgba(255, 255, 255, 0.82);
  --c-faint: rgba(255, 255, 255, 0.62);
  --c-line: rgba(255, 255, 255, 0.16);
  --c-rule: rgba(255, 255, 255, 0.3);
  --c-surface: rgba(255, 255, 255, 0.05);
  --c-raised: rgba(255, 255, 255, 0.09);
  --c-red: #ff7186;
  --c-blue: #6fb3f2;

  margin-top: clamp(28px, 4vw, 48px);
  border: 1px solid rgba(255, 255, 255, 0.14);
  background-color: #001861;
  background-image: linear-gradient(348deg, rgba(7, 10, 44, 0.92) 0%, rgba(7, 10, 44, 0) 62%);
  color: #fff;
  overflow: hidden;
}

.my-panel__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px clamp(18px, 3vw, 30px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(0, 0, 0, 0.22);
}

.my-panel__flag {
  width: 34px;
  height: auto;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.28);
}

.my-panel__head h3 {
  margin: 0;
  font-size: clamp(1rem, 2vw, 1.25rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
}

.my-panel__ref {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.62);
  white-space: nowrap;
}

.my-panel__body {
  padding: clamp(20px, 3vw, 34px);
}

/* The blocks inside lose their own framing: the panel is the frame. */
.my-panel .cti {
  margin-block: 0;
}

.my-panel .cti + .cti {
  margin-top: clamp(26px, 4vw, 40px);
  padding-top: clamp(22px, 3vw, 32px);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.my-panel .cti--exposure {
  padding-left: 0;
  border-left: 0;
}

.my-panel .cti-fig--alert .cti-fig__n {
  color: #ff8f9c;
}

@media (max-width: 560px) {
  .my-panel__ref {
    display: none;
  }
}

/* A section that opens the page sits straight under the header bar, where the
   full band of top padding reads as a gap rather than as rhythm. Page heroes
   set their own spacing, so this only catches pages that lead with a section. */
#main > .section:first-child {
  padding-top: clamp(32px, 4vw, 56px);
}

.section-alt {
  background: var(--base);
  border-block: 1px solid var(--line);
}

/* Severity chips */
.sev {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  box-shadow: inset 0 0 0 1px currentColor;
}

.sev::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.sev-critical {
  color: var(--sev-critical);
}
.sev-high {
  color: var(--sev-high);
}
.sev-medium {
  color: var(--sev-medium);
}
.sev-low {
  color: var(--sev-low);
}

/* ==========================================================================
   6. Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  isolation: isolate;
  /* Same two brand colours as --header-bg, but that gradient is drawn for a
     549px banner; squeezed into a 73px bar it lands as a dark smudge along the
     bottom. Here the deep navy is a soft foot on royal blue instead. */
  background-color: var(--navy);
  background-image: linear-gradient(
    348deg,
    rgba(7, 10, 44, 0.9) 0%,
    rgba(7, 10, 44, 0) 58%
  );
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  transition: box-shadow 0.3s;
}

/* The bar is opaque, so scrolling only earns it a shadow. A blur behind an
   opaque background would cost a compositing layer and show nothing. */
.site-header.is-scrolled {
  box-shadow: 0 10px 26px -16px rgba(0, 24, 97, 0.75);
}

/* Registration overrun on the header rule, matching the service rows. Only
   drawn once the header has a rule to overrun. */
.site-header.is-scrolled::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 96px;
  height: 1px;
  background: var(--on-navy-lit);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 32px;
  height: var(--header-h);
}

.brand {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* The supplied master logo is white-on-transparent, so it sits directly on
   the dark theme with no treatment. */
.brand img {
  width: auto;
  height: 39px;
}

.site-footer .brand img {
  height: 52px;
}

.main-nav {
  display: none;
  flex: 1;
}

.main-nav ul {
  display: flex;
  align-items: center;
  gap: 4px;
  list-style: none;
  padding: 0;
}

.main-nav li {
  position: relative;
}

/* Nav items as instrument labels: mono, tracked, with a diamond marker that
   fills on hover and for the current page. Same marker as the lifecycle axis
   below, so the two read as one system. */
.main-nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-navy);
  transition: color 0.2s;
}

.main-nav > ul > li > a::before {
  content: "";
  width: 8px;
  height: 8px;
  rotate: 45deg;
  border: 1px solid rgba(255, 255, 255, 0.42);
  background: transparent;
  transition:
    border-color 0.2s,
    background-color 0.2s;
}

.main-nav a:hover,
.main-nav .current-menu-item > a,
.main-nav .current-menu-ancestor > a {
  color: #fff;
}

.main-nav > ul > li > a:hover::before,
.main-nav .current-menu-item > a::before,
.main-nav .current-menu-ancestor > a::before {
  border-color: var(--on-navy-lit);
  background: var(--on-navy-lit);
}

/* The dropdown panel is a light card hanging off the dark bar, so its links
   revert to body ink. */
.main-nav .sub-menu a {
  color: var(--ink-dim);
}

.main-nav .sub-menu a:hover,
.main-nav .sub-menu .current-menu-item > a {
  color: var(--ink);
}

/* Dropdowns */
.main-nav .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  display: block;
  min-width: 258px;
  padding: 8px;
  margin-top: 8px;
  background: var(--base);
  border: 1px solid var(--line);
  border-top: 2px solid var(--cyan);
  border-radius: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition:
    opacity 0.15s,
    transform 0.15s,
    visibility 0.15s;
}

.main-nav li:hover > .sub-menu,
.main-nav li:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.main-nav .sub-menu a {
  padding: 10px 12px;
  letter-spacing: 0.1em;
}

.main-nav .sub-menu a:hover {
  background: var(--raised);
  color: var(--ink);
}

.nav-toggle {
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-left: auto;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 9px;
  color: #fff;
}

.nav-toggle span {
  display: block;
  width: 16px;
  height: 1px;
  background: currentColor;
  transition: transform 0.2s;
}

.nav-toggle[aria-expanded="true"] span:first-child {
  transform: translateY(3px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:last-child {
  transform: translateY(-3px) rotate(-45deg);
}

.mobile-nav {
  display: none;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  background: var(--navy);
  background-image: var(--header-bg);
  backdrop-filter: blur(18px);
  max-height: 72vh;
  overflow-y: auto;
}

.mobile-nav.is-open {
  display: block;
}

.mobile-nav ul {
  list-style: none;
  padding: 20px 0;
  margin: 0;
}

.mobile-nav a {
  display: block;
  padding: 10px 0;
  font-size: 15px;
  color: #fff;
}

.mobile-nav .sub-menu {
  padding: 0 0 8px 16px;
}

.mobile-nav .sub-menu a {
  font-size: 13.5px;
  color: var(--on-navy);
  padding: 7px 0;
}

@media (min-width: 1024px) {
  .main-nav {
    display: flex;
  }
  .nav-toggle {
    display: none;
  }
  .mobile-nav {
    display: none !important;
  }
}

/* ==========================================================================
   7. Hero
   ========================================================================== */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(72px, 10vw, 128px) clamp(64px, 8vw, 112px);
}

.hero-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.hero-bg .grid-field {
  position: absolute;
  inset: 0;
  opacity: 0.7;
}

.hero-bg .glow-accent {
  left: 50%;
  top: -18rem;
  width: 42rem;
  height: 42rem;
  translate: -50% 0;
  background: rgba(30, 115, 190, 0.12);
  animation: drift 14s ease-in-out infinite;
}

.hero-bg .glow-cyan {
  right: -10rem;
  top: 6rem;
  width: 30rem;
  height: 30rem;
  background: rgba(34, 211, 238, 0.08);
}

.hero-radar {
  position: absolute;
  left: 50%;
  top: -26rem;
  width: 52rem;
  height: 52rem;
  translate: -50% 0;
}

.hero-radar span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(30, 115, 190, 0.16);
}

.hero-radar span:nth-child(2) {
  inset: 18%;
}
.hero-radar span:nth-child(3) {
  inset: 36%;
}

.hero-radar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    transparent 300deg,
    rgba(30, 115, 190, 0.09) 350deg,
    rgba(30, 115, 190, 0.2) 360deg
  );
  animation: radar 8s linear infinite;
}

.hero-fade {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 16rem;
  background: linear-gradient(to bottom, transparent, var(--void));
}

.hero-inner {
  max-width: 860px;
  margin-inline: auto;
  text-align: center;
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ink-dim);
}

.hero-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan);
  animation: pulse-ring 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.hero h1 {
  margin-top: 32px;
  font-size: clamp(2.75rem, 8vw, 4.75rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
}

.hero-title .underline {
  position: relative;
  display: inline-block;
}

/* Drawn under the whole headline. Inside .underline it could only span the two
   words that span colours; on the h1 it measures the sentence. The round caps
   sit half a stroke past the viewBox, so overflow stays visible or the ends are
   clipped flat. */
.hero-title {
  position: relative;
  /* Hugs the sentence rather than filling the column, so the rule beneath it
     measures the words and not the block. */
  width: fit-content;
  max-width: 100%;
}

.hero-title__rule {
  position: absolute;
  left: 0;
  bottom: -12px;
  width: 100%;
  height: 12px;
  color: var(--red);
  overflow: visible;
}

.hero-sub {
  max-width: 640px;
  margin: 40px auto 0;
  font-size: 18px;
  color: var(--ink-dim);
  text-wrap: balance;
}

/* The company hero runs left-aligned, so the auto margins would shift these
   out of line with the headline above them. The strip also gives up the
   1000px escape hatch it uses when centred: overhanging the column on one
   side only reads as an overflow, so it wraps within it instead. */
.page-hero .hero-sub,
.page-hero ul.hero-strip {
  margin-inline: 0;
  justify-content: flex-start;
}

.page-hero ul.hero-strip {
  width: 100%;
  /* Not the 860px measure the lede uses: the three items need about 1004px at
     this size, and the hero column is wider than that. Capped there they wrapped
     to two lines. Narrow viewports still wrap, hence the row gap. */
  max-width: none;
  font-size: clamp(13px, 1.33vw, 17px);
  row-gap: 12px;
}

/* Set in caps to match the brand lockup. Caps at this size need the tracking
   opened back up, since the -0.03em above is tuned for mixed case. */
.hero-title {
  text-transform: uppercase;
  letter-spacing: -0.015em;
}

/* "AI" sits between the two halves of the name and is held back, so the eye
   still reads NEXT GENERATION / CYBER DEFENSE as the line. */
.hero-title__ai {
  color: var(--ink-faint);
}

/* CYBER DEFENSE in the brand blue sampled from the logo, matching the deck
   title slide. Darker than the lifted tint, and chosen deliberately. */
.hero-title .underline {
  color: var(--blue);
}

/* The three service lines. Pipes are drawn between items rather than typed,
   so the last one never trails one. */
ul.hero-strip {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 0;
  /* The hero column is capped at 860px, which is 80px short of holding these
     three on one line. Symmetric negative margins let the strip alone escape
     it and stay centred. */
  width: min(1000px, calc(100vw - 48px));
  max-width: none;
  margin: 34px calc((100% - min(1000px, 100vw - 48px)) / 2) 0;
  padding: 0;
  /* The body face, not mono: this is the only strip of type in the hero and
     the switch made it read as a different kind of thing from the sentence
     below it. Inter carries less tracking than the mono needed. */
  font-family: var(--font-sans);
  font-size: clamp(10px, 1.1vw, 12px);
  font-weight: 500;
  /* Barely any: the three items only clear the column on one line once the
     tracking comes off. */
  letter-spacing: 0.01em;
  color: var(--ink);
}

ul.hero-strip li + li::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 11px;
  margin: 0 9px;
  vertical-align: -1px;
  background: var(--red);
}

@media (max-width: 560px) {
  ul.hero-strip {
    display: grid;
    justify-items: center;
    gap: 7px;
  }

  ul.hero-strip li + li::before {
    display: none;
  }
}

.hero-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 40px;
}

.hero-actions .btn {
  width: 100%;
}

@media (min-width: 640px) {
  .hero-actions {
    flex-direction: row;
  }
  .hero-actions .btn {
    width: auto;
  }
}

/* Live VTA ticker */
.ticker {
  max-width: 960px;
  margin: 80px auto 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  backdrop-filter: blur(12px);
  overflow: hidden;
}

.ticker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--ink-dim);
}

.ticker-head .live {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ticker-head .live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sev-critical);
  animation: pulse-ring 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.ticker-head a:hover {
  color: var(--cyan);
}

.ticker ul {
  list-style: none;
  padding: 0;
}

.ticker li + li {
  border-top: 1px solid var(--line);
}

.ticker li a {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  transition: background-color 0.2s;
}

.ticker li a:hover {
  background: var(--raised);
}

.ticker .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}

.ticker .label {
  display: none;
  width: 64px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.ticker .title {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.2s;
}

.ticker li a:hover .title {
  color: var(--ink);
}

.ticker .meta {
  display: none;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
}

@media (min-width: 640px) {
  .ticker .label,
  .ticker .meta {
    display: block;
  }
}

/* ==========================================================================
   8. Credential marquee
   ========================================================================== */

.marquee {
  position: relative;
  overflow: hidden;
  padding-block: 20px;
  background: var(--base);
  border-block: 1px solid var(--line);
}

.marquee::before,
.marquee::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 120px;
  z-index: 2;
}

.marquee::before {
  left: 0;
  background: linear-gradient(to right, var(--base), transparent);
}

.marquee::after {
  right: 0;
  background: linear-gradient(to left, var(--base), transparent);
}

.marquee-track {
  display: flex;
  align-items: center;
  gap: 48px;
  width: max-content;
  animation: marquee 38s linear infinite;
}

.marquee:hover .marquee-track {
  animation-play-state: paused;
}

/* Square certification badges. A 30px-tall square reads far smaller than a
   30px-tall wordmark, so these get extra height to match optically. */
.marquee-track img.is-badge {
  height: 42px;
}

.marquee-track span {
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--ink-faint);
}

/* Partner logos. The supplied assets are already white-text versions, so they
   need no filter — only a shared height and a resting opacity so the strip
   reads as one row rather than a collage of competing brand colours. */
.marquee-track img {
  height: 30px;
  width: auto;
  opacity: 0.75;
  transition: opacity 0.25s;
}

.marquee:hover .marquee-track img {
  opacity: 1;
}

.marquee-track .sep {
  width: 4px;
  height: 4px;
  rotate: 45deg;
  background: var(--line);
  flex-shrink: 0;
}

/* ---- Product logos on dark ------------------------------------------------
   These files are already white-ink-on-transparent with the CodeRed red kept,
   so they need no filter. A CSS filter cannot be used here: two of the source
   logos ship with an opaque white background and would render as solid
   blocks. See provintell_product_logo(). */
.product-logo {
  height: 26px;
  width: auto;
}

/* ==========================================================================
   9. Services
   ========================================================================== */

.service-grid {
  display: grid;
  gap: 20px;
  margin-top: 64px;
}

@media (min-width: 900px) {
  .service-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  transition:
    border-color 0.3s,
    background-color 0.3s,
    transform 0.3s;
}

.service-card:hover {
  border-color: rgba(225, 29, 52, 0.4);
  background: var(--surface);
  transform: translateY(-3px);
}

.service-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.service-card-eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
  text-transform: uppercase;
}

.stage-chip {
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--cyan);
  text-transform: uppercase;
  white-space: nowrap;
}

.service-card h3 {
  margin-top: 20px;
  font-size: 24px;
}

/* When a service has real logo artwork, the logo replaces the wordmark and the
   h3 stays in the DOM for search engines and screen readers. */
.service-card .logo-lockup {
  margin-top: 20px;
  min-height: 34px;
  display: flex;
  align-items: center;
}

.service-card .logo-lockup img {
  height: 30px;
}

.service-card .logo-lockup h3 {
  margin: 0;
}

.service-card .tagline {
  margin-top: 8px;
  font-size: 15px;
  font-weight: 500;
  color: var(--red);
}

.service-card .desc {
  margin-top: 16px;
  flex: 1;
  font-size: 14.5px;
  color: var(--ink-dim);
}

.service-card ul {
  list-style: none;
  padding: 24px 0 0;
  margin-top: 24px;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 10px;
}

.service-card ul li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink-dim);
}

.service-card ul li::before {
  content: "";
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  margin-top: 5px;
  background: var(--cyan);
  clip-path: polygon(
    14% 44%,
    0 58%,
    43% 100%,
    100% 22%,
    85% 8%,
    43% 71%
  );
}

.service-card .more {
  margin-top: 28px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.12em;
  transition: color 0.2s;
}

.service-card .more:hover {
  color: var(--red);
}

.service-mini-grid {
  display: grid;
  gap: 20px;
  margin-top: 20px;
}

@media (min-width: 640px) {
  .service-mini-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.service-mini {
  display: flex;
  flex-direction: column;
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  transition:
    border-color 0.2s,
    background-color 0.2s;
}

.service-mini:hover {
  border-color: rgba(34, 211, 238, 0.35);
  background: var(--surface);
}

/* The card link now wraps only the card body, so a second link can sit beneath
   it without nesting anchors. */
.service-mini__main {
  display: block;
  color: inherit;
}

.service-mini__extra {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  align-self: stretch;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.2s;
}

.service-mini__extra::after {
  content: "↗";
  color: var(--cyan);
  transition: translate 0.2s;
}

.service-mini__extra:hover {
  color: var(--cyan);
}

.service-mini__extra:hover::after {
  translate: 3px -3px;
}

.service-mini h3 {
  font-size: 17px;
  font-weight: 600;
}

.service-mini__logo {
  height: 30px;
  width: auto;
}

.service-mini p {
  margin-top: 11px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* ==========================================================================
   9b. Threat Responder Hub showcase
   ========================================================================== */

.hub {
  position: relative;
  overflow: hidden;
}

.hub .glow-cyan {
  left: 50%;
  top: 10%;
  width: 56rem;
  height: 30rem;
  translate: -50% 0;
  background: rgba(34, 211, 238, 0.07);
}

.hub-inner {
  position: relative;
}

/* Browser-chrome frame around the product screenshot. */
.screenshot {
  position: relative;
  margin-top: 56px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--base);
  overflow: hidden;
  box-shadow:
    0 40px 80px -24px rgba(0, 0, 0, 0.8),
    0 0 0 1px rgba(34, 211, 238, 0.06);
}

.screenshot-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.screenshot-bar i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--line);
}

.screenshot-bar .addr {
  margin-left: 12px;
  padding: 4px 12px;
  border-radius: 6px;
  background: var(--base);
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
}

.screenshot img {
  width: 100%;
  display: block;
}

/* Posture score cards — AEAS / SPS / PRS / DPS.
   Each is a 0-100 scale and three of the four are inverted, so direction is
   carried by the scale strip and the accent colour rather than buried in prose.
   ========================================================================== */

.scores {
  display: grid;
  gap: 16px;
  margin-top: 28px;
}

@media (min-width: 700px) {
  .scores {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1180px) {
  .scores {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.score {
  /* One accent for every card: the code, hairline and disclosure all read the
     same. Only the scale bar differs, and it carries the direction. */
  --accent: #ff3049;
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 24px 22px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(120% 70% at 0% 0%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 62%),
    var(--surface);
  overflow: hidden;
  transition:
    border-color 0.25s,
    transform 0.25s;
}

/* Hairline of the accent colour along the top edge. */
.score::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent 75%);
}

.score:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}

/* Direction no longer tints the whole card: colouring the code made a
   definition look like a live verdict. It survives only on the scale. */
.score {
  --dir-lo: #2fd47a;
  --dir-hi: #ff3049;
  --dir-label: #c4142a;
}

.score--better {
  --dir-lo: #ff3049;
  --dir-hi: #2fd47a;
  --dir-label: #1a7f4b;
}

/* ---- Code ---------------------------------------------------------------- */

.score__code {
  display: block;
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
  text-shadow: 0 0 26px color-mix(in srgb, var(--accent) 55%, transparent);
}

.score__name {
  display: block;
  margin-top: 10px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
}

.score__std {
  display: inline-block;
  margin-top: 8px;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--raised);
  box-shadow: inset 0 0 0 1px var(--line);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* ---- Direction scale ----------------------------------------------------- */

.score__scale {
  margin-top: 18px;
}

.score__scale-track {
  display: block;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--dir-lo), #ffc53d, var(--dir-hi));
}

.score__scale-ends {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--ink-faint);
}

.score__dir {
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Not var(--dir-hi): those stops are tuned for the gradient bar and neither
     clears 4.5:1 as text on white. */
  color: var(--dir-label);
}

/* ---- Body ---------------------------------------------------------------- */

.score__what {
  margin-top: 16px;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--ink-dim);
}

.score__why {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

/* Keeps the disclosure off the description without stranding it far below. */
.score__what + .score__why {
  margin-top: 18px;
}

.score__why summary {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  transition: opacity 0.2s;
}

.score__why summary::-webkit-details-marker,
.score__why summary::marker {
  display: none;
  content: "";
}

.score__why summary::after {
  content: "+";
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  font-size: 12px;
  line-height: 1;
}

.score__why[open] summary::after {
  content: "−";
}

.score__why summary:hover {
  opacity: 0.82;
}

.score__why p {
  margin-top: 12px;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--ink-dim);
}

/* ---- Key benefit cards (deck slide 11) -----------------------------------
   Numbered, benefit-led cards with a red edge, replacing the flat module
   grid. Two across on desktop so each benefit gets room to breathe.
   ------------------------------------------------------------------------ */

.modules__engine {
  margin-top: 16px;
  font-size: 14.5px;
  font-style: italic;
  color: var(--ink-dim);
}

.modules {
  display: grid;
  gap: 18px;
  margin-top: 36px;
}

@media (min-width: 860px) {
  .modules {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 22px;
  }
}

.module {
  position: relative;
  display: flex;
  gap: 18px;
  padding: 26px 24px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--red);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(28, 38, 84, 0.06);
  overflow: hidden;
  transition:
    border-color 0.25s,
    transform 0.25s,
    box-shadow 0.25s;
}

.module:hover {
  transform: translateY(-3px);
  border-color: var(--red-hot);
  box-shadow: 0 18px 34px -20px rgba(216, 24, 48, 0.45);
}

/* Numbered disc, as on the slide. */
.module__num {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: 0 0 24px -6px rgba(255, 48, 73, 0.95);
}

.module__body {
  min-width: 0;
}

.module h3 {
  font-size: 18px;
  line-height: 1.25;
  color: var(--ink);
}

.module__tag {
  display: inline-block;
  margin-top: 9px;
  padding: 3px 9px;
  border-radius: 4px;
  background: rgba(30, 115, 190, 0.1);
  box-shadow: inset 0 0 0 1px rgba(30, 115, 190, 0.35);
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue-ink);
}

.module p {
  margin-top: 12px;
  font-size: 13.5px;
  line-height: 1.65;
  /* Lifted off --ink-dim: on the raised card surface the standard dim tone
     read as washed out. */
  color: var(--ink-dim);
}

@media (max-width: 480px) {
  .module {
    gap: 14px;
    padding: 22px 18px;
  }

  .module__num {
    width: 38px;
    height: 38px;
    font-size: 14px;
  }
}

/* "Powered by" logo lockup under a section intro. */
.powered-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 28px;
}

.powered-brand .label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* The mark is a wide-ish lockup (768x322), so it needs more height than a
   single-line wordmark before the CODERED CYBER text becomes legible. */
.powered-brand img {
  height: 44px;
  width: auto;
}

/* Product marks use the pre-processed on-dark artwork, so no filter. */
.powered-brand img.is-dark-artwork {
  height: 30px;
}

.powered-brand .hair {
  width: 28px;
  height: 1px;
  background: var(--line);
  flex-shrink: 0;
}

@media (max-width: 480px) {
  .powered-brand .hair {
    display: none;
  }
}

/* ---- Hub footer links ----------------------------------------------------
   Two plain text links under the Threat Responder Hub panel. Deliberately not
   buttons: the section already carries a primary call to action, and a second
   pair of pills competed with it. A hairline divider keeps them from reading
   as one run-on phrase.
   -------------------------------------------------------------------------- */

.hub-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  margin-top: 30px;
}

.hub-actions a {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  transition: color 0.2s;
}

.hub-actions a::after {
  content: "→";
  font-size: 15px;
  color: var(--cyan);
  transition:
    translate 0.2s,
    color 0.2s;
}

.hub-actions a:hover {
  color: var(--cyan);
}

.hub-actions a:hover::after {
  translate: 4px 0;
}

/* Divider between the two links, drawn on the second so it never dangles
   when the row wraps. */
.hub-actions a + a::before {
  content: "";
  align-self: center;
  width: 1px;
  height: 13px;
  margin-right: 18px;
  background: rgba(154, 164, 189, 0.4);
}

/* The external site link is secondary: mono and smaller, but not dimmed.
   At this size a muted grey went soft on a near-black background. */
.hub-actions a.hub-actions__link {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.hub-actions a.hub-actions__link:hover {
  color: var(--cyan);
}

.hub-actions .hub-actions__link::after {
  content: "↗";
  font-size: 12px;
}

@media (max-width: 480px) {
  .hub-actions {
    gap: 14px;
  }

  .hub-actions a + a::before {
    display: none;
  }
}

.powered-by {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 28px;
  padding: 8px 16px;
  border: 1px solid rgba(225, 29, 52, 0.3);
  border-radius: 999px;
  background: rgba(225, 29, 52, 0.08);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}

.powered-by::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--red);
}

/* ==========================================================================
   9b-ii. VTA Global View embed
   The dashboard renders its own dark UI on var(--base), a shade lighter than our
   --void. Boxing that inside a 1200px card made it read as a pasted-in widget.
   Instead the section adopts the embed's own background, runs full-bleed, and
   fades into the page at both ends so there is no visible seam.
   ========================================================================== */

.vta-section {
  position: relative;
  background: var(--void);
}

/* When the dashboard leads the page it carries the h1, so it needs hero-scale
   type and its own decorative backdrop. */
.vta-section--lead {
  position: relative;
  overflow: hidden;
  border-bottom: 0;
}

.vta-section--lead .grid-field {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  pointer-events: none;
}

.vta-section--lead .glow-accent {
  left: 18%;
  top: -14rem;
  width: 36rem;
  height: 36rem;
  background: rgba(30, 115, 190, 0.1);
}

.vta-lead-title {
  margin-top: 20px;
  /* The viewport term carries it: the line stays whole on a desktop window
     and shrinks with the window below that, rather than breaking in an
     arbitrary place. */
  font-size: clamp(1.9rem, 4.05vw, 3.25rem);
  text-wrap: balance;
}

.vta-lead-lede {
  margin-top: 18px;
  max-width: 62ch;
  font-size: clamp(1rem, 1.35vw, 1.125rem);
  line-height: 1.65;
  color: var(--ink-dim);
}

/* .hero-actions centres itself; this lead block is left-aligned. */
.vta-lead-actions {
  align-items: flex-start;
  justify-content: flex-start;
  margin-top: 28px;
}

@media (min-width: 640px) {
  .vta-lead-actions .btn {
    width: auto;
  }
}

.vta-section .wrap {
  position: relative;
  z-index: 1;
}

/* Full-bleed band. html has overflow-x: clip, so 100vw cannot open a
   horizontal scrollbar here. */
/* The dashboard is dark artwork, so the band it sits in carries the brand
   banner gradient rather than the page's light --base. Tall enough here to
   render the gradient the way provintell.com draws it. */
.vta-bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  background: var(--void);
}

/* Kept as plain spacers. They used to fade the page into a coloured band; the
   dashboard now sits on the same white as everything above it, so there is no
   edge left to blend and only the rhythm they set is still wanted. */
.vta-seam,
.vta-seam-end {
  height: 48px;
  background: var(--void);
}

/* Drop the card treatment the plugin ships by default. */
.vta-section .vta-embed {
  border-radius: 0;
}

/* Hairline top and bottom, so the band still reads as a distinct surface. */
.vta-bleed-inner {
  border-block: 1px solid var(--line);
}

/* Give the dashboard more room than the text column gets. */
.vta-wide {
  width: 100%;
  max-width: 1560px;
  margin-inline: auto;
  padding-inline: 24px;
}

/* ==========================================================================
   9c. SOC 3.0 approach
   ========================================================================== */

/* Slide layout: pillars 1 and 4 down the left, 2 and 3 down the right, Venn
   in the middle. Collapses to a single column below 1100px, where the stacked
   cards replace the diagram. */
/* Below the diagram breakpoint the layout is a plain stack and the four
   pillars fall back to a card grid, so they are never lost on a tablet. */
.soc-layout {
  display: block;
  margin-top: 40px;
}

.soc-aside {
  display: grid;
  gap: 16px;
  margin-top: 16px;
}

@media (min-width: 640px) {
  .soc-aside {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  /* Break out of the 1200px text wrap: the annotations are fixed-width so the
     diagram takes everything left over, instead of being squeezed to a third. */
  .soc-layout {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr) 250px;
    gap: 40px;
    align-items: center;
    margin-top: 48px;
    width: min(1440px, calc(100vw - 48px));
    margin-inline: calc((100% - min(1440px, calc(100vw - 48px))) / 2);
  }

  .soc-aside {
    grid-template-columns: none;
    gap: 96px;
    margin-top: 0;
    align-content: center;
  }

  .soc-aside--left {
    text-align: right;
  }

  .soc-aside--left .soc-pillar {
    flex-direction: row-reverse;
  }
}

/* Venn diagram, shown from 1100px up. Below that the stacked cards take over. */
.soc-venn {
  display: none;
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
}

.soc-venn svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.soc-venn .disc {
  mix-blend-mode: screen;
  stroke-width: 1.5;
}

.soc-venn .disc--intel {
  fill: rgba(34, 211, 238, 0.14);
  stroke: rgba(34, 211, 238, 0.5);
}

.soc-venn .disc--hunt {
  fill: rgba(225, 29, 52, 0.16);
  stroke: rgba(255, 48, 73, 0.5);
}

.soc-venn .disc--response {
  fill: rgba(99, 102, 241, 0.16);
  stroke: rgba(129, 132, 255, 0.5);
}

.soc-venn .soc-venn__core {
  stroke: rgba(255, 48, 73, 0.45);
  stroke-width: 1.5;
}

.soc-venn text {
  font-family: var(--font-sans);
  fill: var(--ink-dim);
}

.soc-venn .t-domain {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.soc-venn .t-intel {
  fill: #67e8f9;
}
.soc-venn .t-hunt {
  fill: #ff8494;
}
.soc-venn .t-response {
  fill: #a5a8ff;
}

.soc-venn .t-core {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 700;
  fill: var(--ink);
  letter-spacing: -0.01em;
}

.soc-venn .t-item {
  font-size: 15px;
}

.soc-venn .t-product {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 500;
  fill: var(--ink);
}

@media (min-width: 1100px) {
  .soc-venn {
    display: block;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .soc-venn .disc {
    transition: fill 0.3s;
  }
}

.soc-core {
  display: grid;
  gap: 16px;
  margin-top: 56px;
}

@media (min-width: 768px) {
  .soc-core {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* The cards are the small-screen form of the diagram. */
@media (min-width: 1100px) {
  .soc-core {
    display: none;
  }
}

.soc-domain {
  position: relative;
  padding: 28px 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
  overflow: hidden;
}

.soc-domain::after {
  content: "";
  position: absolute;
  inset: -40% 20% auto;
  height: 140px;
  border-radius: 50%;
  filter: blur(50px);
  opacity: 0.5;
}

.soc-domain:nth-child(1)::after {
  background: rgba(34, 211, 238, 0.35);
}
.soc-domain:nth-child(2)::after {
  background: rgba(225, 29, 52, 0.35);
}
.soc-domain:nth-child(3)::after {
  background: rgba(99, 102, 241, 0.35);
}

.soc-domain h3 {
  position: relative;
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.soc-domain ul {
  position: relative;
  list-style: none;
  padding: 0;
  margin-top: 18px;
  display: grid;
  gap: 8px;
}

.soc-domain li {
  font-size: 13.5px;
  color: var(--ink-dim);
}

.soc-domain li strong {
  color: var(--ink);
  font-weight: 600;
}

.soc-pillar {
  display: flex;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
}

/* Beside the diagram the pillars are annotations, so they drop the card. */
@media (min-width: 1100px) {
  .soc-layout .soc-pillar {
    padding: 0;
    border: 0;
    background: none;
    align-items: flex-start;
  }

  .soc-layout .soc-pillar h3 {
    font-size: 13px;
    line-height: 1.35;
  }

  .soc-layout .soc-pillar p {
    font-size: 13px;
  }

  .soc-layout .num {
    margin-top: 2px;
  }
}

.soc-layout .soc-pillar h3 {
  color: var(--ink);
}

.soc-layout .soc-pillar p {
  margin-top: 8px;
  line-height: 1.5;
  color: var(--blue-ink);
}

.soc-pillar .num {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(34, 211, 238, 0.12);
  box-shadow: inset 0 0 0 1px rgba(34, 211, 238, 0.3);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--cyan);
}

.soc-pillar h3 {
  font-size: 13.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.soc-pillar p {
  margin-top: 6px;
  font-size: 13px;
  color: var(--ink-dim);
}

/* ==========================================================================
   9d. Awards & regional presence
   ========================================================================== */

@media (min-width: 640px) {
  .awards-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .awards-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ---- Regional map ---------------------------------------------------------
   Pre-projected SVG, no runtime JS. See template-parts/geo-map.php.
   -------------------------------------------------------------------------- */

.geo-ctx {
  fill: var(--line);
  stroke: rgba(120, 140, 190, 0.14);
  stroke-width: 0.6;
}

.geo-hl {
  fill: rgba(34, 211, 238, 0.13);
  stroke: rgba(34, 211, 238, 0.5);
  stroke-width: 0.9;
}

@media (prefers-reduced-motion: no-preference) {
  .geo-link {
    animation: geo-dash 5s linear infinite;
  }
}

@keyframes geo-dash {
  to {
    stroke-dashoffset: -36;
  }
}

/* ---- Award artwork -------------------------------------------------------
   Certificates are light-background scans, so they sit on a white plate rather
   than being filtered; a filter would wreck the gold seals and photography.
   -------------------------------------------------------------------------- */

/* ==========================================================================
   10. Lifecycle
   ========================================================================== */

.lifecycle {
  position: relative;
  overflow: hidden;
}

.lifecycle .grid-field {
  position: absolute;
  inset: 0;
  opacity: 0.4;
  pointer-events: none;
}

.lifecycle .glow-accent {
  left: 50%;
  top: 50%;
  width: 60rem;
  height: 24rem;
  translate: -50% -50%;
  background: rgba(30, 115, 190, 0.06);
}

.lifecycle-inner {
  position: relative;
}

.lifecycle-grid {
  display: grid;
  gap: 40px;
  margin-top: 80px;
  position: relative;
}

.lifecycle-rail {
  display: none;
  position: absolute;
  inset-inline: 0;
  top: 32px;
}

@media (min-width: 900px) {
  .lifecycle-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
  }
  .lifecycle-rail {
    display: block;
  }
}

.phase-head {
  display: flex;
  align-items: center;
  gap: 16px;
}

.phase-index {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--red);
  box-shadow: inset 0 0 0 1px rgba(225, 29, 52, 0.2);
}

.phase-stage {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--cyan);
  text-transform: uppercase;
}

.phase-head h3 {
  margin-top: 4px;
  font-size: 20px;
}

.lifecycle-grid p {
  margin-top: 24px;
  font-size: 14.5px;
  color: var(--ink-dim);
}

.phase-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

.phase-tags span {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
}

/* ==========================================================================
   11. Platform stack
   ========================================================================== */

.platform-grid {
  display: grid;
  gap: 64px;
  align-items: center;
}

@media (min-width: 900px) {
  .platform-grid {
    grid-template-columns: 1fr 1fr;
    gap: 96px;
  }
}

.stack {
  position: relative;
  display: grid;
  gap: 12px;
}

.stack-layer {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  transition: transform 0.3s;
}

.stack-layer:hover {
  transform: translateX(4px);
}

.stack-layer:nth-child(1) {
  border-color: rgba(225, 29, 52, 0.35);
}
.stack-layer:nth-child(2) {
  border-color: rgba(34, 211, 238, 0.25);
  margin-left: 14px;
}
.stack-layer:nth-child(3) {
  border-color: rgba(34, 211, 238, 0.25);
  margin-left: 28px;
}
.stack-layer:nth-child(4) {
  margin-left: 42px;
}

.stack-layer .name {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
}

.stack-layer .detail {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

.stack-layer .pip {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  rotate: 45deg;
  background: var(--line);
}

.stack-layer:nth-child(1) .pip {
  background: var(--red);
}
.stack-layer:nth-child(2) .pip,
.stack-layer:nth-child(3) .pip {
  background: var(--cyan);
}

/* ==========================================================================
   12. Advisories
   ========================================================================== */

.advisory-grid {
  display: grid;
  gap: 16px;
  margin-top: 56px;
}

@media (min-width: 768px) {
  .advisory-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.advisory-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  transition:
    border-color 0.3s,
    background-color 0.3s,
    transform 0.3s;
}

.advisory-card:hover {
  border-color: rgba(97, 108, 138, 0.4);
  background: var(--surface);
  transform: translateY(-3px);
}

.advisory-card > a {
  display: block;
  padding: 24px;
}

.advisory-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.advisory-meta .cve,
.advisory-meta .cvss {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

.advisory-meta time {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

.advisory-card h3 {
  margin-top: 20px;
  font-size: 18px;
  line-height: 1.35;
  transition: color 0.2s;
}

.advisory-card:hover h3 {
  color: var(--red);
}

.advisory-card .excerpt {
  margin-top: 12px;
  font-size: 14px;
  color: var(--ink-dim);
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

.tag-row span {
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-faint);
}

/* News cards carry a featured image above the text. */
.news-card > a {
  padding: 0;
}

.news-card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: var(--base);
}

.news-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:
    transform 0.4s ease,
    opacity 0.3s;
  opacity: 0.85;
}

.news-card:hover .news-card__media img {
  transform: scale(1.03);
  opacity: 1;
}

.news-card__body {
  padding: 24px;
}

/* Archive filter bar */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 40px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--line);
}

.filter-bar a {
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition:
    border-color 0.2s,
    color 0.2s,
    background-color 0.2s;
}

.filter-bar a:hover {
  color: var(--ink);
  border-color: var(--ink-faint);
}

.filter-bar a.is-active {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

/* ==========================================================================
   13. Metrics
   ========================================================================== */

.metrics {
  display: grid;
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  overflow: hidden;
}

@media (min-width: 640px) {
  .metrics {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .metrics {
    grid-template-columns: repeat(4, 1fr);
  }
}

.metric {
  padding: 28px;
  background: var(--surface);
}

.metric .value {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.metric .unit {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--cyan);
  margin-left: 3px;
}

.metric .label {
  margin-top: 12px;
  font-size: 14px;
  font-weight: 500;
}

.metric .detail {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

/* ==========================================================================
   14. CTA band
   ========================================================================== */

.cta-band {
  position: relative;
  overflow: hidden;
  text-align: center;
}

.cta-band .grid-field {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  pointer-events: none;
}

.cta-band .glow-accent {
  left: 50%;
  top: 50%;
  width: 52rem;
  height: 28rem;
  translate: -50% -50%;
  background: rgba(30, 115, 190, 0.12);
  animation: drift 14s ease-in-out infinite;
}

.cta-inner {
  position: relative;
  max-width: 760px;
  margin-inline: auto;
}

.cta-inner h2 {
  font-size: clamp(1.75rem, 4vw, 2.75rem);
}

.cta-inner p {
  max-width: 560px;
  margin: 24px auto 0;
  font-size: 17px;
  color: var(--ink-dim);
  text-wrap: balance;
}

.cta-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 40px;
}

.cta-actions .btn {
  width: 100%;
}

@media (min-width: 640px) {
  .cta-actions {
    flex-direction: row;
  }
  .cta-actions .btn {
    width: auto;
  }
}

.cta-ir {
  margin-top: 32px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
}

.cta-ir a {
  color: var(--red);
}

.cta-ir a:hover {
  color: var(--red-hot);
}

/* ==========================================================================
   15. Page & single
   ========================================================================== */

.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(36px, 4.5vw, 60px) clamp(32px, 5vw, 56px);
  border-bottom: 1px solid var(--line);
}

.page-hero .grid-field {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  pointer-events: none;
}

.page-hero .glow-accent {
  left: 20%;
  top: -12rem;
  width: 34rem;
  height: 34rem;
  background: rgba(30, 115, 190, 0.1);
}

/* The wrap and the hero-inner sit on the same element, so capping this at
   860px replaced the wrap's 1200px and then centred it, indenting every hero
   about 170px further than the page content below. Keep the wrap width and cap
   the text instead, so hero and body share one left edge. */
.page-hero-inner {
  position: relative;
}

.page-hero-inner > * {
  max-width: 860px;
}

/* Whatever opens the hero starts at the padding, not below its own margin. */
.page-hero-inner > :first-child {
  margin-top: 0;
}

.page-hero h1 {
  margin-top: 20px;
  font-size: clamp(2rem, 5vw, 3.25rem);
}

/* Product wordmark standing in for a typeset title. The mark is 300x64, so it
   is sized by height and left to keep its own ratio. */
.page-hero__mark {
  margin-top: 20px;
  line-height: 0;
}

/* Capped at the artwork's native 64px. The only MXDR master we have is
   300x64, so anything larger is an upscale and goes soft. */
.page-hero__mark img {
  height: clamp(44px, 6vw, 64px);
  width: auto;
}

/* What the mark stands for, set quietly so it reads as a definition rather
   than competing with the lede below it. */
.page-hero__expand {
  margin-top: 18px;
  font-family: var(--font-mono);
  font-size: clamp(11px, 1.3vw, 13px);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan);
}

.page-hero .lede {
  margin-top: 24px;
  max-width: 640px;
  font-size: 18px;
  color: var(--ink-dim);
}

.advisory-header-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 28px;
}

.exploited-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border-radius: 6px;
  background: rgba(225, 29, 52, 0.15);
  box-shadow: inset 0 0 0 1px rgba(225, 29, 52, 0.4);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red-hot);
}

.content-layout {
  display: grid;
  gap: 56px;
  padding-block: clamp(48px, 7vw, 80px);
}

@media (min-width: 1000px) {
  .content-layout {
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 72px;
  }
}

/* Long-form content */
.prose {
  max-width: 72ch;
  font-size: 16.5px;
  color: var(--ink-dim);
}

.prose > * + * {
  margin-top: 20px;
}

/* Spacing between blocks belongs between them, not above the first one. */
.prose > :first-child {
  margin-top: 0;
}

.prose h2 {
  margin-top: 48px;
  font-size: 26px;
  color: var(--ink);
}

.prose h3 {
  margin-top: 36px;
  font-size: 20px;
  color: var(--ink);
}

.prose a {
  color: var(--cyan);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.prose ul,
.prose ol {
  padding-left: 22px;
}

.prose li + li {
  margin-top: 8px;
}

.prose strong {
  color: var(--ink);
}

.prose blockquote {
  padding-left: 20px;
  border-left: 2px solid var(--red);
  color: var(--ink);
  font-size: 18px;
}

.prose code {
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--raised);
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--cyan);
}

.prose pre {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--base);
  overflow-x: auto;
}

.prose pre code {
  background: none;
  padding: 0;
  color: var(--ink-dim);
}

.prose img {
  border-radius: 10px;
  border: 1px solid var(--line);
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
}

.prose th,
.prose td {
  padding: 10px 12px;
  border: 1px solid var(--line);
  text-align: left;
}

.prose th {
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Sidebar */
.side-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 24px;
}

.side-panel + .side-panel {
  margin-top: 20px;
}

.side-panel h2 {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
}

.side-panel dl {
  margin-top: 18px;
  display: grid;
  gap: 14px;
}

.side-panel dt {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.side-panel dd {
  margin: 4px 0 0;
  font-size: 14.5px;
  color: var(--ink);
}

/* IOC block */
.ioc-list {
  margin-top: 18px;
  display: grid;
  gap: 8px;
}

.ioc {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--base);
  font-family: var(--font-mono);
  font-size: 11.5px;
  overflow-wrap: anywhere;
}

.ioc .type {
  flex-shrink: 0;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--raised);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cyan);
}

.ioc .value {
  color: var(--ink-dim);
}

/* Pagination */
.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 56px;
  justify-content: center;
}

.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding-inline: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-dim);
  transition:
    border-color 0.2s,
    color 0.2s;
}

.pagination .page-numbers:hover {
  color: var(--ink);
  border-color: var(--ink-faint);
}

.pagination .page-numbers.current {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

/* ==========================================================================
   16. Footer
   ========================================================================== */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--base);
  padding-block: 64px 40px;
}

.footer-grid {
  display: grid;
  gap: 48px;
}

@media (min-width: 900px) {
  /* Two columns: the company on the left, the links it publishes on the right.
     The brand block carries a logo, a second mark and a block of legal text, so
     it needs the wider share. */
  .footer-grid {
    grid-template-columns: 1.4fr 1fr;
    gap: 48px clamp(48px, 8vw, 120px);
  }
}

/* "Connect With Us" repeats the About Us treatment: it is a heading inside the
   same column, not a second column heading. */
.footer-connect {
  margin-top: 34px;
}

/* Headed like every other footer column, so About Us does not read as a
   stray block of branding sitting above the navigation. */
.footer-about h2 {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The two marks stack rather than sit side by side: they are different shapes
   and the Malaysia Digital lockup needs its own baseline to read. */
.footer-marks {
  display: grid;
  justify-items: start;
  gap: 18px;
  margin-top: 22px;
}

.footer-md {
  width: auto;
  /* 40px, up a fifth and then 30% again once it moved to the foot of the links
     column, where it has the corner to itself rather than a wordmark to sit
     under. */
  height: 62px;
}

.footer-about p {
  margin-top: 20px;
  max-width: 340px;
  font-size: 15px;
  color: var(--ink-faint);
}

.footer-legalblock {
  margin-top: 24px;
  display: grid;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.7;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}

.footer-legalblock a:hover {
  color: var(--cyan);
}

/* The icon carries the meaning, so the address itself keeps its own casing
   rather than being shouted in upper case like a reference number. */
.footer-mail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-family: var(--font-sans);
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
}

.footer-mail svg {
  flex: none;
  color: var(--cyan);
}

.footer-col h2 {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.footer-col ul {
  list-style: none;
  padding: 0;
  margin-top: 20px;
  display: grid;
  gap: 12px;
}

.footer-col a {
  font-size: 13.5px;
  color: var(--ink-faint);
  transition: color 0.2s;
}

.footer-col a:hover {
  color: var(--ink);
}

.footer-bottom {
  margin-top: 56px;
  padding-top: 32px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 24px;
}

@media (min-width: 640px) {
  .footer-bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.footer-legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
}

.footer-legal-links a {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.2s;
}

/* Social marks. Sized to a comfortable tap target rather than the text size
   they replaced. */
.footer-social a {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  transition:
    color 0.2s,
    border-color 0.2s;
}

.footer-social a:hover {
  color: var(--cyan);
  border-color: rgba(34, 211, 238, 0.5);
}

.footer-social svg {
  width: 18px;
  height: 18px;
}

.footer-legal-links a:hover {
  color: var(--ink-dim);
}

.footer-social {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Same component inside page content, where the surrounding prose rules would
   otherwise put an underline through the icons. */
.prose .footer-social {
  margin-top: 18px;
}

/* Technology partners in page content: left aligned on one row, no heading of
   its own. The footer keeps its right-aligned placement. */
.prose .footer-tech {
  margin-top: 20px;
  grid-column: auto;
  justify-self: start;
  text-align: left;
}

.prose .footer-tech ul {
  margin-top: 0;
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: 34px;
}

.prose .footer-tech img {
  height: 52px;
}

/* In prose the list items keep display:list-item and the anchors stay inline,
   so the two marks were baseline-aligned and sat 4px apart. Flex removes the
   baseline from the equation. */
.prose .footer-tech li,
.prose .footer-tech a {
  display: flex;
  align-items: center;
}

/* Prose puts margin between consecutive list items, which pushed the second
   mark 8px down and, once centred, 4px out of line with the first. */
.prose .footer-tech li + li {
  margin-top: 0;
}

.prose .footer-tech li::before,
.prose .footer-tech li::marker {
  content: none;
}

@media (max-width: 560px) {
  .prose .footer-tech ul {
    flex-wrap: wrap;
    gap: 22px;
  }

  .prose .footer-tech img {
    height: 38px;
  }
}

.prose .footer-social a {
  text-decoration: none;
}

.footer-social a:hover {
  color: var(--cyan);
}

.footer-copy {
  margin-top: 32px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ==========================================================================
   About Provintell diagram — slide 3 rebuilt as one full-width canvas.
   Map spans the whole area; flags pin to their countries on the left; award
   artwork overlays the right. Everything is positioned in percentages of the
   map's 1600x820 viewBox so it scales as one composition.
   ========================================================================== */

.about-diagram {
  position: relative;
  margin-top: 44px;
}

.about-canvas {
  position: relative;
  aspect-ratio: 1600 / 820;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(70% 90% at 20% 55%, rgba(34, 211, 238, 0.09), transparent 60%),
    var(--surface);
  overflow: hidden;
}

.about-canvas__svg,
.about-map__svg {
  display: block;
  width: 100%;
  height: 100%;
}

.geo-ctx {
  fill: var(--line);
  stroke: rgba(120, 140, 190, 0.13);
  stroke-width: 0.7;
}

.geo-hl {
  fill: rgba(34, 211, 238, 0.11);
  stroke: rgba(34, 211, 238, 0.45);
  stroke-width: 1.1;
}

.about-canvas__links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.about-canvas__links line {
  stroke: rgba(154, 164, 189, 0.55);
  stroke-width: 1.4;
}

/* ---- Market pins -------------------------------------------------------- */

.about-pin {
  position: absolute;
  display: grid;
  gap: 2px;
  justify-items: center;
  width: max-content;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.about-pin--left {
  transform: translate(6%, -50%);
  justify-items: start;
}

.about-pin--right {
  transform: translate(-106%, -50%);
  justify-items: end;
}

.about-pin__flag {
  width: clamp(20px, 2.4vw, 40px);
  height: auto;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.3);
}

.about-pin__marks {
  display: grid;
  gap: 1px;
  justify-items: inherit;
}

.about-pin__mark {
  width: auto;
  height: clamp(6px, 0.72vw, 12px);
}

.about-pin.is-hub .about-pin__flag {
  width: clamp(28px, 3.4vw, 56px);
  box-shadow:
    0 0 0 1px rgba(255, 48, 73, 0.75),
    0 0 20px -2px rgba(255, 48, 73, 0.75);
}

.about-pin.is-hub .about-pin__mark {
  height: clamp(8px, 1.05vw, 17px);
}

.about-pin__note {
  max-width: 15ch;
  font-family: var(--font-mono);
  font-size: clamp(6px, 0.62vw, 10px);
  line-height: 1.3;
  color: var(--ink-dim);
  text-align: left;
}

/* ---- MDEC grant plate, bottom left as on the slide ---------------------- */

.about-grant {
  position: absolute;
  left: 2%;
  bottom: 4%;
  width: 17%;
  display: grid;
  gap: 3px;
  justify-items: start;
}

.about-grant img {
  width: 100%;
  height: auto;
  border-radius: 3px;
}

.about-grant__mark {
  width: 62% !important;
}

.about-grant__tm {
  font-family: var(--font-mono);
  font-size: clamp(6px, 0.6vw, 10px);
  color: #ff6274;
}

/* ---- Award wall --------------------------------------------------------- */

.about-award {
  margin: 0;
  border-radius: 8px;
  background: #fff;
  padding: 6px;
  box-shadow: 0 14px 34px -14px rgba(0, 0, 0, 0.85);
  transition: transform 0.25s;
}

.about-award img {
  display: block;
  width: 100%;
  height: auto;
}

/* The MSSP Alert badge is transparent artwork, so it needs no white plate. */
.about-award--plain {
  background: none;
  padding: 0;
  box-shadow: none;
}

@media (min-width: 900px) {
  .about-awards {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }

  .about-award {
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: var(--w);
    pointer-events: auto;
  }

  .about-award:hover {
    transform: translateY(-3px) scale(1.02);
    z-index: 2;
  }

  .about-award--plain {
    z-index: 3;
  }
}

/* Below the breakpoint the overlay is unreadable, so the awards become a grid
   under the map and the pins shed their captions. */
@media (max-width: 899px) {
  .about-awards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin-top: 14px;
  }

  .about-award {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
  }

  .about-award--plain {
    background: var(--surface);
    border: 1px solid var(--line);
    padding: 8px;
  }

  .about-pin__note {
    display: none;
  }
}

/* ==========================================================================
   Awards timeline (Company page)
   ========================================================================== */

/* ==========================================================================
   2-Tier Threat Responder Structure (MXDR page)
   A node graph with animated data flow, not a table. Flow layout, so it
   reflows instead of needing coordinates per breakpoint.
   ========================================================================== */

.rs {
  --rs-tech: #2fd47a;
  --rs-l1: #38bdf8;
  --rs-l2: #ff8a3d;
  --rs-cs: #a5a8ff;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* Escape the 72ch prose column: a diagram squeezed into a reading measure
     is unreadable. Grows rightwards to the wrap content width. */
  width: min(1152px, calc(100vw - 48px));
  margin: 36px 0;
  padding: 28px 24px 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(to right, rgba(120, 140, 190, 0.05) 1px, transparent 1px) 0 0 / 40px 40px,
    linear-gradient(to bottom, rgba(120, 140, 190, 0.05) 1px, transparent 1px) 0 0 / 40px 40px,
    radial-gradient(80% 60% at 50% -10%, rgba(225, 29, 52, 0.1), transparent 70%),
    #070b16;
}

/* Slow sweep across the panel, like a console refresh. */
.rs__scan {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    100deg,
    transparent 40%,
    rgba(34, 211, 238, 0.05) 50%,
    transparent 60%
  );
  background-size: 250% 100%;
}

@media (prefers-reduced-motion: no-preference) {
  .rs__scan {
    animation: rs-sweep 9s linear infinite;
  }
}

@keyframes rs-sweep {
  to {
    background-position: -250% 0;
  }
}

.rs__eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--red-hot);
}

.rs__eyebrow::before,
.rs__eyebrow::after {
  content: "";
  height: 1px;
  width: clamp(20px, 12%, 90px);
  background: linear-gradient(90deg, transparent, rgba(255, 48, 73, 0.7));
}

.rs__eyebrow::after {
  background: linear-gradient(90deg, rgba(255, 48, 73, 0.7), transparent);
}

/* ---- Telemetry sources --------------------------------------------------- */

.rs__sources {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 20px;
}

.rs__sources-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-right: 4px;
}

.rs__chip {
  padding: 4px 11px;
  border: 1px solid rgba(34, 211, 238, 0.24);
  border-radius: 999px;
  background: rgba(34, 211, 238, 0.05);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  /* Not --blue-ink: this chip lives inside the dark .rs panel, where that
     light-shell tone drops to 2.7:1. --cyan is remapped by the panel scope. */
  color: var(--cyan);
}

/* ---- The bus rail -------------------------------------------------------- */

.rs__rail {
  position: relative;
  height: 26px;
  margin-top: 14px;
}

.rs__rail-line {
  position: absolute;
  inset-inline: 6%;
  top: 50%;
  height: 2px;
  border-radius: 2px;
  background: repeating-linear-gradient(
    90deg,
    rgba(34, 211, 238, 0.85) 0 14px,
    transparent 14px 30px
  );
  background-size: 30px 100%;
  box-shadow: 0 0 14px -2px rgba(34, 211, 238, 0.8);
}

@media (prefers-reduced-motion: no-preference) {
  .rs__rail-line {
    animation: rs-flow 1.4s linear infinite;
  }
}

@keyframes rs-flow {
  to {
    background-position: 30px 0;
  }
}

/* ---- Stage nodes --------------------------------------------------------- */

.rs__flow {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

@media (min-width: 860px) {
  .rs__flow {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 34px;
  }

  /* Data flowing from one stage to the next. */
  .rs__stage + .rs__stage::before {
    content: "";
    position: absolute;
    left: -34px;
    top: 34px;
    width: 34px;
    height: 1px;
    background: repeating-linear-gradient(
      90deg,
      rgba(154, 164, 189, 0.9) 0 5px,
      transparent 5px 11px
    );
    background-size: 11px 100%;
    animation: rs-dash 0.9s linear infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rs__stage + .rs__stage::before {
    animation: none;
  }
}

@keyframes rs-dash {
  to {
    background-position: 11px 0;
  }
}

.rs__stage {
  position: relative;
  padding: 22px 18px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: linear-gradient(180deg, var(--raised), var(--base));
}

.rs__stage.is-hub {
  border-color: rgba(255, 48, 73, 0.42);
  box-shadow:
    inset 0 0 0 1px rgba(255, 48, 73, 0.1),
    0 0 40px -18px rgba(255, 48, 73, 0.9);
}

/* Node marker sitting on the rail. */
.rs__node {
  position: absolute;
  top: -9px;
  left: 22px;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(34, 211, 238, 0.55);
  background: #070b16;
}

.rs__node-core {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 10px 1px rgba(34, 211, 238, 0.9);
}

.is-hub .rs__node {
  border-color: rgba(255, 48, 73, 0.7);
}

.is-hub .rs__node-core {
  background: var(--red-hot);
  box-shadow: 0 0 12px 2px rgba(255, 48, 73, 0.9);
}

@media (prefers-reduced-motion: no-preference) {
  .is-hub .rs__node-core {
    animation: rs-pulse 1.8s ease-in-out infinite;
  }
}

@keyframes rs-pulse {
  50% {
    box-shadow: 0 0 20px 5px rgba(255, 48, 73, 0.55);
  }
}

.rs__stage-no {
  display: block;
  margin-left: 30px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--cyan);
}

.is-hub .rs__stage-no {
  color: var(--red-hot);
}

.rs__stage-label {
  margin-top: 6px;
  font-size: 16px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.rs__steps {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.rs__steps li {
  position: relative;
  display: grid;
  gap: 3px;
  padding: 10px 12px 10px 22px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--void);
  transition:
    border-color 0.2s,
    background-color 0.2s;
}

.rs__steps li:hover {
  border-color: rgba(34, 211, 238, 0.4);
  background: var(--surface);
}

/* Small connector tick on each step. */
.rs__steps li::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 15px;
  width: 5px;
  height: 5px;
  rotate: 45deg;
  border: 1px solid rgba(34, 211, 238, 0.7);
}

.rs__step-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.35;
}

.rs__step-note {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
}

/* Name and note sit on one line where there is room, then the explanation
   runs full width beneath them. */
.rs__step-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}

.rs__step-desc {
  margin-top: 5px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* ---- HUD corner brackets ------------------------------------------------- */

.rs__bracket {
  position: absolute;
  width: 12px;
  height: 12px;
  pointer-events: none;
  opacity: 0.65;
}

.rs__bracket--tl {
  top: -1px;
  left: -1px;
  border-top: 1px solid var(--cyan);
  border-left: 1px solid var(--cyan);
  border-top-left-radius: 12px;
}

.rs__bracket--br {
  bottom: -1px;
  right: -1px;
  border-bottom: 1px solid var(--cyan);
  border-right: 1px solid var(--cyan);
  border-bottom-right-radius: 12px;
}

.is-hub .rs__bracket {
  border-color: var(--red-hot);
}

/* ---- Feedback loop ------------------------------------------------------- */

.rs__loop {
  position: relative;
  display: flex;
  gap: 16px;
  margin-top: 22px;
  padding: 16px 18px;
  border: 1px solid rgba(34, 211, 238, 0.22);
  border-radius: 12px;
  background: rgba(34, 211, 238, 0.04);
}

/* Return path running right to left. */
.rs__loop::before {
  content: "";
  position: absolute;
  left: 18px;
  right: 18px;
  top: -11px;
  height: 1px;
  background: repeating-linear-gradient(
    270deg,
    rgba(34, 211, 238, 0.75) 0 6px,
    transparent 6px 14px
  );
  background-size: 14px 100%;
}

@media (prefers-reduced-motion: no-preference) {
  .rs__loop::before {
    animation: rs-dash-back 1.1s linear infinite;
  }
}

@keyframes rs-dash-back {
  to {
    background-position: -14px 0;
  }
}

.rs__loop-arrow {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border: 1px solid var(--cyan);
  border-right-color: transparent;
  border-radius: 50%;
  rotate: -45deg;
  box-shadow: 0 0 12px -3px rgba(34, 211, 238, 0.9);
}

.rs__loop-title {
  display: block;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cyan);
}

.rs__loop-body p {
  margin-top: 7px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* ---- Teams --------------------------------------------------------------- */

.rs__teams {
  display: grid;
  gap: 14px;
  margin-top: 22px;
}

@media (min-width: 700px) {
  .rs__teams {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .rs__teams {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.rs__team {
  --tc: var(--ink-faint);
  position: relative;
  padding: 18px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--tc) 9%, transparent), transparent 55%),
    var(--base);
  transition:
    transform 0.25s,
    border-color 0.25s;
}

.rs__team:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--tc) 55%, var(--line));
}

.rs__team .rs__bracket {
  border-color: var(--tc);
}

.rs__team--tech {
  --tc: var(--rs-tech);
}

.rs__team--l1 {
  --tc: var(--rs-l1);
}

.rs__team--l2 {
  --tc: var(--rs-l2);
}

.rs__team--cs {
  --tc: var(--rs-cs);
}

.rs__team-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.rs__team-dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--tc);
  box-shadow: 0 0 14px -1px var(--tc);
}

.rs__team-name {
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
}

.rs__team-level {
  display: block;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tc);
}

.rs__team ul {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 9px;
}

.rs__team li {
  position: relative;
  padding-left: 15px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-dim);
}

.rs__team li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 1px;
  background: var(--tc);
  box-shadow: 0 0 6px 0 var(--tc);
}

@media (max-width: 859px) {
  .rs__rail {
    display: none;
  }

  .rs__node {
    left: 18px;
  }
}

/* ===========================================================================
   Service-page figures
   Four graphics that replaced runs of body copy on the MXDR page.

   No panel shell, no scan sweep, no corner brackets, no glow. Each of the four
   has a different structural idea and is set differently on purpose: a figure,
   an editorial list, a spec table, a fork. Uniform decoration across all four
   made them read as wallpaper.

   One accent colour throughout. Type, rules and alignment do the rest.
   =========================================================================== */

.fig,
.mechs,
.spec,
.fork {
  /* Escape the 72ch prose column. A diagram in a reading measure is unreadable. */
  width: min(1152px, calc(100vw - 48px));
  margin: 44px 0;
}

/* ---- Telemetry figure ---------------------------------------------------- */

.fig {
  padding-top: 30px;
  border-top: 1px solid var(--line);
}

ul.fig__sources {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 28px 20px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 760px) {
  ul.fig__sources {
    grid-template-columns: repeat(var(--fig-cols, 4), minmax(0, 1fr));
  }
}

.fig__sources li {
  display: grid;
  justify-items: center;
  gap: 9px;
  text-align: center;
}

.fig__glyph {
  color: var(--cyan);
}

.fig__glyph svg {
  display: block;
  width: 26px;
  height: 26px;
}

.fig__name {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink);
}

.fig__eg {
  max-width: 20ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* Bus line. Laid on the same grid as the sources, so each tick sits on a
   column centre by construction rather than at a guessed coordinate. */
.fig__bus {
  display: grid;
  grid-template-columns: repeat(var(--fig-cols, 4), minmax(0, 1fr));
  column-gap: 20px;
  margin-top: 22px;
}

.fig__tick {
  grid-row: 1;
  justify-self: center;
  width: 1px;
  height: 20px;
  background: var(--line);
}

.fig__rail {
  grid-row: 2;
  grid-column: 1 / -1;
  height: 1px;
  /* Half a column in from each edge, which lands exactly on the outer ticks.
     With N columns there are N-1 gaps, and half a column is the remaining
     width over 2N. */
  margin-inline: calc(
    (100% - (var(--fig-cols, 4) - 1) * 20px) / (2 * var(--fig-cols, 4))
  );
  background: var(--line);
}

.fig__trunk {
  grid-row: 3;
  grid-column: 1 / -1;
  justify-self: center;
  width: 1px;
  height: 20px;
  background: var(--line);
}

/* Below four across the ticks would point at nothing, so it collapses to a
   single drop line. */
@media (max-width: 759px) {
  .fig__bus {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }

  .fig__tick,
  .fig__rail {
    display: none;
  }

  .fig__trunk {
    grid-row: auto;
    grid-column: auto;
  }
}

/* The bus and trunk converge on the centre, so the stages they feed have to sit
   on that axis too. Left-aligned blocks left the connector lines pointing at
   empty space. */
.fig__stage {
  text-align: center;
}

.fig__stage h4 {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
}

.fig__stage-note {
  margin: 12px auto 0;
  max-width: 56ch;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-dim);
}

.fig__link {
  display: grid;
  justify-items: center;
  padding: 20px 0;
}

.fig__link span {
  width: 1px;
  height: 24px;
  background: var(--line);
}

.fig__stage--dest h4 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.fig__stage--dest p {
  margin: 9px auto 0;
  max-width: 56ch;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-dim);
}

.fig figcaption {
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  max-width: 62ch;
  text-align: left;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-faint);
}

/* ---- Five mechanisms ----------------------------------------------------- */

ol.mechs {
  list-style: none;
  padding: 0;
  border-top: 1px solid var(--line);
}

.mech {
  display: grid;
  gap: 6px 24px;
  padding: 26px 0;
  border-bottom: 1px solid var(--line);
  grid-template-areas:
    "n body"
    ". rule";
  grid-template-columns: 2.5ch minmax(0, 1fr);
}

@media (min-width: 900px) {
  .mech {
    grid-template-areas: "n body rule";
    grid-template-columns: 2.5ch minmax(0, 1fr) 21ch;
    align-items: start;
  }
}

/* Hanging numeral, set large and quiet. It marks position in the chain
   without turning into a badge. */
.mech__n {
  grid-area: n;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.mech__body {
  grid-area: body;
}

.mech__body h4 {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

.mech__body p {
  margin-top: 8px;
  max-width: 58ch;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-dim);
}

/* The consequence. This is the payload of each entry, so it gets the accent
   and a rule of its own. */
.mech__rule {
  grid-area: rule;
  padding-top: 9px;
  border-top: 1px solid rgba(34, 211, 238, 0.35);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--cyan);
}

@media (min-width: 900px) {
  .mech__rule {
    padding-top: 10px;
  }
}

/* ---- Autonomy gates, as a spec table ------------------------------------- */

.spec__cond {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.spec__table {
  width: 100%;
  border-collapse: collapse;
}

.spec__table th,
.spec__table td {
  padding: 15px 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: baseline;
}

.spec__table th {
  width: 34%;
  padding-right: 28px;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.spec__table td {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

.spec__n {
  display: inline-block;
  min-width: 3.2ch;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 620px) {
  .spec__table th,
  .spec__table td {
    display: block;
    width: auto;
    padding-right: 0;
  }

  .spec__table th {
    padding-bottom: 5px;
    border-bottom: 0;
  }

  .spec__table td {
    padding-top: 0;
  }
}

/* ---- Triage fork --------------------------------------------------------- */

ul.fork__outs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 26px;
  border-top: 1px solid var(--line);
  padding-top: 26px;
}

@media (min-width: 700px) {
  ul.fork__outs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
  }

  /* Vertical rules between columns rather than three boxes. */
  .fork__out + .fork__out {
    padding-left: 30px;
    border-left: 1px solid var(--line);
  }

  .fork__out {
    padding-right: 30px;
  }
}

.fork__out h4 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.fork__who {
  display: block;
  margin-top: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-faint);
}

.fork__out p {
  margin-top: 10px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* Only the outcome that stops for a person is marked. Marking all three would
   flatten the one distinction the graphic exists to make. */
.fork__out--review h4 {
  color: var(--sev-medium);
}

.fork__out--review .fork__who {
  color: var(--sev-medium);
}

.fork__fail {
  margin-top: 26px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  max-width: 68ch;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-faint);
}

/* ===========================================================================
   Company timeline
   Oversized light year numerals facing a hairline spine, records on the other
   side, and a lot of air between years. Monochrome by design: the only colour
   is the accent on the newest segment of the spine.

   No chips, no tags, no borders, no chamfers, no glow. Scale and whitespace
   carry it.
   =========================================================================== */

.tl {
  margin-top: 24px;
}

ol.tl__years {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The spine. Runs the full height behind the rows, sitting on the column
   boundary, which is the exact centre because the two columns are equal. */
ol.tl__years::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 0;
  left: 0;
  width: 1px;
  /* Not --line: that is tuned as a card edge on white, and as a 1px spine on
     the --base band it lands at 1.2:1 and reads as nothing. */
  background: rgba(28, 38, 84, 0.28);
}

@media (min-width: 900px) {
  ol.tl__years::before {
    left: calc(50% - 0.5px);
  }
}

.tl__year {
  position: relative;
  padding: 0 0 clamp(56px, 8vw, 104px) 34px;
}

@media (min-width: 900px) {
  .tl__year {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 96px;
    padding-left: 0;
  }
}

/* Node on the spine, aligned with the first line of the year numeral. */
.tl__year::after {
  content: "";
  position: absolute;
  top: 10px;
  left: -4px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink);
}

@media (min-width: 900px) {
  .tl__year::after {
    left: calc(50% - 4.5px);
  }
}

/* The most recent year gets the accent on its own stretch of spine, so the
   eye starts at the top. */
.tl__year:first-child::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: clamp(56px, 8vw, 104px);
  left: 0;
  width: 1px;
  background: var(--red);
}

@media (min-width: 900px) {
  .tl__year:first-child::before {
    left: calc(50% - 0.5px);
  }
}

.tl__num {
  font-size: clamp(2.5rem, 4.6vw, 4.25rem);
  font-weight: 200;
  line-height: 0.95;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 900px) {
  .tl__num {
    text-align: right;
  }
}

/* ---- Records ------------------------------------------------------------- */

ul.tl__recs {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  gap: 30px;
}

@media (min-width: 900px) {
  ul.tl__recs {
    margin-top: 18px;
  }
}

.tl__rec {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.tl__text {
  min-width: 0;
}

/* Kind, set as a quiet label. It is here for scanning, not for decoration. */
.tl__kind {
  display: block;
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.tl__rec h4,
.tl__prog h4 {
  max-width: 34ch;
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  font-weight: 400;
  line-height: 1.35;
  color: var(--ink);
}

.tl__by {
  display: block;
  margin-top: 7px;
  font-size: 15px;
  font-weight: 300;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* Sized off the artwork we hold: the smallest issuer mark is 274px wide and
   the badges are 300px square, so this is still well inside native. */
/* Certificate link, on entries that carry a document. */
.tl__doc {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.2s;
}

.tl__doc::after {
  content: "↗";
  color: var(--cyan);
  transition: translate 0.2s;
}

.tl__doc:hover {
  color: var(--cyan);
}

.tl__doc:hover::after {
  translate: 3px -3px;
}

.tl__logo {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  height: 72px;
}

.tl__logo img {
  max-height: 72px;
  max-width: 190px;
  width: auto;
  height: auto;
}

/* ---- Programmes ---------------------------------------------------------- */

.tl__prog {
  margin-top: clamp(24px, 4vw, 48px);
  padding-top: 40px;
  border-top: 1px solid rgba(28, 38, 84, 0.28);
}

.tl__prog h3 {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.tl__prog ul {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  display: grid;
  gap: 34px;
}

.tl__prog li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px 24px;
}

.tl__logorow {
  display: flex;
  align-items: center;
  gap: 14px;
}

.tl__logorow img {
  max-height: 54px;
  max-width: 150px;
  width: auto;
  height: auto;
}

@media (max-width: 560px) {
  .tl__rec {
    flex-direction: column;
    gap: 14px;
  }

  .tl__logo {
    justify-items: start;
  }
}

/* ---- Editor tables --------------------------------------------------------
   The CodeRed IR credit table is authored in Gutenberg, so it arrives as a
   plain wp-block-table. Set to match the spec table on the MXDR page: hairline
   rules, no zebra fill, no boxed cells.
   -------------------------------------------------------------------------- */

.prose .wp-block-table {
  width: min(1152px, calc(100vw - 48px));
  margin: 36px 0;
  overflow-x: auto;
}

.prose .wp-block-table table {
  width: 100%;
  min-width: 660px;
  border-collapse: collapse;
}

.prose .wp-block-table th,
.prose .wp-block-table td {
  padding: 15px 22px 15px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: baseline;
}

.prose .wp-block-table thead th {
  padding-bottom: 11px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.prose .wp-block-table tbody td {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* First column carries the service name, so it reads as the row heading. */
.prose .wp-block-table tbody td:first-child {
  width: 26%;
  font-size: 14.5px;
  color: var(--ink);
}

.prose .wp-block-table tbody td:first-child strong {
  font-weight: 600;
}

/* Credit cost is the number a reader scans for. */
.prose .wp-block-table tbody td:last-child {
  width: 22%;
  padding-right: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.55;
  color: var(--cyan);
  font-variant-numeric: tabular-nums;
}

/* ===========================================================================
   Contact form
   Same fields as the live Formidable form, handled by the theme. Set with the
   page's own language: hairline rules, no boxed panel, labels above inputs.
   =========================================================================== */

.cform {
  width: min(1152px, calc(100vw - 48px));
  margin: 36px 0;
  padding-top: 32px;
  border-top: 1px solid var(--line);
  scroll-margin-top: 90px;
}

.cform__note {
  margin-bottom: 26px;
  padding: 14px 18px;
  border-left: 2px solid var(--cyan);
  background: var(--surface);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink);
}

.cform__note--ok {
  border-left-color: #2fd47a;
}

.cform__note--bad {
  border-left-color: var(--red-hot);
}

.cform__note a {
  color: var(--cyan);
  text-decoration: underline;
}

/* Honeypot. Kept in the layout but off-screen: display:none is a signal some
   bots look for. */
.cform__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.cform__grid {
  display: grid;
  gap: 22px 28px;
}

@media (min-width: 700px) {
  .cform__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Full-width rows: the radios, the service select and the message. */
  .cform__field:not(.is-half) {
    grid-column: 1 / -1;
  }
}

.cform__label {
  display: block;
  margin-bottom: 8px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.cform__req {
  color: var(--red-hot);
}

.cform__field input[type="text"],
.cform__field input[type="email"],
.cform__field input[type="tel"],
.cform__field select,
.cform__field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--base);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  transition:
    border-color 0.18s,
    background-color 0.18s;
}

.cform__field textarea {
  resize: vertical;
  min-height: 132px;
}

/* Native select arrow is drawn light-on-light by the OS on a dark control, so
   the chevron is supplied here instead. */
.cform__field select {
  appearance: none;
  padding-right: 40px;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position:
    calc(100% - 20px) calc(50% + 2px),
    calc(100% - 14px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

.cform__field input:focus-visible,
.cform__field select:focus-visible,
.cform__field textarea:focus-visible {
  outline: none;
  border-color: var(--cyan);
  background: var(--surface);
}

.cform__field.is-bad input,
.cform__field.is-bad select,
.cform__field.is-bad textarea {
  border-color: var(--red-hot);
}

.cform__field input::placeholder,
.cform__field textarea::placeholder {
  color: var(--ink-faint);
}

.cform__radios {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
}

.cform__radio {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 14.5px;
  color: var(--ink);
  cursor: pointer;
}

.cform__radio input {
  width: 16px;
  height: 16px;
  accent-color: var(--cyan);
}

.cform__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
  margin-top: 28px;
}

.cform__small {
  max-width: 52ch;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-faint);
}

@media (max-width: 480px) {
  .cform__foot .btn {
    width: 100%;
    justify-content: center;
  }
}

/* Consent block. Every box has to be ticked, so they are stacked and given
   room rather than squeezed into a row. */
ul.cform__consents {
  list-style: none;
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
}

.cform__check {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-dim);
  cursor: pointer;
}

.cform__check input {
  width: 16px;
  height: 16px;
  margin-top: 2px;
  accent-color: var(--cyan);
}

.cform__check a {
  color: var(--cyan);
  text-decoration: underline;
}

/* Number pairs sit under one shared label, so the second of each pair needs
   its top margin matched to the first. */
.cform__field input[type="number"] {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--base);
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  transition:
    border-color 0.18s,
    background-color 0.18s;
}

.cform__field input[type="number"]:focus-visible {
  outline: none;
  border-color: var(--cyan);
}

/* Card foot. EXPLORE and REQUEST A QUOTE ran together as one string of small
   caps, so they get a real gap and a divider between them. */
.service-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  margin-top: auto;
  padding-top: 22px;
}

.service-card-actions .more {
  margin-top: 0;
}

.service-card-actions .more--quote {
  position: relative;
  color: var(--ink-dim);
}

.service-card-actions .more--quote::before {
  content: "";
  position: absolute;
  left: -12px;
  top: 50%;
  width: 1px;
  height: 12px;
  translate: 0 -50%;
  background: var(--line);
}

.service-card-actions .more--quote:hover {
  color: var(--cyan);
}

@media (max-width: 420px) {
  .service-card-actions {
    display: grid;
    justify-items: start;
    gap: 12px;
  }

  .service-card-actions .more--quote::before {
    display: none;
  }
}

/* ===========================================================================
   Services
   Full-width rows, not cards. Three boxed cards forced equal heights on three
   very different capability lists, which left one with a large dead gap and
   made the section read as a price table.

   A stage rail on the left gives the run its structure, the wordmark gets real
   size, and the capabilities sit in their own column so the description never
   has to stretch to meet them.
   =========================================================================== */

.svcs {
  margin-top: 44px;
  border-top: 1px solid var(--line);
}

.svc {
  position: relative;
  display: grid;
  gap: 24px;
  padding: clamp(32px, 4vw, 52px) 0;
  border-bottom: 1px solid var(--line);
}

/* Registration mark at the head of each row: a short accent overrun on the
   rule above, the way a drawing sheet marks a section start. */
.svc::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 40px;
  height: 1px;
  background: var(--red);
  transition: width 0.35s ease;
}

.svc:hover::before {
  width: 132px;
}

@media (prefers-reduced-motion: reduce) {
  .svc::before {
    transition: none;
  }
}

@media (min-width: 900px) {
  .svc {
    grid-template-columns: 124px minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: 0 clamp(32px, 4vw, 64px);
  }
}

/* ---- Stage rail ---------------------------------------------------------- */

.svc__rail {
  display: flex;
  align-items: baseline;
  gap: 20px;
}

@media (min-width: 900px) {
  .svc__rail {
    display: block;
    padding-top: 4px;
  }
}

.svc__idx {
  display: block;
  font-family: var(--font-mono);
  font-size: 36px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---- Lifecycle axis ------------------------------------------------------
   Three stops on a vertical measure. The stop this service occupies is lit;
   the other two stay as unfilled marks, so the axis reads as a position rather
   than a label.
   -------------------------------------------------------------------------- */

ol.svc__axis {
  list-style: none;
  position: relative;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

/* The measure itself, running behind the stops. */
ol.svc__axis::before {
  content: "";
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 4px;
  width: 1px;
  background: var(--line);
}

.svc__stop {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}

.svc__stop-mark {
  width: 9px;
  height: 9px;
  border: 1px solid var(--ink-faint);
  background: var(--void);
  rotate: 45deg;
}

.svc__stop-label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
  opacity: 0.6;
}

.svc__stop.is-on .svc__stop-mark {
  border-color: var(--red-hot);
  background: var(--red-hot);
}

.svc__stop.is-on .svc__stop-label {
  color: var(--red-hot);
  opacity: 1;
}

@media (max-width: 899px) {
  ol.svc__axis {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 0;
  }

  ol.svc__axis::before {
    display: none;
  }
}

/* ---- Main column --------------------------------------------------------- */

.svc__logo {
  display: block;
  height: clamp(34px, 4vw, 46px);
  width: auto;
  max-width: 100%;
}

.svc__name {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  color: var(--ink);
}

.svc__eyebrow {
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-dim, var(--ink-faint));
}

/* The one-line promise. Sized up and left in ink rather than red: three red
   taglines competing with the red stage labels was too much signal. */
.svc__lead {
  margin-top: 14px;
  max-width: 26ch;
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  font-weight: 400;
  line-height: 1.25;
  color: var(--ink);
}

.svc__desc {
  margin-top: 16px;
  max-width: 52ch;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--ink-dim);
}

.svc__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 28px;
  margin-top: 26px;
}

.svc__cta {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
  transition: color 0.2s;
}

.svc__cta::after {
  content: "→";
  color: var(--cyan);
  transition: translate 0.2s;
}

.svc__cta:hover {
  color: var(--cyan);
}

.svc__cta:hover::after {
  translate: 4px 0;
}

.svc__cta--alt {
  font-weight: 400;
  color: var(--ink-dim);
}

/* Off-site link. The arrow changes so a reader can see they are leaving before
   they click, rather than after a new tab opens. */
.svc__cta--out::after {
  content: "↗";
}

.svc__cta--out:hover::after {
  translate: 3px -3px;
}

/* ---- Capabilities -------------------------------------------------------- */

/* Flex column rather than grid, so the hatch below can absorb whatever height
   is left over with flex:1. PENTESTBOX has four capabilities against ASM's six,
   and that leftover gutter is what the hatch fills. */
ul.svc__caps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* The rule that divides the row now belongs to the column, not to the list
   inside it, so the datasheets below the list sit inside the same division. */
@media (min-width: 900px) {
  .svc__side {
    padding-top: 6px;
    border-left: 1px solid var(--line);
    padding-left: clamp(24px, 3vw, 40px);
  }
}

ul.svc__caps li {
  display: grid;
  grid-template-columns: 3ch minmax(0, 1fr);
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-dim);
}

/* Index per line. Tabular so the column stays true down the list. */
.svc__cap-n {
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.9;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

ul.svc__caps li:first-child {
  padding-top: 0;
}

ul.svc__caps li:last-child {
  border-bottom: 0;
}

/* Diagonal hatch in the leftover gutter. Takes no height when the list already
   fills the row, so it never pushes the layout around. */
@media (min-width: 900px) {
  ul.svc__caps::after {
    content: "";
    flex: 1 1 auto;
    min-height: 0;
    margin-top: 18px;
    background-image: repeating-linear-gradient(
      45deg,
      transparent 0 7px,
      rgba(120, 140, 190, 0.09) 7px 8px
    );
    /* Fades out downwards so it reads as a margin note, not a filled block. */
    mask-image: linear-gradient(to bottom, #000 0%, transparent 88%);
  }
}

/* ===========================================================================
   Partner map
   The same pre-projected SEA map used by the About diagram, with a pin per
   partner country and a card list beneath. Pins are placed in percentages of
   the map canvas, so they hold position at any width.
   =========================================================================== */

.pmap {
  width: min(1152px, calc(100vw - 48px));
  margin: 36px 0;
}

/* Held well under the content width: at full width the 740x586 crop renders
   over 900px tall, which pushed the partner cards off the first screen. */
.pmap__canvas {
  position: relative;
  width: min(100%, 700px);
  margin-inline: auto;
  padding-top: 24px;
}

.pmap {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}

.pmap__canvas svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Map geography. Context landmasses stay near-invisible; the three partner
   countries are the ones picked out. */
.pmap__canvas .geo-ctx {
  fill: rgba(120, 140, 190, 0.07);
}

.pmap__canvas .geo-hl {
  fill: rgba(120, 140, 190, 0.16);
}

.pmap__canvas .geo-hl[data-c="MY"],
.pmap__canvas .geo-hl[data-c="KH"],
.pmap__canvas .geo-hl[data-c="PH"] {
  fill: rgba(225, 29, 52, 0.34);
  stroke: rgba(255, 48, 73, 0.6);
  stroke-width: 1;
}

.pmap__pin {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 10px;
  translate: 0 -50%;
}

.pmap__pin--right {
  flex-direction: row-reverse;
  translate: -100% -50%;
}

.pmap__dot {
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  rotate: 45deg;
  background: var(--red-hot);
}

.pmap__label {
  display: grid;
  gap: 2px;
  white-space: nowrap;
}

.pmap__pin--right .pmap__label {
  text-align: right;
}

.pmap__country {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red-hot);
}

.pmap__name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

@media (max-width: 700px) {
  .pmap__name {
    display: none;
  }

  .pmap__country {
    font-size: 8px;
  }
}

/* ---- Partner cards ------------------------------------------------------- */

ul.pmap__list {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}

@media (min-width: 820px) {
  ul.pmap__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.pcard {
  display: grid;
  align-content: start;
  gap: 0;
  padding: 28px 0;
  border-bottom: 1px solid var(--line);
}

@media (min-width: 820px) {
  .pcard {
    padding: 32px clamp(20px, 2.5vw, 34px);
    border-bottom: 0;
  }

  .pcard + .pcard {
    border-left: 1px solid var(--line);
  }

  .pcard:first-child {
    padding-left: 0;
  }

  .pcard:last-child {
    padding-right: 0;
  }
}

.pcard__idx {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.pcard__country {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red-hot);
}

/* Fixed box so three logos of different proportions sit on one baseline. */
.pcard__logo {
  display: grid;
  align-items: center;
  justify-items: start;
  height: 62px;
  margin-top: 22px;
}

.pcard__logo img {
  max-height: 62px;
  max-width: 100%;
  width: auto;
  height: auto;
}

.pcard__name {
  margin-top: 18px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

.pcard__link {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 12px;
  justify-self: start;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--ink-dim);
  transition: color 0.2s;
}

.pcard__link::after {
  content: "↗";
  color: var(--cyan);
  transition: translate 0.2s;
}

.pcard__link:hover {
  color: var(--cyan);
}

.pcard__link:hover::after {
  translate: 3px -3px;
}

/* Technology partner marks in the footer. Both are supplied as white-on-
   transparent artwork, so they sit on the dark footer untouched. */
.footer-tech {
  margin-top: 30px;
}

.footer-tech h2 {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.footer-tech ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 26px;
  margin: 16px 0 0;
  padding: 0;
}

.footer-tech a {
  display: block;
  opacity: 0.75;
  transition: opacity 0.2s;
}

.footer-tech a:hover {
  opacity: 1;
}

.footer-tech img {
  display: block;
  height: 44px;
  width: auto;
}

@media (max-width: 480px) {
  .footer-tech ul {
    gap: 20px;
  }

  .footer-tech img {
    height: 34px;
  }
}

/* Office photograph on the Company page. Held to the content width and given
   the same hairline framing as the figures elsewhere. */
.office-shot {
  width: min(1152px, calc(100vw - 48px));
  margin: 48px 0 0;
  padding-top: 36px;
  border-top: 1px solid var(--line);
}

.office-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
}

.office-shot figcaption {
  margin-top: 18px;
}

.office-shot__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red-hot);
}

.office-shot address {
  margin-top: 10px;
  font-style: normal;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-dim);
}

/* Heading for the advisory list itself, which sits below the live dashboard.
   Expands the VTA acronym once, at the point the advisories begin. */
.adv-intro {
  max-width: 720px;
  padding-top: clamp(40px, 6vw, 72px);
}

.adv-intro h2 {
  margin-top: 16px;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.2;
}

.adv-intro__lede {
  margin-top: 16px;
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--ink-dim);
}

/* Subscribe call to action at the foot of the advisory archive. */
.adv-subscribe {
  padding-block: clamp(48px, 7vw, 88px);
  border-top: 1px solid var(--line);
}

.adv-subscribe__inner {
  max-width: 620px;
  text-align: center;
  margin-inline: auto;
}

.adv-subscribe .eyebrow {
  justify-content: center;
}

.adv-subscribe h2 {
  margin-top: 16px;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.2;
}

.adv-subscribe p:not(.eyebrow) {
  margin-top: 16px;
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--ink-dim);
}

.adv-subscribe .btn {
  margin-top: 28px;
}

/* Product screenshot inside prose. Shares the framing used by the office photo
   on the Company page. */
.shot {
  width: min(1152px, calc(100vw - 48px));
  margin: 36px 0;
  padding-top: 30px;
  border-top: 1px solid var(--line);
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 4px;
}

.shot figcaption {
  margin-top: 14px;
  max-width: 64ch;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

.shot__label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red-hot);
}

/* ===========================================================================
   MXDR deployment architecture
   An SVG topology: two ingest paths converging on the data lake, and the
   containment loop back out. Drawn rather than described, because the earlier
   text-block version never showed direction or the return path.
   =========================================================================== */

.arch {
  width: min(1152px, calc(100vw - 48px));
  margin: 44px 0;
  padding-top: 30px;
  border-top: 1px solid var(--line);
}

/* Below roughly 900px the labels stop being legible, so the diagram scrolls
   inside its own box rather than shrinking into illegibility. */
.arch__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.arch__svg {
  display: block;
  width: 100%;
  min-width: 860px;
  height: auto;
}

/* ---- Sheet furniture ------------------------------------------------------
   The diagram is drawn as an engineering sheet: a grid field, a frame with
   measure ticks, and a title block. Every part carries a reference designator.
   -------------------------------------------------------------------------- */

.sh__field {
  fill: url(#archGrid);
}

.sh__grid {
  fill: none;
  stroke: rgba(120, 140, 190, 0.09);
  stroke-width: 1;
}

.sh__frame {
  fill: none;
  stroke: var(--line);
  stroke-width: 1;
}

.sh__ticks {
  stroke: rgba(120, 140, 190, 0.35);
  stroke-width: 1;
}

/* ---- Nodes --------------------------------------------------------------- */

.an__box {
  fill: var(--surface);
  stroke: var(--line);
  stroke-width: 1;
}

.an__t,
.an__s {
  font-family: var(--font-mono);
}

/* Component glyph, stroked so it sits in the same weight as the boxes. */
.an__icon {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.an--lake .an__icon {
  stroke: var(--red-hot);
}

.an--cust .an__icon,
.an--analyst .an__icon {
  stroke: var(--ink-dim);
}

/* Corner brackets on each part, as on a drawing. */
.an__mark {
  fill: none;
  stroke: rgba(34, 211, 238, 0.5);
  stroke-width: 1;
}

.an--lake .an__mark {
  stroke: rgba(255, 48, 73, 0.7);
}

.an--lake .an__ref {
  fill: var(--red-hot);
}

.an__t {
  font-size: 14px;
  font-weight: 500;
  fill: var(--ink);
}

.an__s {
  font-size: 12px;
  fill: var(--ink-dim);
}

/* The customer sits outside our estate, so its box is drawn dashed. */
.an--cust .an__box {
  stroke-dasharray: 4 3;
  fill: var(--base);
}

/* Both paths converge here, so the lake carries the accent. */
.an--lake .an__box {
  stroke: var(--red-hot);
  stroke-width: 1.5;
  fill: rgba(30, 8, 16, 0.9);
}

.an--lake .an__t {
  fill: var(--red-hot);
}

.an--hub .an__box {
  stroke: rgba(225, 29, 52, 0.55);
}

.an--analyst .an__box {
  stroke-dasharray: 4 3;
  fill: var(--base);
}

/* The watch link is a relationship, not a data flow, so it is drawn quieter. */
.ae--watch {
  stroke: rgba(154, 164, 189, 0.5);
}

.an--gpu .an__box {
  stroke: rgba(34, 211, 238, 0.4);
}

/* ---- Edges --------------------------------------------------------------- */

.ae {
  fill: none;
  stroke: rgba(34, 211, 238, 0.55);
  stroke-width: 1.2;
  stroke-dasharray: 8 6;
}

/* Dashes travel along each path, so a reader sees which way the data moves
   without tracing the arrowhead. */
@media (prefers-reduced-motion: no-preference) {
  .ae {
    animation: ae-flow 1.1s linear infinite;
  }

  /* Staggered, so parallel edges do not pulse in lockstep. */
  .ae:nth-of-type(even) {
    animation-duration: 1.35s;
  }
}

@keyframes ae-flow {
  to {
    stroke-dashoffset: -14;
  }
}

.ae--back {
  stroke: rgba(255, 48, 73, 0.6);
  stroke-dasharray: 6 4;
}

@media (prefers-reduced-motion: no-preference) {
  .ae--back {
    animation-duration: 1.6s;
  }
}

@keyframes ae-flow-back {
  to {
    stroke-dashoffset: -10;
  }
}

.ae__head {
  fill: rgba(34, 211, 238, 0.85);
}

.ae__head--back {
  fill: rgba(255, 48, 73, 0.9);
}

.ae__l,
.ae__p {
  text-anchor: middle;
  font-family: var(--font-mono);
}

.ae__l {
  font-size: 12px;
  fill: var(--ink);
}

.ae__p {
  font-size: 11px;
  letter-spacing: 0.1em;
  fill: var(--cyan);
}

.ae__l--back {
  fill: var(--red-hot);
  letter-spacing: 0.06em;
}

.arch figcaption {
  margin-top: 20px;
  max-width: 68ch;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--ink-faint);
}

/* ===========================================================================
   Dark panels on a light page
   The technical diagrams and the live dashboard stay on their dark canvas.
   Re-declaring the tokens here means the hundreds of rules inside them need no
   change: they resolve against the dark values while the page stays white.
   =========================================================================== */

.arch,
.rs,
.soc-venn,
.about-canvas,
.pmap__canvas {
  --void: var(--d-void);
  --base: var(--d-base);
  --surface: var(--d-surface);
  --raised: var(--raised);
  --line: var(--d-line);
  --ink: var(--d-ink);
  --ink-dim: var(--d-ink-dim);
  --ink-faint: var(--d-ink-faint);
  --cyan: var(--d-accent);
  --red: #e11d34;
  --red-hot: #ff3049;
  color: var(--d-ink);
}

/* Framed, so a dark block reads as a panel rather than a hole in the page. */
.arch,
.rs,
.soc-venn,
.about-canvas,
.pmap__canvas {
  background: var(--d-base);
  border: 1px solid #1e2740;
  border-radius: 10px;
  padding: clamp(16px, 2.5vw, 28px);
}


/* ==========================================================================
   Incident bar
   The one thing on the page a breached visitor is looking for. Solid red on
   navy so it reads as an alarm and not as another nav item, and inside the
   sticky header so it is still there after a long scroll.
   ========================================================================== */

.ir-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 22px;
  background: var(--red);
  color: #fff;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}

/* A label, not a link. Outlined, so the solid white pill further along is
   unambiguously the thing to press. */
.ir-bar__tag {
  flex: none;
  padding: 3px 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 3px;
}

.ir-bar__msg {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: 14px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ir-bar__alt,
.ir-bar__go {
  flex: none;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
}

/* Secondary: text with a rule under it, so it is legible as a link without
   competing with the button beside it. */
.ir-bar__alt {
  border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}

.ir-bar__alt:hover,
.ir-bar__alt:focus-visible {
  color: #fff;
  border-bottom-color: #fff;
}

.ir-bar__go {
  padding: 6px 14px;
  color: var(--red);
  background: #fff;
  border-radius: 4px;
  transition:
    background 0.18s,
    color 0.18s;
}

.ir-bar__go::after {
  content: " →";
}

.ir-bar__go:hover,
.ir-bar__go:focus-visible {
  color: #fff;
  background: var(--navy);
}

/* The sentence is the first thing to go when there is no room, then the
   strip wraps to two rows rather than crushing the two links together. */
@media (max-width: 860px) {
  .ir-bar__msg {
    display: none;
  }
}

@media (max-width: 540px) {
  .ir-bar {
    flex-wrap: wrap;
    gap: 6px 12px;
    padding: 8px 14px;
  }

  .ir-bar__tag {
    flex: 1 0 100%;
    padding: 2px 8px;
    text-align: center;
  }

  /* Both are thumb targets now, not just the one that looks like a button. */
  .ir-bar__alt,
  .ir-bar__go {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    font-size: 13px;
    text-align: center;
  }

  .ir-bar__alt {
    border-bottom-width: 0;
    text-decoration: underline;
    text-underline-offset: 3px;
  }
}


/* The positioning line under the console headline. Sized between the h1 and
   the small print below it, so it reads as a statement rather than a caption. */
.section-head .vta-lead-claim {
  max-width: 46ch;
  margin-top: 16px;
  /* Half the headline, so it reads as the second half of a statement rather
     than as a caption under it. */
  font-size: clamp(19px, 2vw, 26px);
  line-height: 1.35;
  color: var(--ink-soft, var(--ink));
}

/* The crawl was built for the page body, where it bleeds to the full viewport
   and carries its own vertical rhythm. Pinned inside the header it needs
   neither: the header is already full width, and 48px of margin either side
   turned a 50px bar into a 219px band. The negative bleed also mismeasured
   against the scrollbar and pushed the label off the left edge. */
.site-header .cti-ticker {
  width: auto;
  margin: 0;
  border-bottom: 0;
}

/* Navy, as the component ships. The header sits on navy too, so the two are
   held apart by the hairline below rather than by a change of ground. */
.site-header .cti-ticker {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

/* The crawl inside a section rather than pinned in the header: it keeps the
   panel treatment but not the header's edge-to-edge behaviour. */
.ticker-panel--inline {
  margin-block: 0 clamp(10px, 1.2vw, 16px);
}

/* The crawl brings a block margin from the shared ticker rule, which is right
   in a page body and wrong directly under a section that already padded. */
.ticker-panel--inline .cti-ticker {
  margin-block: 0;
}

/* The crawl bleeds past the wrap, so the line under it does too, or it stops
   short of the edge the crawl ends at. */
.ticker-panel--inline .ticker-source {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-right: clamp(14px, 2.5vw, 24px);
}

/* Red rather than the console's blue. Inside .cybersoc the --red token is
   remapped to blue and the label carries a gradient, so the literal colour
   and an explicit image reset are both required. */
.cybersoc .ticker-panel--inline .cti-ticker__label {
  background-color: #d81830;
  background-image: none;
}

/* Centred, and without an eyebrow above it. The 72px top padding suited an
   intro that opened its own section; here the crawl is directly above. */
.adv-intro--centred {
  margin-inline: auto;
  max-width: 760px;
  padding-top: clamp(14px, 1.8vw, 24px);
  text-align: center;
}

.adv-intro--centred h2 {
  margin-top: 0;
}

.adv-intro--centred .adv-intro__lede {
  margin-inline: auto;
}

/* Continues the white strip the crawl sits on, so the two read as one block
   rather than a bar with a caption floating under it. */
/* The panel carries the white ground for both rows, so nothing is drawn
   between them and the crawl and its source read as one block. */
.ticker-panel {
  background: #fff;
}

/* The header keeps a hairline at its foot, which on the front page fell
   below the white panel and read as a dark rule under it. With the panel
   there, the panel is the edge. */
.site-header:has(.ticker-panel) {
  border-bottom: 0;
}

.ticker-source {
  margin: 0;
  /* Right aligned: it is a footnote to the crawl, and the left edge belongs
     to the red label the eye starts from. */
  text-align: right;
  padding: 5px clamp(14px, 2.5vw, 24px) 6px;
  background: #fff;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
}

/* No rule under it at rest: the red against the grey of the rest of the line
   is enough to read as a link at this size, and the underline was heavy on a
   10.5px monospace face. It returns on hover, where it confirms the target
   rather than decorating it.

   Red rather than blue, matching the crawl's own label and the way out of the
   exposure card, so every route to coderedcyber.ai on this page reads the same.
   Hover darkens instead of changing hue, which at 10.5px is the clearer signal. */
/* Literal, not var(--red): the console scope rebinds --red to its own blue, so
   the crawl inside .cybersoc came out blue while the header banner went red. */
.ticker-source a {
  margin-left: 8px;
  color: #d81830;
  text-decoration: none;
}

.ticker-source a:hover,
.ticker-source a:focus-visible {
  color: #b01226;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ==========================================================================
   Working copy: shouted headline and leadership statements
   Only the /frontpage-v2/ template uses these.
   ========================================================================== */

/* The line above the headline: same words the company hero uses, sized as a
   kicker rather than as a mono eyebrow. */
.section-head .lead-kicker {
  margin: 0 0 14px;
  font-size: clamp(26px, 2.8vw, 39px);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #0b0d12;
}

.section-head .lead-kicker span {
  color: var(--blue);
}

/* Black rather than the navy ink, as supplied. The break is written into the
   markup, so no wrapping rule is needed: two lines by design. */
.vta-lead-title--shout {
  text-transform: uppercase;
  letter-spacing: -0.025em;
  line-height: 1.04;
  font-size: clamp(30px, 4.6vw, 66px);
  color: #0b0d12;
}

/* The claim is what the sentence is about, so it takes the colour. */
.vta-lead-title--shout span {
  color: var(--blue);
}

.section-head .vta-lead-title--shout ~ .vta-lead-claim {
  margin-top: 22px;
  max-width: none;
  font-size: clamp(16px, 1.87vw, 24px);
  line-height: 1.6;
  color: var(--ink-dim);
}

/* Left aligned under the headline rather than centred as it is in the company
   hero, and pulled in from that hero's own breakout width. */
.stmts {
  padding-block: clamp(52px, 6vw, 92px) clamp(14px, 1.8vw, 24px);
}

/* Who said it on the left, what they said on the right, a hairline between.
   The alternative was a byline trailing off the end of a paragraph, which
   reads as an afterthought when three of them run down a page. */
.stmt {
  display: grid;
  grid-template-columns: minmax(160px, 200px) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 44px);
  align-items: start;
  margin: 0 0 clamp(30px, 3.5vw, 48px);
  max-width: 1060px;
}

.stmt__by {
  display: grid;
  justify-items: start;
  gap: 6px;
  padding-top: 6px;
}

/* The index sits in a chamfered chip, the same corner the AVM cards cut. */
.stmt__n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #fff;
  background: #1668ad;
  clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px);
}

/* A measured rail down from the chip, ticked like a scale rather than drawn
   as a solid rule. It runs the height of the statement and stops. */
.stmt__by {
  position: relative;
}

.stmt__by::before {
  content: "";
  position: absolute;
  top: 44px;
  bottom: -6px;
  left: 16px;
  width: 2px;
  background: repeating-linear-gradient(
    to bottom,
    #0ea5e9 0 5px,
    transparent 5px 11px
  );
  opacity: 0.55;
}

.stmt__name {
  margin-top: 10px;
  font-size: clamp(14px, 1.1vw, 16px);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: 0.01em;
  color: var(--ink);
}

/* The divider between the columns becomes an axis: solid where the statement
   starts, falling away down the block. */
.stmt__quote {
  position: relative;
  margin: 0;
  padding-left: clamp(20px, 2.4vw, 36px);
}

.stmt__quote::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 0;
  left: 0;
  width: 2px;
  background: linear-gradient(
    to bottom,
    #0ea5e9 0,
    rgba(14, 165, 233, 0.22) 62%,
    rgba(14, 165, 233, 0) 100%
  );
}

.stmt__quote p {
  margin: 0;
  max-width: 62ch;
  font-size: clamp(15px, 1.28vw, 18px);
  line-height: 1.6;
  color: var(--ink);
  text-wrap: pretty;
}

/* The opening phrase names the approach, so it carries the weight. */
.stmt__quote p::first-line {
  font-weight: 600;
}

@media (max-width: 780px) {
  .stmt {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .stmt__quote {
    padding-left: 0;
  }

  .stmt__quote::before,
  .stmt__by::before {
    display: none;
  }
}

/* ==========================================================================
   Console captures, one at a time
   Scroll-snap does the work; the buttons only drive it. With scripting off the
   track is still a scroller, so every capture stays reachable.
   ========================================================================== */

.hubshow {
  margin: 4px 0 clamp(34px, 4vw, 56px);
}

.hubshow__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: var(--radius);
}

.hubshow__track::-webkit-scrollbar {
  display: none;
}

.hubshow__track:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

.hubshow__slide {
  margin: 0;
  scroll-snap-align: start;
}

/* The captures arrive with their own window frame, so the page adds no second
   one. The corner is cut to the same 16px the AVM cards use, which is what
   ties them to the console rather than any added chrome. */
.hubshow__slide img {
  display: block;
  width: 100%;
  height: auto;
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
}

/* Read as an instrument label: mono, tracked, with a lit tick in front. */
.hubshow__slide figcaption {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding-left: 14px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-left: 2px solid #0ea5e9;
}

.hubshow__n {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.13em;
  color: #1668ad;
}

/* Named buttons rather than anonymous dots: three unlabelled circles make a
   reader click to find out what they are. */
.hubshow__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.hubshow__dot {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 9px 16px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--ink-dim);
  background: var(--raised);
  border: 1px solid var(--line);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  cursor: pointer;
  transition:
    color 0.15s,
    border-color 0.15s,
    background 0.15s;
}

.hubshow__dot:hover {
  color: var(--ink);
  border-color: var(--blue);
}

.hubshow__dot.is-on {
  color: #fff;
  background: #1668ad;
  border-color: #1668ad;
}

.hubshow__dot.is-on .hubshow__dot-n {
  color: #fff;
}

.hubshow__dot-n {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  opacity: 0.75;
}

@media (max-width: 560px) {
  .hubshow__dot span:not(.hubshow__dot-n) {
    display: none;
  }
}

/* A station with nothing to count. The chip and the spine that led to it both
   implied a sequence, so both go and the label carries it alone. */
.cyber-step--plain::before {
  display: none;
}

.cyber-step--plain {
  padding-top: clamp(18px, 3vw, 34px);
}

/* ==========================================================================
   Pinned card stack
   Each approach pins under the header, and the next card rides up over it.
   Pure sticky plus a scroll-driven recede on the card underneath: no library,
   and every card is real text in the DOM at all times.
   ========================================================================== */

.stack {
  /* The pin point has to clear the sticky header, which carries the crawl on
     this page and is 148px tall. */
  --stack-top: 168px;
  --stack-step: 16px;
}

.stack__card {
  position: sticky;
  top: calc(var(--stack-top) + (var(--i) * var(--stack-step)));
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 0 clamp(24px, 3vw, 48px);
  align-items: stretch;
  margin-bottom: clamp(8px, 1vw, 14px);
  padding: clamp(24px, 2.6vw, 38px);
  background: #fff;
  /* The same corner the AVM cards cut, so the stack belongs to the console. */
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
  box-shadow:
    inset 0 0 0 1px var(--line),
    0 24px 48px -32px rgba(11, 27, 58, 0.5);
}

/* The last card has nothing coming up behind it, so it needs no run-out. */
.stack__card:last-child {
  margin-bottom: 0;
}

.stack__label {
  margin: 0 0 14px;
  font-size: clamp(20px, 2vw, 28px);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.stack__quote {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.6;
  color: var(--ink-dim);
  text-wrap: pretty;
}

/* Spans both rows so it still fills the card beside the capture. */
.stack__text {
  grid-row: 1 / -1;
  display: flex;
  flex-direction: column;
}

/* Pushed to the foot of the card rather than trailing the paragraph, so the
   slack under a short statement is used rather than left empty. */
/* Second column, second row: under the capture rather than under the text.
   A column now, so the note can sit beneath the mark on the same right edge. */
.stack__powered {
  grid-column: 2;
  align-self: end;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  padding-top: 18px;
}

.stack__powered .powered-brand {
  justify-content: flex-end;
  gap: 12px;
  margin-top: 0;
}

.stack__powered img {
  height: 34px;
}

.stack__powered p {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-faint);
}

/* The columns stretch so the text can fill the card. The capture does not grow
   with it, so it sits in the middle of the space rather than at the top. */
.stack__show {
  align-self: center;
}

/* One frame, fixed by the first capture's shape, so a fade never resizes the
   card under the reader mid-scroll. */
.stack__frame {
  position: relative;
  overflow: hidden;
  clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
}

.stack__slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  transition: opacity 0.55s ease;
}

.stack__slide.is-on {
  opacity: 1;
}

.stack__slide img {
  display: block;
  width: 100%;
  height: 100%;
  /* The console-GPT captures are a shade wider than the hub ones; cover trims
     the difference rather than letterboxing white bars into the frame. */
  object-fit: cover;
  object-position: top center;
}

.stack__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
}

/* The captions are stacked in one line box so the row cannot change height as
   they swap. */
.stack__cap {
  position: relative;
  flex: 1;
  min-width: 0;
  margin: 0;
  padding-left: 12px;
  min-height: 1.4em;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-left: 2px solid #0ea5e9;
}

.stack__cap span {
  position: absolute;
  inset: 0 0 auto 12px;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.stack__cap span.is-on {
  opacity: 1;
}

.stack__dots {
  display: flex;
  flex: none;
  gap: 7px;
}

.stack__dot {
  width: 22px;
  height: 5px;
  padding: 0;
  background: var(--line);
  border: 0;
  cursor: pointer;
  transition: background 0.25s;
}

.stack__dot:hover,
.stack__dot:focus-visible {
  background: #6aa9d8;
}

.stack__dot.is-on {
  background: #1668ad;
}

/* The card underneath draws back as the next one covers it, so the stack
   reads as depth rather than as a card that simply vanished. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .stack__card {
      animation: stack-recede linear both;
      animation-timeline: view();
      animation-range: exit -20% exit 90%;
    }

    .stack__card:last-child {
      animation: none;
    }
  }
}

@keyframes stack-recede {
  to {
    transform: scale(0.94);
    opacity: 0.45;
  }
}

/* Below this the card is taller than the room above the fold, so pinning
   would hold a card the reader cannot see the bottom of. It becomes an
   ordinary stack instead. */
@media (max-width: 900px) {
  .stack__card {
    position: static;
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
    margin-bottom: 28px;
    animation: none;
  }

  /* The span is written for the two-row desktop card. Left in place here it
     held the text in a row track it no longer shares with anything. */
  .stack__text {
    grid-row: auto;
  }

  /* There is no column 2 at this width. Asking for one made the grid create
     an implicit track, which sized to the mark and took the whole row, so the
     text column was left with nothing and wrapped a character to a line. */
  .stack__powered {
    grid-column: 1;
    align-items: flex-start;
    padding-top: 4px;
  }

  /* Right alignment belonged to the second column. In one column the mark
     starts at the same edge as everything above it. */
  .stack__powered .powered-brand {
    justify-content: flex-start;
  }
}

/* A product lockup at the head of a card. Deliberately small: it names what
   the card is about, it is not the subject of it. */
.stack__brand {
  margin-bottom: 22px;
}

/* Per card: the two lockups are different proportions, so one height cannot
   serve both. MXDR's 34px is the default. */
.stack__brand img {
  display: block;
  width: auto;
  height: var(--logo-h, 34px);
}

.stack__brand p {
  margin: 8px 0 0;
  /* The same declaration .stack__quote carries, so the two cannot drift. */
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.6;
  color: var(--ink-dim);
}

/* Four benefits as a numbered run, in the console's own vocabulary: chamfered
   chip, mono index, a lit rail down the side. Not four boxes, because the
   column is 470px and boxes at half that cannot hold the sentences. */
.stack__points {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 2px 0 0 0;
  display: grid;
  gap: 14px;
}

.stack__points li {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  font-size: clamp(13px, 1.02vw, 14.5px);
  line-height: 1.5;
  color: var(--ink-dim);
}

.stack__pn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 22px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #fff;
  background: #1668ad;
  clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px);
}

/* A rail behind the chips, ticked like the ones on the card rails, so the
   four read as one run rather than four unrelated lines. */
.stack__points::before {
  content: "";
  position: absolute;
  top: 26px;
  bottom: 8px;
  left: 14px;
  width: 2px;
  background: repeating-linear-gradient(
    to bottom,
    #0ea5e9 0 5px,
    transparent 5px 11px
  );
  opacity: 0.45;
}

/* A card with nothing to show is one column, so the text is not squeezed into
   a narrow half beside an empty gap. */
.stack__card--text {
  grid-template-columns: minmax(0, 1fr);
}

.stack__card--text .stack__quote {
  max-width: 74ch;
}

/* The second technology mark. Arctic's lockup is 3.8:1 against CodeRed's
   2.4:1, so matching heights would leave it looking far wider; it is set a
   little shorter so the two carry equal weight. */
.stack__powered img.stack__powered-arctic {
  height: 36px;
  width: auto;
}

.stack__powered-sep {
  width: 1px;
  height: 22px;
  background: var(--line);
}

/* ==========================================================================
   Founder's statement
   A pull quote, not another card: this is a position rather than a product,
   so it is set in its own register and given room either side.
   ========================================================================== */

.creed {
  padding-block: clamp(56px, 7vw, 104px) clamp(40px, 5vw, 72px);
}

.creed__block {
  position: relative;
  max-width: 78ch;
  margin: 0;
  padding-left: clamp(24px, 3vw, 44px);
}

/* The same lit axis the cards use down their divider, so the block belongs to
   the page rather than arriving from somewhere else. */
.creed__block::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 34px;
  left: 0;
  width: 3px;
  background: linear-gradient(
    to bottom,
    #0ea5e9 0,
    rgba(14, 165, 233, 0.2) 70%,
    rgba(14, 165, 233, 0) 100%
  );
}

.creed__block blockquote {
  margin: 0;
}

.creed__block blockquote p {
  margin: 0;
  /* The same declaration the lede carries above it. */
  font-size: clamp(14px, 1.25vw, 16px);
  line-height: 1.6;
  color: var(--ink);
  text-wrap: pretty;
}

.creed__block figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin-top: 20px;
}

.creed__name {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.creed__role {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Statements between two pinned cards. They need their own white ground:
   anything transparent scrolling over a pinned card shows it through. */
.stack__interlude {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(22px, 2.6vw, 40px);
  margin-bottom: clamp(6px, 0.7vw, 10px);
  padding: 0;
  background: #fff;
}

@media (min-width: 860px) {
  .stack__interlude {
    /* auto-fit rather than a fixed pair: two statements share the row, one on
       its own takes the width instead of leaving half the row empty. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
    align-items: start;
  }
}

/* A card with no capture has one column, so the attribution cannot sit in a
   second one. It stays at the foot, aligned right as it is elsewhere. */
.stack__card--text .stack__powered {
  grid-column: 1;
  padding-top: 26px;
}

/* The datasheet button on a component card. Set as an action rather than a
   quiet link, since it is the only thing the card does. */
.service-mini__sheet {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  margin-top: auto;
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: #1668ad;
  border-radius: 4px;
  transition: background 0.18s;
}

.service-mini__sheet:hover,
.service-mini__sheet:focus-visible {
  color: #fff;
  background: var(--navy);
}

/* A card whose heading is text rather than artwork needs the heading to hold
   its own, since there is no logo above it. */
.service-mini__main h3:not(.screen-reader-text) {
  margin-bottom: 8px;
  font-size: clamp(17px, 1.4vw, 20px);
}


/* The subscribe link, now a button under the intro rather than a section of
   its own after the feed. */
.adv-intro__cta {
  margin-top: 22px;
}

/* The exposure check between the radar crawl and the advisories. It no longer
   sits in a .section, so it carries its own breathing room: more above, to
   clear the full-bleed crawl, than below. */
.exposure-block {
  margin-block: clamp(30px, 4vw, 52px) clamp(26px, 3.4vw, 44px);
}

/* Heading for the exposure card. Matched to the advisories heading below it so
   the two blocks in this stretch read as a pair rather than as two designs. */
.exposure-title {
  margin: 0 0 clamp(16px, 1.8vw, 24px);
  text-align: center;
  font-family: var(--font-display, "Space Grotesk"), system-ui, sans-serif;
  font-size: clamp(25px, 2.6vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #0b1b3a;
}

/* Quick Links. The "+" is drawn rather than typed into the label: a screen
   reader announcing "plus Privacy Notice" on every item is noise, and the mark
   is doing a bullet's job. */
.footer-quick ul {
  gap: 10px;
}

.footer-quick li {
  display: flex;
  gap: 8px;
}

.footer-quick li::before {
  content: "+";
  flex: none;
  color: var(--ink-faint);
  line-height: 1.5;
  font-size: 13.5px;
}

/* A rule under each footer heading, as on the published site. It separates the
   heading from a column of links set at much the same weight. */
.footer-about h2,
.footer-col h2 {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

/* No rule under "Connect With Us". It heads a row of icons, not a column of
   links, so there is nothing for a rule to separate -- and a second rule inside
   one column read as the start of a third. */
.footer-about h2.footer-connect {
  padding-bottom: 0;
  border-bottom: 0;
}

.footer-connect + .footer-social {
  margin-top: 16px;
}

/* ==========================================================================
   News crawl — recent awards, across the top of the footer
   ========================================================================== */

/* Full width of the footer rather than the content wrap: it is a band, and a
   band that stops short of the edges reads as a stray row of text. */
/* The band plus the line under it. The wrapper carries the spacing, so the
   band itself can stay flush to the footer's top edge.

   Up through the footer's opening space: the crawl is a band, not a column,
   and belongs above that space rather than inside it. */
.newscrawl-panel {
  margin-top: -64px;
  margin-bottom: clamp(34px, 4vw, 56px);
}

.newscrawl {
  display: flex;
  align-items: stretch;
  background: var(--navy, #001861);
  background-image: linear-gradient(348deg, rgba(7, 10, 44, 0.9) 0%, rgba(7, 10, 44, 0) 58%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

/* Pinned, so what the crawl is never scrolls out of view. */
.newscrawl__label {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  margin: 0;
  padding: 13px clamp(14px, 2.5vw, 24px);
  background: #d81830;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}

.newscrawl__window {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  /* Items enter and leave rather than being chopped against the label. */
  mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
}

.newscrawl__track {
  display: flex;
  width: max-content;
  animation: newscrawl 64s linear infinite;
}

.newscrawl__set {
  display: flex;
  align-items: center;
}

/* Held still while a reader is on it, so a line cannot slide away mid-sentence. */
.newscrawl:hover .newscrawl__track,
.newscrawl:focus-within .newscrawl__track {
  animation-play-state: paused;
}

.newscrawl__item {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 13px clamp(18px, 3vw, 34px);
  color: rgba(255, 255, 255, 0.82);
  font-size: 13.5px;
  white-space: nowrap;
}

.newscrawl__item + .newscrawl__item {
  border-left: 1px solid rgba(255, 255, 255, 0.14);
}

/* The kind, set as a label rather than as part of the sentence. */
.newscrawl__item b {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.5);
}

@keyframes newscrawl {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .newscrawl__track {
    animation: none;
  }

  .newscrawl__window {
    overflow-x: auto;
  }
}

/* CodeRed Cyber, under the Provintell wordmark. Taller than the wordmark's box
   because the lockup is a large mark beside two short lines of type: matched on
   box height its wordmark would set at half the size of Provintell's. */
.footer-codered {
  width: auto;
  height: 77px;
}

/* The links column holds the accreditation mark in its foot. margin-top:auto
   pushes it to the bottom of the column whatever the About block's height, so
   the two columns end level. */
.footer-quick {
  display: flex;
  flex-direction: column;
}

.footer-accred {
  margin-top: auto;
  padding-top: 34px;
  align-self: flex-end;
}

/* No gap above the footer: it opens on the full-bleed announcements band, and
   that band is meant to be the footer's own top edge rather than a strip
   floating below the page. */
.site-footer {
  margin-top: 0;
}

/* The two statements side by side. Each keeps its own lit axis, so the pair
   reads as two voices rather than one block split down the middle. */
.creed__pair {
  display: grid;
  gap: clamp(28px, 4vw, 56px);
}

@media (min-width: 900px) {
  .creed__pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* 78ch was the measure for a single block running the full wrap. In a column
     half that wide it does nothing but block the grid from sizing. */
  .creed__pair .creed__block {
    max-width: none;
  }
}

/* Heading over the component cards. Set to the section-head scale so it reads
   as a peer of the other section titles on this page, with the space above it
   carrying the break from the service articles. */
.mini-grid-title {
  margin: clamp(44px, 5vw, 72px) 0 0;
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* ==========================================================================
   Terms of Service — clause lists and SLA tables
   ========================================================================== */

/* Clauses hang on their own numbers rather than sitting under them, so a long
   clause stays visibly one item. */
.tos-clauses,
.tos-sub {
  margin: 0 0 22px;
  padding-left: 2.4em;
}

.tos-clauses > li,
.tos-sub > li {
  margin-bottom: 12px;
  padding-left: 6px;
  line-height: 1.65;
}

.tos-clauses > li::marker,
.tos-sub > li::marker {
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

/* Sub-items a) b) c) belong to the clause above, so they indent past it. */
.tos-sub {
  margin-top: -10px;
  margin-left: 1.2em;
}

/* The SLA tables were flat images in the source documents. As real tables they
   need to scroll on a narrow screen rather than force the page wide. */
.wp-block-table.tos-table {
  margin: 26px 0 30px;
  overflow-x: auto;
}

.tos-table table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 1.5;
}

.tos-table th,
.tos-table td {
  padding: 10px 12px;
  border: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.tos-table thead th {
  background: var(--raised, #f4f7fb);
  font-weight: 700;
}

.tos-table figcaption {
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-faint);
}

/* Sits under the crawl the way the source line sits under the two threat
   bands. Right-aligned: the left edge belongs to the red label the eye starts
   from. The crawl moves, so the way out of it has to hold still. */
.newscrawl__more {
  margin: 0;
  padding: 7px clamp(14px, 2.5vw, 24px) 0;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
}

.newscrawl__more a {
  color: #d81830;
  text-decoration: none;
}

.newscrawl__more a:hover,
.newscrawl__more a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Datasheet links on a service row. Listed rather than laid out as buttons:
   MXDR carries four and four filled buttons would outweigh the two actions
   above them. */
.svc__sheets {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.svc__sheet {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue);
  text-decoration: none;
}

/* A downward arrow, drawn so the link reads as a download without an icon
   font. */
.svc__sheet::before {
  content: "↓";
  font-size: 13px;
  line-height: 1;
}

.svc__sheet:hover,
.svc__sheet:focus-visible {
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Each mark carries its own height, set so the CODERED lettering measures the
   same across all three. The three lockups give their wordmark a different share
   of the artwork height, so one box height renders three different-looking
   sizes. See the loh values in page-home.php for the arithmetic. */
.svc__logo {
  height: var(--logo-h, 59px);
  width: auto;
}

/* "Download" over the datasheet list. Set as a column label rather than a
   heading, matching the eyebrow scale used elsewhere in the row. */
.svc__sheets-title {
  margin: 26px 0 10px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.svc__sheets-title + .svc__sheets {
  margin-top: 0;
}

/* A section whose eyebrow is its heading. Kept as an h2 so the section is still
   titled in the document outline, sized as the eyebrow it reads as. */
.section-head h2.eyebrow--head {
  margin-top: 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--red);
}

/* The document a download request is for, named above the form. */
.cform__ask {
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* The Company lede, on one line and centred under the strip. It needed 1205px
   at 18px against a 1200px column and was capped at 860px on top of that, so it
   always broke; 17px fits with room. Narrow viewports wrap as before. */
.page-hero .hero-sub {
  max-width: none;
  margin-inline: auto;
  text-align: center;
  font-size: clamp(15px, 1.35vw, 17px);
  text-wrap: balance;
}

/* The body column starts at the wrap's left edge, aligned with the hero above
   it, and runs the full width rather than stopping at a measure that left 427px
   of empty page beside it. */
.page-hero ~ .wrap > .prose {
  max-width: none;
  margin-inline: 0;
}

/* The Company headline on one line: it needs 880px and the shared 860px measure
   was 20px short of holding it. Narrow viewports still wrap. */
.page-hero .hero-title {
  max-width: none;
}

/* ==========================================================================
   Leadership
   ========================================================================== */

.team {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 32px 40px;
}

@media (min-width: 720px) {
  .team {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .team {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* A rule over each entry rather than a card around it: four boxes on a page
   that already carries a timeline and a news grid would be a third kind of
   container saying nothing new. */
.team__member {
  padding-top: 16px;
  border-top: 2px solid var(--red);
}

.team__focus {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.team__name {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.team__role {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--blue);
}

.team__line {
  margin: 14px 0 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-dim);
}

/* Both bands opened on the full section padding above a heading that carries
   its own space, which put 149px between the section above and the title. */
#industryawards,
#news {
  padding-top: clamp(40px, 5vw, 64px);
}

#industryawards .section-head,
#news .section-head {
  margin-bottom: 0;
}

/* The news grid sat 56px under its heading against the timeline's 24px. */
#news .advisory-grid {
  margin-top: 24px;
}

/* The two band headings on the Company page: centred, on one line, and smaller
   than the shared section-head size, which was set for a heading that carries a
   lede paragraph beneath it. These carry nothing but themselves. */
#industryawards .section-head,
#news .section-head {
  max-width: none;
  text-align: center;
}

#industryawards .section-head h2,
#news .section-head h2 {
  font-size: clamp(26px, 3vw, 36px);
}

/* ==========================================================================
   Phones
   The layout is mobile-first throughout, so this holds only the places where
   a rule written for a wide viewport does not survive a narrow one.
   ========================================================================== */

@media (max-width: 620px) {
  /* The crawl's label is a fixed badge and the window beside it takes what is
     left. At 375px the badge was 204px of it, so the headlines ran through a
     171px slot with 40px of fade at each end: about 90px of readable text.
     Tightening the badge roughly doubles what the window can show. */
  .site-header .cti-ticker__label,
  .ticker-panel--inline .cti-ticker__label {
    gap: 7px;
    padding: 12px 10px;
    font-size: 9px;
    letter-spacing: 0.06em;
  }

  /* The fade is sized for a window several hundred pixels wide. At this width
     it was eating most of the slot it was meant to soften. */
  .site-header .cti-ticker__window,
  .ticker-panel--inline .cti-ticker__window {
    mask-image: linear-gradient(90deg, transparent, #000 14px, #000 calc(100% - 14px), transparent);
  }

  /* Right aligned, this wraps to two lines that break at different points and
     read as a stray fragment. Centred, the wrap looks deliberate. */
  .ticker-source {
    text-align: center;
    letter-spacing: 0.06em;
  }

  /* Safari zooms the page in when a field smaller than 16px takes focus, and
     it does not zoom back out. Every field is 15px, so tapping the first one
     left the reader inside a magnified, sideways-scrolling form. */
  .cform__field input[type="text"],
  .cform__field input[type="email"],
  .cform__field input[type="tel"],
  .cform__field input[type="number"],
  .cform__field select,
  .cform__field textarea {
    font-size: 16px;
  }
}
