/* Approved substitutes for the unlicensed Figma originals.
   Neue Montreal / Oakes Grotesk -> DM Sans; brand wordmark serif -> Tinos.
   Both are SIL Open Font License and self-hosted, so nothing calls Google. */
@font-face {
  font-family: "PTSB DM Sans";
  src: url("../fonts/dm-sans/dm-sans-400_700.woff2") format("woff2");
  font-display: swap;
  font-style: normal;
  font-weight: 400 700;
}

@font-face {
  font-family: "PTSB Tinos";
  src: url("../fonts/tinos/tinos-400.woff2") format("woff2");
  font-display: swap;
  font-style: normal;
  font-weight: 400;
}

@font-face {
  font-family: "PTSB Tinos";
  src: url("../fonts/tinos/tinos-700.woff2") format("woff2");
  font-display: swap;
  font-style: normal;
  font-weight: 700;
}

/* v2 design pass, 2026-09-08.
   Same palette, rail and type scale as v1; what changes is the rhythm:
   one section padding, one headline-to-content gap, one hairline set,
   flow layout instead of frozen coordinates. */
:root {
  --ptsb-precision-cream: #fcf9f4;
  --ptsb-precision-navy: #21304d;
  --ptsb-precision-charcoal: #2e2e2e;
  --ptsb-precision-blue-grey: #9aa8b4;
  /* The designer's file declares four colours and no more: blue #21304d,
     white #fcf9f4, black #2e2e2e and gold #a08a65. The theme had been
     carrying #837051 for the gold - a shade darker, which is why the buttons
     read brown rather than khaki - so every use is back on #a08a65.

     In the Figma frames that gold only ever fills a shape. Small text on
     cream is black there, which is why the eyebrow is charcoal below rather
     than a warm colour. Gold on cream measures 3.16:1, under the 4.5:1 that
     WCAG asks of body text; that is the designer's call and it is left as
     drawn. */
  --ptsb-precision-action: #a08a65;
  --ptsb-precision-gold: #eeb44e;
  /* The footer's headings were carrying #f0bf66 as a hardcoded hex - the only
     place in the theme it appeared, and a third gold alongside action and gold.
     It is a token now so the footer's headings and the links that light up
     under them read off one value and cannot drift apart again. */
  --ptsb-precision-gold-light: #f0bf66;
  --ptsb-precision-grey: #81807e;
  --ptsb-precision-hairline: rgba(46, 46, 46, .28);
  --ptsb-precision-hairline-strong: rgba(46, 46, 46, .7);
  --ptsb-precision-hairline-light: rgba(252, 249, 244, .32);
  --ptsb-precision-radius-sm: 10px;
  --ptsb-precision-radius-md: 15px;
  --ptsb-precision-radius-lg: 20px;
  --ptsb-precision-radius-pill: 53px;
  --ptsb-precision-rail: 1170px;
  --ptsb-precision-gutter: clamp(20px, calc((100vw - var(--ptsb-precision-rail)) / 2), 215px);
  --ptsb-precision-section: 120px;
  /* Every page that opens on the navy band uses the same height, so the band
     does not shrink when a headline happens to fit on one line. */
  --ptsb-precision-page-hero: 495px;
  --ptsb-precision-head-gap: 64px;
  --ptsb-precision-display: "PTSB DM Sans", Arial, sans-serif;
  --ptsb-precision-body: "PTSB DM Sans", Arial, sans-serif;
  --ptsb-precision-serif: "PTSB Tinos", Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }
html { overflow-x: hidden; background: var(--ptsb-precision-cream); color: var(--ptsb-precision-charcoal); font-family: var(--ptsb-precision-body); }
body { min-width: 0; margin: 0; background: var(--ptsb-precision-cream); }
a { color: inherit; }
.ptsb-precision-rail { width: min(var(--ptsb-precision-rail), calc(100% - (2 * var(--ptsb-precision-gutter)))); margin-inline: auto; }
.ptsb-precision-skip-link { position: fixed; z-index: 100; top: 12px; left: 12px; padding: 12px 16px; transform: translateY(-160%); border-radius: var(--ptsb-precision-radius-sm); background: var(--ptsb-precision-action); color: var(--ptsb-precision-cream); font-weight: 700; }
.ptsb-precision-skip-link:focus { transform: translateY(0); }

/* Shared header: Figma 1:283 + wordmark 1:292 at the 1600px anchor. */
.ptsb-precision-header { height: 117px; background: var(--ptsb-precision-cream); }
.ptsb-precision-header__inner { position: relative; height: 109px; border-bottom: 1px solid rgba(46, 46, 46, .7); }
.ptsb-precision-wordmark { position: absolute; top: 36px; left: 0; display: block; width: auto; height: 44px; font-family: var(--ptsb-precision-serif); font-size: 22px; font-weight: 400; letter-spacing: -.015em; line-height: 1.1; white-space: nowrap; text-decoration: none; }
.ptsb-precision-wordmark span { font-size: inherit; }
.ptsb-precision-nav { position: absolute; top: 49px; left: 50%; transform: translateX(-50%); }

/* Below the desktop layout the nav stops being a row across the header and
   becomes a panel. It used to paint itself solid cream and set no text colour,
   so the links inherited the header's - cream on About and Services - and the
   menu opened as a set of dividing lines with nothing between them.

   It is now a dark, translucent sheet instead: on the two pages whose header
   floats over a navy hero it continues that header rather than cutting a pale
   hole in the page, and on every page a little of what is behind shows through,
   so it reads as something laid over the page rather than a different page.
   The colour is set here, beside the background it has to contrast with - the
   original fault was a background declared without one. */
@media (max-width: 1023px) {
  .ptsb-precision-nav {
    color: var(--ptsb-precision-cream);
    background: color-mix(in srgb, var(--ptsb-precision-navy) 84%, transparent);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
  }
  /* The panel worked but read as a utility list: four identical 14px uppercase
     labels with rules between them. It now speaks the site's own language
     instead - the display face, title case, at a size closer to a section
     heading than to a form label - because the typography is what this design
     is. Uppercase at 14px is a caption; "Our Services" at 24px is a place you
     can go.

     The page you are on is gold. The site already carried an aria-current rule
     for this and it was switched off down here, so the menu could not answer
     the first question anyone opens a menu with. */
  .ptsb-precision-menu a[aria-current="page"] { color: var(--ptsb-precision-action); }
  .ptsb-precision-menu li:last-child a { border-bottom: 0; }

  /* The rows arrive one after another rather than all at once. It costs no
     height and it is the difference between a panel that appears and a panel
     that opens. */
  @media (prefers-reduced-motion: no-preference) {
    .is-menu-open .ptsb-precision-menu a { animation: ptsb-menu-in .32s cubic-bezier(.2, .6, .2, 1) both; }
    .is-menu-open .ptsb-precision-menu li:nth-child(1) a { animation-delay: .02s; }
    .is-menu-open .ptsb-precision-menu li:nth-child(2) a { animation-delay: .06s; }
    .is-menu-open .ptsb-precision-menu li:nth-child(3) a { animation-delay: .10s; }
    .is-menu-open .ptsb-precision-menu li:nth-child(4) a { animation-delay: .14s; }
    .is-menu-open .ptsb-precision-menu li:nth-child(5) a { animation-delay: .18s; }
  }

  /* Someone who has asked for less transparency gets a solid sheet. */
  @media (prefers-reduced-transparency: reduce) {
    .ptsb-precision-nav { background: var(--ptsb-precision-navy); -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
}
.ptsb-precision-menu { display: flex; gap: 61px; margin: 0; padding: 0; list-style: none; white-space: nowrap; }
.ptsb-precision-menu a { position: relative; display: block; padding: 0; font-size: 16px; font-weight: 600; line-height: 1; text-decoration: none; text-transform: uppercase; }
/* Hover and current page draw the same bar. Hover used to be a text-decoration
   underline, which the font positions itself, so it never lined up with the
   current-page rule below it. */
.ptsb-precision-menu a::after { position: absolute; right: 0; bottom: -9px; left: 0; height: 2px; background: currentColor; opacity: 0; content: ""; transition: opacity .18s ease; }
.ptsb-precision-menu a:hover,
.ptsb-precision-menu a:focus-visible { color: var(--ptsb-precision-grey); }
.ptsb-precision-menu a:hover::after,
.ptsb-precision-menu a:focus-visible::after,
.ptsb-precision-menu .current-menu-item > a::after,
.ptsb-precision-menu a[aria-current="page"]::after { opacity: 1; }
.ptsb-precision-button { display: inline-flex; height: 56px; align-items: center; justify-content: center; padding: 0 32px; white-space: nowrap; border: 0; border-radius: var(--ptsb-precision-radius-pill); background: var(--ptsb-precision-action); color: var(--ptsb-precision-cream); font-size: 16px; font-weight: 600; line-height: 1; text-align: center; text-decoration: none; text-transform: uppercase; transition: filter .2s ease, transform .2s ease; }
.ptsb-precision-button:hover,
.ptsb-precision-button:focus-visible { filter: brightness(1.08); transform: translateY(-1px); }
.ptsb-precision-button--header { position: absolute; top: 26px; right: 0; width: 197px; }
.ptsb-precision-menu-toggle { display: none; }

.ptsb-precision-main { min-height: 300px; }
.ptsb-precision-content-shell { padding: 112px 0; }
.ptsb-precision-placeholder { width: min(680px, 100%); }
/* Action links are a label, a gap and an arrow. text-decoration is not used
   because it underlines the arrow glyph too - that was the stray dash under the
   arrow. Instead the label carries a rule of its own at rest, so the link still
   reads as a link, and hovering runs a single rule from the first letter to the
   tip of the arrow. The rest rule is dropped the instant the pointer lands, so
   the sweep is visible from the very first letter rather than starting halfway. */
.ptsb-precision-textlink {
  position: relative;
  text-decoration: none;
}

.ptsb-precision-textlink__label {
  position: relative;
}

.ptsb-precision-textlink__label::after,
.ptsb-precision-textlink::after {
  position: absolute;
  right: 0;
  bottom: -5px;
  left: 0;
  height: 1px;
  background: currentColor;
  content: "";
}

.ptsb-precision-textlink__label::after {
  transition: opacity .2s ease .1s;
}

.ptsb-precision-textlink::after {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .34s cubic-bezier(.2, .6, .2, 1);
}

.ptsb-precision-textlink:hover .ptsb-precision-textlink__label::after,
.ptsb-precision-textlink:focus-visible .ptsb-precision-textlink__label::after {
  opacity: 0;
  transition: opacity 0s;
}

.ptsb-precision-textlink:hover::after,
.ptsb-precision-textlink:focus-visible::after {
  transform: scaleX(1);
}

@keyframes ptsb-menu-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ptsb-precision-textlink::after { transition: none; }
}

.ptsb-precision-eyebrow { margin: 0 0 14px; color: var(--ptsb-precision-charcoal); font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.ptsb-precision-placeholder h1 { max-width: 600px; margin: 0 0 24px; font-family: var(--ptsb-precision-display); font-size: clamp(56px, 7vw, 96px); font-weight: 400; letter-spacing: -.065em; line-height: .9; }
.ptsb-precision-placeholder p:last-child { max-width: 480px; font-size: 17px; line-height: 1.5; }
.ptsb-precision-content-shell > * { width: min(var(--ptsb-precision-rail), calc(100% - (2 * var(--ptsb-precision-gutter)))); margin-inline: auto; }

/* Shared CTA (v2): flow layout, copy left, button right, centred on each other. */
.ptsb-precision-cta { padding: 104px 0; background: var(--ptsb-precision-charcoal); color: var(--ptsb-precision-cream); }
.ptsb-precision-cta__inner { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 64px; }
.ptsb-precision-cta__copy { max-width: 640px; }
.ptsb-precision-cta h2 { margin: 0; font-family: var(--ptsb-precision-display); font-size: 44px; font-weight: 400; letter-spacing: -.03em; line-height: 1.08; }
.ptsb-precision-cta__ready::after { display: block; content: ""; }
.ptsb-precision-cta__copy p { max-width: 620px; margin: 24px 0 0; font-size: 17px; line-height: 1.5; }
.ptsb-precision-button--cta { flex: 0 0 auto; width: 320px; }
/* Below the desktop anchor the v1 frozen CTA layout takes over again. */
@media (max-width: 1023px) {
  .ptsb-precision-cta { padding: 0; }
  .ptsb-precision-cta__inner { display: block; height: 100%; }
}

/* Shared footer: Figma 1:293 at 1600px (unchanged from v1). */
/* 23px shorter than the Figma frame: the rule sat 75px below the columns but
   only 23px above the line it introduces, so the legal row read as adrift. */
.ptsb-precision-footer { height: 426px; background: var(--ptsb-precision-navy); color: var(--ptsb-precision-cream); }
.ptsb-precision-footer > .ptsb-precision-rail { position: relative; height: 100%; }
.ptsb-precision-footer__grid { position: absolute; inset: 0; }
.ptsb-precision-footer__grid section { position: absolute; min-width: 0; }
/* A step lighter than the brand gold, so the column labels sit below the
   lockup rather than level with it. */
.ptsb-precision-footer h2 { margin: 0; color: var(--ptsb-precision-gold-light); font-size: 16px; font-weight: 600; line-height: 1.27; text-transform: uppercase; }
.ptsb-precision-footer p,
.ptsb-precision-footer a { color: var(--ptsb-precision-cream); font-size: 16px; font-weight: 300; text-decoration: none; }
/* Tapped, a link takes the colour of the heading it sits under rather than the
   slightly darker gold it used - #f0bf66 against #eeb44e, close enough to look
   like a mistake rather than a distinction. */
.ptsb-precision-footer a:hover,
.ptsb-precision-footer a:focus-visible { color: var(--ptsb-precision-gold-light); text-decoration: underline; text-underline-offset: 4px; }
.ptsb-precision-footer__brand { top: 0; left: 0; width: 380px; height: 310px; }
.ptsb-precision-footer__brand-lockup { position: absolute; top: 93px; left: 0; display: block; width: 327px; height: 108px; }
.ptsb-precision-footer__emblem { position: absolute; top: 4px; left: 0; display: block; width: 124px; height: 82px; }
.ptsb-precision-footer__emblem img { display: block; width: 100%; height: 100%; }
.ptsb-precision-footer__brand-copy { position: absolute; top: 8px; left: 143px; display: flex; width: 224px; flex-direction: column; gap: 10px; color: var(--ptsb-precision-gold); font-family: var(--ptsb-precision-serif); font-size: 22px; line-height: 1.3; white-space: nowrap; }
/* The brush wordmark reads as leaning left; this tips the whole lockup back
   to the right. Rigid rotation of the original artwork, nothing redrawn. */
/* No text-stroke here on purpose (2026-09-08): even painted under the fill it
   shifted the English a shade off the brush mark. Weight comes from the real
   bold cut instead; align-self keeps the gradient box hugging the word rather
   than the whole column. */
.ptsb-precision-footer__brand-copy > span { align-self: flex-start; font-weight: 700; }
/* The lockup text carries the same metallic ramp as the mark. Guarded, because
   without background-clip the transparent fill would hide the words entirely.
   The navigation headings stay flat gold on purpose - at 16px a ramp only
   muddies them and drops the dark end to 4.5:1. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ptsb-precision-footer__brand-copy > span {
    /* The fern's light carries straight on into the words: it starts at the
       cream the frond tip ends on, then deepens away from the mark. The
       Chinese SVG carries the identical ramp. */
    background-image: linear-gradient(to right, #fbe6bd 0%, #f2c877 22%, #eeb44e 55%, #e1a747 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}
/* Bold widens the English to 178px, so the brush line is scaled to match;
   the two must stay equal width or the lockup reads ragged. */
.ptsb-precision-footer__brand-copy img { display: block; width: 178px; height: 31.5px; transform: rotate(1.5deg); transform-origin: 50% 50%; }
/* Wide enough for three lines instead of four: at 282 the last line was a
   stub. text-wrap: balance evens the three out (they end within 38px of
   each other); browsers without it break identically at this width. */
.ptsb-precision-footer__description { position: absolute; top: 205px; left: 0; width: 380px; margin: 0; line-height: 1.3; text-wrap: balance; }
/* The three info columns are spaced by the air between their text, not by an
   even step: the blocks are 96 / 178 / 240 wide, so an even step left a hole
   after Navigation and crowded Office against Contact. 80px of air between
   each, with Contact still locked to the right of the rail. */
.ptsb-precision-footer__navigation { top: 105px; left: 494px; width: 170px; }
.ptsb-precision-footer__navigation > div { margin-top: 18px; }
.ptsb-precision-footer__navigation a { display: block; margin: 0 0 14.5px; line-height: 1; }
.ptsb-precision-footer__office { top: 105px; left: 670px; width: 200px; }
.ptsb-precision-footer__address { margin: 14px 0 0; line-height: 1.5; }
.ptsb-precision-footer__hours { margin: 24px 0 0; line-height: 1; }
.ptsb-precision-footer__hours span { display: block; margin-top: 14.5px; }
.ptsb-precision-footer__contact { top: 105px; right: 0; left: auto; width: 242px; }
.ptsb-precision-footer__phone,
.ptsb-precision-footer__email { position: absolute; right: 0; left: 0; width: auto; }
.ptsb-precision-footer__phone { top: 38px; }
.ptsb-precision-footer__email { top: 130px; }
.ptsb-precision-footer__phone p,
.ptsb-precision-footer__email p { margin: 0 0 14.5px; line-height: 1; }
.ptsb-precision-footer__phone a { display: block; line-height: 1.1; }
/* The two numbers were set solid; 8px separates them without pushing the Email
   group below the row its neighbours in the other columns sit on. */
.ptsb-precision-footer__phone a + a { margin-top: 8px; }
.ptsb-precision-footer__email a { display: block; line-height: 1; }
/* The legal line breaks before the copyright on a phone, where it would
   otherwise wrap mid-sentence. One line everywhere wider. */
.ptsb-precision-footer__meta-break { display: none; }
@media (max-width: 767px) {
  .ptsb-precision-footer__meta-break { display: inline; }
}

.ptsb-precision-footer__meta { position: absolute; top: 336px; right: 0; left: 0; display: flex; height: 63px; align-items: flex-start; justify-content: space-between; padding-top: 23px; border-top: 1px solid rgba(154, 168, 180, .9); color: var(--ptsb-precision-blue-grey); font-size: 16px; font-weight: 300; line-height: 1.25; letter-spacing: -.011em; }

.ptsb-precision-pill { display: inline-flex; min-width: 150px; height: 39px; align-items: center; justify-content: center; padding: 0 22px; border: 1px solid currentColor; border-radius: var(--ptsb-precision-radius-pill); font-size: 14px; font-weight: 400; letter-spacing: .04em; line-height: 1; text-transform: uppercase; }
.ptsb-precision-crop { display: block; overflow: hidden; border-radius: var(--ptsb-precision-radius-md); background: var(--ptsb-precision-blue-grey); }
.ptsb-precision-crop > img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Tablet interpolation: deliberately responsive, not an invented Figma frame. */
@media (min-width: 768px) and (max-width: 1100px) {
  .ptsb-precision-header { height: 89px; }
  .ptsb-precision-header__inner { height: 81px; }
  .ptsb-precision-wordmark { top: 22px; width: 150px; height: 40px; font-size: 20px; }
  .ptsb-precision-button--header { top: 18px; right: 52px; width: 150px; height: 44px; padding-inline: 20px; font-size: 13px; }
  .ptsb-precision-menu-toggle { position: absolute; top: 23px; right: 0; display: grid; width: 36px; height: 36px; place-content: center; gap: 7px; padding: 0; border: 0; background: transparent; color: inherit; cursor: pointer; }
  .ptsb-precision-menu-toggle span { display: block; width: 28px; height: 1px; background: currentColor; transition: transform .2s ease, opacity .2s ease; }
  .ptsb-precision-nav { z-index: 10; top: 81px; right: calc(-1 * var(--ptsb-precision-gutter)); left: calc(-1 * var(--ptsb-precision-gutter)); display: none; transform: none; padding: 14px var(--ptsb-precision-gutter) 18px; border-bottom: 1px solid rgba(252, 249, 244, .24); }
  .is-menu-open .ptsb-precision-nav { display: block; }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(2) { opacity: 0; }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
  .ptsb-precision-menu { display: grid; gap: 0; }
  .ptsb-precision-menu a { padding: 10px 0; border-bottom: 1px solid rgba(252, 249, 244, .16); font-family: var(--ptsb-precision-display); font-size: 20px; font-weight: 400; letter-spacing: -.02em; line-height: 1.2; text-transform: none; }
  .ptsb-precision-menu a::after { display: none; }

  .ptsb-precision-footer { height: auto; min-height: 620px; padding: 50px 0 32px; }
  .ptsb-precision-footer > .ptsb-precision-rail { height: auto; }
  .ptsb-precision-footer__grid { position: static; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 42px 56px; }
  .ptsb-precision-footer__grid section { position: static; width: auto; height: auto; }
  .ptsb-precision-footer__brand-lockup { position: relative; top: auto; left: auto; width: 313px; max-width: 100%; }
  .ptsb-precision-footer__description { position: static; width: min(282px, 100%); margin-top: 18px; }
  .ptsb-precision-footer__navigation > div { margin-top: 18px; }
  .ptsb-precision-footer__address { margin-top: 14px; }
  .ptsb-precision-footer__hours { margin-top: 24px; }
  .ptsb-precision-footer__phone,
  .ptsb-precision-footer__email { position: static; width: auto; margin-top: 18px; }
  .ptsb-precision-footer__email { margin-top: 28px; }
  .ptsb-precision-footer__meta { position: relative; top: auto; margin-top: 42px; }
}

/* Narrow tablets cannot safely hold the desktop CTA copy and button side by side. */
@media (min-width: 768px) and (max-width: 1023px) {
  .ptsb-precision-cta { height: 415px; }
  .ptsb-precision-cta__copy { position: absolute; top: 60px; left: 0; width: 100%; }
  .ptsb-precision-cta h2 { width: min(592px, 100%); font-size: clamp(52px, 7.3vw, 60px); }
  .ptsb-precision-cta__copy p { width: min(620px, 100%); margin-top: 22px; }
  .ptsb-precision-button--cta { position: absolute; top: auto; right: 0; bottom: 51px; width: min(369px, 100%); }
}

/* Mobile anchors: Projects CTA 2047:921, short CTA 2047:331, Footer 2047:931. */
@media (max-width: 767px) {
  :root { --ptsb-precision-gutter: clamp(16px, 7.4627vw, 30px); }
  .ptsb-precision-header { height: 76px; }
  /* A row, not three things pinned at top: 45px inside a 76px box. That pinning
     is why every control here was 31px tall: 76 - 45 leaves 31, and the design
     was scaled to fit rather than laid out. Centred in the same 76px band the
     controls can be 44px - the smallest target a thumb hits reliably - with
     16px of air above and below, and the header does not change height. The nav
     dropdown is absolute and stays out of this row. */
  .ptsb-precision-header__inner { display: flex; width: min(342px, calc(100% - (2 * var(--ptsb-precision-gutter)))); height: 76px; gap: 12px; align-items: center; border-bottom: 0; }
  /* Shawn's call, and a deliberate departure from the mobile frame: the frame
     draws the wordmark small and the gold pill large, which was fine as a
     picture but not once the pill has to be 44px tall to be tappable - at that
     size it out-weighs the company's own name. The name goes up, the pill comes
     down to the smallest label that still reads, and the pill keeps its 44px
     height because that is the dimension a thumb actually needs. */
  /* The name was the faintest mark in a row that also holds a filled pill and
     three solid rules. Weight cannot fix that here: Tinos ships 400 and 700 and
     nothing between, so asking for 600 silently returns 700, which is what read
     as too heavy. Presence comes from size instead - 19px at the regular weight
     is larger than the pill's label and holds the left of the row without
     thickening the strokes. */
  .ptsb-precision-wordmark { position: static; width: auto; height: auto; margin-right: auto; font-size: 19px; font-weight: 400; line-height: 1.15; }
  /* top/right have to be cleared explicitly: the desktop rule sets top: 26px for
     an absolutely positioned header button, and switching to relative here would
     otherwise keep that offset live and push the pill 26px below the row. */
  .ptsb-precision-button--header { position: relative; top: auto; right: auto; width: auto; height: 36px; padding: 0 12px; font-size: 11px; letter-spacing: .04em; }
  /* The pill is 36px because that is the size Shawn wants to look at; the thing
     a thumb aims at is still 44px. This ::after is transparent, sits inside the
     anchor, and reaches 4px past it top and bottom - so the touch area keeps
     its full height while the gold shape shrinks. Painting and hit-testing are
     not the same problem and do not have to share a number. */
  .ptsb-precision-button--header::after { position: absolute; top: -4px; right: 0; bottom: -4px; left: 0; content: ""; }
  .ptsb-precision-menu-toggle { position: static; display: grid; width: 44px; height: 44px; flex: 0 0 auto; place-content: center; gap: 8px; padding: 0; border: 0; background: transparent; color: inherit; cursor: pointer; }
  .ptsb-precision-menu-toggle span { display: block; width: 31px; height: 1px; background: currentColor; transition: transform .2s ease, opacity .2s ease; }
  .ptsb-precision-nav { z-index: 10; top: 76px; right: calc(-1 * var(--ptsb-precision-gutter)); left: calc(-1 * var(--ptsb-precision-gutter)); display: none; transform: none; padding: 12px var(--ptsb-precision-gutter) 16px; border-bottom: 1px solid rgba(252, 249, 244, .24); }
  .is-menu-open .ptsb-precision-nav { display: block; }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(2) { opacity: 0; }
  .is-menu-open .ptsb-precision-menu-toggle span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }
  .ptsb-precision-menu { display: grid; gap: 0; }
  .ptsb-precision-menu a { padding: 10px 0; border-bottom: 1px solid rgba(252, 249, 244, .16); font-family: var(--ptsb-precision-display); font-size: 20px; font-weight: 400; letter-spacing: -.02em; line-height: 1.2; text-transform: none; }
  .ptsb-precision-menu a::after { display: none; }

  .ptsb-precision-content-shell { padding: 76px 0; }
  /* The frozen frame is gone. It gave the band a fixed height and pinned the
     copy and the button at absolute offsets, so a paragraph that wrapped to two
     lines ran its last line 10px under the button - the overlap Shawn saw. Flow
     layout instead, the same move v2 made on desktop: nothing is pinned, so no
     amount of text can collide with anything. The sizes come up with it; 12px
     body copy and a 37px button were a 320px frame scaled down, not a phone
     design. */
  .ptsb-precision-cta { height: auto; padding: 56px 0 60px; }
  .ptsb-precision-cta--mobile-short { height: auto; }
  .ptsb-precision-cta--mobile-tall { height: auto; }
  /* The band was computing its own width - min(351px, 100% - 52px) - which put
     its contents at 26px from the edge while every other block on the page sits
     on the rail at 29px. Three pixels, on every page, at the bottom of the
     scroll. It uses the rail's own formula now, so it cannot drift again. */
  .ptsb-precision-cta__inner { width: min(var(--ptsb-precision-rail), calc(100% - (2 * var(--ptsb-precision-gutter)))); margin-inline: auto; }
  .ptsb-precision-cta__copy { position: static; width: 100%; }
  /* 32, the section-heading size. It was 48 - larger than the page's own H1 at
     40 and larger than every section heading at 32, which made the closing
     band the loudest thing on a phone. On desktop this heading is 44 against a
     96px H1 and 56px section headings, i.e. the quietest heading on the page;
     mobile had inverted that. The 325px width cap goes with it: the block now
     sits on the rail, so the sentence wraps on the rail. */
  .ptsb-precision-cta h2 { width: 100%; font-size: 32px; letter-spacing: -.03em; line-height: 1.08; }
  .ptsb-precision-cta__copy p { width: 100%; margin-top: 20px; font-size: 16px; line-height: 1.45; }
  .ptsb-precision-button--cta { position: static; width: 100%; height: 52px; margin-top: 32px; padding: 0; transform: none; font-size: 14px; }
  .ptsb-precision-button--cta:hover,
  .ptsb-precision-button--cta:focus-visible { transform: translateY(-1px); }
  .ptsb-precision-cta--mobile-short .ptsb-precision-cta__ready::after { display: none; }
  .ptsb-precision-cta--mobile-short .ptsb-precision-cta__discuss::after { display: block; content: ""; }
  .ptsb-precision-cta--mobile-short h2 { width: 100%; font-size: 32px; letter-spacing: -.03em; }

  /* The footer was 1091px of fixed height with every block pinned at an absolute
     offset - 51, 263, 489, 720, 1001 - which is a drawing, not a layout, and on
     a 874px screen it ran for a screen and a quarter. Flow layout instead, and
     two things that were stacked are no longer: the five navigation links wrap
     as a row rather than a column of five, and Office sits beside Contact Us.
     Nothing is removed; the same content is folded rather than cut. */
  /* The footer was 1091px of fixed height with every block pinned at an absolute
     offset - 51, 263, 489, 720, 1001 - which is a drawing, not a layout, and on
     a 874px screen it ran for a screen and a quarter.

     Flow layout instead, and organised the way the reference Shawn sent does it:
     the brand stays centred, everything under it reads from the left, and each
     block folds its own contents into two columns rather than the whole footer
     folding into two. Centring a list of five links and a set of phone numbers
     gives every line a different starting point, so the eye has nowhere to run
     down; a left edge gives it one. */
  .ptsb-precision-footer { height: auto; padding: 56px 0 28px; text-align: left; }
  .ptsb-precision-footer > .ptsb-precision-rail { width: min(342px, calc(100% - (2 * var(--ptsb-precision-gutter)))); height: auto; }
  .ptsb-precision-footer__grid { position: static; display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .ptsb-precision-footer__grid section { position: static; width: auto; height: auto; transform: none; }
  .ptsb-precision-footer__brand { text-align: center; }
  .ptsb-precision-footer h2 { font-size: 14px; line-height: 20px; }
  .ptsb-precision-footer p,
  .ptsb-precision-footer a { font-size: 14px; }
  .ptsb-precision-footer__brand-lockup { position: relative; top: auto; left: auto; width: 273px; height: 92px; margin: 0 auto; transform: none; }
  .ptsb-precision-footer__emblem { width: 93px; height: 61px; }
  .ptsb-precision-footer__brand-copy { top: 14px; left: 100px; width: 173px; height: 78px; align-items: flex-start; font-size: 19px; text-align: left; }
  .ptsb-precision-footer__brand-copy [lang] { font-size: 24px; }
  .ptsb-precision-footer__brand-copy img { width: 154px; height: 27.2px; }
  .ptsb-precision-footer__description { position: static; width: min(339px, 100%); margin: 18px auto 0; transform: none; font-size: 14px; line-height: 1.4; }
  /* Contact Us comes out of this list on a phone. The footer already carries a
     CONTACT US block of its own a little below, with the phone numbers and the
     address in it, so the link was pointing at something already on screen.
     Matched on its href rather than its position, so reordering the menu later
     cannot hide the wrong one. Desktop keeps all five. */
  .ptsb-precision-footer__navigation a[href*="#contact-details"] { display: none; }
  /* The four that remain fill down the first column and then the second - Home
     over About Us, Our Services over Our Projects - rather than left to right
     along each row. Read down, each column is a pair that belongs together;
     read across, the old order split them. Two explicit rows with the flow
     turned to column is what puts them that way round. */
  .ptsb-precision-footer__navigation > div {
    display: grid;
    grid-template-rows: repeat(2, auto);
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 14px 20px;
    margin-top: 16px;
  }
  .ptsb-precision-footer__navigation a { margin: 0; font-size: 14px; line-height: 20px; }
  /* One spacing scale, so the gaps say what belongs to what:
       4px   inside one fact   - the days and the hours are one opening time
       16px  heading to its content
       24px  between two facts in the same block
       40px  between blocks
     Before this every one of those was 16px, which is why the block read as a
     flat list of five equal things instead of a heading over two facts. */
  .ptsb-precision-footer__address { margin-top: 16px; font-size: 14px; line-height: 1.5; }
  .ptsb-precision-footer__hours { margin: 24px 0 0; line-height: 1.5; }
  /* The span is already block-level, so the <br> before it only contributes an
     empty line box - 15px of the hours block's 57px height was that ghost. */
  .ptsb-precision-footer__hours br { display: none; }
  .ptsb-precision-footer__hours span { display: block; margin-top: 4px; }
  /* Phone and email side by side inside their own section, which is what makes
     the block read as one set of contact details rather than two stacked lists. */
  .ptsb-precision-footer__contact > div:first-of-type { margin-top: 16px; }
  .ptsb-precision-footer__contact { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
  .ptsb-precision-footer__contact h2 { grid-column: 1 / -1; }
  .ptsb-precision-footer__phone,
  .ptsb-precision-footer__email { position: static; top: auto; width: 100%; margin-top: 16px; }
  /* These two columns stand side by side, so they have to keep the same line
     rhythm - and they did not. The phone numbers are two separate links, spaced
     by an 8px margin on top of a 1.1 line-height, which put 23.4px between
     them; the email is one link that wraps, on a line-height of 1.0, which put
     14px between its lines. First lines matched at 693.8 and the second lines
     were 9.4px apart, which is what read as crooked.

     One 20px line box for both, and the margin between the numbers goes - the
     line box is doing that job now. Both columns are then the same height and
     every line lands on the same baseline as the one beside it. 1.0 was too
     tight for a wrapping address anyway.

     The labels give their values a little more room with it - 14px rather than
     10 - which is the "move the numbers down" half. It applies to both columns,
     so they stay level. */
  .ptsb-precision-footer__phone p,
  .ptsb-precision-footer__email p { margin-bottom: 14px; }
  .ptsb-precision-footer__phone a,
  .ptsb-precision-footer__email a { line-height: 20px; }
  .ptsb-precision-footer__phone a + a { margin-top: 0; }
  .ptsb-precision-footer__meta { position: static; height: auto; margin-top: 36px; padding-top: 16px; font-size: 14px; line-height: 1.3; text-align: left; }
  /* 155px and 47px were measured off the frozen frame and broke both halves onto
     two ragged lines once the type changed. Auto widths and the row's own
     space-between put the legal line and the grade at opposite ends, each on one
     line. */
  .ptsb-precision-footer__meta span:first-child { width: auto; }
  .ptsb-precision-footer__meta span:last-child { width: auto; text-align: right; white-space: nowrap; }


  .ptsb-precision-pill { width: 141px; min-width: 0; height: 27px; padding: 0 12px; font-size: 12px; }
}

@media (max-width: 360px) {
  /* The header used to shrink again here, and again at 290px, down to an 8px
     label on an 84px button. A flex row needs none of that - it just closes the
     gaps - so only the wordmark steps down, and the controls keep their 44px. */
  .ptsb-precision-wordmark { font-size: 16px; }
  .ptsb-precision-header__inner { gap: 8px; }
  .ptsb-precision-button--header { padding: 0 10px; }
  /* the rail's own gutter already narrows here; nothing to override */
  /* the heading no longer grows as the screen shrinks */
  .ptsb-precision-cta--mobile-short h2 { font-size: 43px; }
}

@media (max-width: 290px) {
  .ptsb-precision-wordmark { font-size: 15px; }
  .ptsb-precision-cta h2 { font-size: 46px; }
  .ptsb-precision-cta--mobile-short h2 { font-size: 39px; }
  .ptsb-precision-footer__brand-copy { left: 96px; }
}

/* ===== Photo / document viewer (used by the project gallery and by the
   testimonial document link, so it lives in the shared sheet) ===== */
.ptsb-lightbox-open { overflow: hidden; }
.ptsb-lightbox { position: fixed; z-index: 100; inset: 0; display: flex; align-items: center; justify-content: center; padding: 72px 88px; }
.ptsb-lightbox[hidden] { display: none; }
.ptsb-lightbox__backdrop { position: absolute; inset: 0; background: rgba(23, 23, 23, .93); cursor: zoom-out; }
.ptsb-lightbox__figure { position: relative; display: flex; max-width: 100%; max-height: 100%; flex-direction: column; align-items: center; margin: 0; gap: 18px; }
.ptsb-lightbox__image { display: block; max-width: 100%; max-height: calc(100vh - 190px); width: auto; height: auto; border-radius: var(--ptsb-precision-radius-md); cursor: zoom-in; object-fit: contain; opacity: 1; transition: opacity .2s ease; }
/* Zoomed: the file's own pixels, and the figure scrolls around them. */
.ptsb-lightbox.is-zoomed .ptsb-lightbox__figure { max-width: 100%; max-height: 100%; overflow: auto; align-items: flex-start; }
.ptsb-lightbox.is-zoomed .ptsb-lightbox__image { max-width: none; max-height: none; width: auto; height: auto; border-radius: 0; cursor: zoom-out; }
.ptsb-lightbox.is-zoomed .ptsb-lightbox__caption { display: none; }
.ptsb-lightbox.is-loading .ptsb-lightbox__image { opacity: .35; }
.ptsb-lightbox__caption { display: flex; max-width: min(760px, 100%); gap: 20px; align-items: baseline; justify-content: center; color: rgba(252, 249, 244, .72); font-family: var(--ptsb-precision-body); font-size: 15px; line-height: 1.45; text-align: center; }
.ptsb-lightbox__text[hidden] { display: none; }
/* Optional download link. No page passes data-file today - see
   docs/viewer-download-link.md for how to switch it back on. */
.ptsb-lightbox__file { color: var(--ptsb-precision-cream); font-weight: 600; letter-spacing: .04em; text-decoration: underline; text-transform: uppercase; text-underline-offset: 5px; }
.ptsb-lightbox__file[hidden] { display: none; }
.ptsb-lightbox__file:hover { color: var(--ptsb-precision-gold); }
.ptsb-lightbox__count { color: rgba(252, 249, 244, .45); font-variant-numeric: tabular-nums; }
.ptsb-lightbox__close,
.ptsb-lightbox__nav { position: absolute; display: flex; align-items: center; justify-content: center; padding: 0; border: 1px solid rgba(252, 249, 244, .28); border-radius: 50%; background: rgba(23, 23, 23, .55); color: var(--ptsb-precision-cream); cursor: pointer; font-family: var(--ptsb-precision-body); line-height: 1; transition: background-color .18s ease, border-color .18s ease; }
.ptsb-lightbox__close:hover,
.ptsb-lightbox__nav:hover { border-color: rgba(252, 249, 244, .6); background: rgba(23, 23, 23, .9); }
.ptsb-lightbox__close:focus-visible,
.ptsb-lightbox__nav:focus-visible { outline: 2px solid var(--ptsb-precision-gold); outline-offset: 3px; }
.ptsb-lightbox__close { top: 24px; right: 28px; width: 44px; height: 44px; font-size: 17px; }
.ptsb-lightbox__nav { top: 50%; width: 56px; height: 56px; margin-top: -28px; font-size: 30px; }
.ptsb-lightbox__nav--prev { left: 24px; }
.ptsb-lightbox__nav--next { right: 24px; }
.ptsb-lightbox__nav[hidden] { display: none; }

@media (max-width: 767px) {
  .ptsb-lightbox { padding: 64px 16px; }
  .ptsb-lightbox__image { max-height: calc(100vh - 180px); }
  .ptsb-lightbox__close { top: 14px; right: 14px; width: 38px; height: 38px; }
  .ptsb-lightbox__nav { bottom: 18px; top: auto; width: 46px; height: 46px; margin-top: 0; font-size: 26px; }
  .ptsb-lightbox__nav--prev { left: 50%; margin-left: -58px; }
  .ptsb-lightbox__nav--next { right: 50%; margin-right: -58px; }
  .ptsb-lightbox__caption { font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .ptsb-lightbox__image,
  .ptsb-lightbox__close,
  .ptsb-lightbox__nav { transition: none; }
}
