/* ==========================================================================
   The two faces, served from here

   They used to come from fonts.googleapis.com: a blocking request to a third
   party before any text could be drawn, and then the font files themselves on
   a second connection. From here there is no third party and no extra
   connection, and the faces the hero needs can be preloaded.

   Only the characters a visitor can see are in these files — ASCII, the
   latin-1 supplement so an accented name typed into the enquiry form still
   renders in the right face, and the punctuation the copy uses. Google's
   "latin" subset is latin for the whole world, which this page is not.

   Inter is one variable file covering every weight. Google serves it that
   way, so asking for 400, 500 and 600 fetched the same font three times.

   Rebuilt by scratch/fonts.py + scratch/subset.py if a weight is added.
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var.woff2') format('woff2-variations');
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/poppins-300.woff2') format('woff2');
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/poppins-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/poppins-500.woff2') format('woff2');
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/poppins-600.woff2') format('woff2');
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/poppins-700.woff2') format('woff2');
}

/* ==========================================================================
   Ampus Electrical

   THE DIRECTION
   -------------
   Taken from welco.com.au, which is what was asked for: a full-bleed
   photographic hero that fills the screen, type centred over it in two
   weights, pill-shaped buttons, a centred wordmark with the phone number
   always in reach, and a lot of air between sections. Soft corners
   throughout — nothing on the page is a hard-edged box.

   What makes it NOT a copy of welco: their palette is orange over bright,
   optimistic photography. This is black and red, the photography is dark,
   and the page cuts between near-black bands and white ones. Same posture,
   different temperature.

   The palette is unchanged from the previous Ampus site — --red is still
   #ca2f08, --ink is still #0a0a0a. Only the shapes, the type and the
   photography are new.
   ========================================================================== */

:root {
  --red: #ca2f08;
  --red-dark: #a32506;
  --red-tint: #fdf2ef;
  /* The brand red reads 2.5:1 on the slate band and 3.7:1 on the black one,
     both short of the 4.5:1 small text needs. This is the same hue lightened
     until it clears it: 5.2:1 and 7.6:1. */
  --red-on-dark: #ef8360;

  --ink: #0a0a0a;
  --white: #ffffff;
  --surface: #ffffff;
  --surface-alt: #f6f6f5;
  --surface-dark: #0a0a0a;
  --surface-dark-alt: #151515;

  --text: #1a1a1a;
  --text-muted: #5c5c5c;
  --text-on-dark: #ffffff;
  --text-on-dark-muted: #b4b4b4;

  --line: #e4e3e1;
  --line-dark: #2a2a2a;

  --font-display: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --fs-hero: clamp(2.4rem, 5.6vw, 4.6rem);
  --fs-h2: clamp(1.8rem, 3.4vw, 2.9rem);
  --fs-h3: clamp(1.1rem, 1.5vw, 1.3rem);
  --fs-lead: clamp(1rem, 1.25vw, 1.15rem);

  --container: 1340px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --band-y: clamp(4.5rem, 9vw, 8rem);

  /* Soft everywhere. This, more than anything, is what separates the page
     from the square-cornered version it replaces. */
  --r-card: 18px;
  --r-media: 20px;
  --r-pill: 999px;

  --shadow-soft: 0 18px 40px -24px rgba(10, 10, 10, .28);
  --shadow-lift: 0 26px 60px -28px rgba(10, 10, 10, .38);

  --head-h: 76px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* -------------------------------------------------------------------------
   Reset
   ------------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--head-h) + 12px);
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

/* height:auto matters: every <img> carries width/height attributes so the
   browser can reserve space before the file arrives, and without this the
   attribute height wins over aspect-ratio — which rendered the square
   portraits as 522x900 letterboxes. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
p { margin: 0 0 1.1em; }
ul, ol, dl { margin: 0; padding: 0; list-style: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.015em;
  font-weight: 600;
}

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

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--red); color: var(--white); padding: 12px 18px; font-weight: 600;
}
.skip:focus { left: 0; }

:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
.muted { color: var(--text-muted); font-weight: 400; }

/* -------------------------------------------------------------------------
   Pills

   Every button on the page is a pill. welco's are; the previous Ampus site's
   were 2px-radius rectangles, and swapping that one decision changes the
   temperature of the whole page.
   ------------------------------------------------------------------------- */

.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 11px 22px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-family: var(--font-display);
  font-size: .875rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background .22s var(--ease), color .22s var(--ease),
              border-color .22s var(--ease), transform .22s var(--ease);
}
.pill:hover { transform: translateY(-1px); }
.pill:active { transform: translateY(0); }
.pill--lg { padding: 15px 32px; font-size: .95rem; }
.pill--block { width: 100%; }

.pill--accent { background: var(--red); color: var(--white); border-color: var(--red); }
.pill--accent:hover { background: var(--red-dark); border-color: var(--red-dark); }

/* For a dark background: the hero and the promo band. */
.pill--outline { background: transparent; color: var(--white); border-color: rgba(255,255,255,.55); }
.pill--outline:hover { background: rgba(255,255,255,.12); border-color: var(--white); }

/* The same idea on a light one. Without this, --outline on the page's own
   surface is white text on white and the button is invisible. */
.pill--line { background: transparent; color: var(--ink); border-color: var(--line); }
.pill--line:hover { background: var(--surface-alt); border-color: var(--muted-line, var(--text-muted)); }

.pill--quiet {
  background: rgba(255,255,255,.1);
  color: var(--white);
  border-color: rgba(255,255,255,.22);
  backdrop-filter: blur(6px);
}
.pill--quiet:hover { background: rgba(255,255,255,.2); }
.pill--quiet svg {
  width: 14px; height: 14px; fill: none;
  stroke: var(--red); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* -------------------------------------------------------------------------
   Header
   ------------------------------------------------------------------------- */

.head {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  transition: background .3s var(--ease), border-color .3s var(--ease);
  border-bottom: 1px solid transparent;
}
/* Transparent over the photograph, solid once the page moves — the hero is
   the brand statement and a bar across it would blunt it. */
.head.is-stuck {
  background: rgba(10, 10, 10, .92);
  backdrop-filter: blur(10px);
  border-bottom-color: var(--line-dark);
}

.head__inner {
  height: var(--head-h);
  max-width: 1360px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 20px;
}

.head__nav { display: flex; align-items: center; gap: clamp(14px, 2vw, 28px); }
.head__nav a {
  color: rgba(255,255,255,.82);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 400;
  transition: color .2s var(--ease);
}
.head__nav a:hover, .head__nav a.is-current { color: var(--white); }

.head__brand {
  justify-self: center;
  display: flex;
  /* The brand used to be a lone <img> inside this link, so the underline a
     link carries by default had nothing to draw on. It holds text now, and
     without this the word wears a rule straight through it — in the link's
     own inherited colour, which is the dark ink, so over a pale section it
     read as a black bar beside the mark. */
  text-decoration: none;
  color: var(--white);
}

/* ---- The lockup ----

   Two things rather than one picture, so the mark and the name can be
   sized against each other instead of scaling together. Everything here
   hangs off --mark: the word is a fraction of it, and so is the gap.

   --word is the word's cap height as a fraction of the mark. Poppins sits
   at roughly .70em cap, which is what turns that into a font-size. */
.brand {
  display: inline-flex;
  align-items: center;
  --mark: 56px;
  --word: .50;
  gap: calc(var(--mark) * .30);
}
.brand__mark { height: var(--mark); width: auto; display: block; flex: none; }
.brand__word {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(var(--mark) * var(--word) / .70);
  line-height: 1;
  letter-spacing: .28em;
  /* Tracking puts a gap after the S as well as between the letters, which
     throws the whole lockup off centre in the header. */
  margin-right: -.28em;
  color: var(--white);
  white-space: nowrap;
}

.head__actions { justify-self: end; display: flex; align-items: center; gap: 10px; }

.burger {
  display: none;
  width: 42px; height: 42px; padding: 0;
  border: 1px solid rgba(255,255,255,.25);
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.1);
  cursor: pointer;
}
.burger span {
  display: block; width: 17px; height: 1.6px; margin: 4px auto;
  background: var(--white);
  transition: transform .25s var(--ease), opacity .2s var(--ease);
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.6px) rotate(-45deg); }

@media (max-width: 1020px) {
  .head__nav--left { display: none; }
  .head__inner { grid-template-columns: auto 1fr auto; }
  .head__brand { justify-self: start; }
  .burger { display: block; }
}
@media (max-width: 620px) {
  .head__cta, .pill--quiet span { display: none; }
  .pill--quiet { padding: 11px 14px; }
}

/* ---- Drawer ---- */

.drawer {
  position: fixed; inset: 0; z-index: 190;
  background: var(--surface-dark);
  padding: calc(var(--head-h) + 30px) var(--gutter) 40px;
  display: flex; flex-direction: column; gap: 26px;
  overflow-y: auto;
}
.drawer[hidden] { display: none; }
.drawer nav { display: flex; flex-direction: column; }
.drawer nav a {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--white);
  text-decoration: none;
  padding: 16px 0;
  border-bottom: 1px solid var(--line-dark);
}
.drawer .pill { align-self: flex-start; }

/* -------------------------------------------------------------------------
   Hero — the whole point of the redesign
   ------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  color: var(--white);
  /* Was 120px at the foot to clear the scroll cue. With that gone the block
     is centred properly, with just enough bottom bias to keep it off the
     credentials band. */
  padding: calc(var(--head-h) + 40px) var(--gutter) 70px;
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; }
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* A slow drift, so the photograph is alive without anything moving on
     scroll — parallax on a contractor's site is a liability on a phone. */
  animation: drift 26s var(--ease) infinite alternate;
}
@keyframes drift {
  from { transform: scale(1.06) translate3d(0, 0, 0); }
  to   { transform: scale(1.14) translate3d(0, -1.4%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__media img { animation: none; transform: scale(1.06); }
}

/* Two layers: a wash for legibility, and a heavier foot so the credentials
   band below reads as part of the same object. */
.hero__media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(10,10,10,.78) 0%, rgba(10,10,10,.5) 38%, rgba(10,10,10,.82) 100%),
    linear-gradient(90deg, rgba(202,47,8,.16) 0%, transparent 42%);
}

.hero__body { position: relative; max-width: 940px; }

.hero__kicker {
  margin: 0 0 22px;
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: rgba(255,255,255,.72);
}

.hero__title { font-size: var(--fs-hero); margin: 0; text-wrap: balance; }
/* The welco device: one line light, the next heavy. Their light line is a
   greeting; here it is the substance and the heavy line is the promise. */
.hero__title-light { display: block; font-weight: 300; letter-spacing: -0.01em; }
.hero__title-bold  { display: block; font-weight: 700; }

.hero__lede {
  margin: 26px auto 0;
  max-width: 54ch;
  font-size: var(--fs-lead);
  color: rgba(255,255,255,.84);
}

.hero__actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;
  margin-top: 34px;
}

/* -------------------------------------------------------------------------
   Credentials
   ------------------------------------------------------------------------- */

.creds { background: var(--surface-dark); color: var(--text-on-dark); }
.creds__grid {
  display: grid;
  /* Sized by what is in it rather than by a number written down here: the
     band held four credentials, holds three now, and should not need this
     line edited again to hold a different number. */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  padding-block: clamp(2rem, 4vw, 3.2rem);
}
.cred { text-align: center; padding: 10px 16px; position: relative; }
.cred + .cred::before {
  content: ''; position: absolute; left: 0; top: 12%; bottom: 12%;
  width: 1px; background: var(--line-dark);
}
.cred__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.3rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--white);
}
.cred__value--sm { font-size: 1rem; font-weight: 500; line-height: 1.5; padding-top: .4em; }
.cred__label {
  display: block; margin-top: 8px;
  font-size: .73rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
@media (max-width: 800px) {
  .creds__grid { row-gap: 16px; padding-block: 2.4rem; }
  /* The divider sits on the left edge of every credential after the first,
     which reads as a column rule while they are in columns and as a stray
     line hanging beside one once they stack. The gap separates them here. */
  .cred + .cred::before { display: none; }
  .cred:nth-child(odd)::before { display: none; }
}

/* -------------------------------------------------------------------------
   Bands and the centred section lede
   ------------------------------------------------------------------------- */

.band { padding-block: var(--band-y); }
.band--tint { background: var(--surface-alt); }
.band--dark { background: var(--surface-dark); color: var(--text-on-dark); }

.lede {
  margin: 0 0 clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  column-gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
  text-align: left;
}
.lede .kicker { grid-column: 1; grid-row: 1; }
.lede h2 {
  grid-column: 1; grid-row: 2;
  font-size: var(--fs-h2);
  text-wrap: balance;
  max-width: 18ch;
}
.lede__text {
  grid-column: 2; grid-row: 1 / span 2;
  align-self: end;
  margin: 0;
  max-width: 54ch;
  font-size: var(--fs-lead);
  color: var(--text-muted);
}

/* Stacked below the split, where two columns would leave both too narrow
   to read. */
@media (max-width: 900px) {
  .lede { grid-template-columns: 1fr; }
  .lede .kicker, .lede h2, .lede__text { grid-column: 1; }
  .lede h2 { grid-row: auto; max-width: none; }
  .lede .kicker { grid-row: auto; }
  .lede__text { grid-row: auto; margin-top: 18px; max-width: none; }
}
.lede--light .lede__text { color: var(--text-on-dark-muted); }

.kicker {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--red);
}

/* Over a dark band the kicker is 11.5px of brand red on near-black, which is
   not readable and does not pass. Same hue, lighter. */
.aow .kicker,
.band--dark .kicker,
.promo .kicker { color: var(--red-on-dark); }

/* -------------------------------------------------------------------------
   Text + picture pairs
   ------------------------------------------------------------------------- */

.duo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.duo--reverse .duo__media { order: -1; }
@media (max-width: 880px) {
  .duo { grid-template-columns: 1fr; }
  .duo--reverse .duo__media { order: 0; }
}

.duo__text p { color: var(--text-muted); }
.duo__title { font-size: var(--fs-h2); margin-bottom: 18px; text-wrap: balance; }
.duo__sub { font-size: var(--fs-h3); margin: 26px 0 14px; }

.duo__media { margin: 0; }
.duo__media img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--r-media);
  box-shadow: var(--shadow-soft);
}

/* ---- About our work: the horizontal accordion ----

   Modelled on the Leroux "About our work" panel the client sent. Collapsed
   panels are narrow strips carrying a vertical label and an oversized ghost
   numeral; the one under the pointer opens and plays its clip.

   The palette is sampled from that reference rather than guessed — the band
   is its blue-grey rather than the site's near-black, which is what was
   asked for. It is the one place on the page that leaves the black-and-red
   scheme; swapping --aow-bg for var(--ink) puts it back if that reads wrong
   beside everything else.
   ------------------------------------------------------------------------- */

.aow {
  --aow-bg: #223035;
  --aow-ink: #afc1c5;
  --aow-line: rgba(150, 162, 162, .28);
  --aow-arrow: #515d61;

  background: var(--aow-bg);
  color: var(--aow-ink);
  /* The strip reaches the window edges, so the band carries no side padding
     of its own below the heading. */
  padding-bottom: 0;
  overflow: hidden;
}
.aow .lede h2 { color: #dfe8ea; }
.aow .lede__text { color: rgba(175, 193, 197, .82); }

.aow__strip {
  display: flex;
  align-items: stretch;
  min-height: clamp(420px, 52vw, 560px);
  border-top: 1px solid var(--aow-line);
}

.aow__panel {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 26px 0 0;
  border-left: 1px solid var(--aow-line);
  cursor: pointer;
  /* flex-grow animates reliably; animating grid columns does not, in every
     browser this has to run in. */
  transition: flex-grow .55s var(--ease), background .4s var(--ease);
}
.aow__panel:last-child { border-right: 1px solid var(--aow-line); }
.aow__panel:hover { background: rgba(255, 255, 255, .02); }
.aow__panel.is-active { flex-grow: 4.6; background: rgba(255, 255, 255, .03); }

/* ---- the rail: arrow, vertical label, ghost numeral ---- */

.aow__rail {
  flex: none;
  width: clamp(64px, 6vw, 92px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}
.aow__arrow {
  width: 30px; height: 30px;
  fill: none; stroke: var(--aow-arrow); stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
  transition: stroke .35s var(--ease), transform .45s var(--ease);
}
.aow__panel.is-active .aow__arrow { stroke: var(--aow-ink); transform: rotate(45deg); }

.aow__label {
  writing-mode: vertical-rl;
  /* Rotated so it reads bottom-to-top, the way the reference sets it. */
  transform: rotate(180deg);
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.3vw, 1.25rem);
  font-weight: 400;
  letter-spacing: .02em;
  color: rgba(175, 193, 197, .72);
  transition: color .35s var(--ease);
}
.aow__panel.is-active .aow__label { color: var(--aow-ink); }

/* The numeral is drawn rather than written: on a desktop it is 13% of a pale
   grey over slate, which is texture, not text, and a checker reading it as
   text is right to fail it. The element already said aria-hidden; generated
   content says the same thing to everything that looks. */
.aow__num::before { content: attr(data-num); }

.aow__num {
  font-family: var(--font-display);
  font-size: clamp(4.5rem, 8vw, 7.5rem);
  font-weight: 600;
  line-height: .78;
  letter-spacing: -.04em;
  color: rgba(175, 193, 197, .13);
  /* Deliberately running off the bottom edge, as in the reference — the
     numeral is texture as much as a label. */
  margin-bottom: -.22em;
  user-select: none;
}
.aow__panel.is-active .aow__num { color: rgba(175, 193, 197, .2); }

/* ---- the content that opens ---- */

.aow__content {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(16px, 2vw, 26px);
  padding: 0 clamp(18px, 2.5vw, 44px) 26px;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s var(--ease), visibility 0s linear .35s;
}
.aow__panel.is-active .aow__content {
  opacity: 1;
  visibility: visible;
  transition: opacity .45s var(--ease) .12s, visibility 0s;
}

.aow__title {
  font-size: clamp(1.2rem, 1.9vw, 1.75rem);
  font-weight: 500;
  color: #dfe8ea;
  max-width: 20ch;
}
.aow__content video {
  width: 100%;
  /* Wide enough to fill the panel it opens into — at 620px the open panel
     was a third empty to the right of the clip. */
  max-width: 820px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 14px;
  display: block;
}

/* ---- Stacked on small screens ----

   A row of four narrow strips is unusable on a phone: there is no width to
   open into. Each step becomes a full-width row instead, its label reading
   normally, with the clip beneath the one that is open. */

@media (max-width: 900px) {
  .aow__strip {
    flex-direction: column;
    min-height: 0;
    border-bottom: 1px solid var(--aow-line);
  }
  .aow__panel {
    flex: none;
    display: block;
    padding: 0;
    border-left: 0;
    border-top: 1px solid var(--aow-line);
  }
  .aow__panel:first-child { border-top: 0; }
  .aow__panel:last-child { border-right: 0; }
  .aow__panel.is-active { flex-grow: 0; }

  .aow__rail {
    width: auto;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    padding: 18px var(--gutter);
  }
  .aow__label {
    writing-mode: horizontal-tb;
    transform: none;
    font-size: 1.05rem;
    order: 2;
  }
  .aow__arrow { width: 22px; height: 22px; order: 3; margin-left: auto; }
  .aow__num {
    font-size: 1.05rem;
    line-height: 1;
    margin: 0;
    order: 1;
    color: rgba(175, 193, 197, .72);
  }
  .aow__panel.is-active .aow__num { color: var(--aow-ink); }

  .aow__content {
    padding: 0 var(--gutter) 24px;
    /* Collapsed rather than merely transparent, so the closed steps take no
       vertical space on a phone. */
    display: none;
  }
  .aow__panel.is-active .aow__content { display: flex; }
  .aow__title { font-size: 1.1rem; max-width: none; }
  /* Let the ratio set the height instead of the height attribute. */
  .aow__content video { height: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .aow__panel,
  .aow__content,
  .aow__arrow { transition: none; transition-delay: 0s !important; }
}

/* -------------------------------------------------------------------------
   Service tiles
   ------------------------------------------------------------------------- */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}
.tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(1.5rem, 2.4vw, 2rem);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: transparent;
}
.tile__icon {
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border-radius: 14px;
  background: var(--red-tint);
  margin-bottom: 18px;
}
.tile__icon svg {
  width: 22px; height: 22px;
  fill: none; stroke: var(--red); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.tile h3 { font-size: var(--fs-h3); margin-bottom: 14px; }
.tile ul li {
  position: relative;
  padding: 6px 0 6px 18px;
  font-size: .9rem;
  color: var(--text-muted);
}
.tile ul li::before {
  content: '';
  position: absolute; left: 0; top: 1.05em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--red);
  opacity: .55;
}

/* -------------------------------------------------------------------------
   Capability checks
   ------------------------------------------------------------------------- */

.checks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(14px, 1.6vw, 20px);
}
.checks li {
  position: relative;
  background: var(--surface-dark-alt);
  border: 1px solid var(--line-dark);
  border-radius: var(--r-card);
  padding: 24px 24px 24px 62px;
  font-size: .94rem;
  color: var(--text-on-dark);
}
.checks li::before {
  content: '';
  position: absolute; left: 26px; top: 29px;
  width: 12px; height: 7px;
  border-left: 2px solid var(--red);
  border-bottom: 2px solid var(--red);
  transform: rotate(-45deg);
}

/* -------------------------------------------------------------------------
   Projects
   ------------------------------------------------------------------------- */

.work__card {
  background: var(--surface);
  border-radius: var(--r-media);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
}
.work__card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lift); }

.work__media { position: relative; overflow: hidden; }
.work__shot {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
/* Where a project has two photographs, the second lies over the first and
   comes up on hover: a second look at the job without a second card. */
.work__media--pair .work__shot--alt {
  position: absolute;
  inset: 0;
  height: 100%;
  opacity: 0;
  transition: opacity .5s var(--ease);
}
.work__card:hover .work__shot--alt,
.work__card:focus-within .work__shot--alt { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .work__media--pair .work__shot--alt { transition: none; }
}

/* ---- The strip ----

   The nine cards run off the right-hand edge instead of wrapping. By default
   that is a plain horizontal scroller: it works with no script, on a phone,
   and from the keyboard. Where the script can do better it pins the strip and
   hands it the page scroll, so scrolling down walks sideways through the
   projects — the ScrollTrigger gallery, without the paid smoother. */
.rail__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.rail__viewport::-webkit-scrollbar { display: none; }

.rail__strip {
  display: flex;
  flex-wrap: nowrap;
  width: max-content;
  gap: clamp(16px, 1.8vw, 26px);
  /* The first card lines up with the heading above it, whatever the width. */
  padding: 4px calc(max(0px, (100vw - var(--container)) / 2) + var(--gutter)) 12px;
  will-change: transform;
}
.rail__item {
  flex: 0 0 clamp(264px, 25vw, 358px);
  scroll-snap-align: center;
}
/* Tighter than a card in a grid. Pinned, the whole block — heading, strip
   and bar — has to fit inside a laptop screen under the header, and the
   tallest card sets the height for all nine. */
.rail__item .work__body { padding: 16px 18px 18px; }
/* A shade wider than the 3:2 used elsewhere, which is 15px of height saved on
   every card — the difference between the block fitting a 900px laptop
   window under the header and not. */
.rail__item .work__shot { aspect-ratio: 16 / 10; }
.rail__item .work__body h3 { font-size: 1.06rem; line-height: 1.25; margin-bottom: 7px; }
.rail__item .work__body p { font-size: .875rem; line-height: 1.5; }
/* Every card is as tall as the tallest, so the tags are dropped to the
   bottom edge rather than left floating under short copy: nine cards, one
   baseline. */
.rail__item { display: flex; flex-direction: column; }
.rail__item .work__body { flex: 1; display: flex; flex-direction: column; }
.rail__item .chips { margin-top: auto; padding-top: 14px; gap: 6px; }

/* Narrow, where the strip is swiped rather than pinned.

   One height for all nine is worth having while they stand in a row and you
   can see the bottoms line up. On a phone you see one card, so all it buys
   is the tallest card's height under the shortest card's copy — a 160px of
   white between the description and the tags, in the middle of the card.
   Letting each card end where its content ends puts that space outside the
   cards, where the background already is and nobody reads it. */
@media (max-width: 899px) {
  .rail__item { flex-basis: min(82vw, 340px); }
  .rail__strip { align-items: flex-start; }
  .rail__item .work__body { flex: 0 0 auto; }
  .rail__item .chips { margin-top: 0; }
  /* The card is wider here than in the pinned row, so the tags can be too. */
  .rail__item .chips li { font-size: .76rem; padding: 6px 12px; }
}
.rail__item .chips li { font-size: .72rem; padding: 5px 11px; }

/* Pinned: the viewport stops scrolling itself, because the tween is moving
   the strip instead. */
.rail.is-pinned .rail__viewport { overflow: hidden; scroll-snap-type: none; }
.rail > .wrap > .lede { margin-bottom: clamp(1rem, 2vw, 1.5rem); }

/* How far through the strip you are. Pinned, the page stops moving, so
   without this there is nothing to say the section has an end. */
.rail__bar {
  height: 3px;
  border-radius: 3px;
  background: var(--line);
  overflow: hidden;
  margin-top: clamp(.85rem, 1.6vw, 1.25rem);
}
.rail__bar span {
  display: block;
  height: 100%;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
}
.work__sector {
  position: absolute; left: 16px; bottom: 16px;
  background: var(--red); color: var(--white);
  font-family: var(--font-display);
  font-size: .68rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 7px 14px;
  border-radius: var(--r-pill);
}
.work__body { padding: 24px; }
.work__body h3 { font-size: var(--fs-h3); margin-bottom: 10px; }
.work__body p { color: var(--text-muted); font-size: .94rem; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips li {
  font-size: .76rem;
  color: var(--text-muted);
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 6px 13px;
}
.chips--lg li { font-size: .85rem; padding: 8px 16px; background: var(--surface); }

/* -------------------------------------------------------------------------
   Clients
   ------------------------------------------------------------------------- */

.clients {
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
}
.clients h3 { font-size: var(--fs-h3); margin-bottom: 22px; }
.clients__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.clients__list li {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px;
  font-size: .9rem;
  font-weight: 500;
}

/* -------------------------------------------------------------------------
   People
   ------------------------------------------------------------------------- */

.people {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}
.person { text-align: center; }
.person img {
  width: 180px; height: 180px;
  margin: 0 auto 22px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  box-shadow: var(--shadow-soft);
}
.person h3 { font-size: 1.35rem; }
.person__role {
  margin: 6px 0 18px;
  font-family: var(--font-display);
  font-size: .72rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--red);
}
.person p { color: var(--text-muted); font-size: .94rem; }
.person .chips { justify-content: center; }

/* -------------------------------------------------------------------------
   Promo band over photography
   ------------------------------------------------------------------------- */

.promo {
  position: relative;
  color: var(--white);
  text-align: center;
  padding-block: clamp(4rem, 9vw, 7rem);
  overflow: hidden;
}
.promo__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.promo::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,10,10,.82), rgba(10,10,10,.72));
}
.promo__inner { position: relative; z-index: 1; }
.promo h2 { font-size: var(--fs-h2); max-width: 20ch; margin: 0 auto; text-wrap: balance; }
.promo p { margin: 18px auto 0; color: rgba(255,255,255,.82); max-width: 50ch; }
.promo__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 30px; }

/* -------------------------------------------------------------------------
   Contact
   ------------------------------------------------------------------------- */

.contact {
  display: grid;
  /* One column since the address block came off. What is left beside the
     form is three lines of registration detail, which does not earn half a
     row next to a form 800px tall - it goes under it, where fine print
     goes, and the form keeps the width they were sharing. */
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  max-width: 760px;
  margin-inline: auto;
}
.contact__side { order: 2; }
.contact .card { order: 1; }
@media (max-width: 880px) { .contact { grid-template-columns: 1fr; } }

.info { margin-bottom: 34px; }
.info dt {
  font-family: var(--font-display);
  font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 20px;
}
.info dt:first-child { margin-top: 0; }
.info dd { margin: 6px 0 0; font-size: 1.05rem; font-weight: 500; }
.info--small dd { font-size: .95rem; font-weight: 400; color: var(--text-muted); }
.info a { text-decoration: none; border-bottom: 1px solid var(--red); }
.info a:hover { color: var(--red); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-media);
  box-shadow: var(--shadow-soft);
  padding: clamp(1.6rem, 3vw, 2.4rem);
}
.card h3 { font-size: var(--fs-h3); margin-bottom: 22px; }

.field { margin-bottom: 20px; }
.field label {
  display: block;
  font-family: var(--font-display);
  font-size: .78rem; font-weight: 600;
  letter-spacing: .06em;
  margin-bottom: 8px;
}
.req { color: var(--red); }

.field input, .field textarea {
  width: 100%;
  padding: 13px 16px;
  font: inherit;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: 12px;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.field input:focus, .field textarea:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-tint);
}
.field textarea { resize: vertical; min-height: 120px; }

.field__hint { margin: 8px 0 0; font-size: .78rem; color: var(--text-muted); }
.field__error {
  display: none;
  margin: 8px 0 0;
  font-size: .78rem; font-weight: 500; color: var(--red-dark);
}
.field.is-invalid .field__error { display: block; }
.field.is-invalid input, .field.is-invalid textarea { border-color: var(--red); }

.form__note { margin: 18px 0 0; font-size: .8rem; color: var(--text-muted); }
.form__note a { color: var(--red); }
.form__note.is-error { color: var(--red-dark); font-weight: 500; }

/* The honeypot. Taken off the page rather than given display:none, because
   some bots skip anything that is display:none and fill in everything else.
   Nothing here is reachable by tab or read by a screen reader. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------------------------
   Thank you

   Where a form post lands with JavaScript off. One card, centred, tall
   enough that the footer does not ride up under it on a desktop.
   ------------------------------------------------------------------------- */
.thanks {
  display: grid;
  place-items: center;
  min-height: calc(100svh - var(--head-h) - 120px);
  padding-block: clamp(2.5rem, 7vw, 5rem);
  text-align: center;
}
.thanks__card { max-width: 540px; }

.thanks__tick {
  display: grid;
  place-items: center;
  width: 62px; height: 62px;
  margin: 0 auto 22px;
  border-radius: 50%;
  background: var(--red-tint);
}
.thanks__tick svg {
  width: 28px; height: 28px;
  fill: none; stroke: var(--red); stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.thanks h1 {
  font-size: var(--fs-h2);
  margin: 0 0 14px;
  text-wrap: balance;
}
.thanks__lede {
  font-size: 1.05rem;
  color: var(--text-muted);
  margin: 0 0 12px;
  text-wrap: pretty;
}
.thanks__urgent { color: var(--text-muted); margin: 0 0 30px; }
.thanks__urgent a {
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--red);
  text-underline-offset: 4px;
}
.thanks__actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}
@media (max-width: 520px) {
  /* Two pills of different widths stacked centrally reads as a mistake, and
     the wider target is easier to hit. */
  .thanks__actions { flex-direction: column; align-items: stretch; }
  .thanks__actions .pill { width: 100%; }
}

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */

.foot {
  background: var(--surface-dark);
  color: var(--text-on-dark-muted);
  padding-top: clamp(3rem, 6vw, 4.5rem);
  font-size: .9rem;
}
.foot__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(1.8rem, 4vw, 3rem);
  padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
@media (max-width: 880px) { .foot__inner { grid-template-columns: repeat(2, 1fr); } }
/* Still two columns on a phone, because one made the footer a thousand pixels
   of scrolling for four short lists. The brand and the address keep the full
   width — one is a lockup and the other is a street address — and the two
   link lists sit side by side between them. */
@media (max-width: 520px) {
  .foot__inner { grid-template-columns: repeat(2, 1fr); column-gap: 1.25rem; }
  /* The lockup and the address: one is a lockup, the other is a street
     address, and neither belongs in half a column. The address is the last
     thing in the footer rather than a class of its own. */
  .foot__brand,
  .foot__inner > :last-child { grid-column: 1 / -1; }
}

.foot__brand .brand { --mark: 32px; }
.foot__brand p {
  margin: 18px 0 0;
  font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
  /* Four disciplines over two lines, rather than three and "Energy". */
  text-wrap: balance;
}
.foot h4 {
  font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--white);
  margin-bottom: 16px;
}
.foot__col { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; }
.foot__col a { text-decoration: none; }
.foot__col a:hover { color: var(--red); }
.foot__col p { margin: 0; }

.foot__legal {
  border-top: 1px solid var(--line-dark);
  padding-block: 22px;
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px;
  font-size: .76rem;
}
.foot__legal p { margin: 0; }

/* =========================================================================
   Phone

   Measured at 390px rather than guessed. Three things were wrong: seventeen
   tap targets came in under the 44px that a thumb needs — footer links were
   21px tall — the hero kicker broke across two lines with one word stranded,
   and the two hero buttons were different widths, which reads as an
   accident.
   ========================================================================= */

@media (max-width: 720px) {

  /* The footer's own spacing, which is about the column and not the finger.
     The tap targets themselves are below, under pointer: coarse. */
  .foot__col { gap: 0; }
  /* Deliberately left inline. This is a phone number inside a sentence, and
     WCAG exempts targets in a block of text for good reason: padding it out
     to 44px would break the line spacing of the paragraph around it. */
  /* Underlined because the line is narrow and the link needs to be findable
     in it. How big it is to hit is a question for the finger, and is answered
     under `pointer: coarse` below. */
  .form__note a { text-decoration: underline; text-underline-offset: 3px; }

  /* ---- Hero ---- */

  .hero__kicker {
    /* Tighter so the four disciplines sit on one line instead of stranding
       "Energy" on a line of its own — but tighter rather than smaller. At
       .62rem this was under 10px, which is small for the first words on the
       page; the tracking is what buys the line back. */
    font-size: .7rem;
    letter-spacing: .05em;
    margin-bottom: 16px;
    /* Below about 340px it does not fit on one line at any size worth
       reading, so it wraps — evenly, rather than dropping "Energy" on a
       line by itself. */
    text-wrap: balance;
  }
  .hero__title { font-size: clamp(2.1rem, 9vw, 2.9rem); }
  .hero__lede { font-size: .98rem; margin-top: 20px; }

  .hero__actions {
    /* Full width and equal: two pills of different widths stacked centrally
       looks like a mistake, and a full-width target is easier to hit. */
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    margin-top: 28px;
  }
  .hero__actions .pill { width: 100%; }

  /* The same pair of buttons closes the page, so it gets the same shape. */
  .promo__actions { flex-direction: column; align-items: stretch; gap: 10px; }
  .promo__actions .pill { width: 100%; }

  /* ---- Credentials ----

     The labels are the longest text in the band and were running to three
     lines against a two-line neighbour, which left the dividers straddling
     unequal rows. */
  .cred { padding: 12px 10px; }
  .cred__label { font-size: .7rem; letter-spacing: .08em; }
  .cred__value { font-size: 1.5rem; }
  .cred__value--sm { font-size: .92rem; }

  /* ---- Leadership: collapse the long bios ----

     Two five-line paragraphs each is a wall of text on a phone, and the
     second profile is below it. The clamp is applied by the script, not by
     this file: with JavaScript off the bios stay open and the button stays
     hidden, because a Read more control that cannot expand anything is
     worse than no control at all. */

  .person.is-clamped .person__bio {
    max-height: 7.8em;
    overflow: hidden;
  }
  /* Fades the cut rather than slicing a line of text in half. */
  .person.is-clamped .person__bio::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0;
    height: 3.2em;
    background: linear-gradient(to bottom, transparent, var(--surface));
    pointer-events: none;
  }
  .person__bio { position: relative; }

  .person__more {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 6px;
    padding: 11px 4px;
    min-height: 44px;
    border: 0;
    background: none;
    font-family: var(--font-display);
    font-size: .88rem;
    font-weight: 600;
    color: var(--red);
    cursor: pointer;
  }
  .person__more svg {
    width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 2.2;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform .25s var(--ease);
  }
  /* The chevron points down to open and up to close. */
  .person.is-clamped .person__more svg { transform: rotate(0deg); }
  .person__more svg { transform: rotate(180deg); }

  /* ---- Rhythm ----

     The desktop band spacing is generous by design; on a phone it turns into
     a lot of scrolling past nothing. */
  .band { padding-block: clamp(3rem, 12vw, 4.5rem); }
  .promo { padding-block: clamp(3rem, 12vw, 4.5rem); }
}

/* -------------------------------------------------------------------------
   Reveal — behind a class the script adds, so with JavaScript off the page
   is simply visible rather than a column of blank space.
   ------------------------------------------------------------------------- */

.js .reveal { opacity: 0; transform: translateY(20px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.js .reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; } }

/* -------------------------------------------------------------------------
   Safety and Quality: the prose folds on a phone

   Same control and same wording as the leadership bios, because a second way
   of doing the same thing is a thing to learn for no reason. The clamp is
   applied by script, so with JavaScript off every word is there and no
   button appears.
   ------------------------------------------------------------------------- */
@media (max-width: 720px) {
  .duo__copy { position: relative; }
  .duo.is-clamped .duo__copy {
    max-height: 9.5em;
    overflow: hidden;
  }
  /* Faded rather than cut, so it reads as folded rather than broken. */
  .duo.is-clamped .duo__copy::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0; height: 3.2em;
    background: linear-gradient(to bottom, transparent, var(--surface-alt));
    pointer-events: none;
  }
  .duo__more {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 2px;
    padding: 11px 4px;
    min-height: 44px;
    border: 0;
    background: none;
    font-family: var(--font-display);
    font-size: .88rem;
    font-weight: 600;
    color: var(--red);
    cursor: pointer;
  }
  .duo__more svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2.2;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform .25s var(--ease);
  }
  .duo.is-clamped .duo__more svg { transform: rotate(0deg); }
  .duo__more svg { transform: rotate(180deg); }
}

/* -------------------------------------------------------------------------
   Contact, on a phone

   The address block came first and ran to 639px, so the form it introduces
   was most of a screen below the heading. On a wide layout the two sit side
   by side and the order means nothing; stacked, it means everything.
   ------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* One voice for the whole block. The address, phone, email and website
     were set a size up and a weight heavier than the entity and ABN right
     below them, which made one list look like two. They are all the same
     kind of fact, below a form rather than competing with it, so they are
     all the quieter treatment. */
  /* Only .info--small is left wearing these classes - the address block
     came off the page - so this is the fine print's own type. */
  .info { margin-bottom: 16px; }
  .info dt {
    margin: 0;
    font-size: .64rem;
    letter-spacing: .1em;
  }
  /* The same size, weight and colour as the entity and ABN below: they are
     the same kind of fact, and two treatments made one list look like two. */
  .info dd {
    margin: 0;
    font-size: .86rem;
    font-weight: 400;
    color: var(--text-muted);
    line-height: 1.45;
  }
  .info dt:not(:first-child),
  .info dt:not(:first-child) + dd { margin-top: 8px; }

  /* The entity, the ABN and the insurances are fine print, and reading them
     as four separate labelled rows gave them the weight of the address.
     One small block, labels inline. */
  .info--small {
    display: block;
    border-top: 1px solid var(--line);
    padding-top: 14px;
    margin-bottom: 0;
  }
  /* Three facts, three lines. Running them together with a middle dot
     between each wrapped so that a line began with the dot. */
  .info--small dd {
    display: block;
    font-size: .86rem;
    margin: 0 0 4px;
    line-height: 1.45;
  }
  .info--small dd:last-of-type { margin-bottom: 0; }

  /* "Ampus Electrical Pty Ltd" does not need telling it is an entity, and a
     list of policies does not need telling it is insurances. The ABN does
     need its three letters, so that one label stays. */
  .info--small dt { display: none; }
  .info--small dt:nth-of-type(2) {
    display: inline;
    transform: none;
    font-size: .64rem;
  }
  .info--small dt:nth-of-type(2) + dd { display: inline; }
}

/* -------------------------------------------------------------------------
   Quality assurance, on a phone

   Four pills at .85rem with 16px of side padding came to 280px each, so
   every one took a row of its own: 188px for four short phrases. Smaller
   type and tighter padding lets the short ones share a row.
   ------------------------------------------------------------------------- */
@media (max-width: 720px) {
  .chips--lg {
    display: grid;
    gap: 7px;
  }
  .chips--lg li {
    /* No pill: the border was drawing a button around a sentence. */
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0 0 0 24px;
    font-size: .92rem;
    line-height: 1.4;
    color: var(--ink);
    position: relative;
  }
  /* A tick, drawn rather than typed, so it keeps its weight next to the
     text at any size and needs no font that has the glyph. */
  .chips--lg li::before {
    content: '';
    position: absolute;
    left: 2px; top: .34em;
    width: 11px; height: 6px;
    border-left: 2px solid var(--red);
    border-bottom: 2px solid var(--red);
    transform: rotate(-45deg);
  }
}

/* -------------------------------------------------------------------------
   The four steps, swiped

   On a wide screen the panels open on hover, which is the whole point of
   them. A phone has no hover, and tapping each one in turn is a worse
   version of the same idea - so the panels become cards swiped sideways,
   the same gesture as the projects strip further down the page, and there
   is one thing to learn rather than two.
   ------------------------------------------------------------------------- */
/* The dots belong to the carousel. The script adds them whatever the width,
   so above the breakpoint they have to be taken off the page rather than
   merely left unstyled - an unstyled <ul> is still a list taking up room,
   and it was adding 109px to the desktop layout. */
.aow__dots { display: none; }

@media (max-width: 900px) {
  .aow__strip {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* Both off here. They divide the panel grid on a desktop; once the
       panels are separate cards with their own borders, the strip's rule is
       a line hanging above them across the whole screen. */
    border-top: 0;
    border-bottom: 0;
    /* The first card lines up with the heading above it, and the last one
       can still reach the middle of the screen. */
    padding-inline: var(--gutter);
    gap: 14px;
  }
  .aow__strip::-webkit-scrollbar { display: none; }

  .aow__panel {
    flex: 0 0 min(86vw, 420px);
    scroll-snap-align: center;
    border: 1px solid var(--aow-line);
    border-radius: var(--r-card);
    background: rgba(255, 255, 255, .02);
    overflow: hidden;
    display: block;
  }
  .aow__panel:first-child,
  .aow__panel:last-child { border-top: 1px solid var(--aow-line); }

  .aow__rail {
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 16px 18px 10px;
  }
  .aow__label { writing-mode: horizontal-tb; transform: none; font-size: 1.05rem; order: 2; }
  .aow__num   { font-size: 1.05rem; line-height: 1; margin: 0; order: 1; color: var(--aow-ink); }
  .aow__arrow { width: 20px; height: 20px; order: 3; margin-left: auto; opacity: .5; }

  /* Every card shows its own content — that is the point of the carousel.
     The rule that collapsed the closed ones belongs to the accordion. */
  .aow__content {
    display: flex !important;
    opacity: 1;
    visibility: visible;
    padding: 0 18px 18px;
    gap: 14px;
  }
  .aow__title { font-size: 1.05rem; max-width: none; }
  .aow__content video { height: auto; border-radius: 10px; }

  /* Nothing is dimmed or lifted: there is no "selected" card, only the one
     in front of you. */
  .aow__panel.is-active { flex-grow: 0; background: rgba(255, 255, 255, .02); }

  /* Which of the four you are on. A carousel with no dots is a carousel
     people do not know is a carousel. */
  .aow__dots {
    display: flex;
    justify-content: center;
    list-style: none;
    gap: 0;
    padding: 10px 0 0;
    margin: 0;
  }
  .aow__dots li { display: block; }

  /* The button is the target and the dot is drawn inside it. The other way
     round - a dot that is itself the button - gives a finger eight pixels
     to land on. */
  .aow__dots button {
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .aow__dots button::before {
    content: '';
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--aow-line);
    transition: background .25s var(--ease), transform .25s var(--ease);
  }
  .aow__dots button[aria-current="true"]::before {
    background: var(--red);
    transform: scale(1.35);
  }
}

@media (prefers-reduced-motion: reduce) {
  .aow__dots button::before { transition: none; }
}

/* -------------------------------------------------------------------------
   A short, wide screen - a phone turned sideways

   The hero is built for a tall viewport: 116px of padding above to clear the
   fixed header and 70 below. On a 390px-tall screen that is half the height
   gone before any words, and the buttons ended up below the fold. Tightened
   here and nowhere else.
   ------------------------------------------------------------------------- */
@media (max-height: 460px) and (orientation: landscape) {
  .hero {
    min-height: 0;
    padding: calc(var(--head-h) + 12px) var(--gutter) 24px;
  }
  /* The title is sized off the width, which on a sideways phone is generous
     while the height is not. Smaller here buys the two lines back. */
  .hero__title { font-size: clamp(1.9rem, 4.6vw, 2.5rem); }
  .hero__lede { margin-top: 14px; }
  .hero__actions { margin-top: 18px; }
}

/* -------------------------------------------------------------------------
   Tap targets

   Asked of the input rather than of the screen. `max-width: 720px` is a guess
   at "this is a phone" that is wrong both ways: a phone turned sideways is
   844px wide and stops matching, every tablet is 768px or more and never
   matched, and a desktop window dragged narrow matches but has a mouse.

   `pointer: coarse` is true wherever the primary input is a finger, at any
   width and any rotation, and false for a mouse at any size.

   44px is the floor. Most of these were the right size visually and only
   short vertically, so the height comes from padding: the text does not
   move, the target grows around it.
   ------------------------------------------------------------------------- */
@media (pointer: coarse) {
  .head__brand { min-height: 44px; align-items: center; }
  .head__actions .pill { min-height: 44px; }
  .burger { width: 44px; height: 44px; }

  .foot__col a,
  .foot__contact a {
    display: flex;
    align-items: center;
    /* Full width as well as tall: in a vertical list of links the whole row
       should be tappable, not just the few characters of the word. "About"
       is five letters and was a 41px-wide target. */
    width: 100%;
    min-height: 44px;
  }
  .foot__col p { margin: 0; min-height: 44px; display: flex; align-items: center; }
  /* The address is two lines and should not be stretched by the rule above. */
  .foot__col p:first-of-type { display: block; min-height: 0; padding: 6px 0; }

  /* Padding rather than a min-height on a flex box: this link carries a
     red rule under it, and in a 44px-tall flex box that rule draws at the
     bottom of the box instead of under the text. Padding on an inline box
     grows what can be tapped and leaves the border where it belongs. */
  /* Above 1020px the burger gives way to the desktop nav, which is right -
     there is room for it. An iPad Pro in landscape has the room and a finger,
     and these were 20px tall. */
  .head__nav a { display: inline-flex; align-items: center; min-height: 44px; }

  /* A phone number inside a sentence stays inline - WCAG exempts targets in a
     block of text, and padding it to 44px would break the paragraph's line
     spacing. Vertical padding on an inline box grows what can be hit without
     moving the line it sits on. */
  .form__note a { padding-block: 10px; }

  /* The service tiles' "View more" and the leadership bios' "Read more" are
     buttons in the middle of content, and were sized for a cursor. */
  .tile__more,
  .person__more { min-height: 44px; }
}

@media print {
  .head, .drawer, .promo, .hero__media { display: none !important; }
  body { color: #000; }
  .band { padding-block: 1.5rem; }
}


/* ==========================================================================
   Core capabilities, and the long service lists
   ========================================================================== */

/* Text for a screen reader and for print, out of the way of everyone else. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- The wheel ----

   Drawn rather than placed: the supplied diagram as geometry, so it stays
   sharp at any size, carries the brand red rather than an approximation of
   it, and can respond to a pointer. Hovering a segment lifts it out of the
   ring, turns it red and dims the rest, which is the whole point of having
   redrawn it. */
.cap__figure { margin: 0; display: grid; place-items: center; }
.cap__wheel {
  width: min(100%, 620px);
  height: auto;
  font-family: var(--font-display);
}
.cap__seg {
  transform-box: view-box;
  transform-origin: center;
  transition: transform .32s var(--ease), filter .32s var(--ease);
  cursor: default;
}
.cap__slice { transition: fill .28s var(--ease), opacity .28s var(--ease); }
.cap__label {
  font-size: 16px; font-weight: 600; letter-spacing: .005em;
  text-anchor: middle;
  transition: fill .28s var(--ease), opacity .28s var(--ease);
}

.cap__seg--dark  .cap__slice { fill: #1e2a33; }
.cap__seg--mid   .cap__slice { fill: #767a7c; }
.cap__seg--light .cap__slice { fill: #c3c6c7; }
.cap__seg--red   .cap__slice { fill: var(--red); }

.cap__seg--dark .cap__label,
.cap__seg--mid  .cap__label,
.cap__seg--red  .cap__label { fill: #fff; }
/* The diagram sets white on the pale segments, where it is barely legible.
   Dark ink there costs nothing and reads at a glance. */
.cap__seg--light .cap__label { fill: #16212a; }

.cap__hub circle { fill: var(--surface); }
.cap__hub text {
  font-size: 34px; font-weight: 700; fill: var(--ink);
  text-anchor: middle; letter-spacing: -.01em;
}

/* The highlight: one segment forward, the others held back. */
.cap__seg:hover,
.cap__seg.is-on { transform: translate(var(--tx), var(--ty)); }
/* On the slice, not the group: the shadow is the sector's, and the label
   should not cast one of its own. The filter is defined in the SVG with a
   region wide enough for the blur to fall away instead of being cut off
   square, which is what a CSS drop-shadow does here. */
.cap__seg:hover .cap__slice,
.cap__seg.is-on .cap__slice { filter: url(#capLift); }
.cap__seg:hover .cap__slice,
.cap__seg.is-on .cap__slice { fill: var(--red); }
.cap__seg:hover .cap__label,
.cap__seg.is-on .cap__label { fill: #fff; }

.cap__wheel:hover .cap__seg:not(:hover) .cap__slice,
.cap__wheel.has-on .cap__seg:not(.is-on) .cap__slice { opacity: .42; }
.cap__wheel:hover .cap__seg:not(:hover) .cap__label,
.cap__wheel.has-on .cap__seg:not(.is-on) .cap__label { opacity: .5; }

@media (prefers-reduced-motion: reduce) {
  .cap__seg, .cap__slice, .cap__label { transition: none; }
  .cap__seg:hover, .cap__seg.is-on { transform: none; }
}

/* On a phone the wheel is about a third of its drawn width, so the labels are
   set larger in its own units to come back to a readable size.

   19 was too large for the geometry rather than for the reader: a label sits
   200 units out, where a 40-degree segment is only about 136 wide, and
   "Workmanship" and "Compliance" were finishing within two or three units of
   the dividers. That margin is a ratio of type size to viewBox and does not
   change with how big the wheel is drawn — so the labels come down to 17 and
   the wheel goes out to the full width of the screen, which hands back the
   rendered size the smaller number gave up. The artwork keeps a sixteenth of
   the box clear on each side, so nothing touches the edge. */
@media (max-width: 760px) {
  .cap__label { font-size: 17px; }
}
@media (max-width: 620px) {
  .cap__figure { margin-inline: calc(var(--gutter) * -1); }
  .cap__wheel { width: 100%; }
}

/* ---- What each capability means ----

   A description per segment, shown only while that segment is pointed at, on
   the side of the wheel it sits on: left-hand segments read to the left,
   right-hand ones to the right. The one that straddles the bottom reads right
   and the one at the top reads left, since neither has a side of its own.

   The three columns are sized so the wheel holds the middle and the text
   columns are equal either side. The wheel is the tallest thing in the row, so
   text appearing and disappearing never moves anything. */
.cap__stage {
  display: grid;
  /* The middle column is sized outright. Left to `auto` it collapses to
     whatever the SVG's percentage width resolves against, and the wheel comes
     out a third of the size it should be. */
  grid-template-columns: 1fr clamp(300px, 42vw, 620px) 1fr;
  align-items: center;
  gap: clamp(12px, 2.5vw, 36px);
}
.cap__say {
  max-width: 34ch;
  opacity: 0;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
.cap__say--left  { justify-self: end;   transform: translateX(10px); }
.cap__say--right { justify-self: start; transform: translateX(-10px); }
.cap__say.is-on { opacity: 1; transform: none; }

.cap__say h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.15rem;
  margin: 0 0 8px;
}
.cap__say h3::before {
  content: '';
  flex: none;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--red);
}
.cap__say p { margin: 0; color: var(--text-muted); }

.cap__hint {
  margin: clamp(1rem, 2vw, 1.6rem) 0 0;
  text-align: center;
  font-size: .86rem;
  color: var(--text-muted);
  transition: opacity .25s var(--ease);
}
/* It has said its piece once somebody is reading a description. */
.cap.is-reading .cap__hint { opacity: 0; }

/* With the script running, the nine cards are the source of the words rather
   than the display of them. Without it they stay on the page, because a list
   nobody can reveal is worse than a list that is simply there. */
.cap.is-live .caps {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.caps {
  list-style: none;
  margin: clamp(2rem, 4vw, 3.25rem) 0 0;
  padding: 0;
  display: grid;
  gap: clamp(14px, 1.6vw, 22px);
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
@media (min-width: 900px) { .caps { grid-template-columns: repeat(3, 1fr); } }
.caps__item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(1.1rem, 1.9vw, 1.5rem);
}
.caps__item h3 {
  display: flex; align-items: center; gap: 10px;
  font-size: 1.02rem; margin: 0 0 7px;
}
.caps__item h3::before {
  content: '';
  flex: none;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--dot, var(--line));
}
.caps__item p { margin: 0; font-size: .9rem; color: var(--text-muted); }

/* Narrow: the sides stop meaning anything, so the text goes under the wheel
   and the wheel takes the full width. */
@media (max-width: 860px) {
  .cap__stage { grid-template-columns: 1fr; }
  .cap__figure { order: -1; }
  .cap__say {
    max-width: none;
    justify-self: stretch;
    transform: translateY(-8px);
    text-align: center;
  }
  .cap__say:not(.is-on) { display: none; }
  .cap__say h3 { justify-content: center; }
}

/* ---- Long service lists ----

   Some tiles run to a dozen bullets, which buries the tiles below them. Five
   are shown and the rest are a button away. The clamp is applied by the
   script, so with JavaScript off every bullet is visible and no button
   appears: a View more that cannot expand anything is worse than none. */
.tile.is-clamped ul li:nth-child(n+6) { display: none; }
.tile__more {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  padding: 10px 2px;
  min-height: 44px;
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-size: .86rem;
  font-weight: 600;
  color: var(--red);
  cursor: pointer;
}
.tile__more:hover { color: var(--red-dark); }
.tile__more svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform .25s var(--ease);
}
/* Chevron down to open, up to close. */
.tile__more[aria-expanded="true"] svg { transform: rotate(180deg); }

/* -------------------------------------------------------------------------
   Core services, collapsed

   Nine tiles and fifty-eight bullets came to 3,646px on a phone - four and a
   bit screens, a quarter of the whole page, and no way to find the one
   service you came for without scrolling past the eight you did not.

   Collapsed to a row each, the section is about a screen. Nothing is removed
   from the page, only from the screen, so every bullet is still read by a
   crawler and still printed.
   ------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .tiles { gap: 10px; }

  .tile {
    padding: 0;
    overflow: hidden;
    transition: border-color .25s var(--ease);
  }
  .tile.is-open { border-color: var(--red); }

  /* ---- the row you tap ---- */
  .tile__head {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 14px 16px;
    background: none;
    border: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
    min-height: 60px;
  }
  .tile__head h3 { margin: 0; font-size: 1.02rem; line-height: 1.25; flex: 1; }

  /* The icon shrinks: at 46px it was a decoration with a heading beside it,
     and this is a list. */
  .tile .tile__icon {
    width: 36px; height: 36px;
    border-radius: 10px;
    margin: 0;
    flex: none;
  }
  .tile .tile__icon svg { width: 18px; height: 18px; }

  .tile__chev {
    width: 18px; height: 18px; flex: none;
    fill: none; stroke: var(--text-muted); stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform .25s var(--ease);
  }
  .tile.is-open .tile__chev { transform: rotate(180deg); stroke: var(--red); }

  /* ---- what opens ---- */
  .tile__body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .3s var(--ease);
  }
  .tile.is-open .tile__body { grid-template-rows: 1fr; }
  .tile__body > div { overflow: hidden; }
  .tile__body ul { padding: 0 16px 14px; margin: 0; }

  /* Every bullet is shown once the tile is open: the tile is the thing that
     collapses now, so a second "View more" inside it is one fold too many. */
  .tile.is-clamped ul li:nth-child(n+6) { display: list-item; }
  .tile__more { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .tile__body, .tile__chev { transition: none; }
}

/* Above the breakpoint nothing changes: the head is not a button, and the
   body is just the tile's contents. */
@media (min-width: 901px) {
  .tile__head { display: contents; }
  .tile__chev { display: none; }
  .tile__body > div { display: contents; }
}


/* ---- The lockup ----

   The wordmark now matches the height of the symbol, which makes the lockup
   two and a half times wider than it was. It cannot stay at the header size
   on a handset, where it would be wider than the screen. */
/* One number per width, and the word follows it. */
@media (max-width: 1020px) { .head__brand .brand { --mark: 44px; } }
@media (max-width: 620px)  { .head__brand .brand { --mark: 34px; } }
@media (max-width: 420px)  { .head__brand .brand { --mark: 30px; } }




/* ---- The 404 page ----

   It is the site's own furniture around one short apology, so the header has
   no photograph to sit over and the band has to clear it. */
.head--solid { background: var(--ink); }
.notfound {
  padding-top: calc(var(--head-h) + clamp(3rem, 9vw, 7rem));
  padding-bottom: clamp(3rem, 9vw, 7rem);
}
.notfound .lede { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.notfound__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.notfound__call {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.notfound__call:hover { border-color: var(--ink); }
