/* ==========================================================================
   IMS Services — components
   ========================================================================== */

/* ==========================================================================
   Buttons
   Radii stay tight. The wordmark is squared and confident; pill buttons would
   fight it.
   ========================================================================== */

.ims-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ims-sp-2);
  padding: 0.85rem 1.5rem;
  border-radius: var(--ims-r-sm);
  font-family: var(--ims-font-display);
  font-size: 0.9375rem;
  font-weight: 600;
  font-stretch: 105%;
  letter-spacing: 0.005em;
  line-height: 1.2;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background-color var(--ims-dur-base) var(--ims-ease),
    border-color var(--ims-dur-base) var(--ims-ease),
    color var(--ims-dur-base) var(--ims-ease),
    transform var(--ims-dur-base) var(--ims-ease-spring),
    box-shadow var(--ims-dur-base) var(--ims-ease);
}

.ims-btn:hover { transform: translateY(-2px); }
.ims-btn:active { transform: translateY(0); }

.ims-btn__icon {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  transition: transform var(--ims-dur-base) var(--ims-ease-out);
}

.ims-btn:hover .ims-btn__icon { transform: translateX(3px); }

/* Primary: navy on light ground. */
.ims-btn--primary {
  background-color: var(--ims-navy-800);
  color: var(--ims-white);
  box-shadow: var(--ims-shadow-sm);
}

.ims-btn--primary:hover {
  background-color: var(--ims-navy-700);
  color: var(--ims-white);
  box-shadow: var(--ims-shadow-md);
}

/* Secondary: outlined, quiet. */
.ims-btn--secondary {
  background-color: transparent;
  color: var(--ims-navy-800);
  border-color: var(--ims-border);
}

.ims-btn--secondary:hover {
  color: var(--ims-navy-800);
  border-color: var(--ims-navy-800);
  background-color: var(--ims-mist-50);
}

/* On dark grounds cyan becomes the fill, because here it IS the live thing. */
.ims-deep .ims-btn--primary,
.ims-section--deep .ims-btn--primary {
  background-color: var(--ims-cyan-400);
  color: var(--ims-navy-950);
  box-shadow: none;
}

.ims-deep .ims-btn--primary:hover,
.ims-section--deep .ims-btn--primary:hover {
  background-color: var(--ims-cyan-300);
  color: var(--ims-navy-950);
  box-shadow: var(--ims-glow);
}

.ims-deep .ims-btn--secondary,
.ims-section--deep .ims-btn--secondary {
  color: var(--ims-on-dark);
  border-color: rgba(143, 227, 226, 0.32);
}

.ims-deep .ims-btn--secondary:hover,
.ims-section--deep .ims-btn--secondary:hover {
  color: var(--ims-white);
  border-color: var(--ims-cyan-300);
  background-color: rgba(26, 199, 198, 0.08);
}

.ims-btn--lg { padding: 1.0625rem 2rem; font-size: 1rem; }
.ims-btn--block { display: flex; width: 100%; }

.ims-btn[disabled],
.ims-btn[aria-disabled="true"] {
  opacity: 0.55;
  pointer-events: none;
}

.ims-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ims-sp-3);
  align-items: center;
}

/* ==========================================================================
   Header and navigation
   ========================================================================== */

.ims-header {
  position: sticky;
  top: 0;
  z-index: var(--ims-z-header);
  background-color: rgba(255, 255, 255, 0.88);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition:
    background-color var(--ims-dur-base) var(--ims-ease),
    border-color var(--ims-dur-base) var(--ims-ease),
    box-shadow var(--ims-dur-base) var(--ims-ease);
}

/* Over a dark hero the header starts transparent and inverts its type, then
   solidifies once the page scrolls past the hero. */
.ims-header--over-dark:not(.is-stuck) {
  background-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.ims-header--over-dark:not(.is-stuck) .ims-nav__link,
.ims-header--over-dark:not(.is-stuck) .ims-header__tel {
  color: var(--ims-on-dark);
}

.ims-header--over-dark:not(.is-stuck) .ims-logo { color: var(--ims-white); }

.ims-header.is-stuck {
  border-bottom-color: var(--ims-border);
  box-shadow: var(--ims-shadow-sm);
}

.ims-header__inner {
  display: flex;
  align-items: center;
  gap: var(--ims-sp-5);
  min-height: 4.75rem;
}

.ims-logo {
  display: inline-flex;
  align-items: center;
  flex: none;
  color: var(--ims-navy-800);
  text-decoration: none;
  line-height: 0;
}

.ims-logo svg {
  height: 2.4rem;
  width: auto;
  display: block;
}

@media (max-width: 30rem) {
  .ims-logo svg { height: 2rem; }
}

.ims-header__spacer { flex: 1 1 auto; }

/* ---- Primary nav ------------------------------------------------------- */

.ims-nav__list {
  display: flex;
  align-items: center;
  gap: var(--ims-sp-1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.ims-nav__list li { margin: 0; }

.ims-nav__link {
  display: block;
  padding: 0.55rem 0.85rem;
  border-radius: var(--ims-r-sm);
  color: var(--ims-ink-mid);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  position: relative;
  transition: color var(--ims-dur-fast) var(--ims-ease),
              background-color var(--ims-dur-fast) var(--ims-ease);
}

.ims-nav__link:hover {
  color: var(--ims-navy-800);
  background-color: rgba(7, 53, 103, 0.05);
}

/* Cyan marks the live location. This is signal, not decoration. */
.ims-nav .current-menu-item > .ims-nav__link,
.ims-nav .current_page_item > .ims-nav__link,
.ims-nav .current-menu-ancestor > .ims-nav__link,
.ims-nav .current_page_ancestor > .ims-nav__link {
  color: var(--ims-navy-800);
  font-weight: 600;
}

.ims-nav .current-menu-item > .ims-nav__link::after,
.ims-nav .current_page_item > .ims-nav__link::after,
.ims-nav .current-menu-ancestor > .ims-nav__link::after,
.ims-nav .current_page_ancestor > .ims-nav__link::after {
  content: "";
  position: absolute;
  left: 0.85rem;
  right: 0.85rem;
  bottom: 0.15rem;
  height: 2px;
  border-radius: 2px;
  background-color: var(--ims-cyan-400);
}

.ims-header--over-dark:not(.is-stuck) .ims-nav .current-menu-item > .ims-nav__link,
.ims-header--over-dark:not(.is-stuck) .ims-nav .current_page_item > .ims-nav__link {
  color: var(--ims-white);
}

/* ---- Submenu ----------------------------------------------------------- */

.ims-nav__list .menu-item-has-children { position: relative; }

.ims-nav__list .sub-menu {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 15rem;
  background-color: var(--ims-white);
  border: 1px solid var(--ims-border);
  border-radius: var(--ims-r-md);
  box-shadow: var(--ims-shadow-lg);
  padding: var(--ims-sp-2);
  list-style: none;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    opacity var(--ims-dur-base) var(--ims-ease),
    transform var(--ims-dur-base) var(--ims-ease-out),
    visibility var(--ims-dur-base);
}

.ims-nav__list .menu-item-has-children:hover > .sub-menu,
.ims-nav__list .menu-item-has-children:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.ims-nav__list .sub-menu .ims-nav__link {
  white-space: normal;
  color: var(--ims-ink);
  padding: 0.6rem 0.75rem;
}

.ims-header__tel {
  display: inline-flex;
  align-items: center;
  gap: var(--ims-sp-2);
  font-family: var(--ims-font-mono);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ims-navy-800);
  text-decoration: none;
  white-space: nowrap;
}

.ims-header__tel svg { width: 1rem; height: 1rem; flex: none; }
.ims-header__tel:hover { color: var(--ims-teal-600); }

/* ---- Mobile toggle ----------------------------------------------------- */

.ims-nav-toggle {
  display: none;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--ims-r-sm);
  border: 1px solid var(--ims-border);
  color: var(--ims-navy-800);
  background-color: var(--ims-white);
  flex: none;
}

.ims-nav-toggle__bars,
.ims-nav-toggle__bars::before,
.ims-nav-toggle__bars::after {
  display: block;
  width: 1.125rem;
  height: 2px;
  background-color: currentColor;
  border-radius: 2px;
  transition: transform var(--ims-dur-base) var(--ims-ease-out),
              opacity var(--ims-dur-fast) var(--ims-ease);
}

.ims-nav-toggle__bars { position: relative; }
.ims-nav-toggle__bars::before,
.ims-nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.ims-nav-toggle__bars::before { top: -6px; }
.ims-nav-toggle__bars::after  { top: 6px; }

.ims-nav-toggle[aria-expanded="true"] .ims-nav-toggle__bars { background-color: transparent; }
.ims-nav-toggle[aria-expanded="true"] .ims-nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.ims-nav-toggle[aria-expanded="true"] .ims-nav-toggle__bars::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 61.9375rem) {
  .ims-nav-toggle { display: inline-flex; }

  /* Hide only the VISIBLE number, never the screen-reader span, or the link
     loses its accessible name on exactly the device most likely to dial it. */
  .ims-header__tel span[aria-hidden="true"] { display: none; }

  .ims-nav {
    position: fixed;
    inset: 4.75rem 0 auto 0;
    background-color: var(--ims-white);
    border-bottom: 1px solid var(--ims-border);
    box-shadow: var(--ims-shadow-lg);
    padding: var(--ims-sp-4) var(--ims-gutter) var(--ims-sp-6);
    max-height: calc(100dvh - 4.75rem);
    overflow-y: auto;
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition:
      opacity var(--ims-dur-base) var(--ims-ease),
      transform var(--ims-dur-base) var(--ims-ease-out),
      visibility var(--ims-dur-base);
  }

  .ims-nav.is-open { opacity: 1; visibility: visible; transform: translateY(0); }

  /* Without JavaScript the toggle cannot fire, so the panel must not be
     hidden in the first place. It falls back to an ordinary block of links
     in the document flow, which is navigable and keyboard reachable. */
  .no-js .ims-nav {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    max-height: none;
    box-shadow: none;
    padding-inline: 0;
  }

  .no-js .ims-nav-toggle { display: none; }

  .ims-nav__list { flex-direction: column; align-items: stretch; gap: 0; }

  .ims-nav__link {
    padding: 0.9rem 0.25rem;
    border-bottom: 1px solid var(--ims-border);
    border-radius: 0;
    font-size: 1.0625rem;
  }

  .ims-nav__list .sub-menu {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    box-shadow: none;
    border: none;
    border-radius: 0;
    padding: 0 0 0 var(--ims-sp-4);
    min-width: 0;
  }

  .ims-nav .current-menu-item > .ims-nav__link::after,
  .ims-nav .current_page_item > .ims-nav__link::after { left: 0.25rem; right: auto; width: 1.5rem; bottom: 0.4rem; }
}

/* ==========================================================================
   THE SIGNATURE: services topology

   The seven brief services are not a list, they are the layers of an actual
   IT environment. The brief's own words: "from endpoint devices to cloud,
   Microsoft productivity, and security layers."

   So: nodes on a spine, read bottom-up from the device on the desk to the
   cloud behind it, with security drawn as a band that WRAPS the stack rather
   than sitting in it. That is what security actually does, and it is why
   this is information rather than decoration.
   ========================================================================== */

.ims-topology {
  position: relative;
  border: 1px solid var(--ims-border);
  border-radius: var(--ims-r-lg);
  padding: var(--ims-sp-7) var(--ims-sp-5) var(--ims-sp-5);
  background-color: var(--ims-bg);
}

.ims-section--deep .ims-topology,
.ims-deep .ims-topology {
  border-color: var(--ims-line-dark);
  background-color: rgba(255, 255, 255, 0.02);
}

/* The wrapping security band, labelled like a fieldset legend so the
   "wraps everything" relationship is legible at a glance. */
.ims-topology__wrap-label {
  position: absolute;
  top: 0;
  left: var(--ims-sp-5);
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: var(--ims-sp-2);
  padding: 0.3rem 0.75rem;
  background-color: var(--ims-bg);
  border: 1px solid var(--ims-teal-600);
  border-radius: var(--ims-r-full);
  font-family: var(--ims-font-mono);
  font-size: var(--ims-fs-label);
  font-weight: 500;
  letter-spacing: var(--ims-ls-label);
  text-transform: uppercase;
  color: var(--ims-teal-600);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--ims-dur-base) var(--ims-ease),
              color var(--ims-dur-base) var(--ims-ease);
}

.ims-topology__wrap-label:hover {
  background-color: var(--ims-teal-600);
  color: var(--ims-white);
}

.ims-topology__wrap-label svg { width: 0.9rem; height: 0.9rem; flex: none; }

.ims-section--deep .ims-topology__wrap-label {
  background-color: var(--ims-navy-950);
  border-color: var(--ims-cyan-400);
  color: var(--ims-cyan-300);
}

.ims-section--deep .ims-topology__wrap-label:hover {
  background-color: var(--ims-cyan-400);
  color: var(--ims-navy-950);
}

/* ---- The stack --------------------------------------------------------- */

.ims-topology__list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.ims-topology__list li { margin: 0; }

/* The spine. A single line running through every node, echoing the node
   graph in the logo mark. */
.ims-topology__list::before {
  content: "";
  position: absolute;
  left: 1.35rem;
  top: 2.25rem;
  bottom: 2.25rem;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent,
    var(--ims-teal-500) 12%,
    var(--ims-teal-500) 88%,
    transparent
  );
  opacity: 0.45;
}

/*
 * A signal running down the spine, the same language as the hero graphic: the
 * stack is not a static diagram, it is something under observation. Slow and
 * low contrast so it stays peripheral.
 */
.ims-topology__list::after {
  content: "";
  position: absolute;
  left: 1.35rem;
  width: 1px;
  height: 3.5rem;
  top: 0;
  background: linear-gradient(to bottom, transparent, var(--ims-cyan-400) 50%, transparent);
  filter: drop-shadow(0 0 4px rgba(26, 199, 198, 0.7));
  pointer-events: none;
  animation: ims-spine-run 7s var(--ims-ease) infinite 1.5s;
}

@keyframes ims-spine-run {
  0%   { top: 0;    opacity: 0; }
  8%   { opacity: 0.95; }
  88%  { opacity: 0.95; }
  100% { top: 100%; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ims-topology__list::after { display: none; }
}

.ims-layer {
  display: grid;
  grid-template-columns: 2.7rem 1fr auto;
  align-items: center;
  gap: var(--ims-sp-4);
  padding: var(--ims-sp-4) var(--ims-sp-3);
  border-radius: var(--ims-r-md);
  text-decoration: none;
  color: inherit;
  position: relative;
  transition: background-color var(--ims-dur-base) var(--ims-ease),
              transform var(--ims-dur-base) var(--ims-ease-out);
}

.ims-layer + .ims-layer { margin-top: 2px; }

.ims-layer:hover {
  background-color: var(--ims-mist-100);
  transform: translateX(4px);
}

.ims-section--deep .ims-layer:hover { background-color: rgba(26, 199, 198, 0.07); }

/* The node itself. Sits on the spine. */
.ims-layer__node {
  width: 2.7rem;
  height: 2.7rem;
  display: grid;
  place-items: center;
  border-radius: var(--ims-r-sm);
  background-color: var(--ims-bg);
  border: 1px solid var(--ims-border);
  color: var(--ims-teal-600);
  position: relative;
  z-index: 1;
  transition: border-color var(--ims-dur-base) var(--ims-ease),
              color var(--ims-dur-base) var(--ims-ease),
              box-shadow var(--ims-dur-base) var(--ims-ease);
}

.ims-layer__node svg { width: 1.25rem; height: 1.25rem; }

.ims-section--deep .ims-layer__node {
  background-color: var(--ims-navy-900);
  border-color: var(--ims-line-dark);
  color: var(--ims-cyan-300);
}

.ims-layer:hover .ims-layer__node {
  border-color: var(--ims-cyan-400);
  color: var(--ims-cyan-400);
  box-shadow: var(--ims-glow);
}

.ims-layer__title {
  font-family: var(--ims-font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  font-stretch: 104%;
  letter-spacing: -0.01em;
  margin: 0 0 0.15rem;
  color: var(--ims-text);
}

.ims-layer__desc {
  font-size: var(--ims-fs-sm);
  line-height: 1.5;
  color: var(--ims-text-mid);
  margin: 0;
  max-width: 46ch;
}

.ims-layer__go {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  color: var(--ims-ink-soft);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--ims-dur-base) var(--ims-ease),
              transform var(--ims-dur-base) var(--ims-ease-out),
              color var(--ims-dur-base) var(--ims-ease);
}

.ims-layer:hover .ims-layer__go,
.ims-layer:focus-visible .ims-layer__go {
  opacity: 1;
  transform: translateX(0);
  color: var(--ims-cyan-400);
}

@media (max-width: 34rem) {
  /* The wrap label is nowrap by design so it reads as one band, but its text
     is long enough to exceed a 320px viewport once gutters are taken off.
     Let it wrap and sit inside the box rather than pushing the page wide. */
  .ims-topology__wrap-label {
    position: static;
    transform: none;
    white-space: normal;
    display: inline-flex;
    margin-bottom: var(--ims-sp-4);
    border-radius: var(--ims-r-md);
    line-height: 1.4;
  }

  .ims-topology { padding-block-start: var(--ims-sp-5); }
  .ims-topology { padding-inline: var(--ims-sp-3); }
  .ims-layer { grid-template-columns: 2.25rem 1fr; gap: var(--ims-sp-3); padding-inline: var(--ims-sp-2); }
  .ims-layer__go { display: none; }
  .ims-layer__node { width: 2.25rem; height: 2.25rem; }
  .ims-topology__list::before { left: 1.125rem; }
  .ims-layer:hover { transform: none; }
}

/* ==========================================================================
   Cards
   ========================================================================== */

.ims-card {
  display: flex;
  flex-direction: column;
  gap: var(--ims-sp-3);
  padding: var(--ims-sp-6);
  background-color: var(--ims-bg);
  border: 1px solid var(--ims-border);
  border-radius: var(--ims-r-lg);
  transition: border-color var(--ims-dur-base) var(--ims-ease),
              box-shadow var(--ims-dur-base) var(--ims-ease),
              transform var(--ims-dur-base) var(--ims-ease-out);
}

.ims-card--link { text-decoration: none; color: inherit; }

.ims-card--link:hover {
  border-color: var(--ims-teal-500);
  box-shadow: var(--ims-shadow-md);
  transform: translateY(-3px);
}

.ims-card__icon {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: var(--ims-r-sm);
  background-color: var(--ims-mist-100);
  color: var(--ims-teal-600);
}

.ims-card__icon svg { width: 1.25rem; height: 1.25rem; }
.ims-card__title { font-size: var(--ims-fs-h4); margin: 0; }
.ims-card__text { font-size: var(--ims-fs-sm); color: var(--ims-text-mid); margin: 0; }

/* ==========================================================================
   Brand strip
   Set in the mono voice as wordmarks rather than logo images: no trademark
   permissions to chase, nothing pixelated on a retina screen, and it reads
   as a specification list rather than a wall of badges.
   ========================================================================== */

.ims-brands {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ims-sp-3) var(--ims-sp-6);
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.ims-brands li { margin: 0; }

.ims-brand {
  font-family: var(--ims-font-display);
  font-size: clamp(1.125rem, 0.9rem + 1vw, 1.75rem);
  font-weight: 700;
  font-stretch: 115%;
  letter-spacing: 0.01em;
  color: var(--ims-ink-soft);
  transition: color var(--ims-dur-base) var(--ims-ease);
}

.ims-brands:hover .ims-brand { color: var(--ims-line); }
.ims-brands .ims-brand:hover { color: var(--ims-navy-800); }

.ims-section--deep .ims-brand { color: var(--ims-on-dark-soft); }
.ims-section--deep .ims-brands:hover .ims-brand { color: var(--ims-navy-700); }
.ims-section--deep .ims-brands .ims-brand:hover { color: var(--ims-cyan-300); }

/* ==========================================================================
   Forms
   ========================================================================== */

.ims-field { margin-bottom: var(--ims-sp-5); }

.ims-field__label {
  display: block;
  font-size: var(--ims-fs-sm);
  font-weight: 600;
  color: var(--ims-text);
  margin-bottom: var(--ims-sp-2);
}

.ims-field__optional {
  font-weight: 400;
  color: var(--ims-ink-soft);
  font-size: var(--ims-fs-xs);
}

.ims-field input[type="text"],
.ims-field input[type="email"],
.ims-field input[type="tel"],
.ims-field input[type="url"],
.ims-field select,
.ims-field textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  background-color: var(--ims-white);
  border: 1px solid var(--ims-border);
  border-radius: var(--ims-r-sm);
  color: var(--ims-ink);
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color var(--ims-dur-fast) var(--ims-ease),
              box-shadow var(--ims-dur-fast) var(--ims-ease);
}

.ims-field textarea { min-height: 9rem; resize: vertical; }

.ims-field input:focus,
.ims-field select:focus,
.ims-field textarea:focus {
  outline: none;
  border-color: var(--ims-cyan-400);
  box-shadow: 0 0 0 3px rgba(26, 199, 198, 0.18);
}

.ims-field input[aria-invalid="true"],
.ims-field textarea[aria-invalid="true"],
.ims-field select[aria-invalid="true"] {
  border-color: var(--ims-danger);
}

.ims-field__error {
  display: block;
  margin-top: var(--ims-sp-2);
  font-size: var(--ims-fs-sm);
  color: var(--ims-danger);
  font-weight: 500;
}

.ims-form-notice {
  padding: var(--ims-sp-4) var(--ims-sp-5);
  border-radius: var(--ims-r-md);
  margin-bottom: var(--ims-sp-6);
  font-weight: 500;
  border: 1px solid;
}

.ims-form-notice--success {
  background-color: rgba(3, 134, 158, 0.07);
  border-color: var(--ims-teal-600);
  color: var(--ims-teal-700);
}

.ims-form-notice--error {
  background-color: rgba(180, 40, 60, 0.06);
  border-color: var(--ims-danger);
  color: var(--ims-danger);
}

/* The honeypot. Off-screen rather than display:none, because some bots skip
   fields that are display:none. */
.ims-visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Contact form module bindings.

   inc/forms/ is deliberately self-contained and ships its own BEM class names
   rather than depending on this stylesheet. These rules bind those names to
   the design system so the module stays swappable: nothing here reaches into
   the PHP, and the module needs no knowledge of these tokens.
   -------------------------------------------------------------------------- */

.ims-contact-form__wrap { scroll-margin-top: 7rem; }

/* The status region. Focused programmatically after a submit, so it must have
   a visible focus treatment as well as colour. */
.ims-contact-form__status {
  padding: var(--ims-sp-4) var(--ims-sp-5);
  border-radius: var(--ims-r-md);
  margin-bottom: var(--ims-sp-6);
  font-weight: 500;
  border: 1px solid;
  border-left-width: 3px;
}

.ims-contact-form__status p { margin: 0; max-width: none; }
.ims-contact-form__status p + p { margin-top: var(--ims-sp-2); }

.ims-contact-form__status--success {
  background-color: rgba(3, 134, 158, 0.07);
  border-color: var(--ims-teal-600);
  color: var(--ims-teal-700);
}

.ims-contact-form__status--error {
  background-color: rgba(180, 40, 60, 0.06);
  border-color: var(--ims-danger);
  color: var(--ims-danger);
}

.ims-contact-form__error-summary {
  margin: var(--ims-sp-3) 0 0;
  padding-left: 1.15em;
  font-weight: 400;
}

.ims-contact-form__error-summary a { color: inherit; }

/* The submit button carries no .ims-btn class, and base.css strips native
   button chrome, so without this it renders as bare text. */
.ims-contact-form__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ims-sp-2);
  padding: 1.0625rem 2rem;
  border-radius: var(--ims-r-sm);
  background-color: var(--ims-navy-800);
  color: var(--ims-white);
  font-family: var(--ims-font-display);
  font-size: 1rem;
  font-weight: 600;
  font-stretch: 105%;
  line-height: 1.2;
  border: 1px solid transparent;
  box-shadow: var(--ims-shadow-sm);
  transition:
    background-color var(--ims-dur-base) var(--ims-ease),
    transform var(--ims-dur-base) var(--ims-ease-spring),
    box-shadow var(--ims-dur-base) var(--ims-ease);
}

.ims-contact-form__submit:hover {
  background-color: var(--ims-navy-700);
  transform: translateY(-2px);
  box-shadow: var(--ims-shadow-md);
}

.ims-contact-form__submit:active { transform: translateY(0); }

.ims-contact-form__submit[aria-disabled="true"] {
  opacity: 0.6;
  pointer-events: none;
}

.ims-field--submit { margin-bottom: 0; margin-top: var(--ims-sp-7); }

/* The module names its inputs; the element selectors above already catch
   them, but naming the class keeps specificity predictable if either side
   changes later. */
.ims-field__input { width: 100%; }

.ims-field__required { color: var(--ims-danger); margin-left: 0.15em; }

.ims-field__hint {
  display: block;
  margin-top: var(--ims-sp-1);
  margin-bottom: var(--ims-sp-2);
  font-size: var(--ims-fs-xs);
  color: var(--ims-ink-soft);
  font-weight: 400;
}

.ims-field--invalid .ims-field__label { color: var(--ims-danger); }

/* ==========================================================================
   Footer
   ========================================================================== */

.ims-footer {
  background-color: var(--ims-navy-950);
  color: var(--ims-on-dark-mid);
  padding-block: var(--ims-sp-10) var(--ims-sp-6);
  font-size: var(--ims-fs-sm);
  position: relative;
  overflow: hidden;
}

.ims-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 100% at 15% 0%, rgba(3, 134, 158, 0.16), transparent 60%),
    radial-gradient(circle, rgba(143, 227, 226, 0.09) 1px, transparent 1.5px);
  background-size: 100% 100%, 30px 30px;
  pointer-events: none;
}

.ims-footer > * { position: relative; }

/* The logo wordmark is currentColor, so one SVG serves both grounds: navy in
   the header on white, white here on navy. The teal cloud mark is unchanged
   because teal reads on both. */
.ims-footer .ims-logo { color: var(--ims-white); }

.ims-footer a { color: var(--ims-on-dark-mid); text-decoration: none; }
.ims-footer a:hover { color: var(--ims-cyan-300); }

.ims-footer__grid {
  display: grid;
  gap: var(--ims-sp-8);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  padding-bottom: var(--ims-sp-8);
  border-bottom: 1px solid var(--ims-line-dark);
}

.ims-footer__brand .ims-logo { color: var(--ims-white); margin-bottom: var(--ims-sp-4); }
.ims-footer__brand .ims-logo svg { height: 2.6rem; }

.ims-footer__heading {
  font-family: var(--ims-font-mono);
  font-size: var(--ims-fs-label);
  font-weight: 500;
  letter-spacing: var(--ims-ls-label);
  text-transform: uppercase;
  color: var(--ims-cyan-300);
  margin: 0 0 var(--ims-sp-4);
}

.ims-footer__list { list-style: none; margin: 0; padding: 0; }
.ims-footer__list li { margin-bottom: var(--ims-sp-2); }

.ims-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ims-sp-3) var(--ims-sp-5);
  justify-content: space-between;
  align-items: center;
  padding-top: var(--ims-sp-6);
  font-size: var(--ims-fs-xs);
  color: var(--ims-on-dark-soft);
}

/* Legal links. These are text, not icons; they previously inherited the
   .ims-social class by mistake and were squeezed into 2.4rem icon boxes. */
.ims-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ims-sp-2) var(--ims-sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--ims-fs-xs);
}

.ims-footer__legal li { margin: 0; }

.ims-footer__legal a {
  color: var(--ims-on-dark-soft);
  text-decoration: none;
  transition: color var(--ims-dur-fast) var(--ims-ease);
}

.ims-footer__legal a:hover { color: var(--ims-cyan-300); }

/* Studio credit. Quiet by default, brand cyan on hover: present without
   competing with the client's own footer content. */
.ims-footer__credit {
  font-family: var(--ims-font-mono);
  font-size: var(--ims-fs-xs);
  letter-spacing: 0.04em;
  color: var(--ims-on-dark-soft);
}

.ims-footer__credit a {
  color: var(--ims-on-dark-mid);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color var(--ims-dur-fast) var(--ims-ease),
              border-color var(--ims-dur-fast) var(--ims-ease);
}

.ims-footer__credit a:hover {
  color: var(--ims-cyan-300);
  border-bottom-color: var(--ims-cyan-400);
}

.ims-social {
  display: flex;
  gap: var(--ims-sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.ims-social li { margin: 0; }

.ims-social a {
  width: 2.4rem;
  height: 2.4rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--ims-line-dark);
  border-radius: var(--ims-r-sm);
  color: var(--ims-on-dark-mid);
  transition: border-color var(--ims-dur-base) var(--ims-ease),
              color var(--ims-dur-base) var(--ims-ease),
              background-color var(--ims-dur-base) var(--ims-ease);
}

.ims-social a:hover {
  border-color: var(--ims-cyan-400);
  color: var(--ims-cyan-300);
  background-color: rgba(26, 199, 198, 0.08);
}

.ims-social svg { width: 1.05rem; height: 1.05rem; }
