/* ==========================================================================
   Opus Keystone Inc. — Layout C (Conversion)

   One form on the page, pinned in the hero and sticky on desktop, so the
   primary action is never more than a glance away. CTAs elsewhere are limited
   to actions the form does not already cover:
     - call, for people who will not fill in a form
     - request a sample OK-CIS report, a genuinely different ask
     - apply, a different audience entirely
   Safety and Projects carry none; they exist to build trust, not to transact.

   On mobile the sticky form falls out of view, so a compact bottom bar takes
   over. That single element replaces the scattered per-section buttons.
   ========================================================================== */

:root {
  --ink:      #14181D;
  --ink-2:    #545C66;
  --ink-3:    #858D97;

  --paper:    #FFFFFF;
  --paper-2:  #F5F7F9;
  --rule:     #E2E6EA;
  --rule-2:   #EDF0F3;

  --deep:     #0E1116;
  --deep-2:   #161B22;
  --deep-rule:#262D38;
  --deep-ink: #F2F4F7;
  --deep-ink2:#A6AEB8;

  /* Logo blue, exact on white; lifted where it sits on the dark ground */
  --blue:     #01429E;
  --blue-hi:  #002F77;
  --blue-lift:#7FA9E8;

  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
          Arial, sans-serif;

  --gut:  clamp(20px, 5vw, 60px);
  --max:  1260px;
  --read: 64ch;

  --bar: 0px;              /* height of the mobile action bar, set in media */
}

*, *::before, *::after { box-sizing: border-box; }

/* scroll-padding-top has to track the sticky header's real height, or every
   in-page jump lands its target underneath the header. */
html { scroll-behavior: smooth; scroll-padding-top: 96px; }
@media (max-width: 520px) { html { scroll-padding-top: 80px; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  padding-bottom: var(--bar);
  -webkit-font-smoothing: antialiased;
}

/* height:auto is load-bearing: the markup carries width/height attributes so
   the browser can reserve space, and those map to the CSS height property.
   Without this, every `aspect-ratio` below is ignored and images render at
   their full intrinsic height. */
img { max-width: 100%; height: auto; display: block; }
a { color: var(--blue); }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gut);
}

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.015em; text-wrap: balance; }
h2 { font-size: clamp(27px, 3.4vw, 42px); line-height: 1.14; }
h3 { font-size: clamp(20px, 2.2vw, 27px); line-height: 1.24; }

.lbl { font-size: 11px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; }
.lede { font-size: clamp(17.5px, 1.5vw, 19.5px); color: var(--ink-2); max-width: var(--read); margin: 16px 0 0; }
.prose { max-width: var(--read); color: var(--ink-2); }
.prose p { margin: 0 0 16px; }
.prose p:last-child { margin: 0; }
.prose strong { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------------ CTAs */

.cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-size: 12px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  padding: 16px 28px; border: 1px solid var(--blue); background: var(--blue);
  color: #fff; text-decoration: none; cursor: pointer; transition: .16s;
}
.cta:hover { background: var(--blue-hi); border-color: var(--blue-hi); }
.cta--ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.cta--ghost:hover { background: transparent; border-color: var(--ink); color: var(--ink); }
.cta--wide { width: 100%; }
.ctaRow { display: flex; flex-wrap: wrap; gap: 12px; }

/* A phone link that reads as a phone number, not a button */
.tel { font-weight: 700; color: inherit; text-decoration: none; white-space: nowrap; }
.tel:hover { text-decoration: underline; }

/* -------------------------------------------------------------- top bars */

.util { background: var(--deep); color: var(--deep-ink2); }
.util__in {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 20px; padding-block: 10px; font-size: 13.5px;
}
.util a { color: #fff; }
.util__tel { font-size: 16px; color: #fff; }

.head {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255,255,255,.97); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
.head__in { display: flex; align-items: center; justify-content: space-between; gap: 20px; height: 80px; }
.brand { display: flex; align-items: center; flex: none; text-decoration: none; }
.brand img { height: 50px; width: auto; }

.nav { display: flex; align-items: center; gap: 24px; }
.nav a { font-size: 14.5px; font-weight: 600; color: var(--ink-2); text-decoration: none; }
.nav a:hover { color: var(--ink); }
/* .nav a out-specifies .cta, which would grey out the button label */
.nav a.cta, .nav a.cta:hover { color: #fff; padding: 12px 22px; font-size: 11.5px; }

@media (max-width: 980px) { .nav a:not(.cta) { display: none; } }
@media (max-width: 520px) {
  .head__in { height: 66px; }
  .brand img { height: 40px; }
  .nav a.cta { padding: 11px 16px; font-size: 11px; }
}

/* ------------------------------------------------------------------ hero */

.hero { position: relative; background: var(--deep); overflow: hidden; }
.hero__bg { position: absolute; inset: 0; }
.hero__bg img { width: 100%; height: 100%; object-fit: cover; opacity: .42; }
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right, rgba(14,17,22,.92), rgba(14,17,22,.6) 55%, rgba(14,17,22,.35));
}
.hero__in { position: relative; padding-block: clamp(40px, 5.5vw, 72px); }
.hero__cols {
  display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,404px);
  gap: clamp(28px, 4vw, 54px); align-items: start;
}
.hero .lbl { color: var(--blue-lift); }
.hero h1 { font-size: clamp(31px, 4.3vw, 51px); line-height: 1.1; color: #fff; margin: 12px 0 0; max-width: 16ch; }
.hero__sub { color: #C9D0D8; margin: 18px 0 0; max-width: 46ch; font-size: 18px; }

.ticks { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 10px; }
.ticks li { display: grid; grid-template-columns: 22px 1fr; gap: 10px; color: #E4E8ED; font-size: 16.5px; }
.ticks svg { width: 17px; height: 17px; margin-top: 5px; fill: none; stroke: var(--blue-lift); stroke-width: 2.4; }

/* The single form on the page */
.quote { background: #fff; border: 1px solid var(--rule); box-shadow: 0 20px 54px rgba(6,14,28,.34); padding: 26px; }
.quote h2 { font-size: 21px; margin: 0 0 4px; }
.quote__sub { margin: 0 0 18px; font-size: 14.5px; color: var(--ink-2); }
.quote label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
/* 16px is a functional minimum, not a taste call: below it, iOS Safari zooms
   the viewport on focus and does not zoom back out. */
.quote input, .quote select, .quote textarea {
  width: 100%; font-family: var(--sans); font-size: 16px; color: var(--ink);
  padding: 13px 14px; border: 1px solid #D3D9DF; background: #fff; margin-bottom: 14px; border-radius: 0;
  min-height: 48px;
}
.quote textarea { min-height: 86px; resize: vertical; }
.quote input:focus, .quote select:focus, .quote textarea:focus { border-color: var(--blue); outline: none; }

/* appearance:none removes the native arrow, so the control has to draw its own
   or it reads as a text field that someone already typed "Cladding" into. */
.quote select {
  appearance: none; cursor: pointer; padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23545C66' stroke-width='1.7'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 15px center; background-size: 12px 8px;
}
.quote__alt { margin: 14px 0 0; font-size: 14px; color: var(--ink-2); text-align: center; }
.quote__note { margin: 12px 0 0; font-size: 12px; color: var(--ink-3); line-height: 1.55; }
.quote__note:empty { margin: 0; }
.quote button[disabled] { opacity: .6; cursor: default; }

/* ---------------------------------------------------- form confirmation

   Shown in place of the form after a successful send. Same white card and
   padding as .quote so the panel lands in the same footprint and the sticky
   column does not jump.

   The sequence is deliberately short (about 900ms end to end): ring draws,
   tick draws, text lifts in. Anything longer reads as a loading state rather
   than a confirmation, which is the opposite of the reassurance intended. */
.done {
  background: #fff;
  border: 1px solid var(--rule);
  box-shadow: 0 20px 54px rgba(6, 14, 28, .34);
  padding: 40px 26px 34px;
  text-align: center;
}
.done[hidden] { display: none; }

.done h2 { font-size: 21px; margin: 18px 0 6px; }
.done p  { margin: 0; font-size: 14.5px; color: var(--ink-2); line-height: 1.6; }

.done__mark { width: 72px; height: 72px; display: block; margin: 0 auto; }
.done__ring,
.done__tick {
  fill: none;
  stroke: var(--blue);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* r=24 gives a circumference of ~150.8; the tick path measures ~31. Each is
   drawn by walking its own dash offset back to zero. */
.done__ring { stroke-dasharray: 151; stroke-dashoffset: 151; }
.done__tick { stroke-dasharray: 31;  stroke-dashoffset: 31; }

.done__again {
  margin-top: 22px;
  background: none;
  border: 0;
  padding: 6px 2px;
  font: inherit;
  font-size: 13.5px;
  color: var(--blue);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.done__again:hover { color: var(--blue-hi); }

/* Animation runs only when the panel is actually revealed, so re-showing it
   replays cleanly rather than presenting an already-finished drawing. */
.done.is-in .done__ring { animation: ok-ring .45s ease-out forwards; }
.done.is-in .done__tick { animation: ok-tick .30s ease-out .40s forwards; }
.done.is-in h2,
.done.is-in p,
.done.is-in .done__again { animation: ok-rise .40s ease-out .48s both; }

@keyframes ok-ring { to { stroke-dashoffset: 0; } }
@keyframes ok-tick { to { stroke-dashoffset: 0; } }
@keyframes ok-rise {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* Reduced motion: show the finished state immediately. The confirmation still
   has to be legible — suppressing the animation must never leave an
   undrawn ring and an invisible message behind. */
@media (prefers-reduced-motion: reduce) {
  .done.is-in .done__ring,
  .done.is-in .done__tick,
  .done.is-in h2,
  .done.is-in p,
  .done.is-in .done__again { animation: none; }
  .done .done__ring,
  .done .done__tick { stroke-dashoffset: 0; }
}

/* Honeypot: off-canvas rather than display:none, since some bots skip fields
   that are explicitly hidden. Never reachable by keyboard or screen reader. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.stick { position: sticky; top: 100px; }

@media (max-width: 1000px) {
  .hero__cols { grid-template-columns: 1fr; }
  .stick { position: static; }
}

/* On a phone the form is taller than the viewport, so it can never read as a
   floating card — cropped top and bottom with hero photo down each side, it
   looks like a fragment. Full-bleed, it reads as its own panel. */
@media (max-width: 560px) {
  .quote {
    margin-inline: calc(var(--gut) * -1);
    padding: 24px var(--gut) 26px;
    border-left: 0; border-right: 0;
    box-shadow: 0 -8px 30px rgba(6,14,28,.30);
  }
  .hero__in { padding-bottom: 0; }
}

/* ----------------------------------------------------------- trust strip */

.trust { border-bottom: 1px solid var(--rule); background: var(--paper-2); }
.trust dl { display: grid; grid-template-columns: repeat(4,1fr); gap: 1px; background: var(--rule); margin: 0; }
.trust dl > div { background: var(--paper-2); padding: 22px clamp(16px,2.2vw,28px); }
.trust dt { color: var(--ink-3); margin-bottom: 6px; }
.trust dd { margin: 0; font-size: 17px; font-weight: 600; }
@media (max-width: 860px) { .trust dl { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 520px) { .trust dl { grid-template-columns: 1fr; } }

/* -------------------------------------------------------------- sections */

.sec { padding-block: clamp(46px, 5vw, 76px); border-bottom: 1px solid var(--rule); }
.sec--tint { background: var(--paper-2); }

.cards { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; margin-top: 32px; }
.card { border: 1px solid var(--rule); background: #fff; padding: 22px; }
.sec--tint .card { background: #fff; }
.card h3 { font-size: 19px; margin-bottom: 9px; }
.card p { margin: 0; font-size: 15.5px; color: var(--ink-2); line-height: 1.6; }
@media (max-width: 940px) { .cards { grid-template-columns: repeat(2,1fr); } }
/* Six stacked cards are the tallest block on a phone; trimming the padding and
   leading takes ~200px off without touching the copy. */
@media (max-width: 620px) {
  .cards { grid-template-columns: 1fr; gap: 12px; margin-top: 28px; }
  .card { padding: 20px; }
  .card h3 { font-size: 18px; margin-bottom: 7px; }
  .card p { font-size: 15px; line-height: 1.55; }
}

/* Alternating image / copy rows.
   The row is as tall as its taller half, so the image column is deliberately
   the narrower one: a 3:2 crop at 0.82fr clears the copy instead of setting
   the floor, and the wider copy column costs fewer wrapped lines. */
.alt { display: grid; grid-template-columns: minmax(0,0.82fr) minmax(0,1.18fr); gap: clamp(26px,3.4vw,48px); align-items: center; }
.alt + .alt { margin-top: clamp(38px,5vw,64px); padding-top: clamp(38px,5vw,64px); border-top: 1px solid var(--rule); }
.alt img { width: 100%; aspect-ratio: 3/2; object-fit: cover; }
.alt--flip .alt__m { order: -1; }
.alt h3 { margin-top: 10px; }
.alt p { color: var(--ink-2); margin: 14px 0 0; }
@media (max-width: 860px) {
  .alt, .alt--flip .alt__m { grid-template-columns: 1fr; order: 0; }
  /* Stacked, a 4:3 image eats most of a phone screen before any copy is
     reached. A letterbox crop keeps the photo as evidence, not as a wall. */
  .alt img { aspect-ratio: 16/9; }
  /* Except the careers portrait: its source is 1200x1600, so a 16:9 crop
     throws away the crew and the site and leaves a head shot. */
  #careers .alt img { aspect-ratio: 4/3; }
}

/* OK-CIS verification list. Three columns once the copy side is wide enough:
   eight items become three rows instead of four. */
.verify { list-style: none; margin: 18px 0 0; padding: 0; display: grid; grid-template-columns: repeat(3,1fr); gap: 8px 18px; }
@media (max-width: 1080px) { .verify { grid-template-columns: 1fr 1fr; } }
.verify li { display: grid; grid-template-columns: 20px 1fr; gap: 9px; font-size: 15px; color: var(--ink-2); }
.verify svg { width: 15px; height: 15px; margin-top: 5px; fill: none; stroke: var(--blue); stroke-width: 2.6; }
@media (max-width: 560px) { .verify { grid-template-columns: 1fr; } }

/* Safety routine — a genuine sequence, so it is numbered */
.steps { list-style: none; margin: 18px 0 0; padding: 0; border-top: 1px solid var(--rule); }
.steps li { display: grid; grid-template-columns: 34px 1fr; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--rule-2); font-size: 15.5px; color: var(--ink-2); }
.steps b { font-size: 12px; font-weight: 700; color: var(--blue); padding-top: 3px; }
.steps span { color: var(--ink); font-weight: 600; }

/* Projects — a uniform two-row index. The old 2-wide feature tile forced a
   471px row and left the cell beside it half empty; even tiles read as a
   catalogue and cost roughly half the height. */
.work { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px 16px; margin-top: 32px; }
.work figure { margin: 0; }
.work img { width: 100%; aspect-ratio: 3/2; object-fit: cover; }
.work figcaption { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--rule); font-size: 13px; color: var(--ink-3); }
@media (max-width: 900px) { .work { grid-template-columns: repeat(2,1fr); } }
/* On a phone two columns would put each facade in a 160px-wide tile, too small
   to read as evidence. One column, but letterboxed so six photos still cost
   about a third of what a 4:3 stack would. */
@media (max-width: 560px) {
  .work { grid-template-columns: 1fr; gap: 20px; }
  .work img { aspect-ratio: 16/9; }
}

/* ------------------------------------------------------- tender CTA band */

.band { background: var(--blue); color: #fff; padding-block: clamp(44px,5.5vw,72px); }
.band__in { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 28px; align-items: center; }
.band h2 { max-width: 22ch; }
.band p { margin: 12px 0 0; color: #D2E0F6; max-width: 52ch; }
.band .cta { background: #fff; color: var(--blue); border-color: #fff; }
.band .cta:hover { background: var(--deep); color: #fff; border-color: var(--deep); }
.band .cta--ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.band .cta--ghost:hover { background: transparent; border-color: #fff; color: #fff; }
@media (max-width: 860px) { .band__in { grid-template-columns: 1fr; } }

/* -------------------------------------------------------------- contact */

.dl { margin: 26px 0 0; border-top: 1px solid var(--rule); }
.dl > div { display: grid; grid-template-columns: 150px 1fr; gap: 16px; padding: 15px 0; border-bottom: 1px solid var(--rule-2); }
.dl dt { color: var(--ink-3); }
.dl dd { margin: 0; font-size: 16.5px; }
.dl a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--rule); }
.dl a:hover { color: var(--blue); border-bottom-color: var(--blue); }
@media (max-width: 560px) { .dl > div { grid-template-columns: 1fr; gap: 4px; } }

/* --------------------------------------------------------------- footer */

.foot { background: var(--deep); color: var(--deep-ink2); padding-block: clamp(46px,5vw,68px); }
.foot__g { display: grid; grid-template-columns: 1.5fr repeat(3,1fr); gap: clamp(26px,4vw,50px); padding-bottom: 34px; border-bottom: 1px solid var(--deep-rule); }
.foot__logo { height: 72px; width: auto; margin-bottom: 16px; }
.foot__tag { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.foot__tag span { color: var(--blue-lift); padding-inline: 5px; }
.foot h3 { font-size: 11px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; color: #fff; margin: 0 0 15px; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot a { color: var(--deep-ink2); text-decoration: none; font-size: 14.5px; }
.foot a:hover { color: #fff; }
.foot__legal { display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: space-between; padding-top: 24px; font-size: 12.5px; color: #6E7783; }
@media (max-width: 900px) { .foot__g { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .foot__g { grid-template-columns: 1fr; } }

/* ------------------------------------------------------ mobile action bar

   Only appears once the sticky form has scrolled away, and only on the
   viewports where the form is not sticky at all. */

.mbar {
  position: fixed; inset: auto 0 0 0; z-index: 80; display: none;
  grid-template-columns: 1fr 1fr; gap: 1px; background: var(--deep-rule);
  border-top: 1px solid var(--deep-rule);
  transform: translateY(100%); transition: transform .22s ease;
}
.mbar.is-up { transform: none; }
.mbar a {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 15px 10px; background: var(--deep); color: #fff; text-decoration: none;
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}
.mbar a.pri { background: var(--blue); }

@media (max-width: 1000px) {
  :root { --bar: 52px; }
  .mbar { display: grid; }
}

/* ----------------------------------------------------------------- print */

@media print {
  .head, .util, .mbar, .quote, .band, .nav { display: none !important; }
  body { padding-bottom: 0; }
  .hero { background: #fff; }
  .hero__bg { display: none; }
  .hero h1, .hero__sub, .ticks li { color: #000; }
  .foot { background: #fff; color: #000; }
  a { color: #000; }
}
