﻿/* ==========================================================================
   VDPL Next — Layout
   Header, mega panels, mobile drawer, footer. Structures that appear on
   every page. Page-specific layout lives in assets/css/page-*.css.
   ========================================================================== */

/* ==========================================================================
   Header
   ========================================================================== */

.c-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--c-bg) 78%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
/* Hairline appears only once scrolled, so the header floats over the hero but
   stays separated from content beneath it. Class set by motion.js. */
.c-header.is-stuck { border-bottom-color: var(--c-line-soft); }

/* Positioning context for the mega panels, so they align with the page
   container instead of with whichever trigger opened them. */
.c-header__in {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-8);
  min-height: 64px;
}

.c-brand {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-shrink: 0;
  font-size: 1.1875rem;
  font-weight: var(--w-heavy);
  letter-spacing: -.03em;
}
.c-brand__mark {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  border-radius: var(--r-sm);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-size: .8125rem;
  font-weight: var(--w-heavy);
  letter-spacing: -.02em;
}
/* Height-constrained with width:auto, so the width/height attributes in the
   markup reserve the right ratio without dictating the rendered size. */
.c-brand__logo { height: 30px; width: auto; max-width: 180px; }
.c-footer .c-brand__logo { height: 34px; }

/* The supplied logo is monochrome black, so on the dark footer it disappears.
   Inverting it is correct for a single-colour mark and costs nothing; if a
   colour logo is ever uploaded, delete this rule rather than fight it. The
   header sits on a light ground, so its mark is left alone. */
.c-footer .c-brand__logo { filter: invert(1); }

.c-header__actions {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-inline-start: auto;
}

.c-iconBtn {
  display: grid;
  place-items: center;
  width: var(--target-touch);
  height: var(--target-touch);
  border-radius: var(--r-sm);
  color: var(--c-ink-2);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.c-iconBtn:hover { background: var(--c-surface-2); color: var(--c-ink); }

/* ==========================================================================
   Primary navigation
   ========================================================================== */

.c-nav { display: flex; align-items: center; }
.c-nav__list { display: flex; align-items: center; gap: var(--s-1); }
.c-nav__item { position: static; }

.c-nav__trigger,
.c-nav__link {
  display: flex;
  align-items: center;
  gap: 5px;
  min-height: var(--target-touch);
  padding-inline: var(--s-4);
  border-radius: var(--r-sm);
  font-size: .9375rem;
  font-weight: var(--w-medium);
  letter-spacing: -.01em;
  color: var(--c-ink-2);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.c-nav__trigger:hover,
.c-nav__link:hover,
.c-nav__trigger[aria-expanded="true"] {
  color: var(--c-ink);
  background: var(--c-surface-2);
}
.c-nav__link[aria-current="page"] { color: var(--c-accent-text); }

.c-nav__chev { transition: transform var(--dur) var(--ease); }
.c-nav__trigger[aria-expanded="true"] .c-nav__chev { transform: rotate(180deg); }

/* ==========================================================================
   Mega panels
   Positioned relative to the nav item, clamped so a wide panel never pushes
   past the viewport on a narrow desktop window.
   ========================================================================== */

/* Anchored to the header container, not to the nav item.

   Centring each panel on its trigger overflowed the viewport for the first
   and last items: an 880px panel centred on a trigger 200px from the left
   edge hangs 240px off screen, and the content was simply unreachable. All
   panels now open from the same edge, which is also easier to read - the eye
   does not have to find the panel again for each menu item. */
.c-mega {
  position: absolute;
  top: calc(100% + 10px);
  /* The gutter has to be added back by hand: .c-header__in IS the .l-wrap,
     so `left: 0` resolves to the padding box edge, which is outside the
     gutter. Without this the panel sits flush against the window. */
  left: var(--gutter);
  width: min(880px, calc(100% - var(--gutter) * 2));
  padding: var(--s-6);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  box-shadow: var(--e-lg);

  opacity: 0;
  transform: translateY(-8px) scale(.985);
  transform-origin: top center;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.c-mega.is-open { opacity: 1; transform: none; }
.c-mega--narrow { width: min(90vw, 620px); }
/* Four groups need the room. 880px across four columns leaves ~190px each,
   which is narrower than the two-line descriptions want. */
.c-mega--wide { width: min(1120px, calc(100% - var(--gutter) * 2)); }

.c-mega__cols {
  display: grid;
  grid-template-columns: 1fr 1fr 250px;
  gap: var(--s-6);
}
.c-mega__cols--two { grid-template-columns: 1fr 1fr; }
/* The Capabilities panel carries four groups. Without this it fell back to the
   three-column rule above and the fourth wrapped onto a second row under the
   first column, with the rest of that row empty. This is the same bug that was
   fixed once already when a panel grew from two groups to three: the column
   COUNT has to follow the group count, in the CSS and not only in the class
   name. If a fifth group is ever added, add a rule here too. */
.c-mega__cols--four { grid-template-columns: repeat(3, 1fr) 220px; }

@media (max-width: 1180px) {
  /* Below this the four-column panel would squeeze past reading width, so it
     becomes two rows of two - deliberate and even, rather than 3 + 1. */
  .c-mega--wide { width: min(880px, calc(100% - var(--gutter) * 2)); }
  .c-mega__cols--four { grid-template-columns: 1fr 1fr; }
}

.c-mega__group { display: flex; flex-direction: column; gap: var(--s-2); }
.c-mega__label {
  font-size: var(--t-xs);
  font-weight: var(--w-bold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-ink-3);
  padding-inline: var(--s-3);
}
.c-mega__items { display: flex; flex-direction: column; gap: 1px; }

.c-mega__item {
  display: block;
  padding: var(--s-3);
  border-radius: var(--r-sm);
  transition: background var(--dur-fast) var(--ease);
}
.c-mega__item:hover { background: var(--c-surface-2); }
.c-mega__item b {
  display: block;
  font-size: .9375rem;
  font-weight: var(--w-semi);
  letter-spacing: -.012em;
}
.c-mega__item span {
  display: block;
  margin-top: 2px;
  font-size: .8125rem;
  line-height: 1.4;
  color: var(--c-ink-3);
  letter-spacing: -.004em;
}
.c-mega__item[aria-current="page"] b { color: var(--c-accent-text); }

/* The "view all" row inside a group.

   It is not a sibling of the items above it — those go to a thing you can buy,
   this goes to a listing — so it takes the accent and the arrow the site
   already uses for that job on "View all Capabilities" at the foot of the
   panel. Without the distinction it read as a fourth solution named "View all
   solutions". */
.c-mega__item--all b {
  color: var(--c-accent-text);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.c-mega__item--all b::after {
  content: "";
  width: 14px;
  height: 14px;
  background: currentColor;
  /* Same chevron as c-link__arrow, as a mask so it inherits the accent. */
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform var(--dur-fast) var(--ease);
}
.c-mega__item--all:hover b::after { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .c-mega__item--all:hover b::after { transform: none; }
}

.c-mega__promo {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-5);
  border-radius: var(--r-md);
  border: 1px solid var(--c-line-soft);
  background: linear-gradient(160deg, var(--c-surface-2), var(--c-accent-wash));
}
.c-mega__promoTitle {
  font-size: 1rem;
  font-weight: var(--w-semi);
  letter-spacing: -.016em;
  line-height: 1.3;
}
.c-mega__promo .c-link { margin-top: auto; }

/* ==========================================================================
   Mobile drawer
   ========================================================================== */

.c-burger { display: none; flex-direction: column; gap: 5px; }
.c-burger__bar {
  width: 18px; height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.c-burger[aria-expanded="true"] .c-burger__bar:first-child { transform: translateY(3.25px) rotate(45deg); }
.c-burger[aria-expanded="true"] .c-burger__bar:last-child  { transform: translateY(-3.25px) rotate(-45deg); }

/* Opens as a sheet from the right, the way an app's menu does, rather than
   fading in 8px lower than it lands. A translate across the whole width reads
   as a surface arriving; an 8px nudge reads as a repaint. Both are one
   compositor property, so the cost is the same. */
.c-drawer {
  position: fixed;
  inset: 64px 0 0;
  z-index: var(--z-drawer);
  background: var(--c-bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(100%);
  transition: transform .34s cubic-bezier(.32, .72, 0, 1);
  will-change: transform;
}
.c-drawer.is-open { transform: none; }

/* Motion is the whole point above, so with it turned off the drawer simply
   appears rather than sliding slowly - a long slide is exactly what the
   preference is asking us not to do. */
@media (prefers-reduced-motion: reduce) {
  .c-drawer { transition: none; }
}

/* --- Sections as disclosures ---------------------------------------------
   Collapsed, the menu is six rows on a 375px screen instead of 1,806px of
   list. See VDPL_Drawer_Walker for why flat stopped working. */

.c-drawer__disc { display: block; }

/* Reads as the row it now is, not as the caption it used to be. As a static
   label the uppercase --t-xs treatment was right; as the control you tap to
   reach eleven pages it left the parent visibly smaller than its own children
   and the hierarchy read backwards. Matches .c-drawer__top exactly, because
   "Capabilities" and "Work" are the same kind of thing in this list - one
   happens to expand and the other happens to navigate. */
/* Scoped through the parent rather than left as a bare class: .c-drawer__label
   is defined further down this file with the same specificity, so source order
   decided it and the uppercase 12px caption won. */
.c-drawer__disc > .c-drawer__label--disc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: var(--target-touch);
  cursor: pointer;
  list-style: none;              /* Firefox */
  border-bottom: 1px solid var(--c-line-soft);
  font-size: 1.125rem;
  font-weight: var(--w-semi);
  letter-spacing: -.014em;
  text-transform: none;
  color: var(--c-ink);
  padding-block: 0;
}
.c-drawer__label--disc::-webkit-details-marker { display: none; }

.c-drawer__chev {
  flex: none;
  color: var(--c-ink-3);
  transition: transform .24s var(--ease);
}
.c-drawer__disc[open] > .c-drawer__label--disc > .c-drawer__chev { transform: rotate(180deg); }

/* 0fr to 1fr is what animates. The row has to be able to reach zero, which is
   why the inner element carries the overflow and the outer carries nothing.

   🔑 The collapsed state lives behind `.js-acc`, a class the script adds to the
   drawer. A closed `<details>` does not render its content at all, so there is
   no start value for the row to animate from and no way to animate the close
   either - the script has to hold `open` on until the row reaches zero. If the
   0fr default were unconditional, a visitor without JavaScript would open a
   section and see nothing, which is worse than no animation. */
.c-drawer__panel { display: grid; grid-template-rows: 1fr; }
.c-drawer__panelIn { overflow: hidden; min-height: 0; }

.c-drawer.js-acc .c-drawer__panel {
  grid-template-rows: 0fr;
  transition: grid-template-rows .28s var(--ease);
}
.c-drawer.js-acc .c-drawer__disc.is-expanded > .c-drawer__panel { grid-template-rows: 1fr; }

@media (prefers-reduced-motion: reduce) {
  .c-drawer.js-acc .c-drawer__panel { transition: none; }
  .c-drawer__chev { transition: none; }
}

.c-drawer__in {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  padding: var(--s-6) var(--gutter) var(--s-16);
}
.c-drawer__list,
.c-drawer__sub { display: flex; flex-direction: column; }
.c-drawer__list { gap: var(--s-6); }
.c-drawer__section { display: flex; flex-direction: column; gap: var(--s-1); }

.c-drawer__label {
  font-size: var(--t-xs);
  font-weight: var(--w-bold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-ink-3);
  padding-block: var(--s-2);
}

/* A column heading from the desktop mega panel ("Build", "Solutions &
   products", ...), repeated inside a flattened section so an item like a
   named product still reads as one rather than sitting unlabelled among
   capabilities. One step quieter than .c-drawer__label, which names the
   whole section rather than a group inside it. */
.c-drawer__group-label {
  font-size: var(--t-xs);
  font-weight: var(--w-semi);
  color: var(--c-ink-3);
  padding-top: var(--s-3);
  margin-top: var(--s-1);
  border-top: 1px solid var(--c-line-soft);
}
.c-drawer__group-label:first-child {
  padding-top: 0;
  margin-top: 0;
  border-top: 0;
}
.c-drawer__sub a,
.c-drawer__top {
  display: flex;
  align-items: center;
  min-height: var(--target-touch);
  font-size: 1.0625rem;
  font-weight: var(--w-medium);
  letter-spacing: -.014em;
  border-bottom: 1px solid var(--c-line-soft);
}

/* A step below the section that contains them, and indented, so an open
   section reads as nested rather than as the list continuing. Without the
   indent the only thing separating a child from the next section is weight. */
.c-drawer__sub a {
  font-size: 1rem;
  color: var(--c-ink-2);
  padding-inline-start: var(--s-3);
}
.c-drawer__sub a[aria-current="page"] { color: var(--c-accent-text); }
.c-drawer__top { font-size: 1.125rem; font-weight: var(--w-semi); }
.c-drawer__sub a[aria-current="page"],
.c-drawer__top[aria-current="page"] { color: var(--c-accent-text); }

/* ==========================================================================
   Responsive
   The nav collapses at 1000px rather than a device width: that is the point
   at which four items plus the CTA stop fitting comfortably, which is a
   property of this design, not of any particular phone.
   ========================================================================== */

@media (max-width: 999px) {
  .c-nav { display: none; }
  .c-burger { display: flex; }
  .c-header__cta { display: none; }   /* the drawer carries the CTA instead */
}
@media (min-width: 1000px) {
  .c-drawer { display: none; }
}

/* ==========================================================================
   Main and footer
   ========================================================================== */

.c-main { display: block; min-height: 40vh; }

.c-footer {
  background: var(--c-invert);
  color: var(--c-invert-ink-2);
  padding-block: var(--s-24) var(--s-10);
  margin-top: var(--section);
}
.c-footer a { color: var(--c-invert-ink-2); transition: color var(--dur-fast) var(--ease); }
.c-footer a:hover { color: var(--c-invert-ink); }
.c-footer :focus-visible { outline-color: var(--c-invert-ink); }

/* Brand column plus five link columns. The brand column keeps the wider share
   because it carries the address and the social list; the link columns are
   even, because a footer column that is wider than its neighbour for no reason
   reads as a mistake. */
.c-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(5, 1fr);
  gap: var(--s-10) var(--s-6);
  padding-bottom: var(--s-16);
  border-bottom: 1px solid var(--c-invert-line);
}
@media (max-width: 1280px) { .c-footer__grid { grid-template-columns: 1fr 1fr 1fr; } }

/* Phones. Two columns is right for the link lists - one column would make the
   footer a very long scroll - but three things had to change with it:

     1. The top padding. 96px of empty dark before the first word is a lot of
        screen to spend on a footer nobody scrolled this far to admire.
     2. The row gap. At 40px between five stacked pairs of columns, the footer
        ran on well past the last thing in it.
     3. The column gap. `--s-6` left the two columns nearly touching once the
        links wrapped onto two lines each, which they do at this width. */
@media (max-width: 700px) {
  .c-footer { padding-block: var(--s-12) var(--s-8); }

  .c-footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-8) var(--s-5);
    padding-bottom: var(--s-10);
  }

  /* The brand column is the one that must not be halved: the address and the
     description need the full width to avoid breaking every second word. */
  .c-footer__brandCol { grid-column: 1 / -1; }

  /* Collapsed link columns, full width each. Two-up would put a half-width
     accordion beside another and make the headings the widest thing on the
     row; stacked, each is a full-width bar, which is what a phone expects to
     be able to tap. */
  .c-footer__col:not(.c-footer__brandCol) { grid-column: 1 / -1; gap: var(--s-2); }

  .c-footer__col > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    min-height: var(--target-touch);
    padding-block: var(--s-2);
    border-bottom: 1px solid var(--c-invert-line);
    cursor: pointer;
  }

  /* A plus that becomes a minus. Two rules and a pseudo-element rather than
     an icon file, because it is two lines. */
  .c-footer__colMark {
    position: relative;
    display: block;
    width: 12px;
    height: 12px;
    flex: none;
  }

  .c-footer__colMark::before,
  .c-footer__colMark::after {
    content: "";
    position: absolute;
    inset: 50% 0 auto 0;
    height: 1.5px;
    background: currentColor;
    transition: transform var(--dur-fast) var(--ease);
  }

  .c-footer__colMark::after { transform: rotate(90deg); }
  .c-footer__col[open] .c-footer__colMark::after { transform: rotate(0deg); }

  .c-footer__col[open] > .c-footer__links { padding-block: var(--s-2) var(--s-3); }
}

@media (prefers-reduced-motion: reduce) {
  .c-footer__colMark::before,
  .c-footer__colMark::after { transition: none; }
}

/* A <details>, but only behaving like one on a phone. Above 700px the marker
   is gone and the summary is inert, so it reads and behaves exactly as the
   heading it replaced. */
/* NOT `display: flex` on the <details> itself. Setting any display value on a
   details element makes every child a box in that formatting context, and the
   browser then lays the content out whether or not the element is open — the
   columns toggled their `open` attribute correctly and never actually
   collapsed. The details stays `block` and the flex column moves to the
   brand div and to the desktop rule below, where the element is always open
   anyway. */
.c-footer__col { display: block; }
.c-footer__brandCol { display: flex; flex-direction: column; gap: var(--s-4); }
.c-footer__col > summary { list-style: none; }
.c-footer__col > summary::-webkit-details-marker { display: none; }

@media (min-width: 701px) {
  /* Not clickable at this width. The columns ship open and stay open; a
     heading that collapses under a mouse click nobody meant to make is a
     footer that appears to lose half its links.

     The mark is hidden HERE rather than as a base rule with a mobile
     override: the mobile block sits earlier in this file, so a later base
     `display: none` of equal specificity would beat it and the plus/minus
     would never appear. */
  .c-footer__col > summary { pointer-events: none; }
  .c-footer__colMark { display: none; }

  /* Safe here: above this width the columns are always open, so nothing is
     relying on the browser hiding closed content. */
  .c-footer__col { display: flex; flex-direction: column; gap: var(--s-4); }
}
.c-footer__brandCol { grid-column: span 1; }
@media (max-width: 1280px) { .c-footer__brandCol { grid-column: 1 / -1; } }

.c-footer__heading {
  font-size: var(--t-xs);
  font-weight: var(--w-bold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-invert-ink);
}
.c-footer__links { display: flex; flex-direction: column; gap: var(--s-1); }
.c-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  padding-block: var(--s-1);
  font-size: .9375rem;
}

.c-footer__address { font-style: normal; max-width: 34ch; }

/* Two offices, so each needs naming. The label is a block above its address
   rather than an inline prefix: run together, "Corporate office Tower A, 312"
   reads as one street line. */
.c-footer__addressLabel {
  display: block;
  color: var(--c-ink-3);
  font-size: var(--t-xs);
}
.c-footer__address--reg { margin-top: var(--s-3); }

.c-footer__places { margin-top: var(--s-3); }
.c-footer__places a { margin-right: var(--s-3); }

.c-footer__social { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.c-footer__social a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  font-size: .9375rem;
}

/* Marks, not names. Five words set in a row read as another link list and
   competed with the real one below them; five marks read as one control at a
   glance, which is all a social row is for. The name stays in the markup for
   screen readers - an icon on its own is not a label.

   A 40px circle, so it clears the 24px minimum with room to spare and is
   comfortable under a thumb, which is where this row mostly gets used. */
.c-footer__socialIcon {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  border: 1px solid var(--c-invert-line);
  color: var(--c-invert-ink-2);
  transition: background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
  /* Without this, Chromium sometimes leaves the inline SVG's
     fill="currentColor" painted with the pre-hover colour after this
     element's own `color` changes - the circle flips to its filled
     background but the icon inside stays invisible until something else
     forces a repaint. Promoting the icon to its own compositing layer
     ahead of time keeps the two in sync. */
  will-change: color;
}

.c-footer__socialIcon:hover {
  background: var(--c-invert-ink);
  border-color: var(--c-invert-ink);
  /* The footer ground, so the mark reverses out of the filled circle. */
  color: var(--c-invert);
}

.c-footer__socialIcon svg { display: block; }

.c-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-8);
  padding-top: var(--s-8);
  font-size: var(--t-sm);
}
.c-footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-5); margin-inline-start: auto; }

.c-footer .c-brand__word { color: var(--c-invert-ink); }

/* ==========================================================================
   Mobile action bar
   Shown only on phones, and only between the hero and the closing CTA panel.
   See template-parts/mobile-cta.php for why this and not a bottom tab bar.
   ========================================================================== */

.c-actionbar {
  position: fixed;
  z-index: var(--z-sticky);
  inset-inline: 0;
  bottom: 0;
  display: none;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--gutter);
  /* Keeps the bar clear of the iOS home indicator and Android gesture bar. */
  padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--c-surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  border-top: 1px solid var(--c-line);
  transform: translateY(100%);
  transition: transform var(--dur) var(--ease-out);
}

.c-actionbar__cta { flex: 1; }

.c-actionbar__call {
  display: grid;
  place-items: center;
  width: var(--control-h);
  height: var(--control-h);
  flex: none;
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  color: var(--c-ink);
}

@media (max-width: 760px) {
  .c-actionbar { display: flex; }
  .c-actionbar.is-in { transform: none; }

  /* Stop the bar covering the last few lines of the footer. */
  .has-actionbar { padding-bottom: calc(var(--control-h) + var(--s-8)); }
}

@media (prefers-reduced-motion: reduce) {
  .c-actionbar { transition: none; }
}

/* ==========================================================================
   Swipeable card rails, phones only

   Below 760px a card grid becomes a horizontally snapping rail. Four stacked
   cards on a phone is roughly two thousand pixels of scrolling to see a list
   the eye could take in with two flicks.

   The rail bleeds to both screen edges rather than stopping at the gutter,
   because a card cut off at the edge is what tells the reader there is more
   to the right. A rail that ends neatly inside the margin looks finished.
   ========================================================================== */

@media (max-width: 760px) {
  .l-rail {
    grid-auto-flow: column;
    grid-auto-columns: 78%;
    grid-template-columns: none;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    /* Without this, iOS treats the touch gesture as a page scroll attempt
       instead of momentum-scrolling the rail itself - the swipe simply does
       nothing. See .h-clients__row--fill above for the same requirement. */
    -webkit-overflow-scrolling: touch;

    /* Break out of the wrap's gutter, then pay it back as scroll padding so
       the first and last cards still align with the text above them. */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    scroll-padding-inline: var(--gutter);

    /* Room for the lift-on-hover shadow, which would otherwise be clipped. */
    padding-block: var(--s-2);

    scrollbar-width: none;
  }
  .l-rail::-webkit-scrollbar { display: none; }
  .l-rail > * { scroll-snap-align: start; }

  /* A rail with one card in it is not a rail. */
  .l-rail > :only-child { grid-column: 1 / -1; }
}

/* ==========================================================================
   Cross-document view transitions

   A native crossfade between pages, which is most of what makes an app feel
   like an app. Costs nothing: no library, no client-side router, no effect on
   Core Web Vitals. Browsers without support simply navigate as before.
   ========================================================================== */

@view-transition { navigation: auto; }

/* The header and footer are on every page, so they are named and therefore
   held still while the body of the page crossfades under them. Without this
   the whole viewport fades, chrome included, which reads as a page reload. */
.c-header { view-transition-name: vdpl-header; }
.c-footer { view-transition-name: vdpl-footer; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* "View all" row at the foot of a mega panel.

   The top-level menu item is rendered as a button because it opens the panel,
   which leaves its own page - /capabilities/, /industries/ - with no route in
   from the navigation at all. This is that route. */
.c-mega__foot {
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-line-soft);
}

/* A drawer section heading that is also a link to its hub page. Underlined on
   purpose: it sits among plain labels, so it has to look different from them
   rather than only behave differently. */
.c-drawer__label--link {
  display: flex;
  align-items: center;
  min-height: var(--target-touch);
  color: var(--c-accent-text);
  text-decoration: underline;
  text-underline-offset: .25em;
}

/* A menu column with many links needs tighter rows than one with three, or
   the panel outgrows the viewport. Applied by count so the two columns in the
   Industries panel can differ without a second class. */
.c-mega__items:has(> li:nth-child(7)) .c-mega__item { padding-block: var(--s-2); }
