/* ==========================================================================
   Northline Electrical
   Every colour, font and spacing decision lives in the :root block below.
   Change it there and it changes everywhere on the site.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The typeface, served from this site rather than from Google.

   It used to be a <link> to fonts.googleapis.com in the page head. That is a
   slow way to load a font, because nothing can be drawn until it finishes and
   it is a chain of three waits: fetch the page, fetch Google's stylesheet
   from one domain, then fetch the font itself from a second domain. Each hop
   needs its own DNS lookup and its own secure connection, and on a phone away
   from wifi that is most of a second before a single word appears.

   Coming from here, the browser already has the connection open. It also
   means nobody visiting the site is announced to Google on the way in.

   Only the Latin subsets are here. Google offers Cyrillic, Greek and
   Vietnamese as well, which this site has no use for. unicode-range tells the
   browser which characters live in which file, so the extended one is only
   fetched if a page actually uses a character from it.

   Inter is under the SIL Open Font License, which permits this.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;          /* one variable file covers the whole range */
  font-display: swap;            /* show the fallback immediately, swap later */
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
                 U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                 U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
                 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
                 U+FFFD;
}

:root {
  /* --- Colour. The site is dark. -----------------------------------------
     "Paper" still means the surface and "ink" still means what is written on
     it. The surface is now warm charcoal and the ink is warm white, so every
     rule in this file that says background:var(--paper) or color:var(--ink)
     kept working when the site inverted. That is the whole point of putting
     colour in one place. */
  --paper:      #16130E;   /* the page surface */
  --paper-2:    #1E1A14;   /* raised: form fields, footer, mobile bar */
  --paper-3:    #241F17;   /* the guarantee band, so it still reads as a break */
  --ink:        #F2EFE9;   /* primary text */
  /* Secondary text. Brightened from #A9A296 on 26 August 2026 because it read
     as too dim against the dark page. 7.32:1 -> 9.20:1, a 26% lift, while
     staying 1.75x below --ink so the hierarchy between primary and secondary
     copy still reads. Used in 17 places, so this one line moves all of them. */
  --slate:      #BDB6A9;
  --hairline:   rgba(242, 239, 233, .14);   /* rules and dividers */
  --brass:      #B8802B;   /* the one accent. 5.36:1 on the surface */
  --brass-dark: #CE9439;   /* hover now goes lighter, not darker */

  /* Text sitting ON brass must stay dark. --ink is light now, so a brass
     button with --ink text would measure 3.4:1 and fail. */
  --on-brass:   #16130E;

  --paper-dim:     rgba(242, 239, 233, .72);  /* secondary text on dark */
  --hairline-dark: rgba(242, 239, 233, .14);  /* dividers on dark */
  /* Control edges need 3:1. The divider value above is nowhere near it. */
  --border-on-dark: rgba(242, 239, 233, .4);

  --mobile-bar-h: 76px;

  /* --- Type --- */
  /* Inter for everything, per DESIGN.md. Both tokens kept rather than merged,
     so display and body can diverge again later without touching every rule.

     Letter-spacing below is expressed in em, not px. DESIGN.md quotes px
     against its own sizes: -5.5px on 110px type is -5%, -0.15px on 15px body
     is -1%. This site's sizes are different and several are fluid, so px
     would give the wrong tracking at every size. em reproduces the table's
     exact ratios at whatever size the text actually renders, which is what
     DESIGN.md means by "letter-spacing scales with size, hard". */
  --font-display: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Exact ratios from the DESIGN.md typography hierarchy table. */
  --ls-display-lg: -0.05em;      /* -3.1px on 62px  */
  --ls-display-md: -0.03125em;   /* -1.0px on 32px  */
  --ls-headline:   -0.03636em;   /* -0.8px on 22px  */
  --ls-body:       -0.01em;      /* -0.15px on 15px, and every smaller tier */

  /* --- Layout --- */
  --header-height: 76px;
  --gutter: clamp(20px, 6vw, 104px);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  /* NO scroll-behavior:smooth here, deliberately. With it set, a browser that
     restores your scroll position on reload ANIMATES its way there from the
     top, so you see the hero flash past every time you refresh partway down
     the page. Safari does this particularly readily. Smooth scrolling for
     anchor links is done in main.js instead, where it only ever runs on a
     click. */
  /* Anchor links land under a sticky header unless the browser is told to
     stop short of it. Without this the section heading you jumped to is
     hidden behind the header and it looks like the link went to the wrong
     place. The extra 28px stops it sitting flush against the header. */
  scroll-padding-top: calc(var(--header-height) + 28px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  letter-spacing: var(--ls-body);
  /* DESIGN.md: "Keep body type Inter with character variants cv01, cv05,
     cv09, cv11, ss03, ss07 enabled, the brand voice depends on them."
     Without these it is just Inter. */
  font-feature-settings: 'cv01', 'cv05', 'cv09', 'cv11', 'ss03', 'ss07';
  -webkit-font-smoothing: antialiased;
}

h1 { margin: 0; }
p  { margin: 0; }
/* ol as well as ul. An ordered list otherwise keeps its own numbers, and they
   sit next to the written step labels and read as "1. Step one". */
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

/* The `hidden` attribute hides an element by applying `display: none` from the
   browser's own stylesheet, which means ANY display value written in this file
   silently beats it, and the element stays on screen with no warning. This line
   makes `hidden` win everywhere and closes off that whole class of bug. */
[hidden] { display: none !important; }

/* Visible focus ring for anyone navigating by keyboard. Inputs and textareas
   are included or they fall back to the browser's own bright blue ring, which
   is nowhere in this palette and looks like a mistake on a dark page. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Hidden from the screen but still read aloud by a screen reader. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--paper);
  padding: 12px 20px; font-family: var(--font-display); font-size: 14px;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Error bar: shows only if this page's JavaScript fails
   -------------------------------------------------------------------------- */

.error-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 300;
  background: #8B1A1A; color: #fff;
  font-family: var(--font-body); font-size: 14px; line-height: 1.4;
  padding: 10px 16px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-weight: 600; font-size: 15px; letter-spacing: var(--ls-body);
  text-decoration: none; white-space: nowrap;
  padding: 16px 28px;
  border-radius: 4px;            /* a small radius reads more considered than a pill */
  border: 1px solid transparent;
  transition: background-color .18s ease, border-color .18s ease, transform .18s ease;
}

.btn--primary { background: var(--brass); color: var(--on-brass); }
.btn--primary:hover { background: var(--brass-dark); transform: translateY(-1px); }

.btn--ghost {
  background: transparent; color: var(--ink);
  /* --hairline is 1.6:1 here. A control edge needs 3:1. */
  border-color: var(--border-on-dark);
}
.btn--ghost:hover { border-color: var(--ink); transform: translateY(-1px); }

.btn--sm { padding: 11px 20px; font-size: 14px; }

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

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid var(--hairline);
  transition: box-shadow .2s ease;
}

/* Added by JavaScript once you scroll, so the header lifts off the page. */
.site-header.is-scrolled { box-shadow: 0 1px 20px rgba(0, 0, 0, .55); }

.site-header__inner {
  height: var(--header-height);
  padding: 0 var(--gutter);
  display: flex; align-items: center; gap: 40px;
}

.wordmark {
  display: flex; flex-direction: column; justify-content: center;
  text-decoration: none; margin-right: auto;
}
.wordmark__name {
  font-family: var(--font-display); font-weight: 700;
  font-size: 17px; letter-spacing: 0.02em; line-height: 1.1;
}
.wordmark__sub {
  font-family: var(--font-display); font-weight: 500;
  font-size: 9px; letter-spacing: 0.3em; line-height: 1.1;
  color: var(--slate);
}

.nav { display: flex; gap: 32px; }
.nav a {
  font-size: 15px; color: var(--slate); text-decoration: none;
  transition: color .18s ease;
}
.nav a:hover { color: var(--ink); }

.header-actions { display: flex; align-items: center; gap: 24px; }

.header-divider { width: 1px; height: 20px; background: var(--hairline); }

.header-phone {
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  text-decoration: underline;
  text-decoration-color: var(--brass);
  text-underline-offset: 5px;
  text-decoration-thickness: 1.5px;
}

.header-mobile { display: none; align-items: center; gap: 4px; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  background: none; border: 0; padding: 0;
  color: var(--ink); cursor: pointer;
}

/* Stays off by default at every screen size. It is only switched on inside the
   phone breakpoint below, and only when the `hidden` attribute is absent. */
.mobile-menu {
  display: none;
  border-top: 1px solid var(--hairline);
  padding: 8px var(--gutter) 24px;
  flex-direction: column; gap: 4px;
}
.mobile-menu a {
  text-decoration: none; font-size: 17px;
  padding: 12px 0; border-bottom: 1px solid var(--hairline);
}
/* padding is restated because `.mobile-menu a` sets `padding: 12px 0` and beats
   `.metal` on specificity, which flattened the 2px rim to nothing. The rim IS
   the padding on a metal button, so losing it loses the brass edge entirely. */
.mobile-menu .metal {
  margin-top: 16px;
  border-bottom: 0;
  padding: 2px;
}
.mobile-menu .metal__face { width: 100%; }

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

/* The hero is now two parts stacked: the two-column main block, and a
   full-width trust band beneath it that runs under both columns. */

.hero__main {
  display: grid;
  grid-template-columns: 56% 44%;
  align-items: center;
  /* Deliberately short of a full screen, so the trust band and the section
     after it peek above the fold and the page invites a scroll. */
  min-height: min(72vh, 700px);
}

.hero__text {
  padding: clamp(56px, 7vw, 96px) clamp(40px, 5vw, 80px)
           clamp(56px, 7vw, 96px) var(--gutter);
}

.eyebrow {
  /* flex-start, not center, so that if this ever does wrap the brass square
     stays level with the first line instead of floating between the two. */
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--slate);
}
.eyebrow__mark {
  width: 6px; height: 6px; background: var(--brass);
  flex: 0 0 auto; margin-top: 7px;   /* nudged down to sit on the text baseline */
}

.hero__title {
  margin-top: 28px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(38px, 5.2vw, 64px);
  line-height: 1.04;
  letter-spacing: var(--ls-display-lg);
  /* text-wrap: balance asks the browser to even out the lines itself rather
     than filling each one before starting the next. Without it this headline
     breaks on an iPad as "Fixed prices, agreed dates, certified" and then
     "work." alone on a line of its own, which looks like a mistake.

     Supported in Chrome and in Safari 17.4 up. Anything older ignores it and
     falls back to ordinary wrapping, which is untidy but never broken.

     max-width still caps the measure so the headline cannot run the full
     width of a wide screen. In ch rather than px so it scales with the type
     as the heading shrinks. */
  text-wrap: balance;
  max-width: 17ch;
}

.hero__lead {
  margin-top: 26px;
  font-size: 18px; line-height: 1.6;
  color: var(--slate);
  max-width: 44ch;
}

.hero__actions {
  margin-top: 40px;
  display: flex; flex-wrap: wrap; gap: 16px;
}

/* Full-width band closing the hero. Four equal columns, so the dividers are
   evenly spaced by construction rather than by luck. Equal columns also mean
   the band can never wrap into a ragged second line. */
.trust-row {
  border-top: 1px solid var(--hairline);
  /* Closed at the bottom too, now that a section follows it. Without this the
     band has no lower edge and its items read as belonging to whatever comes
     next rather than to the hero. */
  border-bottom: 1px solid var(--hairline);
  padding: 26px var(--gutter);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.trust-row li {
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--slate);
  padding-left: 28px;
  border-left: 1px solid var(--hairline);
}
.trust-row li:first-child { padding-left: 0; border-left: 0; }

/* --- The photo column: bleeds to the right edge, no margin, no radius --- */

.hero__media { align-self: stretch; }

.photo-placeholder {
  height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px;
  background: #221D16;
  border: 2px dashed #4A4237;
  color: var(--slate);
  font-family: var(--font-display); font-weight: 600;
  font-size: 13px; letter-spacing: 0.16em;
}
.photo-placeholder__note {
  font-weight: 500; font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; opacity: .8;
}

/* --------------------------------------------------------------------------
   Services
   -------------------------------------------------------------------------- */

.services {
  padding: clamp(72px, 9vw, 132px) var(--gutter) clamp(80px, 10vw, 148px);
}

.section-head { max-width: 640px; margin-bottom: clamp(44px, 5vw, 68px); }

.section-title {
  margin-top: 26px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.1;
  letter-spacing: var(--ls-display-md);
  /* The h1 in the hero has a wide safe band, so a measured max-width holds it
     steady. This heading does not. The good two-line break only survives
     between 560px and 570px, which one slow-loading font would tip over. So
     the browser evens the lines out itself instead. Anything too old to
     support text-wrap falls back to the max-width, which still gives a
     sensible three-line break rather than a broken one. */
  max-width: 22ch;
  text-wrap: balance;
}

.section-lead {
  margin-top: 20px;
  font-size: 17px; line-height: 1.6;
  color: var(--slate);
}

/* The 1px gap lets the section background show between cards, which draws
   every hairline for us. No card owns a border, so no line is ever doubled
   and the outer edge stays clean. */
.services-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}

.services-grid > li { display: flex; }

.service-card {
  flex: 1;
  display: flex; flex-direction: column;
  background: var(--paper);
  padding: clamp(28px, 2.6vw, 40px);
  text-decoration: none;
}

.service-card__icon {
  color: var(--ink);
  transition: color .2s ease;
}
.service-card__icon svg { display: block; width: 26px; height: 26px; }

.service-card__title {
  margin: 26px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 18px; line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.service-card__text {
  margin-top: 12px;
  font-size: 15px; line-height: 1.62;
  color: var(--slate);
}

/* margin-top:auto pushes the cue to the bottom of the card, so the cues line
   up across a row even when the descriptions run to different lengths. */
.service-card__cue {
  margin-top: auto;
  padding-top: 32px;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-weight: 600;
  font-size: 13px; letter-spacing: var(--ls-body);
  color: var(--ink);
}
.service-card__cue svg {
  width: 15px; height: 15px;
  transition: transform .2s ease;
}

/* Hover uses the accent and a small movement rather than a colour wash, so no
   new colour is introduced and the grid stays quiet. */
.service-card:hover .service-card__icon { color: var(--brass); }
.service-card:hover .service-card__title { text-decoration: underline;
  text-decoration-color: var(--brass); text-underline-offset: 4px;
  text-decoration-thickness: 1.5px; }
.service-card:hover .service-card__cue svg { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   How it works
   -------------------------------------------------------------------------- */

/* Top padding is deliberately small: the services section above already ends
   with a large bottom padding, and stacking two full paddings would leave a
   gap wide enough to read as a mistake. */
.how {
  padding: clamp(16px, 2vw, 28px) var(--gutter) clamp(80px, 10vw, 148px);
}

.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 4vw, 68px);
}

.step {
  padding-top: 22px;
  border-top: 1px solid var(--ink);
}

.step__num {
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--slate);
}

.step__title {
  margin: 16px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 21px; line-height: 1.25; letter-spacing: var(--ls-headline);
  color: var(--ink);
}

.step__text {
  margin-top: 12px;
  font-size: 16px; line-height: 1.65;
  color: var(--slate);
  max-width: 38ch;
}

/* --------------------------------------------------------------------------
   Previous work
   -------------------------------------------------------------------------- */

.work {
  padding: clamp(16px, 2vw, 28px) var(--gutter) clamp(80px, 10vw, 148px);
}

.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(24px, 3vw, 40px);
  row-gap: clamp(48px, 5vw, 76px);
}

/* aspect-ratio reserves the full height of the picture before anything loads,
   so the text below never jumps down when a real photograph arrives. Every
   image must be 3:2 or it will be squashed. */
.work__media {
  aspect-ratio: 3 / 2;
  /* overflow:hidden is what makes the radius actually clip the photograph.
     Without it the image keeps its own square corners and pokes out. */
  overflow: hidden;
  border-radius: 8px;

  /* Two parts, and both are needed on a dark background.

     The drop shadows sit UNDER the photograph and lift it off the page. On a
     near-black surface a black shadow does very little on its own, which is
     why the pictures looked flat.

     So the second part is the inset hairline. It draws a faint light lip
     right on the edge of the photograph, which is what actually separates it
     from the background. Inset rather than a border, because a border would
     push the image inwards and break the 3:2 ratio. */
  box-shadow:
    0 22px 44px rgba(0, 0, 0, .55),
    0 8px 16px  rgba(0, 0, 0, .42),
    inset 0 0 0 1px rgba(242, 239, 233, .10);
}

/* The same placeholder as the hero, so both read as one unfinished thing
   rather than two different mistakes. */
.work__media .photo-placeholder { height: 100%; }

.work__place {
  margin-top: 22px;
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--slate);
}

.work__title {
  margin: 10px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 20px; line-height: 1.3; letter-spacing: var(--ls-headline);
  color: var(--ink);
}

.work__text {
  margin-top: 10px;
  font-size: 16px; line-height: 1.62;
  color: var(--slate);
  max-width: 46ch;
}

/* --------------------------------------------------------------------------
   Guarantee band
   -------------------------------------------------------------------------- */

/* No max-width and no side margins. The band runs the full width of the
   window so it reads as a break in the page rather than another section. */
.guarantee {
  background: var(--paper-3);
  padding: clamp(64px, 8vw, 104px) var(--gutter);
}

/* Brass is legible as text here and nowhere else on the site. */
.guarantee .eyebrow { color: var(--brass); }

.guarantee .section-title { color: var(--ink); max-width: 21ch; }

/* section-head carries a bottom margin meant for the light sections. The
   band sets its own spacing instead. */
.guarantee .section-head { margin-bottom: 0; max-width: none; }

.guarantee-list {
  margin-top: clamp(48px, 6vw, 76px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.guarantee-list li {
  padding-left: clamp(20px, 2.2vw, 32px);
  border-left: 1px solid var(--hairline-dark);
}
.guarantee-list li:first-child { padding-left: 0; border-left: 0; }

.guarantee__claim {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 17px; line-height: 1.3; letter-spacing: var(--ls-body);
  color: var(--ink);
}

.guarantee__note {
  margin-top: 10px;
  font-size: 15px; line-height: 1.55;
  color: var(--paper-dim);
}

/* --------------------------------------------------------------------------
   Service area
   -------------------------------------------------------------------------- */

.area {
  padding: clamp(72px, 9vw, 128px) var(--gutter) clamp(80px, 10vw, 148px);
}

.area__inner {
  display: grid;
  grid-template-columns: 38% 1fr;
  gap: clamp(32px, 5vw, 88px);
  align-items: start;
}

.area .section-title { margin-top: 26px; max-width: 15ch; }

/* Larger than normal body copy. This section is one block of prose with no
   pictures and nothing to click, so the type has to carry it on its own. */
.area__text {
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.62;
  /* Full --ink, the same white as the heading beside it, rather than the
     secondary grey used for body copy elsewhere. This section is one block
     of prose carrying the whole local search job on its own, so it reads as
     primary content rather than as supporting text.
     The town names keep their own colour: .place sets it on the spans, which
     beats the colour inherited from this paragraph. */
  color: var(--ink);
  max-width: 54ch;
}
.area__text + .area__text { margin-top: 26px; }

/* Emphasis only, not semantic. A screen reader announcing twelve separate
   pieces of "strong importance" in two paragraphs would be worse than no
   emphasis at all, so this is a plain span carrying weight and colour. */
/* Town names, picked out so the eye can find its own area at a glance.
   #B8900A. Brighter than the 4.86:1 of #9F7F03 without going back to the
   glare of #D4AA04. Measured value is printed below by the audit.
   It is a brighter, more yellow gold than the brass used for button fills,
   and that is on purpose: text needs more luminance to stay readable than a
   solid fill does, so the two are doing different jobs. */
.place { color: #B8900A; font-weight: 500; }

/* --------------------------------------------------------------------------
   Reviews
   -------------------------------------------------------------------------- */

.reviews {
  padding: clamp(16px, 2vw, 28px) var(--gutter) clamp(80px, 10vw, 148px);
}

.reviews-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 4vw, 64px);
}

.reviews-grid > li { display: flex; }

/* No boxes and no rules. The services grid is bordered and the how it works
   steps sit under rules, so quotes floating on the background is the third
   distinct treatment rather than a repeat of either. */
.review {
  margin: 0;
  flex: 1;
  display: flex; flex-direction: column;
}

.review__text { margin: 0; }

.review__text p {
  font-size: 17px; line-height: 1.7;
  color: var(--ink);
}

/* margin-top:auto pins the attribution to the bottom of the column, so the
   three names sit on one line even though the quotes are different lengths
   on purpose. */
.review__by {
  margin-top: auto;
  padding-top: 28px;
  display: flex; flex-direction: column; gap: 5px;
}

.review__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 14px; letter-spacing: var(--ls-body);
  color: var(--ink);
}

.review__job {
  font-family: var(--font-display); font-weight: 500;
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
}

/* --------------------------------------------------------------------------
   Quote form
   -------------------------------------------------------------------------- */

.quote {
  padding: clamp(16px, 2vw, 28px) var(--gutter) clamp(88px, 10vw, 148px);
}

.quote__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

.quote .section-title { margin-top: 26px; max-width: 15ch; }

.quote__lead {
  margin-top: 22px;
  font-size: 17px; line-height: 1.62;
  color: var(--slate);
  max-width: 40ch;
}

.quote__alt {
  margin-top: 28px;
  font-size: 16px;
  color: var(--slate);
}

.quote__tel {
  font-family: var(--font-display); font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--brass);
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
  white-space: nowrap;
}

/* Holds the form and the success message. The min-height stops the page
   collapsing when the 508px form is replaced by the 125px thank you, which
   would otherwise yank everything below it up the screen at the exact moment
   the person is reading the confirmation. 508px is the measured height of
   the form, and it is the same at every width from 940px up because the
   fields are full width and the labels never wrap. */
.quote__panel {
  /* 508px is the measured height of the form. The glass adds padding inside
     the same border box, so the reservation has to include it or the page
     jumps by exactly that padding when the form is replaced by the thank you.
     The clamp is repeated rather than guessed so the two can never drift.
     537 rather than the measured 533 because the form's real height is
     fractional. Over-reserving by a few pixels is invisible. Under-reserving
     by one is a visible jump.

     This number has to be re-measured every time a field is added or removed.
     The character counter under the message box added 25px to the form and
     the page started jumping again until this was updated. */
  min-height: calc(537px + 2 * clamp(22px, 2.4vw, 34px));
  /* Centring matters only once the form is gone. The form fills the 508px
     exactly, so this does nothing to it, but it puts the short thank you in
     the middle of the reserved space rather than leaving it stranded at the
     top of a gap that looks like a mistake. */
  display: flex; flex-direction: column; justify-content: center;
}

.gotcha { position: absolute; left: -9999px; width: 1px; height: 1px; }

.field { margin-bottom: 18px; }

.field label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--font-display); font-weight: 600;
  font-size: 13px; letter-spacing: var(--ls-body);
  color: var(--ink);
}


.field input,
.field textarea {
  width: 100%;
  padding: 13px 15px;
  font-family: var(--font-body);
  font-size: 16px;              /* 16px stops iOS zooming in when tapped */
  line-height: 1.5;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--border-on-dark);   /* 3.5:1 on the dark surface */
  border-radius: 4px;
  transition: border-color .18s ease;
}
.field input:focus,
.field textarea:focus { border-color: var(--ink); }

.field textarea { resize: vertical; min-height: 88px; }

.btn--block { width: 100%; margin-top: 8px; }

/* Only visible when a send has failed. */
.form-status {
  margin-bottom: 18px;
  padding: 15px 17px;
  border: 1px solid #E4736B;   /* a dark red is invisible on a dark surface */
  border-radius: 4px;
  font-size: 15px; line-height: 1.55;
  color: var(--ink);
}
.form-status a {
  font-family: var(--font-display); font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}

.quote__done { padding-top: 4px; }

.quote__done-title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 22px; line-height: 1.3; letter-spacing: var(--ls-headline);
  color: var(--ink);
}

.quote__done-text {
  margin-top: 12px;
  font-size: 16px; line-height: 1.65;
  color: var(--slate);
  max-width: 40ch;
}

/* --------------------------------------------------------------------------
   Phone and tablet
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .quote__inner { grid-template-columns: minmax(0, 1fr); gap: 36px; }
  .quote .section-title { max-width: none; }
  .quote__lead { max-width: none; }
  /* The reservation is only needed where the two columns sit side by side.
     Stacked, the form is the last thing on the page and nothing below it
     can be pushed around. */
  .quote__panel { min-height: 0; }
}

/* Straight from three columns to one. Two would leave the third quote sitting
   on its own row looking like an afterthought. */
@media (max-width: 940px) {
  .reviews-grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .review__by { margin-top: 0; padding-top: 20px; }
}

@media (max-width: 880px) {
  .area__inner { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .area .section-title { max-width: none; }
  .area__text { max-width: none; }
}

/* Two by two, then stacked. The divider moves from the left edge to the top
   edge when stacked, the same way the hero trust band handles it. */
@media (max-width: 1080px) {
  .guarantee-list { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 32px; }
  .guarantee-list li:nth-child(odd) { padding-left: 0; border-left: 0; }
}

@media (max-width: 620px) {
  .guarantee-list { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .guarantee-list li {
    padding: 22px 0 0;
    border-left: 0;
    border-top: 1px solid var(--hairline-dark);
  }
  .guarantee-list li:first-child { padding-top: 0; border-top: 0; }
}

/* One photograph per row on a phone. Two would make each one too small to be
   worth including. */
@media (max-width: 720px) {
  .work-grid { grid-template-columns: minmax(0, 1fr); row-gap: 44px; }
  .work__text { max-width: none; }
}

/* The three steps stay side by side down to tablet, then stack. Two across
   would orphan the third step on a row of its own. */
@media (max-width: 820px) {
  .steps { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .step__text { max-width: none; }
}

/* Two across on tablet. */
@media (max-width: 1080px) {
  .services-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* One across on phone. */
@media (max-width: 620px) {
  .services-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
  .nav, .header-actions { display: none; }
  .header-mobile { display: flex; }
  .mobile-menu:not([hidden]) { display: flex; }

  .hero__main {
    grid-template-columns: 1fr;
    min-height: 0;
  }

  /* Photo first, words underneath. Kept to roughly a third of the screen so
     the "Get a free quote" button still lands above the fold on a phone.
     At 40vh it fell 34px short, which hides the only thing that matters. */
  /* Height comes from an aspect ratio, not from viewport height. A vh slot is
     short and wide while this photograph is tall and narrow, so cover was
     throwing away up to 69% of the height and the top of his head went first.
     An aspect ratio keeps the slot in proportion to the picture. */
  .hero__media { order: -1; height: auto; aspect-ratio: 3 / 2; min-height: 0; }

  .hero__text { padding: 36px var(--gutter) 56px; }

  .hero__title  { max-width: none; }
  .hero__lead   { max-width: none; font-size: 17px; }

  .hero__actions { flex-direction: column; align-items: stretch; }
  .hero__actions .btn { width: 100%; }

  /* Stacked, with the divider moved from the left edge to the top edge so the
     separation stays consistent rather than disappearing. */
  .trust-row {
    grid-template-columns: 1fr;
    padding: 22px var(--gutter) 32px;
  }
  .trust-row li {
    padding: 14px 0 0;
    border-left: 0;
    border-top: 1px solid var(--hairline);
  }
  .trust-row li:first-child { padding-top: 0; border-top: 0; }
}

/* Short screens. An iPhone SE is only 667px tall. Squeeze the photo band
   further so the button still lands above the fold. This targets height, not
   width, so it can never affect a normal-sized phone. */
/* Narrow screens can afford a taller picture, and 4:5 is close to the
   photograph's own 0.88 so barely anything is cropped. This has to sit AFTER
   the 900px block: it was originally written above it, where the 3:2 rule
   overrode it and it silently did nothing. Equal specificity means the last
   one in the file wins. */
@media (max-width: 620px) {
  .hero__media { aspect-ratio: 4 / 5; }
}

@media (max-width: 900px) and (max-height: 700px) and (orientation: landscape) {
  /* Short landscape windows, for example a phone turned sideways. Wider than
     3:2 so the hero does not fill the whole screen, but still tall enough to
     keep his head. */
  /* max-height as well as the ratio. On a phone held sideways, 21:9 across
     844px comes out 362px tall on a 390px screen, so the photograph fills 93%
     of it and you cannot see there is a page underneath. Capping at 75vh
     leaves the headline showing, and the head still survives the crop. */
  /* width:100% matters here. max-height caps the box, and with only an
     aspect-ratio to go on the browser then works the width back out from
     that capped height, leaving a strip of empty page down the right. */
  .hero__media {
    width: 100%;
    height: auto; aspect-ratio: 21 / 9; min-height: 0; max-height: 75vh;
  }
  .hero__text  { padding-top: 28px; }

  /* This box is served the wide crop, which is a different picture with the
     head in a different place: top of the hat at 3.4%, chin at 39%. Anchored
     at 4% so the whole head clears both the top edge and the action bar
     across the bottom. */
  .hero__img { object-position: 50% 4%; }
}

/* Respect the system setting for people who find motion uncomfortable. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ==========================================================================
   SITE FOOTER
   Self-contained. Nothing outside this block styles the footer, and nothing
   in this block styles anything else, so the whole thing lifts out with the
   markup between the FOOTER STARTS and FOOTER ENDS comments in the HTML.
   Depends only on the tokens in :root.
   ========================================================================== */

.site-footer {
  background: var(--paper-2);
  color: var(--ink);
  padding: clamp(56px, 7vw, 88px) var(--gutter) clamp(28px, 3vw, 40px);
}

.site-footer__top {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1.4fr 1.1fr;
  gap: clamp(32px, 4vw, 64px);
}

/* The header wordmark is an <a>. In the footer it is a <p>, because linking
   to the page you are already on is a dead end. Same look either way. */
.wordmark--footer { display: flex; flex-direction: column; }
.site-footer .wordmark__name { color: var(--ink); }
.site-footer .wordmark__sub  { color: var(--paper-dim); }

.footer-niceic {
  margin-top: 22px;
  font-size: 14px; line-height: 1.6;
  color: var(--paper-dim);
  max-width: 38ch;
}

.footer-col__head {
  margin: 0 0 18px;
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--paper-dim);
}

.footer-links { display: flex; flex-direction: column; gap: 11px; }
.footer-links a,
.footer-address a {
  font-size: 15px;
  color: var(--ink);
  text-decoration: none;
  transition: color .18s ease;
}
.footer-links a:hover,
.footer-address a:hover { color: var(--brass); }

/* <address> is italic by default in every browser. */
.footer-address {
  font-style: normal;
  display: flex; flex-direction: column; gap: 11px;
  font-size: 15px; line-height: 1.55;
}

.footer-strong {
  font-family: var(--font-display); font-weight: 600;
  font-size: 17px !important;
}

.footer-postal { color: var(--paper-dim); line-height: 1.7; }

.footer-hours { display: flex; flex-direction: column; gap: 11px; }
.footer-hours li {
  display: flex; justify-content: space-between; gap: 16px;
  font-size: 15px;
  color: var(--paper-dim);
}
.footer-hours li span:last-child { color: var(--ink); white-space: nowrap; }

.site-footer__base {
  margin-top: clamp(48px, 6vw, 76px);
  padding-top: 26px;
  border-top: 1px solid var(--hairline-dark);
  display: flex; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 32px;
  font-size: 13px;
  color: var(--paper-dim);
}
.site-footer__base p { margin: 0; }

/* The "this is a demonstration" note.
   flex-basis: 100% pushes it onto its own line under the copyright row
   rather than sitting alongside it. Two classes so it beats the margin: 0
   set on every other paragraph in this block. */
/* Sits below the copyright row, not inside it. An ordinary block, so it
   starts at the left edge and the rule above it runs the full width. */
.footer-demo {
  margin: 22px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--hairline-dark);
  max-width: 62ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--paper-dim);
}

@media (max-width: 1080px) {
  .site-footer__top { grid-template-columns: 1fr 1fr; row-gap: 44px; }
  .footer-niceic { max-width: none; }
}

@media (max-width: 620px) {
  .site-footer__top { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .site-footer__base { flex-direction: column; }
}

/* ==========================================================================
   MOBILE ACTION BAR
   Part of the footer copy block. Off at every width except phones.
   ========================================================================== */

.mobile-bar { display: none; }

@media (max-width: 900px) {

  .mobile-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
    display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
    background: var(--paper-2);
    border-top: 1px solid var(--hairline-dark);
    /* env() returns 0 unless the page opts into viewport-fit=cover, which it
       does not, so this is a no-op today and correct if that ever changes.
       Written with an explicit 0px fallback because older Safari returns
       nothing rather than zero for an unknown inset. */
    height: calc(var(--mobile-bar-h) + env(safe-area-inset-bottom, 0px));
    padding: 12px var(--gutter);
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }

  /* Metal, like every other quote button on the site. These two were the only
     ones left as plain buttons. Because the header's metal button is hidden
     below 900px, they were the ONLY quote buttons a phone or iPad user could
     see, so the brass rim looked desktop-only. It was not a glitch, they had
     simply never been converted.

     No height:100% here. A grid item already stretches to fill its row, and
     percentage heights on flex children are the kind of thing Safari has
     historically resolved differently from Chrome. Letting the grid do it
     avoids the question entirely. */
  .mobile-bar .metal { width: 100%; }
  .mobile-bar .metal__face {
    width: 100%;
    padding: 0 10px;
    gap: 9px;
    font-size: 15px;
  }

  /* The bar stays out of the way until you have scrolled past the hero.

     Without this it sat on top of the hero's own "Get a free quote" button
     on anything between about 650px and 900px wide, an iPad held upright
     included, hiding up to 111px of a button only 52px tall. Two competing
     calls to action in the same place, one covering the other.

     It is also simply redundant up there: the hero already offers the quote
     button and the phone number, so the bar has nothing to add until they
     have scrolled off.

     Only applies when JavaScript is running. Without it there is no .js
     class, none of this matches, and the bar behaves as it always did. */
  .js .mobile-bar {
    transform: translateY(110%);
    transition: transform .32s cubic-bezier(.22, .61, .36, 1);
  }
  .js .mobile-bar.is-visible { transform: translateY(0); }

  .site-footer {
    padding-bottom: calc(clamp(28px, 3vw, 40px) + var(--mobile-bar-h)
                         + env(safe-area-inset-bottom, 0px));
  }
}

/* ==========================================================================
   PHOTOGRAPHS
   The containers already reserve the right height (the hero column stretches,
   the work cards have aspect-ratio 3/2), so object-fit fills that box without
   distorting the picture. Any image that is not 3:2 gets cropped rather than
   squashed.
   ========================================================================== */

.hero__img,
.work__media img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* The hero photograph is nearly square (1400 x 1584) and sits in a tall
   narrow column on desktop, so the sides get trimmed. The man is centred in
   the file, so this is centred too.

   Vertically it is anchored near the top, not centred. Centre crops outwards
   from the middle, so the first thing lost is the top of his head. Measured
   on the file itself: the top of his hat is at 4%, his eyes at 23%, his chin
   at 42%. Anchoring at 8% keeps the whole head in frame at every size tested,
   including a 320px iPhone SE and a phone held sideways. */
.hero__img { object-position: 50% 8%; }

/* This one is a portrait shot in a landscape box, so it loses a lot of top
   and bottom. Pulled up to keep the hands and the breaker rail in frame
   rather than centring on empty bench. */
.work-item:first-child .work__media img { object-position: 50% 42%; }

/* ==========================================================================
   METAL BUTTONS
   Rebuilt from a WebGL component in plain CSS. The metal is a 2px rim, not a
   fill: the outer element carries a conic-gradient that slowly rotates, and
   the inner face sits on top covering everything except that rim.
   ========================================================================== */

.metal {
  position: relative;
  display: inline-flex;
  padding: 2px;                 /* this padding IS the rim thickness */
  border-radius: 6px;
  overflow: hidden;             /* clips the spinning square to the shape */
  isolation: isolate;
  text-decoration: none;
  transition: box-shadow .22s cubic-bezier(.4,0,.2,1), transform .12s ease;

  /* Four stacked shadows rather than one. A single shadow looks like a
     drawing of a shadow; several at increasing blur look like an object. */
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .55),
    0 22px 12px rgba(0, 0, 0, .18),
    0 10px 9px  rgba(0, 0, 0, .28),
    0 3px 4px   rgba(0, 0, 0, .36);
}

/* The metal itself. A square far larger than the button, spun slowly behind
   it. Uneven gradient stops read as metal; even ones read as a rainbow. */
.metal::before {
  content: '';
  position: absolute; z-index: 0;
  left: 50%; top: 50%;
  width: 300%; aspect-ratio: 1;
  translate: -50% -50%;
  background: conic-gradient(from 0turn,
    #6B4A18   0deg,
    #E8B563  38deg,
    #8A6220  92deg,
    #F2D49B 138deg,
    #6B4A18 188deg,
    #D6A253 246deg,
    #7A5620 302deg,
    #E8B563 338deg,
    #6B4A18 360deg);
  animation: metal-spin 9s linear infinite;
}

@keyframes metal-spin { to { rotate: 360deg; } }

.metal__face {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  /* Grows to fill the button whenever the button is stretched, which is what
     happens on a phone. Without it the face stays content-width, the metal
     square behind is left uncovered, and the 2px rim becomes a gold fan
     across half the button. Never shrinks below its own text. */
  flex: 1 0 auto;
  padding: 14px 26px;           /* 2px rim + 14px = the 16px used elsewhere */
  border-radius: 4px;
  font-family: var(--font-display);
  font-weight: 600; font-size: 15px; letter-spacing: var(--ls-body);
  white-space: nowrap;
  transition: box-shadow .15s cubic-bezier(.4,0,.2,1);
}

.metal--dark  .metal__face { background: var(--brass);   color: var(--on-brass); }
.metal--light .metal__face { background: var(--paper-2); color: var(--ink);      }

/* Tightens rather than grows, so the button settles toward the page instead
   of leaping off it. Copied from the original, and the better choice. */
.metal:hover {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .7),
    0 8px 6px rgba(0, 0, 0, .22),
    0 4px 4px rgba(0, 0, 0, .3),
    0 1px 2px rgba(0, 0, 0, .4);
}

.metal:active { transform: translateY(1px) scale(.985); }
.metal:active .metal__face {
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .35), inset 0 1px 2px rgba(0, 0, 0, .25);
}

/* Ripple, drawn from wherever the pointer actually landed. */
.metal__ripple {
  position: absolute; z-index: 2;
  width: 20px; height: 20px; border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle,
    rgba(184, 128, 43, .55) 0%, rgba(184, 128, 43, 0) 70%);
  animation: metal-ripple .6s ease-out forwards;
}
@keyframes metal-ripple {
  from { transform: translate(-50%, -50%) scale(0);  opacity: .7; }
  to   { transform: translate(-50%, -50%) scale(4);  opacity: 0;  }
}

@media (prefers-reduced-motion: reduce) {
  .metal::before { animation: none; }
  .metal__ripple { display: none; }
}

/* ==========================================================================
   HERO BACKGROUND
   The one dark moment at the top of the page. Technique adapted from a dark
   shadcn component: a radial base, one skewed and masked streak, and a grain
   overlay. Palette deliberately not theirs. Their version was cyan on pure
   black with a dot grid, which is the most common look on the internet right
   now. This is brass on warm charcoal with film grain.

   The page reads dark, light, light, light, DARK, light, light, light, DARK
   from top to bottom. Three dark moments, evenly spaced, and body copy stays
   dark-on-light where it is easiest to read.
   ========================================================================== */

:root {
  /* Grain as an inline SVG turbulence filter. No image file, no request. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.hero {
  position: relative;
  isolation: isolate;
  background: var(--paper);
  /* Required, not cosmetic. The streak below is skewed 45deg and inset -20%,
     so without this it pokes out past both sides of the hero and gives the
     whole page a horizontal scrollbar. Same for the grain, which is inset
     -100px. Nothing inside the hero is meant to escape it. */
  overflow: hidden;
}
.hero > * { position: relative; z-index: 2; }

.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(120% 115% at 0% 0%, #33291B 0%, #16130E 72%);
}

/* One streak, skewed and masked so it fades in and out across the width.
   The original stacked five at 20% each, which reads as stripes. One at 32%
   reads as light falling across a surface.
   -webkit-mask-image first: older Safari needs the prefix and drops the
   whole rule without it, which would leave a hard-edged brass wedge. */
.hero::after {
  content: ''; position: absolute; inset: -20% 0; z-index: 1;
  transform: skewX(45deg);
  opacity: .32;
  background: linear-gradient(rgba(184,128,43,.85) 0%, rgba(184,128,43,0) 62%);
  -webkit-mask-image: linear-gradient(90deg,
    rgba(0,0,0,0) 0%, rgb(0,0,0) 17%, rgba(0,0,0,.2) 29%, rgb(0,0,0) 44%,
    rgba(0,0,0,0) 52%, rgba(0,0,0,.35) 68%, rgb(0,0,0) 79%, rgba(0,0,0,0) 96%);
  mask-image: linear-gradient(90deg,
    rgba(0,0,0,0) 0%, rgb(0,0,0) 17%, rgba(0,0,0,.2) 29%, rgb(0,0,0) 44%,
    rgba(0,0,0,0) 52%, rgba(0,0,0,.35) 68%, rgb(0,0,0) 79%, rgba(0,0,0,0) 96%);
}

.hero__text { position: relative; }
.hero__text::before {
  content: ''; position: absolute; inset: -100px; z-index: -1;
  background: var(--grain); background-size: 180px;
  opacity: .05; pointer-events: none;
}

.hero__title { color: var(--ink); }
.hero__lead  { color: var(--paper-dim); }
.hero .eyebrow { color: var(--brass); }

.trust-row { border-color: var(--hairline-dark); }
.trust-row li {
  color: var(--paper-dim);
  border-left-color: var(--hairline-dark);
}

@media (max-width: 900px) {
  .trust-row li { border-top-color: var(--hairline-dark); }
}

/* ==========================================================================
   PAGE GRAIN
   The texture runs over the whole site, not only the hero. Fixed rather than
   scrolling, so it reads as the surface the page is printed on instead of a
   pattern travelling with the content. Sits above the section backgrounds
   and below the header, the mobile bar and the error bar.
   ========================================================================== */

body::after {
  content: '';
  position: fixed; inset: 0; z-index: 1;
  background: var(--grain); background-size: 190px;
  opacity: .035;
  pointer-events: none;
}

/* The guarantee band is a shade lighter than the page so it still reads as a
   break now that everything around it is dark too. It also gets the same
   brass wash as the hero, at a fraction of the strength. */
.guarantee { position: relative; isolation: isolate; overflow: hidden; }
.guarantee > * { position: relative; z-index: 2; }
.guarantee::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(90% 140% at 100% 0%, rgba(184,128,43,.16) 0%, rgba(184,128,43,0) 62%);
}

/* ==========================================================================
   GLASS PANEL
   Rebuilt from a React component in plain CSS. Wraps the quote form only.
   The heading beside it is deliberately left bare, so the glass reads as a
   thing sitting on the page rather than as the section's background.
   ========================================================================== */

/* Blur needs something behind it or it does nothing. This puts a soft brass
   glow under the right hand side of the section, which is what the panel
   then refracts. Without it the glass would just look like a paler box. */
.quote { position: relative; isolation: isolate; overflow: hidden; }
.quote > * { position: relative; z-index: 2; }
.quote::before {
  content: ''; position: absolute; z-index: 0;
  right: -8%; top: -10%; width: 70%; height: 90%;
  background:
    radial-gradient(50% 50% at 62% 38%, rgba(184,128,43,.30) 0%, rgba(184,128,43,0) 70%),
    radial-gradient(45% 55% at 88% 78%, rgba(184,128,43,.16) 0%, rgba(184,128,43,0) 72%);
  filter: blur(10px);
  pointer-events: none;
}

.glass {
  position: relative;
  border-radius: 16px;
  padding: clamp(22px, 2.4vw, 34px);

  /* Barely there. Any more and it stops being glass and becomes a grey card. */
  background: rgba(242, 239, 233, .045);

  /* saturate as well as blur. Blur alone goes muddy; pushing saturation back
     up keeps the colour behind it alive, which is what real glass does.
     -webkit- first, Safari still wants the prefix. */
  -webkit-backdrop-filter: blur(20px) saturate(1.35);
  backdrop-filter: blur(20px) saturate(1.35);

  border: 1px solid rgba(242, 239, 233, .12);

  box-shadow:
    /* floats it off the page */
    0 24px 48px rgba(0, 0, 0, .45),
    0 4px 10px  rgba(0, 0, 0, .3),
    /* the bevel. Two insets with opposite offsets, both light, so one pair of
       edges catches the light and the other pair falls away. This is the part
       that makes it read as a pane of glass rather than a flat panel. */
    inset  2px  2px 2px rgba(242, 239, 233, .16),
    inset -2px -2px 2px rgba(242, 239, 233, .09);
}

/* A single bright hairline along the top edge, the way light catches the lip
   of a real sheet of glass. */
.glass::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(242, 239, 233, .22) 0%, rgba(242, 239, 233, 0) 42%);
  -webkit-mask-image: linear-gradient(180deg, #000 0 1.5px, transparent 1.5px);
  mask-image: linear-gradient(180deg, #000 0 1.5px, transparent 1.5px);
}

/* Fields need to sit ON the glass, not punch holes in it. */
.glass .field input,
.glass .field textarea {
  background: rgba(22, 19, 14, .35);
  /* .28 measured 2.36:1 against the glass, under the 3:1 a control edge needs.
     .42 measures 3.68:1, which clears it with room rather than scraping it. */
  border-color: rgba(242, 239, 233, .42);
}
.glass .field input:focus,
.glass .field textarea:focus { border-color: var(--brass); }

/* Nothing to blur on a phone, where the panel is full width and the glow sits
   behind the text instead. Solid keeps it readable and saves the repaint. */
@media (max-width: 900px) {
  .glass {
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background: rgba(242, 239, 233, .05);
  }
}

/* --- Metal button variants ------------------------------------------------
   Added when the header and the form submit joined the hero pair. */

/* A <button> brings its own border, background and font. Strip them or the
   metal rim ends up sitting inside a default grey chrome button. */
button.metal {
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}

.metal--sm .metal__face { padding: 9px 18px; font-size: 14px; }
.metal--block { width: 100%; }

/* While the form is sending. Still clearly the same button, just inert. */
.metal:disabled { cursor: default; opacity: .72; }
.metal:disabled .metal__face { opacity: .9; }

/* --- Character counter ---------------------------------------------------- */

.field__meta {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 16px;
  margin-top: 7px;
  font-size: 12px;
  color: var(--slate);
}

.field__count { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Turns amber as the box fills, red at the limit, so the state is visible
   before you hit the wall rather than only after. */
.field__meta.is-near .field__count { color: var(--brass); }
.field__meta.is-full .field__count { color: #E4736B; }

.field__note { color: #E4736B; }

/* ==========================================================================
   INNER PAGES
   Shared by services, work, about and contact. Everything here uses the same
   tokens as the homepage, so colours and type match by construction rather
   than by being typed out again.
   ========================================================================== */

/* --- Page head -------------------------------------------------------------
   Two columns, not one. The first version put everything in a narrow left
   column and left the entire right half of a 1440px screen empty, which reads
   as an unfinished page rather than as generous space. The right side now
   carries something useful on every page: an index, the key figures, or the
   contact details. -------------------------------------------------------- */

.page-head {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(52px, 7vw, 104px) var(--gutter) clamp(48px, 6vw, 84px);
}
.page-head > * { position: relative; z-index: 2; }

.page-head::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(115% 130% at 0% 0%, #2A2218 0%, var(--paper) 68%);
}
.page-head::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: var(--grain); background-size: 180px;
  opacity: .05; pointer-events: none;
}

.page-head__inner {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(36px, 6vw, 100px);
  align-items: end;
}

.page-head__title {
  margin: 26px 0 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(34px, 4.6vw, 58px);
  line-height: 1.04;
  letter-spacing: var(--ls-display-lg);
  color: var(--ink);
}

.page-head__lead {
  margin-top: 22px;
  font-size: 18px; line-height: 1.6;
  color: var(--slate);
  max-width: 46ch;
}

/* --- Right-hand slot, variant one: a jump index ---------------------------- */

.head-index { border-top: 1px solid var(--hairline); }
.head-index a {
  display: flex; align-items: baseline; gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  transition: padding-left .18s ease, border-color .18s ease;
}
.head-index a:hover { padding-left: 10px; border-color: var(--brass); }
.head-index__num {
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: 0.14em;
  color: var(--brass);
  min-width: 22px;
}
.head-index__label {
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; letter-spacing: var(--ls-body);
  color: var(--ink);
}
.head-index__meta {
  margin-left: auto;
  font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--slate);
  white-space: nowrap;
}

/* --- Right-hand slot, variant two: figures --------------------------------- */

.head-figures {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.head-figures > div { background: var(--paper); padding: 22px 24px; }
.head-figures dt {
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
}
.head-figures dd {
  margin: 10px 0 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(22px, 2.2vw, 30px);
  line-height: 1.1;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}
.head-figures dd a { color: inherit; text-decoration: none; }
.head-figures dd.is-small {
  font-size: 15px; font-weight: 500; letter-spacing: var(--ls-body);
  line-height: 1.5; color: var(--ink);
}

/* --- Service detail rows --------------------------------------------------- */

.service-list { padding: 0 var(--gutter) clamp(72px, 9vw, 128px); }

/* A hairline above each one rather than boxes. The homepage already uses a
   bordered grid for services, so repeating it here would make the two pages
   look like the same thing twice. */
.service-detail {
  display: grid;
  grid-template-columns: 38% 1fr;
  gap: clamp(24px, 4vw, 64px);
  padding: clamp(40px, 5vw, 64px) 0;
  border-top: 1px solid var(--hairline);
}

.service-detail__num {
  font-family: var(--font-display); font-weight: 600;
  font-size: 12px; letter-spacing: 0.14em;
  color: var(--brass);
}

.service-detail__title {
  margin: 14px 0 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(24px, 2.6vw, 34px);
  line-height: 1.12;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}

.service-detail__body p {
  font-size: 17px; line-height: 1.68;
  color: var(--slate);
  max-width: 60ch;
}
.service-detail__body p + p { margin-top: 18px; }

/* --- "What's involved" list ------------------------------------------------ */

.involved {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  display: grid;
  gap: 12px;
}

.involved li {
  position: relative;
  padding-left: 22px;
  font-size: 15px; line-height: 1.55;
  color: var(--ink);
}

/* The same 6px brass square used by every eyebrow on the site. */
.involved li::before {
  content: '';
  position: absolute; left: 0; top: 9px;
  width: 6px; height: 6px;
  background: var(--brass);
}

/* --- Closing call to action ------------------------------------------------ */

.page-cta {
  border-top: 1px solid var(--hairline);
  background: var(--paper-3);
  padding: clamp(56px, 7vw, 96px) var(--gutter);
}

.page-cta__inner { max-width: 640px; }

.page-cta__title {
  margin: 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1.12;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}

.page-cta__text {
  margin-top: 18px;
  font-size: 17px; line-height: 1.62;
  color: var(--slate);
}

.page-cta__actions {
  margin-top: 32px;
  display: flex; flex-wrap: wrap; gap: 16px;
}

/* --- Phone and tablet ------------------------------------------------------ */

@media (max-width: 900px) {
  .page-head__title { max-width: none; }
  .service-detail {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
  }
  .service-detail__body p { max-width: none; }
}

@media (max-width: 620px) {
  .page-cta__actions { flex-direction: column; align-items: stretch; }
  .page-cta__actions .metal { width: 100%; }
  .page-cta__actions .metal__face { width: 100%; }
}

/* --- Previous work detail rows --------------------------------------------- */

.job-list { padding: 0 var(--gutter) clamp(72px, 9vw, 128px); }

.job {
  display: grid;
  grid-template-columns: 54% 1fr;
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
  padding: clamp(44px, 5vw, 72px) 0;
  border-top: 1px solid var(--hairline);
}

/* Every other one runs the other way. The homepage shows these same four jobs
   in a two by two grid, so alternating keeps this page from repeating it. */
.job--flip .job__media { order: 2; }

.job__media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: 8px;
  box-shadow:
    0 22px 44px rgba(0, 0, 0, .55),
    0 8px 16px  rgba(0, 0, 0, .42),
    inset 0 0 0 1px rgba(242, 239, 233, .10);
}
.job__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

.job__place {
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--brass);
}

.job__title {
  margin: 12px 0 20px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.14;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}

.job__body p {
  font-size: 16px; line-height: 1.66;
  color: var(--slate);
}
.job__body p + p { margin-top: 16px; }

/* A definition list, because that is what these are: a label and its value. */
.job__facts {
  margin: 26px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--hairline);
  display: grid; gap: 12px;
}
.job__facts > div { display: flex; justify-content: space-between; gap: 20px; }
.job__facts dt {
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
}
.job__facts dd {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 14px; letter-spacing: var(--ls-body);
  color: var(--ink);
  text-align: right;
}

/* --- About: running text and team ------------------------------------------ */

.prose-block { padding: clamp(56px, 7vw, 96px) var(--gutter); }
.prose-block__inner { max-width: 62ch; }

.prose-lead {
  font-size: clamp(19px, 2vw, 23px);
  line-height: 1.5;
  letter-spacing: var(--ls-body);
  color: var(--ink);
}
.prose-block p:not(.prose-lead) {
  margin-top: 20px;
  font-size: 17px; line-height: 1.68;
  color: var(--slate);
}

.team { padding: 0 var(--gutter) clamp(64px, 8vw, 104px); }

.team-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.team-member { background: var(--paper); padding: clamp(26px, 2.6vw, 38px); }

.team-member__name {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 19px; letter-spacing: var(--ls-headline);
  color: var(--ink);
}
.team-member__role {
  margin-top: 6px;
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--brass);
}
.team-member__text {
  margin-top: 16px;
  font-size: 15px; line-height: 1.62;
  color: var(--slate);
}

.credentials {
  border-top: 1px solid var(--hairline);
  background: var(--paper-3);
  padding: clamp(56px, 7vw, 92px) var(--gutter);
}
.credentials__inner { max-width: 680px; }
.credentials__title {
  margin: 0 0 4px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(24px, 3vw, 36px);
  line-height: 1.14;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}
.credentials .involved { border-top: 0; }
.credentials__note {
  margin-top: 26px;
  font-size: 16px; line-height: 1.62;
  color: var(--slate);
}

/* --- Contact: details list, triage line, map -------------------------------- */

.urgent {
  margin-top: 26px;
  padding: 16px 18px;
  border: 1px solid var(--border-on-dark);
  border-radius: 4px;
  font-size: 15px; line-height: 1.6;
  color: var(--slate);
}
.urgent strong { color: var(--ink); font-weight: 600; }

.contact-details {
  margin: 34px 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px 32px;
}
.contact-details dt {
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 7px;
}
.contact-details dd {
  margin: 0;
  font-size: 15px; line-height: 1.6;
  color: var(--ink);
}
.contact-details a { color: var(--ink); text-decoration: underline;
  text-decoration-color: var(--brass); text-underline-offset: 3px; }
.contact-strong { font-family: var(--font-display); font-weight: 600; font-size: 17px; }

.area-map { padding: clamp(16px, 2vw, 28px) var(--gutter) clamp(72px, 9vw, 128px); }

.area-map__frame {
  margin-top: clamp(32px, 4vw, 48px);
  aspect-ratio: 21 / 9;
  overflow: hidden;
  border-radius: 8px;
  border: 1px solid var(--hairline);
}
/* The placeholder that stands in for the map until somebody asks for it.
   It fills the frame exactly, so swapping the real embed in shifts nothing. */
.map-load {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 100%;
  text-decoration: none;
  color: var(--slate);
  background: var(--paper-2);
  transition: background .25s ease, color .25s ease;
}
.map-load:hover,
.map-load:focus-visible { background: var(--paper-3); color: var(--ink); }

.map-load svg { color: var(--brass); }

.map-load__title {
  font-family: var(--font-display); font-weight: 600;
  font-size: 15px; letter-spacing: var(--ls-body);
  color: var(--ink);
}
.map-load__note { font-size: 13px; }

.area-map__frame iframe {
  display: block; width: 100%; height: 100%; border: 0;
  /* Google's embed is a bright white map, which on this page looks like a hole
     cut in the design. Inverting and rotating the hue turns it dark without
     needing a paid styled-map API key. Saturation pulled back so the roads do
     not go luminous green. */
  filter: invert(0.92) hue-rotate(180deg) saturate(0.55) contrast(0.95);
}

/* --- Phone and tablet ------------------------------------------------------- */

@media (max-width: 900px) {
  .job {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }
  /* Order is reset, so the picture is always above the words on a phone.
     Alternating sides means nothing when there is only one column. */
  .job--flip .job__media { order: 0; }

  .team-grid { grid-template-columns: minmax(0, 1fr); }
  .area-map__frame { aspect-ratio: 4 / 3; }
}

@media (max-width: 620px) {
  .contact-details { grid-template-columns: minmax(0, 1fr); }
  .area-map__frame { aspect-ratio: 1 / 1; }
}

/* --- 404 -------------------------------------------------------------------- */

.error-page { padding-bottom: clamp(64px, 8vw, 104px); }

.error-links {
  margin-top: clamp(36px, 4vw, 52px);
  border-top: 1px solid var(--hairline);
  max-width: 680px;
}
.error-links a {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  transition: padding-left .18s ease;
}
.error-links a:hover { padding-left: 10px; }

.error-links__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 19px; letter-spacing: var(--ls-headline);
  color: var(--ink);
  white-space: nowrap;
}
.error-links__note {
  font-size: 14px; line-height: 1.4;
  color: var(--slate);
  text-align: right;
}

@media (max-width: 560px) {
  .error-links a { flex-direction: column; gap: 5px; }
  .error-links__note { text-align: left; }
}

/* ==========================================================================
   ABOUT PAGE, rebuilt
   The first version was a narrow column of text on a dark background with
   nothing to look at and half the screen empty. This one gives the page three
   anchors: a figures band, monogram cards for the team, and a credentials
   grid. No stock headshots, so the monograms carry the team section instead.
   ========================================================================== */

/* --- Story: lead left, supporting text right ------------------------------- */

.story { padding: clamp(56px, 7vw, 96px) var(--gutter); }
.story__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
.story__lead {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.32;
  letter-spacing: var(--ls-display-md);
  color: var(--ink);
}
.story__body p {
  font-size: 17px; line-height: 1.7;
  color: var(--slate);
}
.story__body p + p { margin-top: 18px; }

/* --- Figures band. The page's main anchor. --------------------------------- */

.figures {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  background: var(--paper-3);
  padding: clamp(40px, 5vw, 64px) var(--gutter);
}
.figures__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 48px);
}
.figures__num {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(38px, 5vw, 64px);
  line-height: 1;
  letter-spacing: var(--ls-display-lg);
  color: var(--ink);
}
.figures__label {
  margin-top: 12px;
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
}

/* --- Team, with monograms rather than stock headshots ---------------------- */

.team { padding: clamp(56px, 7vw, 96px) var(--gutter) clamp(40px, 5vw, 64px); }

.team-grid {
  margin-top: clamp(32px, 4vw, 48px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.team-member {
  background: var(--paper);
  padding: clamp(26px, 2.6vw, 38px);
}

/* Same brass square as the favicon, so the mark reads as brand rather than as
   a placeholder standing in for a missing photograph. */
.team-member__mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px;
  border-radius: 11px;
  background: var(--brass);
  color: var(--on-brass);
  font-family: var(--font-display); font-weight: 700;
  font-size: 19px; letter-spacing: -0.02em;
}

.team-member__name {
  margin: 22px 0 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 20px; letter-spacing: var(--ls-headline);
  color: var(--ink);
}
.team-member__role {
  margin-top: 7px;
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--brass);
}
.team-member__text {
  margin-top: 16px;
  font-size: 15px; line-height: 1.62;
  color: var(--slate);
}

/* --- Credentials as a grid, not a bullet list ------------------------------ */

.credentials { padding: 0 var(--gutter) clamp(64px, 8vw, 104px); background: none;
  border-top: 0; }
.credentials__grid {
  margin-top: clamp(28px, 3vw, 40px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.cred {
  background: var(--paper);
  padding: clamp(22px, 2.4vw, 32px);
  display: flex; gap: 16px; align-items: flex-start;
}
.cred svg { flex: 0 0 auto; width: 20px; height: 20px; color: var(--brass); margin-top: 2px; }
.cred__title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; letter-spacing: var(--ls-body);
  color: var(--ink);
}
.cred__text {
  margin-top: 6px;
  font-size: 14px; line-height: 1.55;
  color: var(--slate);
}

/* --- Phone and tablet ------------------------------------------------------ */

@media (max-width: 900px) {
  .page-head__inner { grid-template-columns: minmax(0, 1fr); gap: 34px; align-items: start; }
  .page-head__lead { max-width: none; }
  .story__inner { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .figures__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 24px; }
  .team-grid { grid-template-columns: minmax(0, 1fr); }
  .credentials__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  .head-figures { grid-template-columns: minmax(0, 1fr); }
  .figures__grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .head-index__meta { display: none; }
}
