/* Micro Metal Finishing - micrometalfinishing.com
 *
 * One stylesheet for the whole site. It replaces, from the CMS build:
 *
 *   publicstyle.css        12 KB   font/colour declarations, one per element
 *   responsive.css          4 KB   the .columnN grid and the home page bands
 *   mbcsmbmcp.css          15 KB   "Easy Button & Menu Maker" nav skin
 *   layerslider.css        ~9 KB   a slider engine driving ONE static slide
 *   feature.presenter.css   2 KB   unused
 *   instalink.min.css      30 KB   unused
 *   Window.Metro.css        3 KB   Telerik RadWindow skin, no RadWindow left
 *   lightbox/Global.css     1 KB   FWDRL lightbox, two images
 *   aos.css                        scroll-reveal, which hid content until the
 *                                  page was scrolled
 *
 * The palette is the CMS's own, read out of publicstyle.css and the artwork:
 * navy #0a2e6a, a darker #002b51 for headings, gold #e4c010, the pale blue
 * #e8eff7 the project band was painted in, and black for the contact strip.
 */

:root {
  --navy: #0a2e6a;
  --navy-dark: #002b51;
  --navy-deep: #061f47;
  --gold: #e4c010;
  --gold-dark: #b8990c;   /* hover only: never carries body text */
  /* The CMS set one heading in #e4c010 on white - 1.77:1. This is the same
     hue and saturation at the lightness that clears 4.5:1 at any size, solved
     in harness/pick_colour.py. */
  --gold-text: #8a750a;
  --pale: #e8eff7;
  --ink: #1a1a1a;
  --muted: #5b6472;
  --line: #d8dee7;
  --shell: 1200px;
  /* the ONE place the nav breakpoint is written; mmf.js reads it back out,
     so the media query and the matchMedia cannot drift apart */
  --nav-break: 1180px;
  --gutter: clamp(16px, 4vw, 40px);
  --bar: 40px;            /* black contact strip */
  --nav: 84px;            /* navy nav bar */
  --sans: Barlow, "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial,
          sans-serif;
  --display: Rajdhani, Barlow, "Segoe UI", system-ui, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  /* Both, not just body: a single overflow rule on body leaves the document
     element free to scroll sideways, and the symptom is a page that jiggles
     horizontally on a phone with nothing visibly overflowing. */
  overflow-x: clip;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  overflow-x: clip;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink);
  background: #fff;
}

img, picture, svg, iframe { max-width: 100%; }
img { height: auto; display: block; }
picture { display: block; }

a { color: var(--navy); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--gold-dark); }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--gold); color: var(--navy-dark);
  padding: 12px 20px; font-weight: 700;
}
.skip:focus { left: 0; }

/* ------------------------------------------------------------- masthead */
/* THE BLACK STRIP SCROLLS AWAY; THE LOGO AND NAV STICK.
   The masthead itself is in normal flow, so it reserves its own height and
   the page needs no top padding at any width - which is what took the last
   `--head` constant out of this file. Only `.navbar` is pinned.

   `position: sticky` has one known failure here and it is handled in mmf.js:
   the drawer's scroll lock sets `position: fixed` on <body>, and a sticky
   element inside a fixed body resolves to its STATIC position, i.e. scrollY
   above the viewport - so the bar vanishes upward the moment the menu opens.
   The lock measures the bar first and pins it where it already was. */
/* THE WHOLE HEADER IS STICKY, PULLED UP BY THE HEIGHT OF THE BLACK STRIP.
   `position: sticky` on `.navbar` alone does NOT work: a sticky element is
   constrained to its own containing block, and `.navbar`'s parent is the
   118px `.masthead` - so it can stick for the 44px the strip occupies and
   then leaves with it. Measured at scrollY 600: top -556, i.e. gone.
   Sticking the masthead at `top: -(strip height)` gives exactly the asked-for
   behaviour with the markup unchanged: the black strip scrolls up out of
   sight, and the navy bar lands at 0 and stays. It relies on the strip being
   exactly `--bar` tall, which it is at every width. */
.masthead {
  position: sticky; top: calc(0px - var(--bar)); z-index: 95;
  background: var(--navy);
}
.navbar { background: var(--navy); }

.topbar {
  background: #000; color: #fff;
  font-size: 14px; line-height: var(--bar);
  height: var(--bar);
}
.topbar .shell {
  display: flex; align-items: center; justify-content: flex-end; gap: 22px;
  height: 100%;
}
.topbar a { color: #fff; text-decoration: none; display: inline-flex;
            align-items: center; gap: 8px; white-space: nowrap;
            /* 24px is the WCAG 2.2 minimum for a target that is not inline in
               a sentence; at line-height alone these were 20. */
            min-height: 24px; }
.topbar a:hover { color: var(--gold); }
.topbar svg { fill: var(--gold); flex: none; }
.topbar b { color: var(--gold); font-weight: 700; }

.searchform { display: flex; margin-left: auto; }
.topbar .searchform + * { margin-left: 0; }
.searchform input {
  font: inherit; font-size: 14px; color: #fff; background: #333;
  border: 0; border-radius: 0; padding: 4px 10px; width: 190px; height: 26px;
}
.searchform input::placeholder { color: #bbb; }
.searchform button {
  font: inherit; background: #333; border: 0; color: var(--gold);
  padding: 0 10px; height: 26px; cursor: pointer; display: flex;
  align-items: center;
}
.searchform button:hover { color: #fff; }
.searchform svg { fill: currentColor; }

.navbar { height: var(--nav); }
.navbar .shell {
  display: flex; align-items: center; gap: 24px; height: 100%;
}
.brand { flex: none; display: block; line-height: 0; }
.brand img { width: 250px; height: auto; }

/* -------------------------------------------------------------- the nav */
.nav { margin-left: auto; }
.nav > ul {
  display: flex; align-items: center; gap: 4px;
  list-style: none; margin: 0; padding: 0;
}
.nav a, .nav .navbtn {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--sans); font-size: 15px; font-weight: 400;
  letter-spacing: .04em; text-transform: uppercase;
  color: #fff; text-decoration: none;
  padding: 10px 12px; background: none; border: 0; cursor: pointer;
  white-space: nowrap;
}
.nav a:hover, .nav .navbtn:hover,
.nav a:focus-visible, .nav .navbtn:focus-visible { color: var(--gold); }
.nav [aria-current="page"] { color: var(--gold); }
.nav svg { fill: currentColor; transition: transform .18s; }

.nav li { position: relative; }
.nav ul ul {
  position: absolute; top: 100%; left: 0; z-index: 10;
  min-width: 230px; margin: 0; padding: 6px 0;
  list-style: none; background: var(--navy-deep);
  box-shadow: 0 10px 24px rgba(0,0,0,.28);
  /* Not `visibility`: transitioning visibility means the panel is still
     hit-testable for the length of the transition, so the first tap after
     closing one lands on a link nobody can see. */
  display: none;
}
.nav li.open > ul { display: block; }
.nav ul ul a { text-transform: none; letter-spacing: 0; padding: 9px 18px; }
.nav ul ul a:hover { background: rgba(255,255,255,.08); color: var(--gold); }
.nav li.open > .navbtn svg { transform: rotate(180deg); }

.navclose { display: none; }   /* base level: the drawer's own close button */

.navtoggle {
  display: none; margin-left: auto;
  background: none; border: 0; color: #fff; cursor: pointer;
  padding: 10px; line-height: 0;
}
.navtoggle svg { fill: currentColor; }

.backdrop {
  display: none;
  position: fixed; inset: 0; z-index: 90;
  background: rgba(6,15,35,.55);
}
.backdrop.on { display: block; }

/* ------------------------------------------------------------------ hero */
.hero {
  position: relative; display: grid; align-items: center;
  min-height: clamp(340px, 46vw, 505px);
  background: #1c1c1c;
  isolation: isolate;
}
.hero > img, .hero > picture {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.hero > picture img { width: 100%; height: 100%; object-fit: cover; }
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(0,0,0,.34);
}
.hero .shell { padding-block: clamp(40px, 7vw, 76px); text-align: center; }
.hero h1 {
  font-family: var(--sans); font-weight: 800;
  font-size: clamp(30px, 5.4vw, 65px); line-height: 1.06;
  letter-spacing: .01em; color: #fff; margin: 0;
  text-shadow: 0 2px 18px rgba(0,0,0,.5);
}
.hero p {
  font-size: clamp(15px, 1.7vw, 21px); letter-spacing: .04em;
  text-transform: uppercase; color: #fff; margin: 18px auto 0; max-width: 46ch;
  text-shadow: 0 2px 12px rgba(0,0,0,.6);
}
.hero .cta { margin-top: clamp(22px, 3vw, 34px); }

/* a slim banner for the inner pages, same artwork family */
.pagehead {
  position: relative; background: var(--navy-dark);
  padding-block: clamp(26px, 4vw, 44px);
  border-bottom: 6px solid var(--gold);
  isolation: isolate;
}
.pagehead > img, .pagehead > picture {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.pagehead > picture img { width: 100%; height: 100%; object-fit: cover; }
.pagehead::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(0,25,60,.72);
}
.pagehead h1 {
  margin: 0; color: #fff;
  font-family: var(--sans); font-weight: 800;
  font-size: clamp(25px, 3.6vw, 44px); line-height: 1.14;
  text-transform: uppercase; letter-spacing: .01em;
}
.pagehead h1::before {
  content: ""; display: block; width: 85px; height: 12px;
  background: var(--gold); margin-bottom: 18px;
}

/* --------------------------------------------------------------- buttons */
.cta { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--sans); font-size: 15px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; text-decoration: none;
  padding: 14px 30px; border: 2px solid var(--gold); cursor: pointer;
  background: var(--gold); color: var(--navy-dark);
  transition: background .22s, color .22s, border-color .22s;
}
.btn:hover, .btn:focus-visible { background: var(--navy-dark); color: #fff;
                                 border-color: var(--navy-dark); }
.btn-ghost { background: transparent; color: #fff; border-color: var(--gold); }
.btn-ghost:hover, .btn-ghost:focus-visible { background: var(--gold);
                                             color: var(--navy-dark); }
.btn svg { fill: currentColor; }

/* --------------------------------------------------------------- content */
main { display: block; }
.band { padding-block: clamp(38px, 6vw, 72px); }
.band-pale { background: var(--pale); }

/* The home page's services band. `/graphics/subfooter1.png` was a 1500x651
   PNG holding solid gold for its top 256 rows and solid white below - a
   gradient, cut for one band height. Two bands do the same job at every
   height. */
.band-gold { background: var(--gold); padding-block: clamp(26px, 4vw, 40px); }
.band-gold h2 {
  margin: 0; text-align: center; color: var(--navy-dark);
  font-family: var(--display); font-weight: 700;
  font-size: clamp(20px, 2.6vw, 30px); line-height: 1.3;
}

h1, h2, h3, h4 { font-family: var(--sans); color: var(--navy-dark);
                 line-height: 1.2; margin: 0 0 .5em; }
h1 { font-weight: 800; font-size: clamp(26px, 3.6vw, 44px); }
h2 { font-family: var(--display); font-weight: 700; color: var(--navy);
     font-size: clamp(20px, 2.4vw, 28px); line-height: 1.3; }
h3 { font-size: clamp(17px, 1.7vw, 20px); font-weight: 700; }
h2.gold { color: var(--gold-text); }

/* The reset comes FIRST and the flow rule after it, at the same specificity,
   so source order decides. Written the other way round - `.prose > * + *`
   then `.prose p { margin: 0 }` - the second rule is (0,1,1) against the
   first's (0,1,0) and it wins on specificity regardless of order, so every
   paragraph on the site sat flush against the one above it. */
.prose > * { margin: 0; }
.prose > * + * { margin-top: 1.1em; }
.prose > h2 { margin-top: 1.7em; }
.prose > h2:first-child { margin-top: 0; }
.prose > table.spec, .prose > .std-grid { margin-top: 1.8em; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: .3em; }
.prose img, .prose picture { margin-inline: auto; }

/* ...and between the blocks a page is built from. Each block the CMS wrote is
   its own `.prose`, so a page can be four siblings with one paragraph each,
   and `.prose > * + *` never matches at all. */
.band > .shell > * + * { margin-top: clamp(22px, 2.8vw, 38px); }

.lead { font-size: clamp(17px, 1.6vw, 19px); }

/* A 1200px shell is 150 characters of 17px text. The intro under the service
   tiles is one paragraph in the middle of a wide band, so it gets a measure
   of its own rather than the shell's. */
.intro { max-width: 70ch; margin: clamp(30px, 4vw, 46px) auto 0; text-align: center; }
.intro h2 { margin-bottom: .6em; }

/* 62 / 33, the CMS's .column2 + .column3 */
.split {
  display: grid; gap: clamp(24px, 3.4vw, 46px);
  grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
  align-items: start;
}
.split > * { min-width: 0; }
.aside figcaption, .aside .cap {
  font-weight: 700; color: var(--navy-dark); margin-top: .7em;
}
.aside::after {
  content: ""; display: block; width: 96px; height: 12px;
  background: var(--gold); margin-top: 18px;
}
.pair { display: grid; gap: clamp(18px, 2.6vw, 30px);
        grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* the contact details panel */
.card {
  background: var(--pale); padding: 24px 26px; font-style: normal;
  border-top: 6px solid var(--gold);
}
.card p:first-child { margin-top: 0; }
.card strong { color: var(--navy-dark); }
.card::after { margin-top: 0; height: 0; }

/* ------------------------------------------------------- service tiles */
/* The three tiles were 395x274 PNGs with a photograph, a white frame, a drop
   shadow in the alpha channel AND the words ZINC / ZINC - IRON /
   ZINC - NICKEL painted into a band at the bottom. The photograph is cropped
   out; the band and its words are drawn here, so the link has real text. */
.tiles {
  display: grid; gap: clamp(18px, 2.6vw, 30px);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0; padding: 0; list-style: none;
}
.tile {
  display: block; text-decoration: none; background: #fff;
  padding: 6px 6px 0; box-shadow: 0 3px 10px rgba(0,0,0,.16);
  transition: transform .3s, box-shadow .3s;
}
.tile:hover, .tile:focus-visible {
  transform: translateY(-5px); box-shadow: 0 12px 22px rgba(0,0,0,.22);
}
.tile img { width: 100%; aspect-ratio: 367 / 198; object-fit: cover; }
.tile span {
  display: block; padding: 13px 10px; margin-top: 0;
  background: var(--tile-band, #767674); color: #fff;
  font-family: var(--sans); font-size: 15px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; text-align: center;
}
.tile::after { content: ""; display: block; height: 6px; background: #fff; }

/* ------------------------------------------------------- project tiles */
.projects {
  display: grid; gap: clamp(16px, 2.4vw, 26px);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0; padding: 0; list-style: none;
}
.project {
  position: relative; display: flex; flex-direction: column;
  justify-content: flex-end; min-height: 387px;
  padding: 26px 24px; text-decoration: none; color: #fff;
  background: var(--navy-dark) center / cover no-repeat;
  isolation: isolate;
}
.project::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(0,0,0,.18) 0%, rgba(0,0,0,.28) 45%,
                              rgba(0,0,0,.74) 100%);
}
.project .arrow {
  width: 50px; height: 50px; border-radius: 50%;
  background: var(--gold); color: #fff;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 14px; transition: transform .3s;
}
.project .arrow svg { fill: currentColor; }
.project:hover .arrow, .project:focus-visible .arrow { transform: translateX(6px); }
.project::after {
  content: ""; position: absolute; left: 24px; bottom: 0; width: 0; height: 0;
}
.project .rule { display: block; width: 85px; height: 12px;
                 background: var(--gold); margin-bottom: 14px; }
/* Matched on the CLASS, not on `h3`. The tile's heading is an <h2> on the
   Project Gallery page and an <h3> on the home page - it takes its level from
   where it sits in the document - and a rule written for `h3` left the
   gallery's three tiles inheriting the site's navy heading colour, i.e. dark
   navy words on a dark photograph. A DOM contrast sweep cannot see that: the
   background is an image, so there is no colour to compare against. */
.project .ttl {
  font-family: var(--display); font-weight: 700; color: #fff;
  font-size: clamp(20px, 2vw, 28px); line-height: 1.12; margin: 0;
  text-transform: uppercase;
}
.project:hover .ttl, .project:focus-visible .ttl { color: var(--gold); }

/* ----------------------------------------------- standards + spec tables */
.std-grid {
  display: grid; gap: 2px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  background: var(--line);
  border: 1px solid var(--line);
}
.std { background: #fff; padding: 16px 20px; }
.std:nth-child(4n+1), .std:nth-child(4n+2) { background: #f4f6fa; }
.std h3 {
  margin: 0 0 .35em; font-size: 15px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--navy-dark);
}
.std ul { margin: 0; padding-left: 1.15em; list-style: square; }
.std li { font-size: 15px; line-height: 1.5; }

table.spec {
  width: 100%; border-collapse: collapse; margin: 0;
  border: 1px solid var(--line);
}
table.spec th, table.spec td {
  padding: 14px 18px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
table.spec th {
  width: 34%; font-size: 14px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--navy-dark); font-weight: 700;
}
table.spec tr:nth-child(odd) { background: #f4f6fa; }
table.spec tr:last-child th, table.spec tr:last-child td { border-bottom: 0; }
table.spec ul { margin: 0; padding-left: 1.15em; }

/* -------------------------------------------------------------- gallery */
.figpair { display: grid; gap: clamp(16px, 2.4vw, 26px);
           grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; }
.figpair figure { margin: 0; }
.figpair a { display: block; line-height: 0; }
.figpair img { width: 100%; }

/* ----------------------------------------------------------------- map */
.mapband { background: #d1d1d1; line-height: 0; }
.mapband iframe { display: block; width: 100%; height: 300px; border: 0; }
.map-inline { width: 100%; height: 460px; border: 1px solid #a6a6a7; }

/* ------------------------------------------------------- address + foot */
.addressband {
  background: var(--navy) url("/img/addressbkg.jpg") center / cover no-repeat;
  /* The artwork is a near-flat gold texture, not a photograph. These are the
     0.1st and 99.9th percentile colours in it, from
     `python harness/bg_range.py`; harness/probe.js contrast-checks the words
     against BOTH, instead of skipping them the way it has to skip text over a
     real photograph. Navy measures 6.54 and 8.20 here. */
  --bg-min: #cdad0c;
  --bg-max: #e6c111;
  text-align: center; padding-block: clamp(26px, 4vw, 40px);
}
.addressband p {
  margin: 0; font-size: clamp(17px, 2.1vw, 28px); line-height: 1.75;
  color: var(--navy-dark); font-weight: 400;
}
.addressband a { color: var(--navy-dark); text-decoration: none; }
.addressband a:hover { text-decoration: underline; }
.addressband b { font-weight: 700; }

.foot { background: var(--navy); color: #fff; padding-bottom: 22px; }
/* the anniversary mark, in the navy band, above the rule - as on the CMS */
.foot-mark { padding-block: clamp(26px, 4vw, 40px); line-height: 0; }
.foot-mark a { display: block; }
.foot-mark .mark { width: 200px; margin-inline: auto; }
.foot-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
  border-top: 1px solid var(--gold); padding-top: 20px;
}
.foot p { margin: 0; font-size: 15px; }
.foot a { color: #fff; }
.foot a:hover { color: var(--gold); }
.foot .social { display: flex; gap: 14px; }
.foot .social a { line-height: 0; }
.foot .social svg { fill: #fff; }
.foot .social a:hover svg { fill: var(--gold); }

/* The ISO badge floated over the bottom-right corner of every page. Kept,
   but it must not sit on top of the content on a phone - below the nav
   breakpoint it becomes a normal link in the footer instead. */
.isobadge {
  position: fixed; right: 24px; bottom: 12px; z-index: 60;
  line-height: 0; transition: transform .4s;
}
.isobadge:hover { transform: scale(1.08); }
.isobadge img { width: 86px; height: auto; }
.foot .isolink { display: none; align-items: center; gap: 8px; }
.foot .isolink svg { fill: var(--gold); }

/* ---------------------------------------------------------------- forms */
.formwrap { max-width: 720px; }
.field { margin-bottom: 20px; }
.field > label, .fieldset > legend {
  display: block; font-weight: 700; color: var(--navy-dark);
  margin-bottom: 6px; font-size: 15px;
}
.req { color: #b3261e; }
/* `input[type=search]` is NOT `input[type=text]`. The search page's own box
   is type=search, so a list that names text/email/tel and stops left it at the
   browser default: 177x21, with none of the padding every other field has. */
.field input[type=text], .field input[type=email], .field input[type=tel],
.field input[type=search], .field input[type=number], .field input[type=url],
.field select, .field textarea, .field input[type=file] {
  font: inherit; width: 100%; max-width: 460px;
  padding: 11px 13px; border: 1px solid #9aa4b2; border-radius: 2px;
  background: #fff; color: var(--ink);
}
.field textarea { min-height: 170px; resize: vertical; max-width: 100%; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 3px solid var(--gold); outline-offset: 1px; border-color: var(--navy);
}
.fieldset { border: 1px solid var(--line); padding: 16px 18px 6px;
            margin: 0 0 20px; }
.fieldset legend { padding-inline: 6px; }
.checks { display: grid; gap: 8px; margin-bottom: 12px; }
.checks label { display: flex; gap: 10px; align-items: center;
                font-weight: 400; min-height: 32px; cursor: pointer; }
/* A 13x13 default checkbox is below any sensible touch target. The <label>
   wraps the box, so the whole row is the target - but the box itself is what
   a finger aims at. */
.checks input[type=checkbox] { width: 20px; height: 20px; flex: none;
                               accent-color: var(--navy); }
.hint { color: var(--muted); font-size: 14px; margin: 6px 0 0; }
.err {
  border-left: 5px solid #b3261e; background: #fdeceb;
  padding: 14px 18px; margin-bottom: 24px;
}
.err ul { margin: .4em 0 0; padding-left: 1.2em; }
.ok {
  border-left: 5px solid #1e7b34; background: #eaf6ec;
  padding: 18px 22px; margin-bottom: 24px;
}
.field-err input, .field-err select, .field-err textarea { border-color: #b3261e; }
.field-err > label { color: #b3261e; }
/* the honeypot: off-screen, not display:none, so a real keyboard user can
   still never reach it but a bot that reads the DOM still fills it in */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px;
      overflow: hidden; }

/* --------------------------------------------------------------- search */
.result { border-bottom: 1px solid var(--line); padding-block: 18px; }
.result h2 { margin: 0 0 .3em; font-family: var(--sans); font-size: 20px;
             font-weight: 700; }
.result p { margin: 0; color: var(--muted); }
.result mark { background: #fff2b8; }

/* ============================== breakpoints ============================= */
/* The nav breakpoint is MEASURED, not chosen, and the measurement is against
   the SHELL, not the viewport.
     logo 250 + gap 24 + the seven nav items 807 + two 40px gutters = 1161px
   so the bar first fits at 1161 and 1180 leaves it 19px of air. The first
   version of this said 1140 - picked as a round number - and at 1141 the nav
   ran 19px into the right-hand gutter. Nothing overflowed the VIEWPORT, so a
   viewport-overflow check passed it; harness/probe.js now measures against
   the container as well, and the sweep tests 1179 and 1181 either side. */
@media (max-width: 1180px) {
  :root { --nav: 74px; }
  .navtoggle { display: block; }
  .nav {
    /* full height at every drawer width, so it never has to know how tall
       the header is; it covers the burger, which is why it carries its own
       close button. Above `.navbar` in z-order, or the bar would draw over
       the drawer's top-right corner - and that is where the close button is. */
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 100;
    width: min(360px, 86vw); margin: 0;
    background: var(--navy-deep);
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    transform: translateX(100%); transition: transform .28s ease;
    display: none;                 /* base-level, so it cannot leak on desktop */
    padding: 14px 0 40px;
  }
  .nav.mounted { display: block; }
  .nav.open { transform: none; }
  .nav > ul { display: block; }
  .navclose {
    display: flex; margin-left: auto; margin-right: 10px;
    background: none; border: 0; color: #fff; cursor: pointer;
    padding: 10px; line-height: 0;
  }
  .navclose svg { fill: currentColor; }
  .navclose:hover { color: var(--gold); }
  .nav > ul > li { border-bottom: 1px solid rgba(255,255,255,.12); }
  .nav a, .nav .navbtn {
    padding: 15px 24px; font-size: 16px; width: 100%; justify-content: space-between;
  }
  .nav ul ul {
    position: static; display: none; min-width: 0; box-shadow: none;
    background: rgba(0,0,0,.28); padding: 0;
  }
  .nav li.open > ul { display: block; }
  .nav ul ul a { padding-left: 40px; }
  .brand img { width: 210px; }
}

@media (max-width: 1000px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .aside { max-width: 460px; }
  .tiles, .projects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .project { min-height: 320px; }
}

@media (max-width: 860px) {
  .topbar { font-size: 13px; }
  .topbar .shell { gap: 14px; }
  .searchform input { width: 130px; }
}

@media (max-width: 720px) {
  /* THE PHONE HEADER IS ONE LINE.
     The e-mail address and the search box are desktop conveniences; on a
     phone they cost two rows of a header already competing with the content,
     and the number is the only one of the three anybody taps in a hurry. */
  :root { --bar: 44px; }
  body { font-size: 16px; }
  .topbar { height: var(--bar); line-height: var(--bar); font-size: 15px; }
  .topbar .shell { justify-content: center; gap: 0; }
  .topbar .tb-mail, .topbar .searchform { display: none; }
  .topbar .tb-tel { justify-content: center; }

  .tiles, .projects, .pair, .figpair { grid-template-columns: minmax(0, 1fr); }
  .std-grid { grid-template-columns: minmax(0, 1fr); }
  .project { min-height: 260px; }
  .aside { max-width: none; }

  /* A spec table cannot render below its widest cell, so on a phone it stops
     being a table and becomes label-above-value. `display: block` on the
     rows, not `width:auto` - a table with `width:auto` shrink-to-fits its
     widest child instead of filling the column. */
  table.spec, table.spec tbody, table.spec tr, table.spec th, table.spec td {
    display: block; width: auto;
  }
  table.spec tr { border-bottom: 1px solid var(--line); }
  table.spec tr:last-child { border-bottom: 0; }
  table.spec th, table.spec td { border-bottom: 0; padding: 12px 16px; }
  table.spec th { padding-bottom: 0; }

  .isobadge { display: none; }
  .foot .isolink { display: inline-flex; }
  .foot-bar { justify-content: center; text-align: center; }
  .mapband iframe { height: 240px; }
  .map-inline { height: 320px; }
}

@media print {
  .masthead, .backdrop, .isobadge, .mapband, .searchform, .cta { display: none; }
  body { padding-top: 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
