/* Prime Infoserv — page composition.
   Arrangements only. Nothing here introduces a new visual rule; every value
   comes from tokens.css. No dashed borders, no rules between sections, no
   monospace, no tracked-out micro-labels — see the prohibition block. */

/* ==== HERO ============================================================
   Full-bleed photograph, copy in the lower-left third. The reference's
   composition; its colour decisions refused per the annotation — a neutral
   charcoal scrim rather than an all-over dark blue, and no purple. ==== */
/* Bottom-aligned, with real air between the masthead and the headline.
   The banner should read as a photograph that happens to carry type. */
/* The copy block is lifted off the floor of the banner so there is air both
   above the headline and below the buttons — the artwork reads as a
   photograph rather than as a backdrop with type sitting on the bottom
   edge of it. */
.heroA {
  position: relative;
  min-height: min(92vh, 860px);
  display: flex;
  align-items: flex-end;
  padding-block: calc(var(--header-h) + var(--s-9)) var(--s-9);
  overflow: hidden;
  background: var(--char-950)
}

.heroA__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%
}

/* weighted to the lower-left where the copy sits, so the photograph is not
   veiled across its subject */
.heroA__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(7, 12, 24, .58) 0%, rgba(7, 12, 24, .10) 30%, rgba(7, 12, 24, .88) 100%),
    linear-gradient(90deg, rgba(7, 12, 24, .72) 0%, rgba(7, 12, 24, 0) 66%)
}

.heroA__in {
  position: relative;
  z-index: 2;
  width: 100%
}

.heroA__h {
  color: var(--white);
  max-width: 17ch
}

/* stepped down so the lead sits under the headline rather than competing
   with it — the two were within one size of each other */
.heroA__l {
  color: rgba(255, 255, 255, .82);
  margin-top: var(--s-5);
  max-width: 52ch;
  font-size: var(--fs-body);
  line-height: 1.6
}

.heroA__a {
  margin-top: var(--s-6)
}

/* ==== ROUTER =========================================================
   A plain grid in open space. The previous build drew this as a dashed
   matrix, which was the Figma-guide artefact. Separation is now space and
   a hover ground, and the only line is the one that grows under the active
   row on hover. */
.routes {
  display: grid;
  gap: var(--s-5) var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr))
}

/* No resting background. A tinted panel with a gutter around it is still a
   box, and a grid of boxes is the device the client rejected. These sit in
   open space and the ground arrives only under the pointer. */
.route a {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3) var(--s-4);
  align-content: start;
  height: 100%;
  padding: var(--s-5) var(--s-5) var(--s-6);
  margin-inline: calc(var(--s-5) * -1);
  background: transparent;
  transition: background var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease)
}

.route a::after {
  content: "";
  position: absolute;
  left: var(--s-5);
  right: var(--s-5);
  bottom: 0;
  height: 2px;
  background: var(--royal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-base) var(--ease)
}

.route a:hover {
  background: var(--ground-tint);
  transform: translateY(-2px)
}

.route a:hover::after {
  transform: scaleX(1)
}

.route__i {
  grid-row: 1/2;
  color: var(--royal)
}

.route__i svg {
  width: 22px;
  height: 22px
}

.route__t {
  font-size: 1.0625rem;
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  line-height: 1.3;
  letter-spacing: var(--tr-h3)
}

.route__d {
  grid-column: 2/3;
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

.route__g {
  grid-column: 2/3;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semi);
  color: var(--royal)
}

.route__g svg {
  width: 15px;
  height: 15px;
  transition: transform var(--dur-base) var(--ease)
}

.route a:hover .route__g svg {
  transform: translateX(4px)
}

/* P9 — the incident route is the only red surface in the body of the page */
.route--urgent .route__i,
.route--urgent .route__g {
  color: var(--urgent)
}

.route--urgent a::after {
  background: var(--urgent)
}

/* ==== THE DEEP FIELD =================================================
   The fading-text sentence. Set at h2 scale rather than display so it
   reads as a statement rather than as a headline, and light-weight so it
   sits with the rest of the type. */
.fieldline {
  font-size: clamp(1.65rem, 3.4vw, 3rem);
  line-height: 1.14;
  letter-spacing: var(--tr-h2);
  font-weight: var(--fw-light);
  color: var(--white);
  max-width: 26ch
}

.line__i {
  transition: opacity var(--dur-base) linear
}

.u-flag {
  color: rgba(255, 255, 255, .6);
  border-bottom: 1px solid currentColor;
  transition: color var(--dur-fast) var(--ease)
}

.u-flag:hover {
  color: var(--white)
}

/* ==== LIFECYCLE — HORIZONTAL ACCORDION ===============================
   Six stages side by side. One is open and carries its detail; the rest are
   closed to an icon, a number and a title. No cards, no fills, no borders —
   the only drawn element is a single grey vertical rule between columns,
   and the ground stays white.

   FLEX, NOT GRID, and the reason matters. The first version used
   `grid-auto-columns` with `grid-column: span 2` on the open item.
   `grid-column` is not an animatable property, so every change snapped: the
   columns jumped to their new widths in one frame while the panel copy
   faded, which read as a white flicker. `flex-grow` IS animatable, so the
   columns now ease to their new widths over the same duration as the copy
   and the two changes are one movement.

   `min-width:0` is load-bearing — without it a flex item refuses to shrink
   below its content width and the closed columns fight the open one. */
.acc {
  display: grid;
  gap: 0;
  align-items: start
}

/* the row reserves its open height permanently, so the block is the same
   size whichever stage is showing */
@media (min-width:1000px) {
  .acc {
    min-height: calc(var(--acc-panel) + 11.5rem)
  }
}

@media (min-width:1000px) {
  .acc {
    display: flex;
    align-items: stretch
  }

  .acc__i {
    flex: 1 1 0;
    min-width: 0;
    border-left: 1px solid var(--hair);
    padding-inline: var(--s-5) var(--s-6);
    transition: flex-grow var(--dur-slow) var(--ease)
  }

  .acc__i:first-child {
    border-left: 0;
    padding-inline-start: 0
  }

  .acc__i[data-open="true"] {
    flex-grow: 2.6
  }
}

.acc__i {
  position: relative;
  padding-block: var(--s-5) var(--s-6)
}

@media (max-width:999px) {
  .acc__i {
    border-top: 1px solid var(--hair)
  }

  .acc__i:first-child {
    border-top: 0
  }
}

.acc__b {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0;
  cursor: pointer;
  color: inherit
}

.acc__ico {
  display: block;
  color: var(--silver);
  transition: color var(--dur-base) var(--ease)
}

.acc__ico svg {
  width: 22px;
  height: 22px
}

.acc__i[data-open="true"] .acc__ico,
.acc__b:hover .acc__ico {
  color: var(--royal)
}

.acc__n {
  display: block;
  margin-top: var(--s-4);
  font-size: 1.75rem;
  font-weight: var(--fw-light);
  line-height: 1;
  letter-spacing: -.04em;
  color: var(--silver);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease)
}

.acc__i[data-open="true"] .acc__n,
.acc__b:hover .acc__n {
  color: var(--royal)
}

.acc__t {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--fs-h3);
  font-weight: var(--fw-med);
  letter-spacing: var(--tr-h3);
  color: var(--ink-strong);
  line-height: 1.25
}

/* THE PANEL OPENS TO A FIXED RESERVED HEIGHT, not to `auto`.

   Opening to `1fr` sized the panel to its own copy, and the six stages do
   not carry the same number of lines — the row height moved by 25px between
   stages. Inside a pinned section that is a layout shift: the pinned
   element changes height, ScrollTrigger recalculates its end, and the page
   jumps. Reserving one height for every stage removes the shift entirely,
   and 0 → a fixed length animates just as smoothly as 0fr → 1fr.

   --acc-panel is sized to the longest stage copy (four lines at this
   measure) plus its padding. If a stage ever needs more, raise this
   value — do not switch back to auto. */
.acc {
  --acc-panel: 7.25rem
}

.acc__p {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--dur-slow) var(--ease),
    opacity var(--dur-base) var(--ease)
}

.acc__i[data-open="true"] .acc__p {
  grid-template-rows: var(--acc-panel);
  opacity: 1;
  transition-delay: 0s, 140ms
}

.acc__p>span {
  overflow: hidden;
  display: block;
  min-width: 0
}

.acc__d {
  display: block;
  padding-top: var(--s-4);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  max-width: 40ch
}

/* the progress hairline under the row, filling as the stages advance */
.acc__rail {
  position: relative;
  height: 2px;
  background: var(--hair);
  margin-top: var(--s-6)
}

.acc__rail span {
  position: absolute;
  inset-block: 0;
  left: 0;
  right: 0;
  background: var(--royal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
  transition: transform var(--dur-base) var(--ease)
}

@media (prefers-reduced-motion:reduce) {

  .acc__i,
  .acc__p,
  .acc__rail span {
    transition: none
  }
}

/* ==== TILES ==========================================================
   The pointer-tracked highlight. Costs one custom-property write per
   pointermove and no layout. */
.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  background: radial-gradient(340px circle at var(--px, 50%) var(--py, 50%),
      rgba(46, 94, 166, .34), transparent 68%);
  transition: opacity var(--dur-base) var(--ease)
}

.tile:hover::before {
  opacity: 1
}

/* ==== PROGRESSIVE SLIDER =============================================
   P16 — THE PIN BEGINS AT THE TABS, NOT AT THE SECTION HEADING.

   The previous build pinned the whole section, heading included. That took
   the heading hostage at the top of the viewport and left only the space
   beneath it for the panel, so every industry's content was cropped. The
   fix is structural: the heading is a normal block that scrolls away, and
   only `.rail__stick` — the tab strip, the progress bar and the panels —
   is pinned. Full viewport height is then available to read the panel in.

   `.rail__stick` is the pin target; `.rail` is only the trigger, so the
   pin's start is measured from the strip rather than from the heading. */
.rail {
  background: var(--ground)
}

.rail__head {
  padding-block: var(--pad-section) 0
}

/* The strip pins BELOW the fixed masthead, not under it. The pin start is
   set from the masthead's measured height in site.js; this padding keeps
   the tabs clear of it once pinned. */
.rail__stick {
  padding-top: var(--s-5);
  padding-bottom: var(--s-7);
  background: var(--ground)
}

.rail__tabs {
  display: flex;
  gap: 0;
  overflow-x: auto;
  scrollbar-width: none
}

.rail__tabs::-webkit-scrollbar {
  display: none
}

.rail__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  white-space: nowrap;
  padding: var(--s-3) var(--s-5) var(--s-4) 0;
  margin-right: var(--s-6);
  font-size: var(--fs-small);
  font-weight: var(--fw-reg);
  color: var(--slate);
  transition: color var(--dur-base) var(--ease)
}

.rail__tab svg {
  width: 18px;
  height: 18px;
  opacity: .55;
  transition: opacity var(--dur-base) var(--ease)
}

.rail__tab:hover {
  color: var(--ink-strong)
}

.rail__tab:hover svg {
  opacity: 1
}

.rail__tab[aria-selected="true"] {
  color: var(--ink-strong);
  font-weight: var(--fw-med)
}

.rail__tab[aria-selected="true"] svg {
  opacity: 1;
  color: var(--royal)
}

.rail__bar {
  position: relative;
  height: 2px;
  background: var(--hair)
}

.rail__fill {
  position: absolute;
  inset-block: 0;
  left: 0;
  right: 0;
  background: var(--royal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform
}

.rail__panel[hidden] {
  display: none
}

/* the panel is sized so a whole industry is readable inside one viewport
   while the pin holds — which is the point of pinning it at all */
/* The industry name is not repeated here: it is already the active tab.
   The heading is the audience line instead, which says something the tab
   does not. */
.indp {
  display: grid;
  gap: var(--s-6);
  padding-top: var(--s-6);
  align-items: start
}

.indp__h {
  font-size: clamp(1.35rem, 2.2vw, 1.9rem);
  line-height: 1.18;
  letter-spacing: var(--tr-h2);
  font-weight: var(--fw-light);
  color: var(--ink-strong);
  max-width: 22ch
}

@media (min-width:900px) {
  .indp {
    grid-template-columns: 1fr .92fr;
    gap: var(--s-8)
  }
}

.indp__m img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover
}

.ticks {
  display: grid;
  gap: var(--s-3)
}

.ticks li {
  position: relative;
  padding-left: var(--s-5);
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .68em;
  width: 9px;
  height: 1px;
  background: var(--steel)
}

/* ==== CASE STUDY STACK ===============================================
   Light grey cards that stack as the reader scrolls: each one sticks at the
   top of the viewport while the next slides over it. The earlier card
   recedes very slightly so the pile reads as depth without a shadow, which
   P1 forbids — the recession is scale and brightness, not elevation.

   Every card is sticky at the same offset; the stagger comes from their
   order in the flow, which is what makes them pile rather than replace. */
.cases {
  display: grid;
  gap: var(--s-6)
}

/* The stack previously dimmed each covered card with a brightness filter,
   which put a dark wash over text the reader was still reading. The wash is
   gone. Separation now comes from a hairline, and any recession is applied
   only once the incoming card has fully covered this one. */
.casecard {
  position: sticky;
  top: calc(var(--header-h) + var(--s-4));
  background: var(--ground-tint);
  border: 1px solid var(--hair);
  padding: clamp(1.5rem, 3.2vw, 2.75rem);
  transform-origin: 50% 0;
  will-change: transform;
}

.casecard__in {
  display: grid;
  gap: var(--s-6);
  align-items: center
}

@media (min-width:880px) {
  .casecard__in {
    grid-template-columns: 1.05fr .95fr;
    gap: var(--s-8)
  }
}

.casecard__m {
  overflow: hidden;
  background: var(--white)
}

.casecard__m img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease)
}

.casecard:hover .casecard__m img {
  transform: scale(1.04)
}

.counts--inline {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s-5)
}

.counts--inline .count__n {
  font-size: clamp(2rem, 3.2vw, 2.75rem)
}

.counts--inline .count__l {
  margin-top: var(--s-3)
}

/* below the breakpoint the pile is more confusing than useful — the cards
   simply follow one another */
@media (max-width:879px) {
  .casecard {
    position: static;
    transform: none !important
  }
}

@media (prefers-reduced-motion:reduce) {
  .casecard {
    position: static;
    transform: none !important
  }
}

/* ==== PEOPLE ========================================================= */
.people {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr))
}

.person {
  overflow: hidden
}

/* 4:5 per the client. The supplied files carried a black band along the
   bottom edge; that is trimmed at source in research/process2.py rather
   than masked here, so the crop is honest. */
.person img {
  width: 100%;
  aspect-ratio: 4/5;
  object-fit: cover;
  object-position: 50% 12%;
  filter: grayscale(1) contrast(1.04);
  transition: filter var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease)
}

.person:hover img {
  filter: none;
  transform: scale(1.03)
}

.person .t3 {
  font-size: 1.0625rem
}

/* ==== CLOSER =========================================================
   Content beside furniture, so 1fr / <fixed>. The urgent column holds
   about 210px of content and is sized to it. */
.closer {
  display: grid;
  gap: var(--s-7)
}

@media (min-width:900px) {
  .closer {
    grid-template-columns: 1fr 280px;
    gap: var(--s-9)
  }
}

.closer__u {
  padding-top: var(--s-5);
  border-top: 1px solid var(--hair-deep)
}

@media (min-width:900px) {
  .closer__u {
    border-top: 0;
    border-left: 1px solid var(--hair-deep);
    padding-top: 0;
    padding-inline-start: var(--s-7)
  }
}

.closer__u .small {
  color: rgba(255, 255, 255, .72)
}

/* ==== INCIDENT WIDGET ================================================
   Sits in the closing field, not in the footer. This is the one place on
   the page where somebody already in trouble is looking for a next step,
   and keeping it here leaves the footer free of an alarm colour. It is
   also the only red on the lower half of the page (P9). */
.incident {
  padding-top: var(--s-5);
  border-top: 1px solid var(--hair-deep)
}

@media (min-width:900px) {
  .incident {
    border-top: 0;
    border-left: 1px solid var(--hair-deep);
    padding-top: 0;
    padding-inline-start: var(--s-7)
  }
}

.incident__k {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-small);
  font-weight: var(--fw-med);
  color: var(--white)
}

.incident__k svg {
  width: 18px;
  height: 18px;
  color: var(--urgent);
  flex: 0 0 auto
}

.incident__d {
  margin-top: var(--s-4);
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, .72)
}

.incident__n {
  margin-top: var(--s-5)
}

.incident__n a {
  font-size: 1.375rem;
  font-weight: var(--fw-light);
  color: var(--white);
  letter-spacing: -.015em;
  border-bottom: 1px solid rgba(255, 255, 255, .28);
  padding-bottom: 3px;
  transition: border-color var(--dur-base) var(--ease)
}

.incident__n a:hover {
  border-bottom-color: var(--white)
}

.incident__m {
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  color: rgba(255, 255, 255, .6)
}

/* ==== PRIME UPDATES ==================================================
   Two panes of equal height: a stack of landscape blog cards on the left,
   and one portrait gallery card on the right that cycles through the
   client's event photography. The right card is a single tall object rather
   than a grid, so the eye is not asked to compare four events at once —
   it shows the most recent and offers the rest behind one link. */
.updates {
  display: grid;
  gap: var(--s-7)
}

@media (min-width:960px) {
  .updates {
    grid-template-columns: 1fr 360px;
    gap: var(--s-8);
    align-items: stretch
  }
}

/* --- left: blog --- */
.updates__blog {
  display: flex;
  flex-direction: column
}

.blist {
  display: grid;
  gap: var(--s-5);
  flex: 1
}

.bitem {
  display: grid;
  gap: var(--s-5);
  align-items: start;
  grid-template-columns: 1fr;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--hair);
  transition: padding-inline-start var(--dur-base) var(--ease)
}

@media (min-width:560px) {
  .bitem {
    grid-template-columns: 196px 1fr
  }
}

.bitem:last-child {
  border-bottom: 0;
  padding-bottom: 0
}

.bitem:hover {
  padding-inline-start: var(--s-3)
}

.bitem__m {
  overflow: hidden;
  background: var(--white)
}

.bitem__m img {
  width: 100%;
  aspect-ratio: 3/2;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease)
}

.bitem:hover .bitem__m img {
  transform: scale(1.05)
}

.bitem__meta {
  display: flex;
  gap: var(--s-4);
  align-items: baseline;
  font-size: var(--fs-micro)
}

.bitem__cat {
  color: var(--royal);
  font-weight: var(--fw-med)
}

.bitem__date {
  color: var(--ink-soft)
}

.bitem__t {
  display: block;
  margin-top: var(--s-3);
  font-size: 1.0625rem;
  font-weight: var(--fw-med);
  line-height: 1.32;
  letter-spacing: var(--tr-h3);
  color: var(--ink-strong)
}

.bitem__go {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semi);
  color: var(--royal)
}

.bitem__go svg {
  width: 14px;
  height: 14px;
  transition: transform var(--dur-base) var(--ease)
}

.bitem:hover .bitem__go svg {
  transform: translateX(4px)
}

/* --- right: the gallery card --- */
.gcard {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 420px;
  background: var(--char-950);
  overflow: hidden
}

.gcard__slides {
  position: absolute;
  inset: 0
}

.gcard__s {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease)
}

.gcard__s[data-on="true"] {
  opacity: 1
}

.gcard__s img {
  width: 100%;
  height: 100%;
  object-fit: cover
}

.gcard::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 34%, rgba(10, 11, 12, .34) 58%, rgba(10, 11, 12, .92) 100%)
}

.gcard__b {
  position: relative;
  z-index: 2;
  margin-top: auto;
  padding: var(--s-6)
}

.gcard__k {
  display: block;
  font-size: var(--fs-micro);
  color: rgba(255, 255, 255, .72)
}

.gcard__t {
  display: block;
  margin-top: var(--s-3);
  font-size: 1.1875rem;
  font-weight: var(--fw-med);
  line-height: 1.28;
  color: var(--white)
}

.gcard__go {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-5);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semi);
  color: var(--white)
}

.gcard__go svg {
  width: 14px;
  height: 14px;
  transition: transform var(--dur-base) var(--ease)
}

.gcard__go:hover svg {
  transform: translateX(4px)
}

.gcard__dots {
  position: absolute;
  z-index: 3;
  right: var(--s-6);
  top: var(--s-6);
  display: flex;
  gap: 6px
}

.gcard__dot {
  width: 20px;
  height: 2px;
  padding: 0;
  background: rgba(255, 255, 255, .4);
  transition: background var(--dur-base) var(--ease)
}

.gcard__dot[aria-current="true"] {
  background: var(--white)
}

.mt-9 {
  margin-top: var(--s-9)
}

/* the gallery card's captions cross-fade with their slides */
.gcard__cap {
  display: none
}

.gcard__cap[data-on="true"] {
  display: block
}

/* the pinned block for the lifecycle — the heading sits outside it and
   scrolls away first, per P16 */
.acc__stick {
  background: var(--ground);
  padding-block: var(--s-4) var(--s-6)
}

/* ======================================================================
   INNER PAGES
   ====================================================================== */

/* ---- the unified banner. One per page, and it spends one of the two
   permitted deep fields — which is why inner pages close on a light band. */
.pbanner {
  padding-block: calc(var(--header-h) + var(--s-9)) var(--s-9)
}

.pbanner__h {
  font-size: clamp(2.1rem, 4.2vw, 3.9rem);
  line-height: 1.04;
  letter-spacing: var(--tr-display);
  font-weight: var(--fw-light);
  color: var(--white);
  margin-top: var(--s-5);
  max-width: 19ch
}

.pbanner__h--wide {
  max-width: 26ch
}

.pbanner__b {
  margin-top: var(--s-5);
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: rgba(255, 255, 255, .78);
  max-width: 56ch
}

.pbanner__b p {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit
}

.pbanner__b p+p {
  margin-top: var(--s-3)
}

.pbanner__b strong,
.pbanner__b b {
  color: var(--white);
  font-weight: var(--fw-med)
}

.pbanner__b em,
.pbanner__b i {
  font-style: italic
}

.pbanner__b a {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 2px
}

.pbanner__b a:hover {
  opacity: .85
}

.pbanner__b ul,
.pbanner__b ol {
  margin-top: var(--s-3);
  padding-left: var(--s-5);
  color: inherit
}

.pbanner__b li {
  margin-top: var(--s-1);
  font-size: inherit;
  line-height: inherit
}

.crumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  font-size: var(--fs-micro);
  color: rgba(255, 255, 255, .6)
}

.crumb li+li::before {
  content: "/";
  margin-inline-end: var(--s-3);
  opacity: .5
}

.crumb a {
  color: rgba(255, 255, 255, .72);
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease)
}

.crumb a:hover {
  color: var(--white);
  border-bottom-color: rgba(255, 255, 255, .5)
}

.crumb [aria-current] {
  color: var(--white)
}

/* ---- the shared closing band ---- */
.closeband {
  display: grid;
  gap: var(--s-7)
}

@media (min-width:900px) {
  .closeband {
    grid-template-columns: 1.35fr 320px;
    gap: var(--s-9);
    align-items: start
  }
}

.closeband__a .hotline {
  border-bottom: 1px solid currentColor
}

/* ---- SERVICES LEDGER ------------------------------------------------
   Three content columns of unequal weight. Divided by a hairline between
   rows, never by a card. */
.svclist {
  display: grid;
  gap: 0
}

.svc {
  display: grid;
  gap: var(--s-6);
  padding-block: var(--s-8);
  border-top: 1px solid var(--hair);
  align-items: start
}

.svc:first-child {
  border-top: 0;
  padding-top: 0
}

@media (min-width:1000px) {
  .svc {
    grid-template-columns: 1fr 1.15fr 210px;
    gap: var(--s-8)
  }
}

.svc__ico {
  display: block;
  color: var(--royal)
}

.svc__ico svg {
  width: 26px;
  height: 26px
}

.svc__a .t3 a {
  transition: color var(--dur-fast) var(--ease)
}

.svc__a .t3 a:hover {
  color: var(--royal)
}

.svc__b p {
  color: var(--ink-soft);
  font-size: var(--fs-small);
  line-height: 1.6
}

.svc__desc p {
  color: var(--ink-soft);
  font-size: var(--fs-small);
  line-height: 1.6;
  margin: 0
}

.svc__desc p+p {
  margin-top: var(--s-3)
}

.svc__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2)
}

.svc__tags a {
  display: inline-block;
  padding: 5px 10px;
  background: var(--ground-tint);
  font-size: var(--fs-micro);
  color: var(--ink-strong);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease)
}

.svc__tags a:hover {
  background: var(--navy);
  color: var(--white)
}

/* ---- DOCUMENT LAYOUT (service-detail) -------------------------------
   Content beside furniture, so 1fr / <fixed>. The aside holds about
   230px of content and is sized to it, never to a grid fraction. */
.doc {
  display: grid;
  gap: var(--s-8)
}

@media (min-width:1000px) {
  .doc {
    grid-template-columns: 1fr 260px;
    gap: var(--s-9)
  }
}

.doc__s+.doc__s {
  margin-top: var(--s-9);
  padding-top: var(--s-8);
  border-top: 1px solid var(--hair)
}

.doc__body p {
  max-width: 68ch
}

.doc__h4 {
  font-size: 1rem;
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  letter-spacing: var(--tr-h3)
}

.doc__side {
  width: 100%
}

@media (min-width:1000px) {
  .doc__side {
    width: 260px
  }

  .doc__stick {
    position: sticky;
    top: calc(var(--header-h) + var(--s-6))
  }
}

.toc li {
  padding-block: 6px
}

.toc a {
  font-size: var(--fs-small);
  color: var(--ink-soft);
  border-left: 2px solid var(--hair);
  padding-left: var(--s-4);
  display: block;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease)
}

.toc a:hover {
  color: var(--royal);
  border-left-color: var(--royal)
}

.doc__cta {
  background: var(--ground-tint);
  padding: var(--s-5)
}

/* Blog sidebar category index (article page): name on the left, published-post count
   on the right. The list is capped and scrolls on its own because the site can carry
   ~50 categories — taller than the viewport, which would otherwise make the sticky
   sidebar impossible to scroll past and push the CTA below out of reach. */
.toc--counts {
  max-height: min(48vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: var(--s-3)
}

/* Count sits inline directly after the name (not right-aligned) so a long name that
   wraps keeps its number attached to it rather than stranded on the first line. */
.toc--counts a {
  display: block
}

.toc--counts .toc__count {
  color: var(--royal);
  font-variant-numeric: tabular-nums;
  white-space: nowrap
}

.toc--counts a[aria-current="true"] {
  color: var(--royal);
  border-left-color: var(--royal);
  font-weight: var(--fw-med)
}

.toc--counts::-webkit-scrollbar {
  width: 6px
}

.toc--counts::-webkit-scrollbar-thumb {
  background: var(--hair);
  border-radius: 3px
}


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

@media (min-width:620px) {
  .scope {
    grid-template-columns: repeat(2, 1fr)
  }
}

.scope p {
  margin-top: var(--s-3);
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

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

.phases li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-5);
  align-items: start
}

.phases__n {
  font-size: 1.5rem;
  font-weight: var(--fw-light);
  color: var(--silver);
  font-variant-numeric: tabular-nums;
  line-height: 1
}

.phases p {
  margin-top: var(--s-3);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  max-width: 56ch
}

@media (min-width:900px) {
  .phases--wide {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-7) var(--s-8)
  }
}

/* ---- CONVERSION LAYOUT (solution-detail) ---------------------------- */
.facts {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr))
}

.facts dt {
  font-size: var(--fs-micro);
  color: var(--ink-soft)
}

.facts dd {
  margin: var(--s-3) 0 0;
  font-size: 1.125rem;
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  line-height: 1.3
}

.twocol {
  display: grid;
  gap: var(--s-8)
}

@media (min-width:960px) {
  .twocol {
    grid-template-columns: 1.25fr 1fr;
    gap: var(--s-9);
    align-items: start
  }
}

/* ---- RICH TEXT / PROSE (pages, blogs, solutions, industries, services) --- */
.prose {
  color: var(--ink-soft);
  font-size: var(--fs-body);
  line-height: var(--lh-body, 1.6)
}

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

/* Headings scale in rich text (balanced downward hierarchy) */
.prose h1 {
  margin-top: var(--s-8);
  margin-bottom: var(--s-4);
  font-size: clamp(2.2rem, 4.2vw, 3.5rem);
  font-weight: var(--fw-light);
  line-height: 1.1;
  letter-spacing: var(--tr-display);
  color: var(--ink-strong);
  text-wrap: balance;
  max-width: 68ch
}

.prose h2 {
  margin-top: var(--s-7);
  margin-bottom: var(--s-4);
  font-size: clamp(1.85rem, 3.6vw, 2.8rem);
  font-weight: var(--fw-light);
  line-height: 1.15;
  letter-spacing: var(--tr-h2);
  color: var(--ink-strong);
  text-wrap: balance;
  max-width: 68ch
}

.prose h3 {
  margin-top: var(--s-6);
  margin-bottom: var(--s-3);
  font-size: clamp(1.4rem, 2.5vw, 1.85rem);
  font-weight: var(--fw-med);
  line-height: 1.25;
  letter-spacing: var(--tr-h3);
  color: var(--ink-strong);
  max-width: 68ch
}

.prose h4 {
  margin-top: var(--s-5);
  margin-bottom: var(--s-3);
  font-size: 1.2rem;
  font-weight: var(--fw-med);
  line-height: 1.35;
  letter-spacing: var(--tr-h3);
  color: var(--ink-strong);
  max-width: 68ch
}

.prose h5 {
  margin-top: var(--s-4);
  margin-bottom: var(--s-2);
  font-size: 1.0625rem;
  font-weight: var(--fw-semi);
  line-height: 1.4;
  color: var(--ink-strong);
  max-width: 68ch
}

.prose h6 {
  margin-top: var(--s-4);
  margin-bottom: var(--s-2);
  font-size: var(--fs-small, 0.9375rem);
  font-weight: var(--fw-semi);
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--slate);
  max-width: 68ch
}

/* Paragraphs & inline typography */
.prose p {
  margin-top: var(--s-5);
  margin-bottom: 0;
  color: var(--ink-soft);
  font-size: var(--fs-body);
  line-height: var(--lh-body, 1.6);
  max-width: 68ch
}

.prose p+p {
  margin-top: var(--s-5)
}

.prose h1+p,
.prose h2+p,
.prose h3+p,
.prose h4+p,
.prose h5+p,
.prose h6+p,
.prose h1+p.mt-5,
.prose h2+p.mt-5,
.prose h3+p.mt-5,
.prose h4+p.mt-5,
.prose h5+p.mt-5,
.prose h6+p.mt-5 {
  margin-top: 0 !important
}

.prose p.lead {
  font-size: var(--fs-body);
  line-height: var(--lh-body, 1.6)
}

.prose strong,
.prose b {
  color: var(--ink-strong);
  font-weight: var(--fw-med)
}

.prose em,
.prose i {
  font-style: italic
}

.prose a {
  color: var(--royal);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--dur-fast) var(--ease)
}

.prose a:hover {
  color: var(--navy)
}

/* Lists */
.prose ul,
.prose ol {
  margin-top: var(--s-5);
  margin-bottom: 0;
  display: grid;
  gap: var(--s-3);
  max-width: 68ch
}

.prose h1+ul,
.prose h2+ul,
.prose h3+ul,
.prose h4+ul,
.prose h5+ul,
.prose h6+ul,
.prose h1+ol,
.prose h2+ol,
.prose h3+ol,
.prose h4+ol,
.prose h5+ol,
.prose h6+ol {
  margin-top: 0
}

.prose ul {
  list-style: none
}

.prose ul li {
  position: relative;
  padding-left: var(--s-5);
  color: var(--ink-soft);
  font-size: var(--fs-body);
  line-height: 1.55
}

.prose ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .68em;
  width: 9px;
  height: 1px;
  background: var(--royal)
}

.prose ol {
  list-style: none;
  counter-reset: prose-ol
}

.prose ol li {
  position: relative;
  padding-left: var(--s-6);
  color: var(--ink-soft);
  font-size: var(--fs-body);
  line-height: 1.55;
  counter-increment: prose-ol
}

.prose ol li::before {
  content: counter(prose-ol) ".";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--royal);
  font-weight: var(--fw-med);
  font-variant-numeric: tabular-nums
}

.prose ul ul,
.prose ul ol,
.prose ol ul,
.prose ol ol {
  margin-top: var(--s-2)
}

/* Blockquotes, media, code, tables */
.prose blockquote {
  margin: var(--s-6) 0;
  padding-left: var(--s-5);
  border-left: 2px solid var(--royal);
  color: var(--ink-strong);
  font-size: var(--fs-lead);
  font-weight: var(--fw-light);
  max-width: 58ch;
  line-height: 1.55
}

.prose blockquote p {
  font-size: inherit;
  color: inherit;
  line-height: inherit;
  margin-top: var(--s-3)
}

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

.prose img {
  display: block;
  max-width: 100%;
  height: auto;
  margin-block: var(--s-6);
  border-radius: 2px
}

.prose hr {
  border: 0;
  border-top: 1px solid var(--hair);
  margin-block: var(--s-7)
}

.prose code {
  font-size: .9em;
  background: var(--ground-tint);
  padding: .15em .4em;
  border-radius: 2px;
  font-family: monospace
}

.prose pre {
  background: var(--ground-tint);
  padding: var(--s-5);
  overflow-x: auto;
  margin-block: var(--s-6);
  border-radius: 4px
}

.prose pre code {
  background: none;
  padding: 0;
  font-size: var(--fs-small)
}

.prose table,
.doc__s table {
  width: 100%;
  border-collapse: collapse;
  margin-block: var(--s-6);
  font-size: var(--fs-small)
}

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

.prose th,
.doc__s th {
  background: var(--ground-tint);
  font-weight: var(--fw-med);
  color: var(--ink-strong)
}

.prose tr:nth-child(even) td,
.doc__s tr:nth-child(even) td {
  background: rgba(0, 0, 0, 0.015)
}

/* Direct content fallback inside .doc__s */
.doc__s>p {
  color: var(--ink-soft);
  font-size: var(--fs-body);
  line-height: var(--lh-body, 1.6);
  max-width: 68ch;
  margin-top: var(--s-5);
  margin-bottom: 0
}

.doc__s>.t2+p,
.doc__s>.t3+p {
  margin-top: var(--s-5)
}

.doc__s>ul,
.doc__s>ol {
  margin-top: var(--s-5);
  max-width: 68ch
}

.evidence {
  background: var(--ground-tint);
  padding: var(--s-6)
}

.faq details {
  border-top: 1px solid var(--hair);
  padding-block: var(--s-4)
}

.faq details:last-child {
  border-bottom: 1px solid var(--hair)
}

.faq summary {
  cursor: pointer;
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  font-size: var(--fs-small);
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  align-items: center
}

.faq summary::-webkit-details-marker {
  display: none
}

.faq summary::after {
  content: "+";
  color: var(--royal);
  font-size: 1.125rem;
  line-height: 1
}

.faq details[open] summary::after {
  content: "\2212"
}

.faq p {
  margin-top: var(--s-4);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  max-width: 62ch
}

/* Answer body for CMS-authored FAQs (article FAQ Schema): the stored answer may be plain
   text or contain formatting tags, so the wrapper carries the type rather than relying on
   a <p> being present. Nested paragraphs/lists inherit from .faq p / .prose above. */
.faq__a {
  margin-top: var(--s-4);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  max-width: 62ch
}

.faq__a>p:first-child {
  margin-top: 0
}

.faq__a ul,
.faq__a ol {
  margin-top: var(--s-4);
  padding-inline-start: var(--s-6)
}

.faq__a li {
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

/* ---- FORMS --------------------------------------------------------- */
.formband {
  display: grid;
  gap: var(--s-8)
}

@media (min-width:900px) {
  .formband {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-9);
    align-items: start
  }
}

/* Google's embed code carries a fixed width/height (e.g. 600x450) meant for a static page,
   not a grid column — left as-is it overflows narrower viewports instead of filling the
   column. Force it back to a fluid, on-brand box regardless of the attributes on the tag. */
.formband__map {
  margin-top: var(--s-6)
}

.formband__map iframe {
  display: block;
  width: 100%;
  height: 320px;
  border: 0
}

.f {
  display: block
}

.f+.f {
  margin-top: var(--s-5)
}

.f label {
  display: block;
  font-size: var(--fs-micro);
  color: var(--ink-soft);
  margin-bottom: var(--s-2)
}

.f input,
.f textarea,
.f select {
  width: 100%;
  font: inherit;
  font-size: var(--fs-small);
  color: var(--ink-strong);
  background: var(--white);
  border: 1px solid var(--silver);
  border-radius: var(--r-none);
  padding: .7rem .85rem;
  transition: border-color var(--dur-fast) var(--ease)
}

.f input:focus,
.f textarea:focus,
.f select:focus {
  outline: none;
  border-color: var(--royal)
}

.f textarea {
  resize: vertical
}

/* Multi-select (Zoho "Service Interest" on the contact form) — same box as a single select,
   but tall enough to show several options, with the site accent on picked rows. */
.f select[multiple] {
  padding: .35rem;
  min-height: 9.5rem
}

.f select[multiple] option {
  padding: .35rem .5rem
}

.f select[multiple] option:checked {
  background: var(--royal) linear-gradient(0deg, var(--royal), var(--royal));
  color: var(--white)
}

.f select+.micro {
  display: block;
  margin-top: var(--s-2)
}

.f input.is-invalid,
.f textarea.is-invalid,
.f select.is-invalid {
  border-color: var(--red)
}

.field-error {
  display: none;
  font-size: var(--fs-micro);
  color: var(--red);
  margin-top: var(--s-2)
}

.field-error.is-visible {
  display: block
}

/* ---- INDUSTRY ------------------------------------------------------- */
.oblist {
  display: grid;
  gap: 0
}

.oblist article {
  padding-block: var(--s-5);
  border-top: 1px solid var(--hair)
}

.oblist article p {
  max-width: 70ch
}

@media (min-width:900px) {
  .oblist {
    grid-template-columns: repeat(2, 1fr);
    gap: 0 var(--s-8)
  }
}

.industryfig img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover
}

/* ---- WHY PRIME: anchored proof register ----------------------------- */
.jump {
  background: var(--ground-tint);
  border-bottom: 1px solid var(--hair);
  position: sticky;
  top: var(--header-h);
  z-index: 40
}

.jump ul {
  display: flex;
  gap: var(--s-6);
  overflow-x: auto;
  scrollbar-width: none;
  padding-block: var(--s-4)
}

.jump ul::-webkit-scrollbar {
  display: none
}

.jump a {
  white-space: nowrap;
  font-size: var(--fs-small);
  color: var(--ink-soft);
  transition: color var(--dur-fast) var(--ease)
}

.jump a:hover {
  color: var(--royal)
}

.reg__ico {
  display: block;
  color: var(--royal)
}

.reg__ico svg {
  width: 26px;
  height: 26px
}

/* ---- CARD GRIDS ----------------------------------------------------- */
.cgrid,
.pgrid,
.evgrid {
  display: grid;
  gap: var(--s-7) var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))
}

.ccard__m,
.pcard__m,
.evcard__m,
.galcard__m {
  display: block;
  overflow: hidden;
  position: relative
}

.ccard__m img,
.evcard__m img,
.galcard__m img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease)
}

.pcard__m img {
  width: 100%;
  aspect-ratio: 3/1;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease)
}

.ccard:hover .ccard__m img,
.pcard:hover .pcard__m img,
.evcard:hover .evcard__m img,
.galcard:hover .galcard__m img {
  transform: scale(1.05)
}

.ccard .t3 a,
.pcard .t3 a,
.evcard .t3 a,
.galcard .t3 a {
  transition: color var(--dur-fast) var(--ease)
}

.ccard .t3 a:hover,
.pcard .t3 a:hover,
.evcard .t3 a:hover,
.galcard .t3 a:hover {
  color: var(--royal)
}

.pcard__meta {
  display: flex;
  gap: var(--s-4);
  align-items: baseline;
  margin-top: var(--s-4);
  font-size: var(--fs-micro)
}

.artmeta {
  display: flex;
  gap: var(--s-4);
  font-size: var(--fs-micro)
}

.artfig img {
  width: 100%;
  height: auto
}

/* ---- CHIPS ---------------------------------------------------------- */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2)
}

.blog-category-filter {
  display: flex;
  align-items: end;
  gap: var(--s-4);
  max-width: 31rem
}

.blog-category-filter__label {
  display: block;
  flex: 0 0 auto;
  margin-bottom: .7rem;
  color: var(--ink-soft);
  font-size: var(--fs-micro);
  font-weight: var(--fw-med);
  letter-spacing: .08em;
  text-transform: uppercase
}

.blog-category-filter__control {
  position: relative;
  flex: 1;
  min-width: 16rem
}

.blog-category-filter__control::after {
  content: '';
  position: absolute;
  top: 50%;
  right: 1rem;
  width: .55rem;
  height: .55rem;
  border-right: 2px solid var(--royal);
  border-bottom: 2px solid var(--royal);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none
}

.blog-category-filter__select {
  width: 100%;
  height: 3.15rem;
  appearance: none;
  padding: 0 3rem 0 1rem;
  border: 1px solid var(--hair);
  border-radius: 0;
  background: var(--white);
  color: var(--ink-strong);
  font: inherit;
  font-size: var(--fs-small);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease)
}

.blog-category-filter__select:hover {
  border-color: var(--royal)
}

.blog-category-filter__select:focus-visible {
  outline: 0;
  border-color: var(--royal);
  box-shadow: 0 0 0 3px rgba(46, 94, 166, .16)
}

.blog-category-filter__submit {
  height: 3.15rem;
  padding: 0 var(--s-4);
  border: 0;
  background: var(--navy);
  color: var(--white);
  font: inherit;
  font-size: var(--fs-small);
  cursor: pointer
}

@media (max-width:560px) {
  .blog-category-filter {
    display: block;
    max-width: none
  }

  .blog-category-filter__label {
    margin-bottom: var(--s-2)
  }

  .blog-category-filter__control {
    min-width: 0
  }

  .blog-category-filter__select {
    height: 3.35rem;
    font-size: 1rem
  }
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding-top: var(--s-6);
  border-top: 1px solid var(--hair)
}

.pagination__link {
  display: inline-flex;
  min-width: 2.65rem;
  height: 2.65rem;
  align-items: center;
  justify-content: center;
  padding: 0 var(--s-3);
  border: 1px solid var(--hair);
  background: var(--white);
  color: var(--ink-strong);
  text-decoration: none;
  font-size: var(--fs-small);
  font-weight: var(--fw-med);
  line-height: 1;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease)
}

.pagination__link--previous,
.pagination__link--next {
  min-width: 5.8rem;
  color: var(--royal)
}

.pagination__link:hover {
  border-color: var(--royal);
  background: var(--off);
  color: var(--navy);
  transform: translateY(-2px)
}

.pagination__link:focus-visible {
  outline: 2px solid var(--royal);
  outline-offset: 3px;
  border-color: var(--royal)
}

.pagination__link--current {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--white);
  box-shadow: inset 0 -3px 0 var(--royal);
  pointer-events: none
}

.pagination__ellipsis {
  display: inline-flex;
  width: 2.1rem;
  height: 2.65rem;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  font-size: 1.1rem;
  letter-spacing: .08em
}

@media (max-width:560px) {
  .pagination {
    gap: var(--s-2) 6px;
    justify-content: stretch
  }

  .pagination__link--previous,
  .pagination__link--next {
    flex: 1 1 calc(50% - 6px);
    min-width: 0
  }

  .pagination__link--page {
    min-width: 2.4rem;
    height: 2.4rem
  }

  .pagination__ellipsis {
    width: 1.25rem;
    height: 2.4rem
  }
}

.chip {
  padding: 7px 14px;
  font-size: var(--fs-micro);
  background: var(--ground-tint);
  color: var(--ink-strong);
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease)
}

.chip:hover {
  background: var(--silver)
}

.chip--on {
  background: var(--navy);
  color: var(--white)
}

/* ---- OFFICES / ROLES ------------------------------------------------ */
.officegrid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr))
}

.officegrid li {
  padding-top: var(--s-5);
  border-top: 1px solid var(--hair)
}

.rolelist {
  display: grid;
  gap: 0
}

.role {
  border-top: 1px solid var(--hair)
}

.rolelist li:last-child .role {
  border-bottom: 1px solid var(--hair)
}

.role a {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-5) var(--s-5) var(--s-5) 0;
  transition: padding-inline-start var(--dur-base) var(--ease), background var(--dur-base) var(--ease)
}

.role a:hover {
  padding-inline-start: var(--s-4);
  background: var(--white)
}

@media (min-width:860px) {
  .role a {
    grid-template-columns: 1.1fr .8fr 1.4fr auto;
    align-items: baseline;
    gap: var(--s-5)
  }
}

.role__t {
  font-size: 1.0625rem;
  font-weight: var(--fw-med);
  color: var(--ink-strong)
}

.role__m {
  font-size: var(--fs-micro);
  color: var(--royal)
}

.role__d {
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

.role__g {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semi);
  color: var(--royal)
}

.role__g svg {
  width: 14px;
  height: 14px;
  transition: transform var(--dur-base) var(--ease)
}

.role a:hover .role__g svg {
  transform: translateX(4px)
}

/* ---- CONTACT ROUTES ------------------------------------------------- */
.droutes {
  display: grid;
  gap: var(--s-5) var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))
}

.droutes a {
  display: grid;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-5) var(--s-6);
  margin-inline: calc(var(--s-5) * -1);
  align-content: start;
  height: 100%;
  position: relative;
  transition: background var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease)
}

.droutes a::after {
  content: "";
  position: absolute;
  left: var(--s-5);
  right: var(--s-5);
  bottom: 0;
  height: 2px;
  background: var(--royal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-base) var(--ease)
}

.droutes a:hover {
  background: var(--ground-tint);
  transform: translateY(-2px)
}

.droutes a:hover::after {
  transform: scaleX(1)
}

/* ---- INCIDENT RESPONSE — the exception page ------------------------- */
/* no rule under it — the section below sits on the tint, so the ground
   change does the dividing (P4) */
.irhero {
  background: var(--ground);
  padding-block: calc(var(--header-h) + var(--s-9)) var(--s-9)
}

.ir__k {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--urgent);
  font-size: var(--fs-small);
  font-weight: var(--fw-med)
}

.ir__k svg {
  width: 20px;
  height: 20px
}

.ir__h {
  font-size: clamp(2.1rem, 4.4vw, 4rem);
  line-height: 1.04;
  font-weight: var(--fw-light);
  letter-spacing: var(--tr-display);
  color: var(--ink-strong);
  margin-top: var(--s-5);
  max-width: 18ch
}

.ir__n {
  margin-top: var(--s-7)
}

.ir__n a {
  font-size: clamp(2rem, 4vw, 3.25rem);
  font-weight: var(--fw-light);
  letter-spacing: -.02em;
  color: var(--urgent);
  font-variant-numeric: tabular-nums;
  border-bottom: 2px solid transparent;
  transition: border-color var(--dur-base) var(--ease)
}

.ir__n a:hover {
  border-bottom-color: var(--urgent)
}

.ir__m {
  margin-top: var(--s-4);
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

/* ======================================================================
   RESTORED RULES
   Written for a homepage variant that was later discarded, and removed
   with it — but the industries, solutions and events templates still used
   them, so those three pages had been rendering unstyled. Nothing errored;
   the per-page gates passed, because unstyled content still has one h1 and
   no overflow. Caught by research/orphan_classes.py, now part of the build.
   ====================================================================== */

/* ---- INDUSTRY MATRIX (industries.html) ------------------------------ */
.indgrid {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--hair);
  grid-template-columns: 1fr
}

@media (min-width:620px) {
  .indgrid {
    grid-template-columns: repeat(2, 1fr);
    border-left: 1px solid var(--hair)
  }
}

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

.indcell {
  border-bottom: 1px solid var(--hair);
  border-right: 1px solid var(--hair)
}

.indcell a {
  display: block;
  padding: var(--s-5) var(--s-5) var(--s-6);
  height: 100%;
  transition: background var(--dur-base) var(--ease)
}

.indcell a:hover {
  background: var(--ground-tint)
}

.indcell__i {
  color: var(--royal);
  display: block
}

.indcell__i svg {
  width: 22px;
  height: 22px
}

.indcell__n {
  display: block;
  margin-top: var(--s-4);
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  font-size: 1.0625rem;
  line-height: 1.3;
  letter-spacing: var(--tr-h3)
}

.indcell__r {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  letter-spacing: .02em;
  color: var(--slate)
}

.indcell__w {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

/* ---- OBLIGATIONS TABLE (solutions.html) -----------------------------
   position:relative is load-bearing — the hidden column header is
   absolutely positioned and escapes the scroll container without it. */
.mtxwrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  position: relative
}

.mtx {
  width: 100%;
  min-width: 820px;
  border-collapse: collapse;
  text-align: left
}

.mtx th,
.mtx td {
  padding: var(--s-4) var(--s-5) var(--s-4) 0;
  vertical-align: top;
  border-bottom: 1px solid var(--hair)
}

.mtx thead th {
  font-size: var(--fs-micro);
  color: var(--ink-soft);
  font-weight: var(--fw-med);
  border-bottom: 1px solid var(--slate)
}

.mtx tbody th {
  font-weight: var(--fw-med);
  color: var(--ink-strong);
  font-size: var(--fs-small);
  width: 22%
}

.mtx tbody th a {
  transition: color var(--dur-fast) var(--ease)
}

.mtx tbody th a:hover {
  color: var(--royal)
}

.mtx td {
  font-size: var(--fs-small);
  color: var(--ink-soft)
}

.mtx__d {
  color: var(--ink-strong);
  white-space: nowrap;
  font-variant-numeric: tabular-nums
}

.mtx__g {
  width: 44px;
  text-align: right;
  padding-right: 0
}

.mtx__g svg {
  width: 17px;
  height: 17px;
  color: var(--royal);
  transition: transform var(--dur-base) var(--ease)
}

.mtx tbody tr {
  transition: background var(--dur-fast) var(--ease)
}

.mtx tbody tr:hover {
  background: var(--ground-tint)
}

.mtx tbody tr:hover .mtx__g svg {
  transform: translateX(4px)
}

/* ---- EVENT CARD DATE BADGE (events.html) ---------------------------- */
.evcard__m {
  position: relative
}

.ev__d {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: var(--s-3) var(--s-4);
  background: var(--white);
  line-height: 1.02;
  text-align: center
}

.ev__d b {
  display: block;
  font-size: 1.5rem;
  font-weight: var(--fw-light);
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums
}

.ev__d span {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-micro);
  color: var(--ink-soft)
}

.ev__p {
  display: block;
  font-size: var(--fs-micro);
  color: var(--royal);
  font-weight: var(--fw-med)
}

/* ---- missing utilities ---- */
.mt-1 {
  margin-top: var(--s-1)
}

.form {
  display: block
}


/* ==== GALLERY =========================================================
   Album cards (.galgrid/.galcard) share the card-grid rules above; only the
   photo-count badge and the empty-cover placeholder are specific to them.
   Note .gcard is already taken by the home page's rotating card — hence the
   galcard/galgrid prefix. */
/* auto-fill, not the auto-fit the other card grids use: auto-fit collapses the empty
   tracks, so a site with one or two albums would render a single card stretched across the
   full page width. auto-fill keeps the track structure, so cards stay card-sized from the
   first album onward. */
.galgrid {
  display: grid;
  gap: var(--s-7) var(--s-6);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
}

.galcard__n {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: var(--s-2) var(--s-4);
  background: var(--white);
  font-size: var(--fs-micro);
  color: var(--ink-strong);
  font-weight: var(--fw-med)
}

.galcard__ph {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 4/3;
  background: var(--ground-tint);
  color: var(--silver)
}

.galcard__ph svg {
  width: 28px;
  height: 28px
}

/* The album's photo grid. Denser than the card grid — these are photographs,
   not cards with copy under them. */
.photogrid {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr))
}

.photogrid__b {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  overflow: hidden;
  position: relative
}

.photogrid__b img {
  display: block;
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease)
}

.photogrid__b:hover img,
.photogrid__b:focus-visible img {
  transform: scale(1.05)
}

.photogrid__c {
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  color: var(--ink-soft)
}

/* ---- Lightbox -------------------------------------------------------
   Appended to <body> by assets/js/public/gallery.js, never authored inline:
   a GSAP reveal leaves a residual transform on its element, which would make
   that element the containing block for a position:fixed child and size the
   overlay to the section instead of the viewport. */
.lb-open {
  overflow: hidden
}

/* The `hidden` attribute gets its display:none from the UA stylesheet, and ANY author rule
   outranks the UA origin — so `.lightbox{display:flex}` below would keep the CLOSED overlay
   laid out across the whole viewport. At opacity:0 it stays invisible but still hit-tests,
   so it swallowed every click on the album page (thumbnails, nav, footer alike) and the
   lightbox appeared dead. This rule is more specific than `.lightbox`, so it wins. */
.lightbox[hidden] {
  display: none
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
  padding: var(--s-5);
  background: rgba(7, 12, 24, .94);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease)
}

.lightbox.is-open {
  opacity: 1
}

.lightbox__f {
  margin: 0;
  max-width: min(1200px, 92vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  align-items: center
}

.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  height: auto;
  object-fit: contain
}

.lightbox__c {
  display: flex;
  gap: var(--s-4);
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, .82);
  text-align: center
}

.lightbox__n {
  color: rgba(255, 255, 255, .58);
  font-variant-numeric: tabular-nums;
  flex: none
}

.lightbox__x,
.lightbox__nav {
  flex: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: rgba(255, 255, 255, .08);
  color: var(--white);
  border: 0;
  transition: background var(--dur-fast) var(--ease)
}

.lightbox__x {
  position: absolute;
  top: var(--s-5);
  right: var(--s-5);
  width: 44px;
  height: 44px;
  font-size: 1.5rem;
  line-height: 1
}

.lightbox__nav {
  width: 48px;
  height: 48px
}

.lightbox__nav svg {
  width: 24px;
  height: 24px
}

.lightbox__x:hover,
.lightbox__nav:hover,
.lightbox__x:focus-visible,
.lightbox__nav:focus-visible {
  background: rgba(255, 255, 255, .2)
}

@media (max-width:640px) {
  .lightbox {
    padding: var(--s-3);
    gap: var(--s-2)
  }

  .lightbox__nav {
    width: 40px;
    height: 40px
  }

  .lightbox__img {
    max-height: 68vh
  }
}

@media (prefers-reduced-motion:reduce) {
  .lightbox {
    transition: none
  }

  .photogrid__b img {
    transition: none
  }
}


/* ==== FOOTER SOCIAL =====================================================
   Sits under the brand blurb in the footer's first column, so the logo,
   the one-line description and the social marks read as one identity block
   rather than competing with the link columns.

   Lives here rather than in system.css with the other .foot rules because
   system.css is kept byte-identical to primeinfo-static (the design source).

   No border-radius: tokens.css states there is exactly one radius token and
   its value is zero, so these are square hit areas, not circles. */
.foot__social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center
}

.foot__social a {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  color: rgba(255, 255, 255, .66);
  background: rgba(255, 255, 255, .06);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease)
}

.foot__social a:hover,
.foot__social a:focus-visible {
  color: var(--white);
  background: var(--royal)
}

/* Font Awesome brand viewBoxes are 512 tall and vary in width, so the glyph is sized by
   height and allowed to find its own width rather than being forced square. */
.foot__social svg {
  width: auto;
  height: 17px;
  max-width: 20px;
  fill: currentColor;
  stroke: none
}