/* TOGO Engineering Limited — design system.
 *
 * Structure and layout follow wsp.com: a near-monochrome dark canvas, a
 * two-tier header, enormous tight uppercase display type, and one saturated
 * red used sparingly for the mark and the calls to action.
 *
 * The palette substitutes WSP's near-black #141212 for a deep green in the
 * same family as the E2 Homes lime, and WSP's white for a bright yellow.
 * WSP's red is carried over unchanged.
 *
 * Measured contrast on --ink #12300F (all computed, none guessed):
 *   --yellow  #FFD400  10.1:1   headings, display type          PASS AA/AAA
 *   --body    #EAF3D8  12.6:1   body copy                       PASS AA/AAA
 *   --muted   #B9CFA3   7.4:1   secondary copy                  PASS AA
 *   --red     #E02F28   3.2:1   LARGE TEXT AND FILLS ONLY — never body copy
 *   #ffffff on --red     4.6:1   button labels                  PASS AA
 *
 * That last line is the rule that matters: the red is a fill colour and a
 * display colour. Setting 16px body text in it on this background would fail,
 * so nothing in this file does that.
 *
 * Spacing runs on an 8px grid: 8 16 24 32 48 64 96 128.
 */

:root {
  --ink:     #12300f;   /* the canvas — WSP's black, in green */
  --ink-2:   #1a4116;   /* raised surfaces: cards, menu panels */
  --ink-3:   #0d2409;   /* recessed: the top utility bar, the footer */
  --yellow:  #ffd400;   /* WSP's white */
  --body:    #eaf3d8;
  --muted:   #b9cfa3;
  --red:     #e02f28;   /* WSP red, exact (rgb 224 47 40) — marks and fills */
  --red-hot: #ff3730;   /* WSP's hover red, exact (rgb 255 55 47) */
  /* The exact reds measure 3.2:1 and 4.0:1 on this background. That is fine
     for the wordmark, for button fills and for display-size type, but the
     eyebrow labels are 12px — below the size where 3:1 is permitted — so they
     use this lightened member of the same red family at 5.7:1. It is the only
     deviation from WSP's palette, and it exists so the labels are legible. */
  --red-label: #ff7a70;
  --line:    rgba(234, 243, 216, .16);

  /* WSP sets everything in PPNeueMontreal — a licensed grotesque we cannot
     ship. This stack is the closest widely-available match: tight, neutral,
     and heavy enough to hold at display sizes. */
  --sans: "Helvetica Neue", Helvetica, Arial, system-ui, -apple-system,
          "Segoe UI", Roboto, sans-serif;

  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 32px;
  --s6: 48px; --s8: 64px; --s12: 96px; --s16: 128px;

  --gut: clamp(20px, 4vw, 56px);
  --pad: clamp(64px, 9vw, 128px);
  --ease: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--ink); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

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

img { max-width: 100%; height: auto; display: block; }
a { color: var(--yellow); text-underline-offset: 3px; }
a:hover { color: #fff; }
:focus-visible { outline: 2px solid var(--yellow); outline-offset: 3px; }

/* WSP's display type: very large, very tight, uppercase, heavy. */
h1, h2, h3, h4 { margin: 0; color: var(--yellow); font-weight: 700; line-height: .95;
  letter-spacing: -.03em; text-wrap: balance; }
h1 { font-size: clamp(2.75rem, 7.2vw, 6rem); text-transform: uppercase; }
h2 { font-size: clamp(2rem, 4.2vw, 3.4rem); text-transform: uppercase; }
h3 { font-size: clamp(1.15rem, 1.6vw, 1.4rem); line-height: 1.15; letter-spacing: -.015em; }
h4 { font-size: 1rem; letter-spacing: 0; }
p { margin: 0; }
.num { font-variant-numeric: tabular-nums; }

.eyebrow {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .18em;
  font-weight: 700; color: var(--red-label); margin: 0;
}
.lead { font-size: clamp(1.05rem, 1.5vw, 1.35rem); color: var(--body); max-width: 60ch; }
.muted { color: var(--muted); }

/* Facts not yet supplied are marked, never invented. */
.fill {
  color: var(--yellow); background: rgba(255, 212, 0, .14);
  padding: 0 .3em; border-radius: 3px; font-weight: 600; font-size: .94em;
  overflow-wrap: anywhere;
}

.wrap { width: min(1440px, 100% - 2 * var(--gut)); margin-inline: auto; }
section { padding-block: var(--pad); }
.stack > * + * { margin-top: var(--s3); }

/* ====================================================== header, two tiers */
/* WSP runs a thin utility bar (Investors / News / Contact us / language)
   above the main navigation. Both are reproduced. */
.util { background: var(--ink-3); border-bottom: 1px solid var(--line); }
.util__in {
  display: flex; align-items: center; justify-content: flex-end;
  gap: var(--s3); min-height: 40px; font-size: .82rem;
}
.util a { color: var(--muted); text-decoration: none; }
.util a:hover { color: var(--yellow); }
.util__lang { color: var(--muted); letter-spacing: .08em; }

.nav { position: sticky; top: 0; z-index: 50; background: var(--ink);
  border-bottom: 1px solid var(--line); }
.nav__in { display: flex; align-items: center; gap: var(--s6); min-height: 84px; }

/* The mark. WSP's logo is its wordmark in red — ours is the same idea. */
.brand { text-decoration: none; display: inline-flex; align-items: baseline; gap: 6px; }
.brand__mark {
  color: var(--red); font-weight: 800; font-size: 1.75rem;
  letter-spacing: -.04em; line-height: 1;
}
.brand__tag {
  color: var(--muted); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .18em; font-weight: 600;
}

.nav__links { display: flex; align-items: center; gap: var(--s6); margin-right: auto; }
.nav__links > a {
  color: var(--body); text-decoration: none; font-size: .98rem; font-weight: 500;
  padding: 30px 0; position: relative; white-space: nowrap;
}
.nav__links > a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 22px; height: 2px;
  background: var(--red); transform: scaleX(0); transform-origin: left;
  transition: transform .24s var(--ease);
}
.nav__links > a:hover::after,
.nav__links > a[aria-current="page"]::after { transform: scaleX(1); }
.nav__links > a:hover { color: var(--yellow); }

.nav__search {
  width: 44px; height: 44px; display: inline-flex; align-items: center;
  justify-content: center; background: transparent; border: 0; cursor: pointer;
  color: var(--body); border-left: 1px solid var(--line); padding-left: var(--s3);
}
.nav__search:hover { color: var(--yellow); }

.nav__toggle {
  display: none; width: 44px; height: 44px; margin-left: auto; padding: 0;
  background: transparent; border: 1px solid var(--line); cursor: pointer;
  align-items: center; justify-content: center;
}
.nav__toggle i, .nav__toggle i::before, .nav__toggle i::after {
  display: block; width: 20px; height: 2px; background: var(--yellow); content: "";
}
.nav__toggle i { position: relative; }
.nav__toggle i::before { position: absolute; top: -6px; }
.nav__toggle i::after  { position: absolute; top: 6px; }

/* ================================================================ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s1);
  min-height: 52px; padding: 0 var(--s4);
  font: inherit; font-size: .95rem; font-weight: 600; text-decoration: none;
  border: 1px solid transparent; border-radius: 0;   /* WSP corners are square */
  cursor: pointer; transition: background .2s var(--ease), color .2s var(--ease),
    border-color .2s var(--ease);
}
/* White on red measures 4.6:1 — the reason the label is white, not yellow. */
.btn--red { background: var(--red); color: #fff; }
.btn--red:hover { background: var(--red-hot); color: #fff; }
.btn--ghost { background: transparent; color: var(--yellow); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--yellow); color: var(--yellow); }

/* =================================================================== hero */
/* WSP insets its hero media in a panel with the headline laid over it. */
.hero { padding-block: var(--s6) var(--s12); }
.hero__panel {
  position: relative; min-height: min(74vh, 720px); display: grid;
  place-items: center; text-align: center; overflow: hidden;
  background: var(--ink-2); padding: var(--s12) var(--s6);
}
/* The wordmark tile WSP runs behind its hero video, rebuilt in CSS so the
   page carries no image weight and no licensing question. */
.hero__panel::before {
  content: ""; position: absolute; inset: -10%;
  background-image: repeating-linear-gradient(
    115deg, rgba(224,47,40,.30) 0 2px, transparent 2px 108px);
  opacity: .85;
}
.hero__panel::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 50% 45%,
    rgba(18,48,15,.35) 0%, rgba(18,48,15,.86) 72%);
}
/* WSP's hero headline holds to two lines. 22ch broke ours onto six, which
   destroys the effect entirely — the display type has to run wide.
   The measure belongs on the HEADING, not the block: constraining the whole
   block also squeezed the buttons, wrapping "Discuss a project" onto two
   lines inside a 90px-wide button. */
.hero__body { position: relative; z-index: 1; max-width: min(100%, 46ch); }
.hero__body h1 { max-width: 15ch; margin-inline: auto; }
.hero__body h1 { color: var(--yellow); }
.hero__cta { margin-top: var(--s6); display: flex; gap: var(--s2); justify-content: center;
  flex-wrap: wrap; }

/* Figures strip under the hero. */
.figures { list-style: none; margin: var(--s12) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); }
.figures li { background: var(--ink); padding: var(--s4) var(--s3); }
.figures b {
  display: block; font-size: clamp(2.5rem, 5vw, 4rem); font-weight: 700;
  color: var(--yellow); letter-spacing: -.04em; line-height: 1;
}
.figures span { display: block; margin-top: var(--s2); font-size: .95rem; color: var(--muted); }
@media (max-width: 780px) { .figures { grid-template-columns: 1fr; } }

/* ============================================== section head, WSP pattern */
/* A short red eyebrow, an enormous heading, and the link pushed to the right. */
.sechead { display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s6); flex-wrap: wrap; margin-bottom: var(--s8); }
.sechead h2 { max-width: 18ch; margin-top: var(--s2); }

/* ================================================================== cards */
.grid { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1000px) { .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px)  { .grid--2, .grid--3 { grid-template-columns: 1fr; } }

.card {
  background: var(--ink); padding: var(--s4);
  display: flex; flex-direction: column; gap: var(--s2);
  transition: background .24s var(--ease);
}
a.card { text-decoration: none; color: inherit; }
.card:hover { background: var(--ink-2); }
.card__n { font-size: .78rem; font-weight: 700; letter-spacing: .16em; color: var(--red-label); }
.card p { color: var(--muted); font-size: .97rem; }
/* The arrow WSP puts on every card link, growing on hover. */
.card__go { margin-top: auto; padding-top: var(--s2); color: var(--yellow);
  font-size: .85rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: var(--s2); }
.card__go i { display: block; width: 24px; height: 2px; background: currentColor;
  transition: width .3s var(--ease); }
.card:hover .card__go i { width: 40px; }

/* ============================================================== numbered  */
/* The seven services, run as WSP runs its capability list. */
.svc { display: grid; grid-template-columns: 120px 1fr; gap: var(--s6);
  padding-block: var(--s8); border-top: 1px solid var(--line); }
.svc:first-of-type { border-top: 0; }
.svc__n { font-size: clamp(2.5rem, 5vw, 4rem); font-weight: 700; line-height: .9;
  color: var(--red); letter-spacing: -.04em; }
.svc__body h2 { font-size: clamp(1.6rem, 3vw, 2.4rem); max-width: 24ch; }
.svc__body p { margin-top: var(--s3); color: var(--muted); max-width: 70ch; }
.svc__body ul { margin: var(--s3) 0 0; padding-left: 1.1em; color: var(--muted); }
.svc__body li + li { margin-top: var(--s1); }
@media (max-width: 680px) {
  .svc { grid-template-columns: 1fr; gap: var(--s2); }
  .svc__n { font-size: 2rem; }
}

/* ================================================================ markets */
.markets { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); }
@media (max-width: 900px) { .markets { grid-template-columns: repeat(2, 1fr); } }
.market { background: var(--ink); padding: var(--s4) var(--s3);
  display: flex; flex-direction: column; gap: 6px; }
.market b { font-size: 1.15rem; color: var(--yellow); font-weight: 700; }
.market span { font-size: .88rem; color: var(--muted); }
.market__flag { font-size: 1.6rem; line-height: 1; }

/* ============================================================== gallery ==
   Photographs of real work. A dark site needs images to sit in their own
   frame, otherwise a bright factory shot glares against the deep green. */
.gal {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
@media (max-width: 1080px) { .gal { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px)  { .gal { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px)  { .gal { grid-template-columns: 1fr; } }

.shot {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--ink-2);
}
/* Portrait sources cropped to a common ratio — a mixed grid of portrait and
   landscape reads as a scrapbook, not a portfolio. */
.shot img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 1.2s var(--ease), filter .4s var(--ease);
  filter: saturate(.92);
}
.shot:hover img { transform: scale(1.05); filter: saturate(1.05); }

.shot__cap {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: 40px 16px 14px;
  background: linear-gradient(180deg, rgba(18,48,15,0) 0%, rgba(9,26,7,.92) 70%);
}
.shot__cap b {
  display: block; color: var(--yellow); font-size: .95rem; font-weight: 700;
  line-height: 1.25; letter-spacing: -.01em;
}
.shot__cap span {
  display: block; margin-top: 3px; color: var(--muted);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .14em;
  font-weight: 600;
}
/* Feature the first tile at two columns on wide screens — an unbroken 4-up
   grid of equal squares has no focal point. */
/* Opt-in feature tile. A 2x2 span consumes four cells, so a four-column grid
   only comes out flush at 5, 9, 13 ... tiles. Applied to the wrong count it
   leaves orphan cells, which is why this is a class rather than :first-child
   on every gallery — the 12-tile Projects grid is flush at 3 uniform rows. */
@media (min-width: 1081px) {
  .gal--feature .shot:first-child { grid-column: span 2; grid-row: span 2; }
  .gal--feature .shot:first-child .shot__cap b { font-size: 1.15rem; }
}

/* A photograph behind the hero, so the landing page is not a flat colour. */
.hero__panel--photo::before {
  background-image: none;
  background-size: cover; background-position: center;
  opacity: 1;
}
.hero__photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0; filter: saturate(.8) contrast(1.05);
}
.hero__panel--photo::after {
  background: linear-gradient(180deg, rgba(18,48,15,.72) 0%, rgba(9,26,7,.88) 100%);
}

/* =================================================================== form */
.form { display: grid; gap: var(--s3); }
.field { display: grid; gap: var(--s1); }
.field--row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
@media (max-width: 680px) { .field--row { grid-template-columns: 1fr; } }
label { font-size: .88rem; font-weight: 600; color: var(--body); }
input, select, textarea {
  font: inherit; font-size: 1rem; color: var(--body);
  padding: 14px var(--s2); min-height: 52px;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: 0;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
textarea { min-height: 150px; resize: vertical; }
input::placeholder, textarea::placeholder { color: #8fa87a; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--yellow);
  box-shadow: 0 0 0 3px rgba(255, 212, 0, .18);
}
.note { font-size: .88rem; color: var(--muted); }

/* Newsletter — WSP's "Keep in touch" strip. */
.keep { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.keep__in { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s6); flex-wrap: wrap; }
.keep h2 { max-width: 14ch; }
.signup { display: flex; gap: var(--s2); flex-wrap: wrap; }
.signup input { min-width: min(340px, 100%); }

/* ================================================================= footer */
.foot { background: var(--ink-3); padding-block: var(--s12) var(--s6); }
.foot a { color: var(--body); text-decoration: none; }
.foot a:hover { color: var(--yellow); }
.foot__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr; gap: var(--s6) var(--s4); }
@media (max-width: 900px) { .foot__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .foot__grid { grid-template-columns: 1fr; } }
.foot h4 { font-size: .74rem; text-transform: uppercase; letter-spacing: .18em;
  color: var(--red-label); margin-bottom: var(--s3); }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s1); font-size: .95rem; }
.foot__legal { margin-top: var(--s12); padding-top: var(--s3);
  border-top: 1px solid var(--line); display: flex; flex-wrap: wrap;
  justify-content: space-between; gap: var(--s2); font-size: .84rem; color: var(--muted); }
.foot__legal-id { display: grid; gap: 4px; }

/* ====================================================== mobile behaviour */
@media (max-width: 1080px) {
  .nav__toggle { display: inline-flex; }
  .nav__search { display: none; }
  .nav__in { min-height: 68px; }
  .nav__links {
    display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0; margin-right: 0;
    background: var(--ink-2); border-bottom: 1px solid var(--line);
    padding: var(--s2) var(--gut) var(--s4);
  }
  .nav[data-open] .nav__links { display: flex; }
  .nav__links > a { padding: 16px 0; border-bottom: 1px solid var(--line); }
  .nav__links > a::after { display: none; }
  .util__in { justify-content: center; gap: var(--s2); font-size: .78rem; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
