/* ==========================================================================
   Scrimgeour & Company — stylesheet (SITE-V2)
   --------------------------------------------------------------------------
   An open, editorial treatment. What characterises it:

     - Full-bleed horizontal BANDS, so a long page reads as a sequence of
       rooms rather than one column of text — a single dark field rather
       than two, so the alternation stays quiet.
     - Much more vertical air: bands breathe at 4-7rem of padding.
     - A bigger, more confident display scale, set in a classical serif.
     - A hairline as the partition rhythm.
     - A deep navy hero with a curved lower edge.

   ⚠️ PALETTE UPDATE — 2026-08-14. This is Site-v2: the firm's finalized
   brand palette (Deep Navy / Refined Bronze / Warm Cream) replaces the
   working navy used in Site-v1. Two of the three brand colours were already
   right — --ground (cream, #F7F5F1) and --bronze (#A6875A) both already
   matched the brief exactly and are UNCHANGED. Only --navy moves, from the
   v1 working value #193761 to the brand value #1B2A45 — darker and less
   saturated. Every token measured against navy (--ink-on-dark, --accent-pale,
   --accent-bright) and every supporting neutral derived from navy's hue
   (--ink, --ink-soft, --accent, --accent-deco, --control) was recomputed
   from that new value and re-verified against WCAG 2.1 AA below. Nothing
   here was eyeballed — see the measurement table in section 1.

   Still: no build step, and NO THIRD-PARTY REQUESTS. The two typefaces are
   self-hosted from assets/fonts/ — same-origin, so privacy.html's statement
   that the only outside request is the OpenStreetMap frame stays true.

   Sections:
     1. Design tokens          6. Bands and rhythm
     1b. Web fonts             7. Components
     2. Reset and base         8. Forms
     3. Typography             9. Utilities
     4. Layout                10. Responsive and motion
     5. Header / footer
   ========================================================================== */

/* ⚠️ BRONZE ROLLOUT — 2026-08-14. This is Site-v4: a copy of Site-v3 with
   four of the five open decisions from the Site-v3/"Web Design 1 Site-v4"
   comparison resolved in favour of the wider, sitewide treatment. All four
   were re-verified against WCAG 2.1 AA in place, not copied blind:

     1. Arrow-link hover DROPS bronze on every band, including navy — see
        the note at .arrow-link below. It previously used bronze on
        .band--navy only; that is gone.
     2. The hero's ampersand is now literal bronze TEXT (the one exception
        to "bronze is never text" — see the note at .hero h1 .amp, which
        explains the large-text threshold that makes it safe).
     3. The link-hover bronze underline, the nav hover/active-page
        indicator, and the footer link hover are now LIVE SITEWIDE, on all
        ten pages, via the shared rules below (a:hover, .nav a:hover,
        .nav a[aria-current="page"], .site-footer a:hover) — no longer the
        scoped .hover-bronze opt-in class Site-v3 used while this was
        still a draft.
     4. .band--navy .callout keeps bronze on its left border instead of
        swapping to --accent-bright — callouts are bronze on every band
        now, light or dark.

   NOT changed by this pass: the .section-head__line--bronze extension
   (still an opt-in modifier, still only on Home's Services/Contact
   headings, still withheld from Client Resources) is untouched, and no
   token was renamed or added — this stays on Site-v3's --ink / --accent-*
   architecture throughout. */


/* 1. DESIGN TOKENS =========================================================
   THE BRAND PALETTE, AS THREE TOKENS:

     --navy   #1B2A45   Primary. Headings, body text on light grounds (via
                        the --ink family below, tuned from it), dark section
                        backgrounds, the nav bar, the footer, the wordmark.
     --bronze #A6875A   Secondary accent, decoration only. Hairline rules,
                        small marks, hover-state underlines, a border on a
                        card or callout. NEVER a button fill, NEVER a large
                        surface. See the per-selector list at each usage
                        below, and the contrast note under --bronze.
     --ground #F7F5F1   Warm cream. Backgrounds, and to soften pure white on
                        light sections.

   EVERYTHING ELSE in this file is either one of those three, --white/--ink
   at the dark end, or a tint DERIVED FROM NAVY'S OWN HUE for secondary text,
   borders and muted UI — never a generic grey and never black. That is
   --ink, --ink-soft, --accent, --accent-deco and --control on light grounds,
   and --ink-on-dark, --accent-pale and --accent-bright on dark grounds: all
   nine share --navy's hue (~219°) at different lightness/saturation, so the
   whole system reads as one family rather than brand colours plus generic
   UI grey bolted on.

   EVERY PAIR BELOW WAS MEASURED with the WCAG relative-luminance formula,
   not eyeballed. The rules that must not be broken:

     --bronze is a mid-tone and clears 4.5:1 NOWHERE it can sit near text:
             4.26:1 on --navy, 3.37:1 on --white, 3.09:1 on --ground, and it
             FAILS 3:1 on --ground-deep (2.76:1). All non-text-only numbers.
             It must never be a text colour, never a fill behind text, and
             never decoration on a .band--ground-deep surface. Restricted to
             hairline rules, borders and hover-state underlines — see the
             full list of every selector that uses it, below the token
             definition.

     --accent-deco is non-text decoration only: 4.39:1 on --ground, 4.78:1 on
             --white, 3.92:1 on --ground-deep — all clear the 3:1 SC 1.4.11
             floor with room, but it is kept out of running text so the
             text/decoration distinction in this file stays unambiguous.

     On light grounds, text is --ink / --ink-soft / --accent (6.47:1 or
     better against both --ground and --white).
     On dark grounds, text is --white / --ink-on-dark / --accent-pale /
     --accent-bright (6.26:1 or better against --navy).

   Full measurement table for the new navy, #1B2A45 (HSL 219°, 44%, 19%):

     --ink           vs --ground   16.62:1   vs --white   18.10:1
     --ink-soft      vs --ground    7.81:1   vs --white    8.51:1
     --accent        vs --ground    6.47:1   vs --white    7.04:1
     --accent-deco   vs --ground    4.39:1   vs --white    4.78:1   (non-text)
     --control       vs --ground    4.52:1   vs --white    4.92:1   (non-text, SC 1.4.11)
     --ink-on-dark   vs --navy     11.77:1
     --accent-pale   vs --navy      8.79:1
     --accent-bright vs --navy      6.26:1   vs --ink      7.89:1   (.btn--ink focus ring)
     --bronze        vs --navy      4.26:1   vs --white    3.37:1   vs --ground 3.09:1   (all non-text)
     --navy          vs --ground   13.18:1   vs --white   14.35:1   (navy text/fill on light ground)

   All comfortably clear AA at their intended use (4.5:1 for the text row,
   3:1 for the two flagged non-text rows). Do not change --navy without
   re-running this table — every other token here is measured against it.
   -------------------------------------------------------------------------- */
:root {
  /* Grounds */
  --ground:      #F7F5F1;   /* BRAND cream — unchanged from Site-v1, already
                                the brief's exact value. Primary light ground
                                and the surface pure white sits on top of.   */
  --ground-deep: #EDE8DF;   /* secondary band, a shade deeper than --ground;
                                same family, for band alternation only.     */
  --white:       #FFFFFF;
  --navy:        #1B2A45;   /* BRAND navy — Site-v2 value, replacing the v1
                                working colour #193761. Darker and less
                                saturated (HSL 219°, 44%, 19% vs 215°, 59%,
                                24%). THE dark field: hero, dark bands, nav
                                bar, footer, and the colour the wordmark
                                itself uses. Every token below was
                                recomputed against this value — see the
                                measurement table above.                    */

  /* Ink — light grounds. Tints of --navy's own hue, not generic grey. */
  --ink:         #0E1625;   /* 16.62:1 on ground, 18.10:1 on white — body
                                and headings                                */
  --ink-soft:    #3B4D6D;   /*  7.81:1 on ground — secondary text           */
  --accent:      #47597B;   /*  6.47:1 on ground — small caps labels, arrow
                                links. A slate, so the 12.5px uppercase
                                labels keep a little life instead of being
                                plain grey.                                 */

  /* Ink — dark grounds. Same navy hue, lifted to sit on --navy. */
  --ink-on-dark: #E4E9F1;   /* 11.77:1 on navy — body text on dark          */
  --accent-pale: #C2CBDB;   /*  8.79:1 on navy — display numerals, labels
                                on dark                                     */
  --accent-bright:#9CACC9;  /*  6.26:1 on navy — accent text on dark, link
                                hover, focus rings                          */

  /* Decoration only — never text, never a ground for white text */
  --accent-deco: #627393;   /*  4.39:1 on ground, 4.78:1 on white — hairline
                                rules and border accents, kept out of
                                running text so it stays unambiguous with
                                --accent above                              */
  /* THE BRAND ACCENT. As of Site-v4's bronze rollout (see the note at the
     top of this file) it is used at: the hero rule, the hero ampersand
     (the one text exception — large type only, see .hero h1 .amp), the
     sitewide link-hover underline, nav hover/active-page, footer link
     hover, callout borders on every band, and — still opt-in, Home only —
     the Services/Contact section-head rules. It is NEVER a button fill and
     NEVER a large surface, and as of this pass it is also never on
     .arrow-link, on any band (see that component below).
     DECORATION-OR-LARGE-TEXT ONLY: clears 3:1 (the non-text / large-text
     floor) on --navy, --white and --ground, but FAILS 3:1 on
     --ground-deep and NEVER clears the 4.5:1 normal-text floor anywhere —
     so outside the hero ampersand it stays off normal-size text and off
     .band--ground-deep entirely. */
  --bronze:      #A6875A;   /* 4.26:1 on navy, 3.37:1 on white, 3.09:1 on
                                ground, 2.76:1 on ground-deep (fails). Text
                                colour only at large-heading size (hero
                                ampersand); everywhere else, non-text only,
                                and never on a .band--ground-deep surface. */
  /* Hairline. 1.30:1 on ground — decorative, deliberately faint. It draws an
     edge without becoming a rule. Do NOT lighten it: a hairline this faint
     stops being visible altogether well before it approaches a threshold
     meant for elements that carry meaning on their own. */
  --line:        #D2D9E5;
  --line-dark:   rgba(194, 203, 219, 0.28);   /* --accent-pale @28%, for
                                hairlines on dark grounds                   */
  --control:     #62718D;   /* interactive borders — 4.52:1 on ground, 4.92:1
                                on white, clears SC 1.4.11 with room         */

  /* Translucent overlays for use ON the dark field. Each is an existing
     token at an alpha, kept as a literal because there is no build step to
     derive them and color-mix() is too new to rely on for this audience —
     but each is named for the token it tracks, so a future navy change
     updates these three lines and nothing else. */
  --line-ghost:  rgba(228, 233, 241, .5);  /* --ink-on-dark @50% — ghost button edge */
  --wash-light:  rgba(255, 255, 255, .1);  /* white @10% — hover wash on dark        */
  --shadow-pin:  rgba(14, 22, 37, .45);    /* --ink @45% — map pin drop shadow       */
  --wash-nav:    rgba(98, 115, 147, .12);  /* --accent-deco @12% — nav hover         */

  /* Elevation. Tinted with the navy rather than black, so cards lift off the
     cool grounds without a muddy grey cast. Kept very faint — this is a
     professional firm, not a dashboard. Never used inside .band--navy, where a
     shadow is invisible; dark bands lift with border and background alpha. */
  --shadow-sm: 0 1px 2px rgba(14,22,37,.05), 0 2px 6px rgba(14,22,37,.06);
  --shadow-md: 0 2px 4px rgba(14,22,37,.06), 0 6px 16px rgba(14,22,37,.08);

  /* Type — a classical serif for display, echoing the logo's lettering.
     Self-hosted faces lead each stack; the previous system stacks stay behind
     them, so if a font file is missing the site degrades to exactly what it
     looked like before rather than breaking. Nothing may DEPEND on these
     loading. */
  --font-display: "Source Serif 4", "Palatino Linotype", "Book Antiqua",
                  Palatino, "Iowan Old Style", Georgia, serif;
  --font-body:    "Source Sans 3", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* A wider scale than v1 — the top end carries the hero */
  --step--2: clamp(0.78rem, 0.76rem + 0.1vw, 0.84rem);
  --step--1: clamp(0.95rem, 0.92rem + 0.15vw, 1.02rem);
  --step-0:  clamp(1.125rem, 1.08rem + 0.2vw, 1.22rem);
  --step-1:  clamp(1.3rem, 1.2rem + 0.45vw, 1.6rem);
  --step-2:  clamp(1.6rem, 1.4rem + 0.9vw, 2.3rem);
  /* The lower bound is set so the longest heading word on the site
     ("Accessibility") still fits across a 320px screen. */
  --step-3:  clamp(1.75rem, 1.28rem + 2.1vw, 3.2rem);
  --step-4:  clamp(2.5rem, 1.9rem + 2.9vw, 4.4rem);
  /* Hero <h1> only — nothing else uses it. Capped at 4.5rem on 2026-08-11, down
     from 6rem: across the two lines of "Scrimgeour / & Company" that alone was
     ~200px of the hero, and the hero was filling the whole fold (item 10). It
     is still comfortably the largest type on the site, which matters more than
     it did — with the logo gone this is the only place the firm is named above
     the fold. Lower bound unchanged so phones are unaffected. */
  --step-5:  clamp(3rem, 2rem + 3.2vw, 4.5rem);

  /* Space */
  --sp-1: .25rem; --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.5rem; --sp-6: 2rem;   --sp-7: 3rem;   --sp-8: 4rem;
  --sp-9: 6rem;

  /* Band padding — the main source of the extra openness. Trimmed at the top
     end: at 8.5rem a band holding a heading and one paragraph read as an empty
     colour block rather than a room. */
  --band-pad: clamp(4rem, 7vw, 7rem);

  --measure: 62ch;
  --wide: 78rem;
  --mid: 62rem;
  /* 3px reads as an accident rather than a decision. 6px is still conservative
     for a professional firm but makes the corner deliberate. */
  --radius: 6px;
  --radius-pill: 999px;   /* tags only — .chips is now its single use          */
}


/* 1b. WEB FONTS ============================================================
   Source Serif 4 and Source Sans 3, both SIL OFL 1.1 (see assets/fonts/OFL.txt).
   Designed as a matched pair on a shared skeleton, so the display/body pairing
   is the same on every machine instead of "whatever sans the OS supplies".

   Self-hosted and same-origin ON PURPOSE — a Google Fonts link would make the
   privacy policy's "the only third-party request is the map" statement false.
   Do not replace these with a CDN link.

   Two files, 56KB total, latin subset.

   The body face is VARIABLE: one 29KB file covers the whole weight axis, and
   the site genuinely uses three of them (400 body, 600 nav and labels, 700
   bold). That is why its font-weight is a RANGE — with a single value the
   browser would synthesise the others instead of interpolating the real ones.

   The display face is a STATIC SemiBold instance, deliberately. Every use of
   --font-display on the site is weight 600, so the variable build cost 122KB
   for an axis that would sit at a single point. If you ever need a second
   display weight, swap in the variable file and change font-weight to a range
   — do NOT declare a range against this static file, or the browser will stop
   synthesising and silently render every weight at 600.

   font-display:swap so text is readable immediately in the fallback face.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/SourceSerif4-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Source Sans 3";
  src: url("../fonts/SourceSans3-Variable.woff2") format("woff2-variations"),
       url("../fonts/SourceSans3-Variable.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}


/* 2. RESET AND BASE ======================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Must clear the sticky header, or an anchor target lands underneath it.
     RE-MEASURED 2026-08-10, after the logo came out (BRIEF-v3 item 1): the
     header is a flat 83-84px at every width where it is sticky — 32px of
     padding-block, a 49px nav row, and the 1px bottom rule. It no longer grows
     with the viewport, because --step-0 caps at 1.22rem and there is no logo
     height clamp left to scale. 6rem (96px) clears it with 12px of air.
     This was 7.5rem (120px), sized for a header that ran 92-113px with the logo
     in it. Below 40rem the header is not sticky at all (see §10) and this drops
     to 1rem. */
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.7;
  text-underline-offset: .2em;
  overflow-x: hidden;   /* the hero's curved edge can round-off sub-pixel */
}

img { max-width: 100%; height: auto; display: block; }
/* Uses --ink, NOT --accent-deco, for the selection highlight — 18.10:1 on
   white. --accent-deco is reserved for decoration (card top borders, the
   short .rule, hairlines) even where it would also pass as text, so the
   text/decoration split in this file stays clean rather than incidental. */
::selection { background: var(--ink); color: var(--white); }


/* 3. TYPOGRAPHY ============================================================ */
/* Weight 600, not 700: Source Serif SemiBold already carries more colour at
   display sizes than Palatino Bold did, and its Bold goes muddy at --step-4.
   The tracking is likewise relaxed from -0.015em — that was compensating for
   Palatino's wide set, and Source Serif is narrower. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.008em;
  color: var(--ink);
  margin: 0 0 var(--sp-5);
  text-wrap: balance;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); letter-spacing: -0.002em; }
h4 { font-size: var(--step-0); letter-spacing: 0; }

p, li { text-wrap: pretty; }
p { margin: 0 0 var(--sp-5); }
address { font-style: normal; }

a { color: inherit; text-decoration-thickness: 1px; }
/* --- BRAND ACCENT — inline link hover, bronze underline (APPROVED, sitewide) ---
   Promoted from Site-v3's scoped .hover-bronze draft: this is now the base
   a:hover rule, live on every plain inline link, on all ten pages. The hover
   TEXT stays --accent (7.04:1 on white, 6.47:1 on ground) — bronze never
   becomes the text colour, only the underline, so the 4.5:1 text floor never
   applies to it. nav, footer, .arrow-link and .chips each restate their own
   hover treatment below and are unaffected by this rule.
   ⚠️ Bronze is 2.76:1 on --ground-deep, below the 3:1 non-text floor — this
   rule is still safe there today only because the two .band--ground-deep
   sections on the site (index.html Resources, about-us.html Partners and
   managers) carry no plain inline links, only .outbound cards, which set
   text-decoration: none and so never render an underline of any colour. If
   a plain inline link is ever added to a .band--ground-deep section, give
   it a scoped override back to a neutral underline colour before it ships. */
a:hover {
  color: var(--accent);
  text-decoration-color: var(--bronze);
  text-decoration-thickness: 2px;
}

/* Eyebrow — wide-tracked small caps, echoing "CPA PROFESSIONAL CORPORATION"
   in the logo lockup. */
.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-4);
}

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 46ch;
}
/* A slightly longer measure for a lede that carries a full intro paragraph
   rather than a single sentence. */
.lede--wide { max-width: 56ch; }
/* No measure cap — for a lede that should fill its column (e.g. a policy
   intro inside .wrap--mid, where the column already limits the line length). */
.lede--full { max-width: none; }

.prose { max-width: var(--measure); }
.prose ul, .prose ol { padding-left: 1.2em; margin: 0 0 var(--sp-5); }
.prose li { margin-bottom: var(--sp-3); }

.rule { border: 0; border-top: 2px solid var(--accent-deco); width: 4rem; margin: 0 0 var(--sp-6); }


/* 4. LAYOUT ================================================================ */
.wrap { width: min(100% - 2.5rem, var(--wide)); margin-inline: auto; }
.wrap--mid { width: min(100% - 2.5rem, var(--mid)); margin-inline: auto; }

/* Home page frame: a more "zoomed-out", spacious feel — a narrower content
   column and more vertical air between bands. Scoped to the MAIN content only,
   so the shared header and footer keep their full width and the nav keeps the
   room it needs to stay on one line. */
/* The home bands used to run to 9.5rem of padding on each side while holding a
   heading and a single sentence — ~300px of content inside a ~700px block of
   solid colour, which read as an unfinished template. The bands now carry real
   content (see index.html), so they need less compensating air, not more. */
.home { --band-pad: clamp(3.5rem, 6vw, 6rem); }
.home main .wrap { width: min(100% - 4rem, 68rem); }
/* Was max-width:none, so the home ledes filled the content column and their
   right edge lined up with the full-width heading and hairline above them
   rather than stopping short.

   ⚠️ REVERSED 2026-08-11 (BRIEF-v3 item 10, which names it). Measured: that gave
   1088px lines — 86 CHARACTERS — on all three home bands at both 1440 and 1920.
   Comfortable reading is roughly 45-75; 86 is well past it, and this site is
   built for an older client base. Alignment lost, legibility won.

   56ch, not the 46ch of a bare .lede, because these carry full intro paragraphs
   — it is exactly what .lede--wide would have given them. index.html has two
   comments noting that .lede--wide was a no-op here because this rule beat it
   on specificity; the markup wanted 56ch all along and now gets it. */
.home main .lede { max-width: 56ch; }

/* Band transitions are straight lines: bands keep their solid grounds
   (band--navy / band--ground) and meet at a clean horizontal edge — no curve,
   fade, or overlap. */

.grid { display: grid; gap: var(--sp-6); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); }
/* Exactly two columns, never three.
   .grid--2 is auto-fit: at a wide viewport it fits as many 21rem tracks as it
   can, so a FOUR-item group lands as 3 + 1 and leaves an orphan on its own row.
   Use .grid--pair for a set that should stay balanced (2x2, 2x3) regardless of
   how much room there is. */
.grid--pair { grid-template-columns: 1fr; }
@media (min-width: 44rem) {
  .grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Split layout: sticky section header beside flowing content. This is what
   creates the open, editorial feel on wide screens. */
.split { display: grid; gap: var(--sp-7); }
/* Grid items default to min-width:auto, which stops a track shrinking below
   its longest unbreakable word. A long heading in the aside column was
   forcing the track wider than the container and pushing the page into
   horizontal scroll at 320px. min-width:0 lets the track shrink properly. */
.split > * { min-width: 0; }
@media (min-width: 60rem) {
  .split { grid-template-columns: minmax(15rem, 22rem) 1fr; gap: var(--sp-9); }
  .split__aside { position: sticky; top: 7rem; align-self: start; }
}
/* A section-head used as a split's sticky aside is the whole column — its
   trailing margin would just push the sticky block down, so drop it. */
.split__aside .section-head { margin-bottom: 0; }

/* 5. HEADER AND FOOTER ===================================================== */
.skip-link {
  position: absolute; left: var(--sp-4); top: -100vh; z-index: 999;
  background: var(--navy); color: var(--white);
  padding: var(--sp-3) var(--sp-5); border-radius: var(--radius);
  font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: var(--sp-4); color: var(--white); }

/* The header ground is opaque on every page. This USED to be load-bearing: the
   logo was a white-ground JPEG shown with mix-blend-mode, and a translucent
   header would have let whatever band was scrolling underneath become part of
   its backdrop. The logo is gone (BRIEF-v3 item 1), so that constraint is
   lifted and a frosted or translucent header is available again if Pass 2
   wants one. Nothing needs it today, and opaque keeps the sticky nav legible
   over every band, so it stays. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--ground);
  border-bottom: 1px solid var(--line);
}
/* NOTE: the home page header used to be transparent and overlaid on the navy
   hero. That was dropped when the logo still existed, and the header has been
   the same cream bar on every page since — which also means the sticky nav
   stays readable the whole way down the long home page. */

/* NAV ONLY, CENTRED. The logo <img> and its wrapping <a class="brand"> came out
   in BRIEF-v3 item 1: the firm is commissioning a new mark and does not want
   the old one shown meanwhile. There is no text wordmark either — the header is
   the navigation and nothing else. Two consequences worth knowing:

     1. Home is now the FIRST nav item, because .brand was previously the only
        link back to the home page and nothing else pointed there.
     2. assets/img/logo.jpg and logo.png stay on disk but are referenced by
        nothing. Do not delete them; the firm may still want the old mark.

   With one child the header is just a centring container. */
.site-header__inner {
  display: flex; justify-content: center;
  padding-block: var(--sp-4);
}
/* (The .brand and .brand img rules lived here — the crop window, the
   object-position offset and the mix-blend-mode white-knockout that displayed
   logo.jpg on the cream ground. All removed with the logo itself. If the new
   mark ever arrives as a vector or a transparent PNG, none of that machinery
   needs to come back: it existed only to work around a white-ground JPEG.) */

.nav ul {
  list-style: none; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center;
  gap: 0; margin: 0; padding: 0;
}
/* A faint vertical bar between each title, with even space on both sides: the
   li's margin-left sits before the border and its padding-left after it. */
.nav li:not(:first-child) { border-left: 1px solid var(--line); margin-left: var(--sp-3); padding-left: var(--sp-3); }
.nav a {
  display: block; padding: var(--sp-2) var(--sp-2);
  text-decoration: none; font-weight: 600;
  font-size: var(--step-0); border-radius: var(--radius);
  border-bottom: 2px solid transparent;
}
/* A faint wash, no colour of its own — comes from --wash-nav (--accent-deco
   at 12% alpha, #627393 as of Site-v2) so it follows --accent-deco/--navy
   automatically rather than being written out longhand here. The hover and
   current-page underline are bronze (APPROVED, sitewide): the header sits
   on --ground throughout, where bronze is 3.09:1 — a border, not text, so
   the 3:1 non-text floor is what applies, and it clears with room to
   spare. The current-page underline is persistent (shown on every load,
   not just on hover) — a deliberate, small, permanent touch rather than a
   large one. */
.nav a:hover { background: var(--wash-nav); border-bottom-color: var(--bronze); }
.nav a[aria-current="page"] { border-bottom-color: var(--bronze); }

:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; border-radius: 2px; }
/* The focus ring must clear 3:1 against whatever it sits on (WCAG 1.4.11).
   The default --ink ring is fine on every light ground, but it disappears on a
   dark one — re-verified against the Site-v2 navy value:
     .hero        — navy, but NOT .band--navy, so it was never covered. The
                    ghost button "Contact the office" measures 1.26:1.
     .skip-link   — background: var(--navy), on all ten pages. 1.26:1.
     .btn--ink    — background: var(--ink), the SAME colour as the ring, so
                    "Open the client portal" measures 1:1 — a literally
                    invisible focus indicator on a primary call to action.
   --accent-bright clears all three: 6.26:1 on --navy, 7.89:1 on --ink.
   These are keyboard-only states — nothing about the page changes visually. */
.band--navy :focus-visible,
.hero :focus-visible,
.site-footer :focus-visible,
.skip-link:focus-visible,
.btn--ink:focus-visible {
  outline-color: var(--accent-bright);
}
/* ...with one exception, and it is the reason the rule above is not simply
   "anything on a dark band". A solid .btn carries its OWN light ground
   (background: var(--ground)) wherever it is placed, so on a dark band the
   ring sits on the button's light face, not on the band. The bright ring
   measures 2.11:1 there — worse than the default. It keeps the dark ring.
   .btn--ghost is transparent and .btn--ink is dark, so both are excluded.
   Today only .hero holds a solid .btn, but this stays correct if one is ever
   dropped into a .band--navy. */
.btn:not(.btn--ghost):not(.btn--ink):focus-visible {
  outline-color: var(--ink);
}

/* --step-0, raised from --step--1 on 2026-08-11. The footer carries the office
   address, the telephone number and the site's secondary navigation — content
   people actually read, not furniture — and at --step--1 it rendered at 15.3px
   on a phone, well under the 18px floor. This is the single most visible part
   of that fix: the footer grows on every page. Drop it back to --step--1 if the
   firm would rather have the compactness than the legibility. */
.site-footer {
  background: var(--navy); color: var(--ink-on-dark);
  padding-block: var(--sp-8) var(--sp-6);
  font-size: var(--step-0); line-height: 1.75;
}
.site-footer a { color: var(--white); }
/* Text stays --accent-bright on hover (6.26:1 on navy, clears the 4.5:1
   text floor) — bronze on navy is only 4.26:1, which fails normal-size
   text, so bronze stays confined to the underline (a border, not text;
   3:1 is the relevant floor there and it clears at the same 4.26:1).
   APPROVED, sitewide. */
.site-footer a:hover { color: var(--accent-bright); text-decoration-color: var(--bronze); text-decoration-thickness: 2px; }
.site-footer h2 {
  font-family: var(--font-body); font-size: var(--step--2);
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--accent-pale); margin: 0 0 var(--sp-4);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
/* Footer links were 22px tall on a phone, under the 24px floor in WCAG 2.2
   SC 2.5.8 (Target Size, Minimum, AA) and tight for the older client base the
   brief calls out. The link must be inline-block for vertical padding to
   affect its box at all. This takes them to ~33px while keeping a 12px gap
   between adjacent targets, at a cost of roughly 60px of footer height on
   mobile. The site targets WCAG 2.1 AA, where this was not a failure — it is
   fixed because the audience makes it worth fixing. */
.site-footer li { margin-bottom: var(--sp-3); }
.site-footer li a { display: inline-block; padding-block: 3px; }
.site-footer address { font-style: normal; }
.footer-grid { display: grid; gap: var(--sp-7); grid-template-columns: repeat(auto-fit, minmax(min(14rem,100%), 1fr)); }
.footer-legal {
  margin-top: var(--sp-8); padding-top: var(--sp-5);
  /* Driven from the token, not a hardcoded value — --accent-pale is the
     "secondary text on dark" value and measures 8.79:1 on the Site-v2 navy. */
  border-top: 1px solid var(--line-dark); color: var(--accent-pale);
}
.footer-legal p { margin-bottom: var(--sp-2); }


/* 6. BANDS AND RHYTHM ======================================================
   A band is a full-bleed horizontal section. Alternating their grounds is
   what makes a long page read as distinct, partitioned rooms.
   -------------------------------------------------------------------------- */
.band { padding-block: var(--band-pad); }
.band--ground      { background: var(--ground); }
.band--ground-deep { background: var(--ground-deep); }
.band--white      { background: var(--white); }
.band--navy       { background: var(--navy); color: var(--ink-on-dark); }
/* h1 added 2026-08-12 (BRIEF-v4 item 10) — the page intro band replaces
   .page-head on a light ground with .band--navy, and .page-head carries the
   page's <h1>. Every other heading level already turned white on dark; h1
   never needed it before because only the home hero used it, and .hero h1
   sets its own colour separately below. */
.band--navy h1, .band--navy h2, .band--navy h3, .band--navy h4 { color: var(--white); }
.band--navy .eyebrow { color: var(--accent-pale); }
.band--navy .lede { color: var(--ink-on-dark); }
.band--navy a { color: var(--white); }
.band--navy a:hover { color: var(--accent-bright); }
.band--tight { padding-block: clamp(3rem, 5vw, 4.5rem); }

/* Section header: eyebrow, title, and a hairline that runs the full width of
   the band. The hairline is the partition rhythm. */
.section-head { margin-bottom: var(--sp-8); }
.section-head h2 { margin-bottom: var(--sp-4); }
.section-head__line { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0 0; }
.band--navy .section-head__line { border-top-color: var(--line-dark); }

/* --- BRAND ACCENT (DRAFT, pending approval) — heading rule, bronze variant ---
   Site-v3: extends the homepage hero's bronze underline (.hero__rule, above
   in §6) to other headings, per the brief's "thin rule under the hero
   heading" example. Opt-in via this modifier class rather than changing
   .section-head__line itself, so a page or band keeps the neutral hairline
   until this is deliberately rolled out to it — see the Site-v3 summary for
   which headings carry it today.
   ⚠️ NEVER on a .band--ground-deep surface — bronze measures 2.76:1 there,
   below the 3:1 non-text floor. Use the plain .section-head__line (no
   modifier) on that band instead. On --ground it is 3.09:1 and on --white /
   --navy it has more room (3.37:1 / 4.26:1) — still non-text only in every
   case, never a colour a heading's own text could take. */
/* Specificity matched to .band--navy .section-head__line (0,2,0) via the
   compound selector below, not just (0,1,0) — otherwise the navy band's own
   override (--line-dark) would win on a dark band regardless of source
   order, and this modifier would silently do nothing there. */
.section-head__line.section-head__line--bronze { border-top-color: var(--bronze); }


/* --- HERO ---------------------------------------------------------------
   A deep navy field with a curved lower edge. It carried a giant ampersand
   watermark and a gold bloom until 2026-08-11 — see the note below where
   those rules were. */
.hero {
  position: relative;
  background: var(--navy);
  color: var(--ink-on-dark);
  /* Trimmed 2026-08-11 (BRIEF-v3 item 10). Was clamp(4.5rem,11vw,9rem) and
     clamp(6rem,14vw,11rem) — 320px of padding at 1440, which put header+hero at
     951px and pushed the two buttons off the bottom of a laptop screen.
     NARROW FIX: padding only. Nothing else about the hero moves. */
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3.5rem, 8vw, 6.5rem);
  overflow: hidden;
  /* The domed bottom edge and its overlap are set with the other home-page
     band curves (see "Curved band transitions"). */
}
/* RETIRED 2026-08-11 — BRIEF-v3 item 11. Two rules lived here:

     .hero::before   a soft gold radial bloom off the top-right, to keep the
                     large navy field from reading as flat.
     .hero__mark     the logo's ampersand set at min(34rem, 44vw) as a
                     watermark, in italic Palatino.

   Both referenced a mark that is being replaced, and both were the least
   minimal things on the site. The <span class="hero__mark"> was deleted from
   index.html in the same change — a decorative element nobody can see should
   not linger in the markup.

   ⚠️ NEITHER USED A TOKEN. Their colours were hardcoded rgba(141,114,73,.2)
   and rgba(217,201,163,.07) — the gold and pale-gold RGB values written out
   longhand. Swapping the palette would have left both sitting there in gold.
   If you ever add decoration to the hero, drive it from a token.

   Checked on screen after removal: the flat navy field reads as confident
   rather than empty. It did not need the bloom. */
.hero__inner { position: relative; z-index: 1; max-width: 54rem; }
.hero .eyebrow { color: var(--accent-pale); }
.hero h1 {
  font-size: var(--step-5);
  color: var(--white);
  margin-bottom: var(--sp-5);   /* was --sp-6; tightened with the fold fix */
  letter-spacing: -0.012em;   /* relaxed with the h1-h4 tracking, see §3 */
}
/* THE HERO AMPERSAND — the one place bronze is text, not decoration.
   --step-5 is 48-72px (clamp(3rem,...,4.5rem) above): comfortably past the
   WCAG large-text threshold (18pt/24px regular, or 14pt/18.66px bold), so
   the 3:1 large-text floor applies here instead of the normal 4.5:1 floor,
   and bronze on navy (4.26:1) clears it. Do not copy this span onto any
   normal-size "Scrimgeour & Company" elsewhere on the site (the footer's,
   for instance) — that text sits at --step-0/--step--1, well under the
   large-text threshold, where bronze fails outright. */
.hero h1 .amp { color: var(--bronze); }
.hero__lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ink-on-dark);
  max-width: 40ch;
  margin-bottom: var(--sp-6);   /* was --sp-7; tightened with the fold fix */
}
/* BRAND ACCENT — bronze, not --accent-bright: the brief's own flagship
   example of restrained use ("a thin rule under a hero heading"). 4.26:1
   on --navy, a non-text hairline so the 4.5:1 text floor doesn't apply.
   (See the token-block note at the top of this file and the .amp rule
   below for the full current list of where bronze is used — it is no
   longer just this rule and two others.) */
.hero__rule { border: 0; border-top: 2px solid var(--bronze); width: 4.5rem; margin: 0 0 var(--sp-6); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); }


/* 7. COMPONENTS ============================================================ */

/* One rule across the whole system: A BUTTON IS SOLID AND HIGH-CONTRAST
   AGAINST ITS OWN GROUND, AND THE ACCENT IS NEVER A BUTTON FILL. That is the
   palette's logic everywhere else — the accent does rules, borders and marks —
   and the buttons were the one exception. (Historically this was written about
   gold: a solid #C9A227 pill was the loudest thing on an otherwise restrained
   page. The hue changed in 2026-08-11; the rule did not.)

   On dark the primary button is the light ground with navy text (16.27:1); on
   light grounds it is .btn--ink, ink with white text (17.48:1). The accent
   keeps the work it is good at: hairlines, underlines, borders and marks —
   .arrow-link is deliberately excluded from bronze specifically (see the
   note at that component, below). */
.btn {
  display: inline-block; font: inherit; font-weight: 700;
  font-size: var(--step--1); letter-spacing: .04em;
  background: var(--ground); color: var(--navy);
  border: 2px solid var(--ground); border-radius: var(--radius);
  padding: var(--sp-3) var(--sp-6); text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn:hover { background: var(--white); border-color: var(--white); color: var(--navy); }
/* Border is derived from --ink-on-dark (#E4E9F1 as of Site-v2), not a
   hardcoded literal, so it tracks the token. Composited at 50% over the
   Site-v2 navy it resolves to about 4.12:1, clearing the 3:1 non-text
   threshold. */
.btn--ghost { background: transparent; color: var(--white); border-color: var(--line-ghost); }
.btn--ghost:hover { background: var(--wash-light); border-color: var(--white); color: var(--white); }
.btn--ink { background: var(--ink); border-color: var(--ink); color: var(--white); }
.btn--ink:hover { background: var(--navy); border-color: var(--navy); color: var(--white); }

/* .band--navy a{color:var(--white)} is more specific than .btn and would
   otherwise paint white text onto the light-ground button — 1.1:1. Restate
   the button colours at equal-or-higher specificity inside dark bands. */
.band--navy .btn { color: var(--navy); }
.band--navy .btn:hover { color: var(--navy); }
.band--navy .btn--ghost { color: var(--white); }
.band--navy .btn--ghost:hover { color: var(--white); }

/* --- Card --- */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.band--white .card { background: var(--ground); }
/* A shadow is invisible on navy. Dark bands get their separation from a
   brighter border and a touch more background alpha instead. */
.band--navy .card {
  background: rgba(255,255,255,.06);
  border-color: var(--line-dark);
  box-shadow: none;
}
.card h3 { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

/* --- Arrow link --- */
.arrow-link {
  display: inline-block; font-weight: 700; font-size: var(--step--1);
  letter-spacing: .03em; color: var(--accent); text-decoration: none;
  border-bottom: 1px solid var(--accent-deco); padding-bottom: 2px;
}
.arrow-link:hover { color: var(--ink); border-bottom-color: var(--ink); }
.band--navy .arrow-link { color: var(--accent-bright); border-bottom-color: var(--accent-bright); }
/* NOT BRONZE, on any band (changed from Site-v3, which put bronze here on
   hover on .band--navy only — 4.26:1, which clears fine on navy on its
   own). Dropped for sitewide consistency rather than a live failure today:
   .arrow-link doesn't currently sit on a .band--ground-deep surface
   anywhere on the site, but bronze measures 2.76:1 there and would fail
   the 3:1 non-text floor outright if it ever did (the ground-deep bands
   that exist — index.html's Client Resources, about-us.html's Partners
   and managers — only ever carry .outbound cards). Rather than get this
   right band-by-band and re-check it every time the component is reused
   somewhere new, .arrow-link stays on the neutral navy scale on every
   band, so the rule is correct anywhere it is ever placed, with nothing
   to verify later. */
.band--navy .arrow-link:hover { color: var(--white); border-bottom-color: var(--white); }

/* --- People --- */
.people-group { margin-top: var(--sp-8); }
.people-group:first-child { margin-top: 0; }
.people-group__head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--sp-3);
  border-bottom: 1px solid var(--accent-deco); padding-bottom: var(--sp-3); margin-bottom: var(--sp-6);
}
.people-group__head h2 { margin: 0; font-size: var(--step-2); }

/* EXACTLY TWO COLUMNS above 44rem, one below. Rewritten 2026-08-11.

   This used to be repeat(auto-fill, minmax(min(20rem,100%), 1fr)). auto-FILL
   was chosen over auto-fit deliberately, because the old roster had groups of
   one, two and three: auto-fit collapses empty tracks, so a one-person group
   stretched its card to 1248px at a 1440px viewport, and card width changed
   from group to group (612, 612, 400, 1248 reading down the page).

   ⚠️ THAT DECISION EXPIRED and became the bug it was preventing. BRIEF-v3
   item 3 cut the roster to Partners and Managers — two people each, both
   groups, permanently. auto-fill kept building THREE 400px tracks at 1440 and
   filling two, so every group carried a 400px hole to the right of it while
   the group heading's rule ran the full width. Measured before the change:
   3 tracks / 2 filled at 1440 and 1100; correct only at 768.

   auto-fit is not the answer either — two 612px columns for three short lines
   is worse. With a fixed 2 + 2 roster the track count is knowable, so it is
   simply stated. If the roster ever grows uneven again, read the paragraph
   above before reaching for auto-fill a second time. */
.people-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-7);
  grid-template-columns: 1fr;
}
@media (min-width: 44rem) {
  .people-list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--sp-8); }
}

/* NO BOX. Each person is a name, a line of credentials and a job title — three
   short lines. It was a bordered, rounded, shadowed card with a 3px accent top
   edge, which is a container bigger than the thing inside it, and it read as
   hollow once BRIEF-v3 item 3 stripped the contact block out of it.

   The group heading and its full-width rule already carry the structure, so the
   entries need no chrome of their own and get none: no background, no border,
   no radius, no elevation, no hover. Whitespace around an unboxed entry reads
   as air; the same whitespace inside a box reads as a gap that should have been
   filled. That is the whole reason for this change.

   Deliberately NOT given a hairline of its own — with two entries side by side
   the borders would sit directly under the group rule and read as a doubled
   line. */
.person { padding: 0; }
/* 600, matching h1-h4: the display face is hosted at a single weight, so a 700
   here would be a synthesised faux-bold sitting right beside real 600 headings. */
.person__name { font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; margin: 0 0 var(--sp-1); line-height: 1.2; }
.person__creds { font-size: var(--step--2); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); margin: 0 0 var(--sp-3); }
/* On a dark band --accent is too dark; --accent-pale is the readable pairing
   (8.79:1). Used by the people preview cards on the home page. */
.band--navy .person__creds { color: var(--accent-pale); }
/* The entry ends at the title — .person__contact was removed by BRIEF-v3 item 3
   and there is nothing below this line, so no trailing margin. */
.person__title { color: var(--ink-soft); margin: 0; }

/* REMOVED 2026-08-10, BRIEF-v3 item 9 — all of it provably unreachable:

     .person--todo / .todo-flag   the dashed "Awaiting confirmation" card and
                                  its badge, for roles that had not been
                                  confirmed. No live card ever used them.
     .filter*                     the directory filter panel, injected by
                                  site.js. The JS that built it never ran (see
                                  the note at the top of site.js) and is gone.
     .person__handles             a one-line "Handles: ..." description. Only
                                  ever appeared in the template comment.
     .people-group__count         a per-group headcount. Never rendered.
     .person__contact             the direct-line/email block pinned to the
                                  bottom of each card. Removed from the markup
                                  by item 3; the rule went with it.

   The pill radius those filter buttons used lives on in .chips below, which is
   the only remaining pill on the site. Keep --radius-pill. */

/* --- Chips --- */
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; }
.chips a {
  display: block; border: 1px solid var(--control); border-radius: var(--radius-pill);
  padding: var(--sp-2) var(--sp-5); text-decoration: none;
  font-size: var(--step--1); font-weight: 600; background: transparent;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.chips a:hover { background: var(--ink); color: var(--white); border-color: var(--ink); }
/* Was a hardcoded rgba(217,201,163,.45) — the pale-gold RGB longhand, which a
   palette swap would have missed. Driven from the token now. */
.band--navy .chips a { border-color: var(--line-dark); }
.band--navy .chips a:hover { background: var(--accent-bright); color: var(--navy); border-color: var(--accent-bright); }

/* --- Map ---
   A SELF-HOSTED STATIC IMAGE, not an interactive frame. Replaced the embedded
   OpenStreetMap iframe on 2026-08-11 at the firm's request.

   This removed THE LAST THIRD-PARTY REQUEST ON THE SITE. privacy.html now says
   the site makes no outside requests at all, with no exception clause. ⚠️ That
   sentence is only true while this stays an image — do not reintroduce an
   embed, here or anywhere, without rewriting that section in the same change.

   Google Maps was considered and rejected twice, most recently here: it sets
   cookies and loads scripts from an advertising company, on a page a client
   visits before walking into their accountant's office. See DECISIONS.md.

   The tiles are CARTO Positron rendering OpenStreetMap data — no API key, no
   account, ODbL + CARTO attribution kept in .map__note. Screenshotting Google
   would have breached their terms even if we had wanted to.

   The map is an ADDITION to the written address, never a replacement. The
   address, the parking description and the link out all stand on their own. */
.map {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--ground-deep);
  position: relative;   /* positioning context for the pins */
}
.map img {
  display: block;
  width: 100%;
  height: auto;
}

/* --- Map pins ---
   Drawn by us, over the image, rather than baked into it. Two reasons: a flat
   Positron export labels no buildings at all, and no basemap would ever mark
   the Talbot Centre garage — which is the single most useful thing on the
   Getting here page.

   Positioned in PERCENTAGES of the image, so they hold at every width without
   a media query. ⚠️ They are tied to this exact crop: if map-office.png is
   ever re-exported or re-cropped, BOTH pins must be repositioned. That is the
   cost of this approach and it is worth knowing before you swap the file.

   The pins are decoration plus a visible text label. Everything they convey is
   also in the image's alt text and in the page copy, so nothing depends on a
   sighted reading of the map. */
/* THE PIN ELEMENT IS THE DOT, and the label hangs beneath it, centred.
   It was a flex row (dot, then label beside it) with translate(-50%,-50%),
   which centred the dot-AND-label pair on the coordinate — so the dot itself
   sat well to the left of the place it was meant to mark, by half the label's
   width. Anchoring the dot directly is both correct and simpler.
   Centring the label under the dot rather than beside it also means a pin near
   the right-hand edge does not push its label out of the frame; at 375px the
   office pin has about 50px of clearance, where a right-hand label would have
   been clipped. */
.map__pin {
  position: absolute;
  transform: translate(-50%, -50%);
  width: .85rem; height: .85rem;
  border-radius: 50%;
  background: var(--navy);
  box-shadow: 0 0 0 3px var(--white), 0 1px 3px var(--shadow-pin);
  pointer-events: none;
}
.map__pin span {
  position: absolute;
  left: 50%; top: calc(100% + .4rem);
  transform: translateX(-50%);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--navy);
  background: rgba(255,255,255,.92);
  border: 1px solid var(--control);
  border-radius: var(--radius);
  padding: 2px var(--sp-3);
  white-space: nowrap;
}
/* Measured off map-office.png at its native 1435 x 943. BOTH POSITIONS WERE
   MARKED BY KADEN on the map itself and read back in pixels, rather than
   estimated from a description — the two earlier attempts were guesses and the
   parking one was wrong.
     Office  (960, 651) -> 66.9% / 69.0%  south-east of the Talbot Centre block,
             just above Fullarton Street.
     Parking (592, 287) -> 41.2% / 30.4%  the service lane running south off
             Dufferin, mid-way along the block's north edge.
   ⚠️ Tied to THIS export. Re-crop the image and both pins must be re-measured
   against it — they are percentages of the picture, not of the world. */
.map__pin--office  { left: 66.9%; top: 69.0%; }
.map__pin--parking { left: 41.2%; top: 30.4%; }

@media (forced-colors: active) {
  /* The pins sit on an image, which forced-colors leaves alone — so give the
     label a real border and ground of its own rather than relying on alpha. */
  .map__pin span { background: Canvas; color: CanvasText; border-color: CanvasText; }
  .map__pin::before { background: CanvasText; box-shadow: 0 0 0 3px Canvas; }
}
.map__note {
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin: var(--sp-4) 0 0;
}
.band--navy .map { border-color: var(--line-dark); }
.band--navy .map__note { color: var(--ink-on-dark); }
/* (A .map iframe rule lived here, squaring the frame up to 4/3 on a phone so a
   16/9 embed did not become a letterbox slot. Gone with the iframe — a static
   image keeps its own aspect ratio at every width and needs no breakpoint.) */

/* --- Callout --- */
/* BRAND ACCENT — bronze border, per the brief's own "border on a card or
   callout" example, on EVERY band, light or dark. Checked against the
   callout's own painted background in each case, not the surrounding band:
   3.37:1 against --white (the light-band callout, so a callout can sit on
   --ground-deep, where bronze itself would fail 3:1, without a problem —
   the callout's own white face is what bronze actually sits on). On a dark
   band the callout background is rgba(255,255,255,.06) over navy, which
   composites to roughly #293750 — bronze against that composited colour is
   ~3.55:1, still clear of the 3:1 non-text floor (recomputed against the
   actual painted colour, not the flat --navy value, since the overlay
   lightens the surface enough to matter at this margin). */
.callout {
  border-left: 3px solid var(--bronze); background: var(--white);
  padding: var(--sp-6); border-radius: 0 var(--radius) var(--radius) 0;
  border-top: 1px solid var(--line); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.band--navy .callout { background: rgba(255,255,255,.06); border-color: var(--line-dark); border-left-color: var(--bronze); box-shadow: none; }
.callout > :last-child { margin-bottom: 0; }
.callout h3 { margin-top: 0; }

/* --- Outbound --- */
.outbound {
  display: block; background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--sp-6); text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .15s ease, border-color .15s ease;
}
.outbound:hover { border-color: var(--accent-deco); box-shadow: var(--shadow-md); }
.outbound h3 { margin: 0 0 var(--sp-2); }
/* --step-0: card descriptions are body copy and were under the 18px floor. */
.outbound p { margin: 0; color: var(--ink-soft); font-size: var(--step-0); }
/* In a dark band the headings turn white, so the card ground must go dark
   too — otherwise it is white text on a white card. */
.band--navy .outbound { background: rgba(255,255,255,.06); border-color: var(--line-dark); box-shadow: none; }
.band--navy .outbound:hover { box-shadow: none; }
.band--navy .outbound:hover { border-color: var(--accent-bright); }
.band--navy .outbound p { color: var(--ink-on-dark); }
.ext::after { content: " \2197"; font-size: .85em; color: var(--accent); }
.band--navy .ext::after { color: var(--accent-bright); }

/* --- Link list (a plain vertical list of links, e.g. the reference block) --- */
.link-list { list-style: none; margin: 0; padding: 0; }
.link-list li { margin-bottom: var(--sp-3); }
.link-list li:last-child { margin-bottom: 0; }
.link-list a { font-weight: 600; }

/* --- Fact list --- */
.facts { margin: 0; }
.facts dt { font-size: var(--step--2); font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--accent); margin-bottom: var(--sp-2); }
.band--navy .facts dt { color: var(--accent-pale); }
.facts dd { margin: 0 0 var(--sp-6); font-size: var(--step-0); }
.facts dd:last-child { margin-bottom: 0; }

/* --- Table --- */
.table-scroll { overflow-x: auto; margin-bottom: var(--sp-6); }
.table-scroll:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.dates { width: 100%; border-collapse: collapse; }
.dates caption { text-align: left; font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; padding-bottom: var(--sp-4); }
.dates th, .dates td { text-align: left; padding: var(--sp-4) var(--sp-5) var(--sp-4) 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.dates thead th { font-family: var(--font-body); font-size: var(--step--2); letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); border-bottom: 2px solid var(--accent-deco); }
.dates td:last-child { font-weight: 700; white-space: nowrap; }
.band--navy .dates th, .band--navy .dates td { border-bottom-color: var(--line-dark); }
.band--navy .dates thead th { color: var(--accent-pale); border-bottom-color: var(--accent-bright); }

/* --- Service block (services page) --- */
.service { border-top: 2px solid var(--accent-deco); padding-top: var(--sp-6); margin-top: var(--sp-8); }
.service:first-of-type { margin-top: 0; }
.service h2 { margin-top: 0; }
.service__list { columns: 2; column-gap: var(--sp-7); }
.service__list li { break-inside: avoid; margin-bottom: var(--sp-3); }
@media (max-width: 44rem) { .service__list { columns: 1; } }
/* (.who-link lived here. It styled the three "Who handles assurance/tax/advisory
   work →" links at the foot of each service section, which pointed at the
   people directory. Removed 2026-08-10: with the directory gone the page cannot
   answer "who handles this", and the firm is routing enquiries to one admin
   address rather than to individuals. The client-type cards now link to
   Contact Us instead.) */

/* --- Page head (inner pages) --- */
.page-head { padding-block: clamp(3rem, 6vw, 5.5rem) clamp(2rem, 4vw, 3.5rem); }
.page-head h1 { margin-bottom: var(--sp-5); }
/* 56ch and --step-0, not the 52ch/--step-1 a content-band lede uses. Added
   2026-08-12 (BRIEF-v4 item 10): .page-head now sits inside .band--navy on
   every inner page, and the intro band has a 300-400px budget — not
   hero-sized. Measured on the rendered page, not eyeballed: About Us carries
   the partner's five-sentence opening statement verbatim (cannot be
   shortened, see the comment on that page) and at the old 52ch/--step-1
   sizing it wrapped to 5 lines and ran the band to 484px. Same reasoning as
   .home main .lede below — this is a full intro paragraph, not a one-line
   strapline, and the wider measure buys fewer wrapped lines without
   reopening the 86-character line width BRIEF-v3 item 10 ruled out. Still at
   the 18px floor (CLAUDE.md constraint 4), just not the larger size a
   content-band section intro gets. Brings every page's intro band to
   ~285-401px at 1440px; see HANDOFF.md for the per-page table. */
.page-head .lede { margin-bottom: 0; max-width: 56ch; font-size: var(--step-0); line-height: 1.6; }
/* Services and Client Resources have no lede — the padding-bottom above was
   sized to sit under a paragraph, so without one it reads as empty blue.
   Scoped to these two pages only; every other .page-head still carries a
   lede and keeps its tuned measurement (see HANDOFF.md's per-page table). */
.page-head--tight { padding-bottom: clamp(1rem, 2vw, 1.75rem); }


/* 8. FORMS ================================================================= */
label { display: block; font-weight: 700; font-size: var(--step--1); margin-bottom: var(--sp-2); }
input, textarea, select {
  font: inherit; width: 100%; padding: var(--sp-3);
  border: 1px solid var(--control); border-radius: var(--radius);
  background: var(--white); color: var(--ink);
}
.field { margin-bottom: var(--sp-5); }
/* --step-0: helper text under a contact detail is read, not glanced at — the
   "documents go through the client portal" line is the clearest example. */
.hint { display: block; font-size: var(--step-0); color: var(--ink-soft); font-weight: 400; line-height: 1.5; margin-top: var(--sp-2); }
.band--navy .hint { color: var(--ink-on-dark); }


/* 9. UTILITIES ============================================================= */
/* Components on this site use display:flex/grid, which would otherwise beat the
   browser default [hidden]{display:none} and leave a "hidden" element visible.
   KEPT DELIBERATELY, though BRIEF-v3 item 9 lists it as removable. The rule
   existed for the JS directory filter, which is gone, and nothing uses the
   hidden attribute today — but it is a one-line safety net against a real and
   silent failure mode, and rediscovering that failure costs far more than the
   line does.
   (It was also justified by the contact form's honeypot field. The form was
   dropped on 2026-08-11, so that reason is gone; the flex/grid one stands on
   its own and is why this is still here.) */
[hidden] { display: none !important; }
.print-head { display: none; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Keep a heading's level while changing its size — never demote a tag to
   fix appearance. */
.as-h2 { font-size: var(--step-2); }
.as-h3 { font-size: var(--step-1); }
/* Margin utilities. Suffix matches the spacing scale: .mt-7 == var(--sp-7).
   These replace one-off inline margins so spacing stays on the scale. */
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.mb-4 { margin-bottom: var(--sp-4); }
.mt-3 { margin-top: var(--sp-3); }
.mt-6 { margin-top: var(--sp-6); }
.mt-7 { margin-top: var(--sp-7); }
.mb-7 { margin-bottom: var(--sp-7); }
/* Padding, not margin: used on the last child inside a band with no padding
   of its own (band--navy alone carries none — see the chips blocks in
   services.html / client-resources.html). A trailing margin there collapses
   straight through the section's bottom edge and escapes the band's
   background entirely, landing as body-grey space OUTSIDE the navy box
   instead of navy space inside it. Padding can't collapse, so it stays put. */
.pb-8 { padding-bottom: var(--sp-8); }
/* Span every column of the parent grid. */
.span-all { grid-column: 1 / -1; }
.tel { font-weight: 700; white-space: nowrap; }
.email { font-weight: 600; }


/* 10. RESPONSIVE AND MOTION ================================================ */

/* THE 59rem BLOCK IS GONE, removed 2026-08-10 with the logo (BRIEF-v3 item 1).
   It released the header from sticky below 944px, because the ~425px logo
   pushed the nav onto a second row there and left a ~151px bar pinned to the
   top of a tablet. That is no longer true of anything. Measured after the
   removal, on services.html (the longest nav labels):

     375px  two rows, 130px header, no overflow
     640px  ONE row, 83px, 21px of slack left  <- wraps just below here
     768px  one row, 83px  (nav needs 589px against 713px available)
     1440px one row, 84px, --step-0 already at its 1.22rem cap

   So the nav holds one line all the way down to 640px, and the tablet gets its
   always-visible nav back — which is exactly what that block cost. */

@media (max-width: 40rem) {
  /* 640px is where the nav genuinely wraps to two rows, so this is where the
     sticky header stops earning its place: a 130px bar is 16% of a 375x812
     phone, pinned there for the whole visit. Same argument the deleted 59rem
     block made, now applied at the width where it is actually true.
     (Worth knowing for Pass 2: the old comment justified this with "~40% of a
     phone screen", measured against the four-item nav sitting beside the logo.
     The real figure today is 16%, so a sticky phone header is far less costly
     than it was — but that is a look-and-feel call, not a fix.) */
  .site-header { position: static; }
  html { scroll-padding-top: 1rem; }

  /* Two centred rows here; drop the dividers so none dangle at a row start (the
     link padding still keeps the titles apart). No centring rules needed any
     more — the header and nav are centred at every width now. */
  .nav li:not(:first-child) { border-left: 0; }

  .dates td:last-child { white-space: normal; }
  .dates th, .dates td { padding-right: var(--sp-3); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

@media (forced-colors: active) {
  /* (A .brand img rule lived here, turning off the logo's multiply blend so a
     forced dark palette could not erase the wordmark by multiplying it against
     black. Gone with the logo. The header carries no image at all now, so
     forced-colors needs nothing special from it.) */

  /* .person is NOT in these lists any more: as of 2026-08-11 it is not a box,
     so giving it a forced border would draw one that exists nowhere else. */
  .card, .outbound, .callout { border: 1px solid CanvasText; }
  /* Elevation carries no meaning in a forced palette and is not reliably
     stripped by the UA — the border above is what separates these. */
  .card, .outbound, .callout { box-shadow: none; }
}
