/* Extra rules for the pages that are not the homepage.

   Kept in its own file rather than appended to style.css because style.css is
   the countdown design itself, shared with the template library. These rules
   only exist for /capabilities/ and /careers/, which are not part of that
   design, and mixing them in would mean every future template swap inherited
   layout for pages it does not have.

   Everything below reads the same custom properties as style.css, so these
   pages take the palette automatically and would follow a recolour. */

/* Lede line under a section heading, for the one sentence that carries the
   point before the paragraphs qualify it. */
.lede {
  font-size: 19px;
  line-height: 1.5;
  color: var(--ink);
  max-width: 32em;
}
/* The bare class above loses every contest it enters: .prose p in style.css and
   .mv .lede below both outrank it, so the 19px it declares never rendered
   anywhere. Restated with the element to win those ties. */
.prose p.lede, .mv p.lede, .mv .lede { font-size: 19px; line-height: 1.5; }

/* Partners strip.

   A continuous marquee rather than a slideshow, so the row reads as one moving
   band instead of a thing that jumps every few seconds.

   How the loop is seamless: .pstrip holds the same list twice, and the
   animation translates it by exactly -50%, which is the width of one copy. At
   the instant it wraps, copy two is sitting precisely where copy one began, so
   there is no visible seam and no gap to fill.

   The width is driven by the content (width:max-content), because a percentage
   translate needs a real width to be a percentage of. animation-play-state
   pauses on hover so a logo can actually be looked at.

   The logos arrive as dark ink on white, which would be invisible against this
   page, so each sits on its own light chip. That is deliberate: knocking the
   backgrounds out would misrepresent marks their owners supply as-is. */
.partners { overflow: hidden; }
.pmask {
  overflow: hidden;
  /* Fade both ends so logos enter and leave rather than being sliced off at
     the viewport edge. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.pstrip {
  display: flex;
  align-items: center;
  gap: 18px;
  width: max-content;
}
.pstrip img {
  display: block;
  height: 62px;
  width: auto;
  padding: 12px 20px;
  background: #ffffff;
  border-radius: 3px;
  /* The marks are supplied on white and are not ours to restyle, so they are
     shown as given and only dimmed slightly so the strip does not glare
     against a black page. Full opacity on hover. */
  opacity: 0.82;
  transition: opacity 0.2s linear;
}
.pstrip img:hover { opacity: 1; }

/* Marks drawn in light ink for a dark ground, Puura's among them. Putting one
   on a white chip would mean recolouring it, which is not ours to do, so it
   keeps the ground it was designed for and takes a hairline border instead, or
   a black chip on a black page has no edge at all. */
.pstrip img.pdark {
  background: #000000;
  box-shadow: inset 0 0 0 1px var(--rule-2);
}

@media (prefers-reduced-motion: no-preference) {
  .pstrip { animation: fp-marquee 42s linear infinite; }
  .partners:hover .pstrip { animation-play-state: paused; }
}
@keyframes fp-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* With motion suppressed the strip does not move, so the second copy is dead
   weight and the row simply wraps instead. */
@media (prefers-reduced-motion: reduce) {
  .pstrip { flex-wrap: wrap; width: auto; justify-content: center; }
  .pstrip .pdup { display: none; }
}

/* Footer with offices and social links.

   style.css declares footer as a flex row with space-between, a max-width and
   its own border-top, which was written for the two-line footer the countdown
   design shipped with. That is wrong for this one: it made .foot-wide and
   .foot-legal flex siblings sitting side by side, and its border stacked with
   the one .foot-wide carried, so two rules appeared above the addresses.

   So footer is reset to a plain block here and keeps the single rule. The
   width and padding move down to the children, which need different values
   anyway. This file loads after style.css, so the reset wins. */
footer {
  display: block;
  max-width: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}

.foot-wide {
  display: block;
  max-width: 1100px;
  margin: 0 auto;
  padding: 34px 5vw 30px;
}
/* Two columns, not four across.

   auto-fit put all four side by side on a wide screen, which left the two
   addresses looking like list items rather than offices. Two columns pairs
   them as intended: the offices on one row, follow-us and talk-to-us on the
   next. One column below the breakpoint, where two would leave each address
   wrapping mid-line. */
.foot-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 34px 44px;
}
@media (max-width: 640px) {
  .foot-cols { grid-template-columns: 1fr; gap: 26px; }
}

/* Link with an icon in front of it. The gap belongs to flex rather than to a
   margin on the icon, so the two stay together if the label wraps, and
   align-items keeps a one-line label optically centred against the glyph. */
.ilink {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 9px;
  font-size: 13.5px;
  line-height: 1.4;
}
/* currentColor on the SVG means the glyph follows the link, including on
   hover, without a second rule to keep in step. */
.ilink .ico { flex: 0 0 auto; }
.foot-cols h3 {
  margin: 0 0 12px;
  font: 700 11px/1 "Courier New", Courier, monospace;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brand);
}
.foot-cols p, .foot-cols address {
  margin: 0 0 6px;
  font-size: 13.5px;
  line-height: 1.6;
  font-style: normal;
  color: var(--ink-soft);
}
.foot-cols a { color: var(--ink-body); text-decoration: none; }
.foot-cols a:hover, .foot-cols a:focus-visible {
  color: var(--brand);
  text-decoration: underline;
}
/* The last line of the page: company hard left, copyright hard right.
   No rule above it, because the footer already has one and a second would
   box the addresses in for no reason. */
/* The same two-column grid as .foot-cols above, not a flex row pushed apart.

   space-between sent the copyright to the container edge, which lines up with
   nothing -- the addresses above it sit in grid columns, and the right-hand one
   starts 44px past the midpoint, not at the edge. Sharing the grid puts the
   copyright directly under the Singapore address instead of out past it.

   The two containers already agree on max-width and horizontal padding, so
   matching grid-template-columns and the column gap is all the alignment
   needs. */
.foot-legal {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 44px;
  row-gap: 8px;
  align-items: baseline;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 5vw 40px;
  font-size: 12.5px;
  color: var(--ink-soft);
}
/* Stacks at the same breakpoint as .foot-cols, or the copyright would keep a
   column the addresses above it no longer have. */
@media (max-width: 640px) {
  .foot-legal { grid-template-columns: 1fr; row-gap: 6px; }
}
.foot-legal p { margin: 0; }

@media (max-width: 700px) {
  .pstrip img { height: 46px; padding: 9px 14px; }
  .foot-wide { padding: 26px 20px 30px; }
  .foot-legal { padding: 14px 20px 30px; }
}

/* Mission and vision, side by side.

   They are a matched pair and belong on one row: stacked, the second reads as a
   footnote to the first. Two columns rather than auto-fit, because there are
   always exactly two and a third would break the pairing anyway.

   The single-column fallback is a max-width query rather than a minmax floor,
   since these boxes carry three or four paragraphs each and need considerably
   more width than a capability card before side by side stops being readable. */
.mv-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin: 8px 0 0;
}

.mv {
  padding: 34px 32px 36px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 2px solid var(--rule);
}
.mv .rung { margin: 0 0 10px; }
.mv h2 { margin: 0 0 18px; }
/* .prose is not used inside these boxes, so the paragraph rules it would have
   supplied are restated here. */
.mv p {
  margin: 0 0 14px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-body);
}
.mv p:last-child { margin-bottom: 0; }
.mv .lede {
  margin-bottom: 18px;
  color: var(--ink);
  max-width: none;
}

@media (max-width: 900px) {
  .mv-grid { grid-template-columns: 1fr; }
}

/* Capability and careers cards.

   auto-fit with a minimum lets the row reflow without media queries: three
   across on a wide screen, two on a tablet, one on a phone. minmax(0, 1fr)
   rather than minmax(320px, 1fr) as the second value, because a bare 1fr
   refuses to shrink below its content and forces a horizontal scrollbar on
   narrow screens. */
.cap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 20px;
  margin: 28px 0 0;
}

.cap {
  padding: 24px 22px 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 2px solid var(--rule);
}
.cap .num {
  margin: 0 0 14px;
  font: 700 26px/1 "Courier New", Courier, monospace;
  letter-spacing: 0.04em;
  color: var(--brand);
}
.cap h3 {
  margin: 0 0 12px;
  color: var(--ink);
  font-size: 19px;
  line-height: 1.25;
}
.cap p {
  margin: 0 0 12px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-body);
}
.cap p:last-child { margin-bottom: 0; }

/* The qualifying detail under a card: requirements, caveats, what to bring.
   Set quieter than the body so the card can be skimmed without it. */
.cap-meta {
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 13.5px !important;
  color: var(--ink-soft) !important;
}

.capnote {
  margin: 22px 0 0;
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* Two buttons side by side, wrapping rather than overflowing on a phone. */
.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 26px;
}

/* The secondary action. Outlined rather than filled, so the pair reads as one
   primary choice and one alternative instead of two competing buttons.
   Declared after .cta in the cascade, and matching its specificity, so it
   overrides the filled background from contact.css. */
.cta.cta-quiet {
  background: transparent;
  color: var(--brand);
  box-shadow: inset 0 0 0 1px var(--brand);
}
a.cta.cta-quiet, a.cta.cta-quiet:link, a.cta.cta-quiet:visited { color: var(--brand); }
a.cta.cta-quiet:hover, a.cta.cta-quiet:focus-visible {
  background: var(--brand);
  color: var(--on-brand);
}

/* The hero on these pages carries no countdown clock under it, so it needs a
   rule of its own to sit against the first section. */
.hero { padding-bottom: 2vh; }

@media (max-width: 700px) {
  .cap-grid { gap: 14px; }
  .cap { padding: 20px 18px 22px; }
  .cta-row > .cta { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------- contact --
   A large mark over the heading, the two offices side by side, and a Google
   Maps tile under each address.

   The iframe in a tile is inert: pointer-events are off, so the anchor laid
   over it takes every click and the square behaves as one link. Without that,
   a map on a phone swallows the scroll gesture. An <a> may not contain an
   <iframe>, so the link is an overlay sibling rather than a wrapper. The
   filter darkens Google's light tiles, which would otherwise burn a white
   square into a black page. */
/* The page mark, pinned to the left of the headline and centred on it. It
   lives inside the h1 so it can be positioned against that box rather than
   against the section, which is the only way to line it up with the heading
   without knowing how tall the eyebrow above it happens to be.

   right: 100% puts it wholly outside the headline box, so it sits beside the
   words rather than behind them. Absolute, so it is out of flow and adding it
   moved nothing on any page.

   The headline box is capped at 18em and centred, so the room to its left is
   whatever the viewport spares. Below 1180px there is none, and the mark is
   hidden rather than allowed to collide with the words or overflow the page. */
.hero h1, .lts-hero h1 { position: relative; }
.pagemark { position: absolute; right: 100%; top: 50%;
  transform: translateY(-50%); margin-right: clamp(44px, calc(1.8vw + 28px), 60px);
  height: clamp(58px, 6.4vw, 104px); width: auto;
  pointer-events: none; user-select: none; }
@media (max-width: 1180px) { .pagemark { display: none; } }

/* Ranged left until now, unlike every other hero on the site. */
.lts-hero { text-align: center; }

/* max-content, not 1fr. With 1fr the address columns stretched to fill the
   section and threw each map to the far right of its own address; sizing to
   content keeps a map beside the text it belongs to and packs the whole row
   left. justify-content does the packing, since the columns no longer fill. */
.offices { display: grid; align-items: start; justify-content: start;
  gap: clamp(12px, 1.6vw, 24px);
  grid-template-columns: repeat(4, max-content); }
/* A wider gutter before the second office than inside a pair, so the row reads
   as two groups rather than four evenly spaced columns. */
.offices > :nth-child(3) { margin-left: clamp(20px, 3.4vw, 64px); }
.office h3 { margin: 0 0 10px; color: var(--ink); font-size: 12px;
  letter-spacing: 0.22em; text-transform: uppercase; }
.office address { margin: 0; font-style: normal; color: var(--ink-body);
  line-height: 1.7; }

/* Fixed width, so the two map columns stay equal and small however wide the
   address columns run. The tiles sit a little below the h3 above them, which
   lines their top edge up with the first line of the address beside them. */
.mapsq { position: relative; width: 172px; aspect-ratio: 1 / 1;
  margin-top: 0; overflow: hidden;
  border: 1px solid var(--border); background: var(--surface); }
.mapsq iframe { position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; pointer-events: none;
  filter: grayscale(1) invert(0.91) contrast(0.87); }
.mapsq-hit { position: absolute; inset: 0; display: flex; align-items: flex-end;
  text-decoration: none; }
.mapsq-hit span { display: inline-flex; align-items: center; gap: 5px;
  width: 100%; padding: 6px 8px; font-size: 11px; letter-spacing: 0.04em;
  color: var(--ink); background: rgba(0, 0, 0, 0.74);
  border-top: 1px solid var(--border); }
.mapsq-hit:hover span, .mapsq-hit:focus-visible span { color: var(--brand); }

/* Two across, so each address keeps its own map beside it rather than the
   pairs breaking apart. */
@media (max-width: 1080px) {
  .offices { grid-template-columns: repeat(2, max-content); }
  .offices > :nth-child(3) { margin-left: 0; }
}
@media (max-width: 460px) {
  .offices { grid-template-columns: 1fr; }
  .mapsq { width: 100%; }
}


/* Centred blocks on the contact page. Scoped to .contact-mid rather than
   edited into shared/contact.css, which serves all eighty-one templates and
   must keep its left-ranged default.

   Field labels stay left inside the centred form: centring them would ragged
   both edges of every input and make the column hard to scan. */
.contact-mid h2 { text-align: center; }
.contact-mid .offices { justify-content: center; }
/* lts.css loads after this file and sets .sec .prose { max-width: none } at
   equal specificity, so auto margins on .prose alone did nothing. .sec.contact-mid
   raises specificity enough to win. It also caps every .prose p at 34em with no
   auto margins, and .cpair IS a p, so the booking row sat in a left-pinned box
   and only centred its contents inside that box. Both are fixed here. */
.sec.contact-mid .prose { max-width: 52em; margin-left: auto; margin-right: auto; }
.contact-mid .prose p, .contact-mid .prose h3 { margin-left: auto; margin-right: auto; }
/* The shared stylesheet pins the label at a fixed 110px so labels line up in a
   left-ranged column. Centred, that fixed width drags the pair off centre, so
   here the label shrinks to its text and the two sit together. */
.contact-mid .cpair { justify-content: center; }
.contact-mid .cpair > span:first-child { flex: 0 0 auto; }
.contact-mid .formhead { text-align: center; }
.contact-mid .reach { margin-left: auto; margin-right: auto; }


/* style.css gives .hero .sub auto margins, which is what centres the standfirst
   on About, Capabilities and Careers. .lts-hero never had it, so on Let's Talk
   Space the text centred inside a box that still sat hard left. Specificity
   beats the bare .sub rule, so load order against lts.css does not matter. */
.lts-hero .sub { margin-left: auto; margin-right: auto; }


/* Reach out is .formhead from shared/contact.css; Where we are and Talk to us
   are .sec h2. Both already computed to the same 12px, but they were set in two
   different stylesheets, so a change to either would have silently split them.
   Pinned together here so the three headings stay one size. */
.contact-mid h2, .contact-mid .formhead {
  font-size: 12px; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--ink); font-weight: 700; }

/* The same heading on 404 and thanks is a <p> inside .prose, where .prose p
   outranks the bare .formhead class and it rendered as body copy. Restated with
   both element names so it holds its size wherever it appears. */
.prose p.formhead, .prose h3.formhead, p.formhead {
  margin: 38px 0 16px; font-size: 12px; font-weight: 700;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--ink); }
/* No stylesheet coloured these links, so they rendered in the browser default
   blue against a black page -- the only unstyled anchors on the site. */
.formhead a { color: var(--brand); text-decoration: none; }
.formhead a:hover { text-decoration: underline; }


/* About us runs five per cent wider than the 34em lts.css gives every .prose p.
   Two classes, because lts.css loads after this file and .prose p alone would
   tie on specificity and lose. */
.prose.about-prose p { max-width: 35.7em; }


/* Visually hidden, still read. For headings that exist to keep the document
   outline intact, and for the skip link until it takes focus. clip-path rather
   than display:none or visibility:hidden, both of which remove the element from
   the accessibility tree, which is the one thing that must not happen here. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}


/* Skip link. Off-screen until focused, then it lands on top of the sticky bar
   so it is actually visible when a keyboard reader tabs into the page. */
.skip {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  padding: 10px 16px; background: var(--brand); color: var(--on-brand);
  font: 700 12px/1 "Courier New", Courier, monospace; letter-spacing: 0.18em;
  text-transform: uppercase; text-decoration: none;
  transition: top 0.12s linear;
}
.skip:focus { top: 8px; }

/* figbox is a <figure> now, so it needs the UA margin cancelled: as a <div> it
   had none, and figure carries 1em on each side by default. */
.figbox { margin: 0; }


/* The standing demo under the capabilities headline. Capped well inside the
   section: .sec runs to 1488px, and a 1280px clip stretched across that
   dominates the page and pushes the whole capability ladder below the fold.
   No top padding, so it reads as part of the hero rather than as a section of
   its own. */
.cap-demo { padding-top: 0; }
.cap-demo .vid-item { max-width: 900px; margin: 0 auto; }


/* The overview follows the hero directly on the homepage, and the two were
   carrying 2vh of hero padding plus this section own 6vh -- 8vh of blank
   between the countdown line and the first heading, which read as a page break
   rather than a continuation. Taken to zero, so the count and the brief belong
   to one another.

   Scoped to .sec.ov, which is the homepage overview and nothing else: the 6vh
   is right for every other section on the site, and .sec.ov at (0,2,0) beats
   the bare .sec whatever the load order. */
.sec.ov { padding-top: 0; }
