/* ============================================================
   Seed Legal Assist — house stylesheet
   Direction: warm bone ground, dark photography as framed objects,
   hairline rules, no cards, no shadows, no radius.
   Type: Newsreader (optical size axis) + Familjen Grotesk.
   ============================================================ */

/* ---------- fonts ----------
   Self-hosted from 2 Sep 2026. These used to come from fonts.googleapis.com,
   which cost every page a stylesheet from a third-party origin before a single
   glyph could even start downloading: HTML, then Google's CSS, then Google's
   woff2. Three hops, two extra DNS lookups and TLS handshakes, on a site sold
   to law firms who would rather we did not hand their visitors to Google.
   Same files, same axes, same ranges, now first-party and preloaded.

   Sourced from @fontsource-variable (the Google Fonts originals, OFL-1.1).
   Licences sit beside the woff2 files in assets/fonts/ — do not delete them,
   the OFL requires the copyright notice travels with the font.

   Both faces are VARIABLE and both axes are load-bearing:
     Newsreader        opsz 6..72, wght 300..600 (italic 300..500)
     Familjen Grotesk  wght 400..600
   The opsz axis alone is 71KB of the 122KB Newsreader file, so pinning it is
   the obvious saving and it is NOT available to us: this stylesheet sets opsz
   explicitly 22 times, from 11 on body text to 72 on the hero. Optical sizing
   is the typography here, not a nicety. Measured 2 Sep, do not re-litigate.

   unicode-range splits latin from latin-ext exactly as Google did. Nothing on
   the site needs latin-ext today, so that file is never fetched — it is here
   so a name like Zoe with a diaeresis does not silently fall back to Georgia.
   Vietnamese is dropped. Filenames carry a date because nginx on the droplet
   has no cache policy at all; replace a font, change the date.
   ---------- */

/* Newsreader — roman */
@font-face{
  font-family:"Newsreader";
  font-style:normal;
  font-weight:300 600;
  font-display:swap;
  src:url(../fonts/newsreader-latin.20260902.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;
}
@font-face{
  font-family:"Newsreader";
  font-style:normal;
  font-weight:300 600;
  font-display:swap;
  src:url(../fonts/newsreader-latin-ext.20260902.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;
}

/* Newsreader — italic. Two <em> spans on privacy.html name the Privacy Act
   1988 and the Privacy Act 2020, and Seed's own legal text will name more.
   A drawn italic, not an obliqued roman. */
@font-face{
  font-family:"Newsreader";
  font-style:italic;
  font-weight:300 500;
  font-display:swap;
  src:url(../fonts/newsreader-italic-latin.20260902.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;
}
@font-face{
  font-family:"Newsreader";
  font-style:italic;
  font-weight:300 500;
  font-display:swap;
  src:url(../fonts/newsreader-italic-latin-ext.20260902.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;
}

/* Familjen Grotesk — roman only. Nothing on the site sets the sans in italic. */
@font-face{
  font-family:"Familjen Grotesk";
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url(../fonts/familjen-grotesk-latin.20260902.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;
}
@font-face{
  font-family:"Familjen Grotesk";
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url(../fonts/familjen-grotesk-latin-ext.20260902.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;
}

/* ---------- tokens ---------- */
:root{
  /* Deliberately single-theme. This is a brand site, not a UI. */
  --paper:      #F4F1EA;   /* warm bone — the Aman register */
  --paper-sunk: #E8E2D4;   /* recessed band — deep enough to read as a band */
  --paper-deep: #14161A;   /* the one dark section */
  --ink:        #16181B;
  --ink-2:      #3F444C;
  --ink-3:      #616670;
  --ink-on-dark:#EDEAE3;
  --ink-on-dark-2:#9BA1AB;
  /* The quiet tone on dark grounds. Added 28 Aug: the dark band and the footer
     had exactly TWO tones, white for the heading and #9BA1AB for absolutely
     everything else, while the light bands have four. Nothing could be quieter
     than anything else. 5.41 on the deep ground, so it passes AA for small text
     — which the #6E747E that was written for the legal links did not (3.85). */
  --ink-on-dark-3:#868D98;
  --rule:       #D6D0C3;
  --rule-soft:  #E4DFD3;
  --rule-dark:  #2C3138;
  --blue:       #0F52C8;
  --blue-deep:  #0B3877;
  --blue-light: #2A9BE0;

  --nav-h: 75px;          /* masthead height incl. hairline; it sits in flow */
  --gutter: clamp(20px, 5vw, 76px);
  --measure: 34em;
  --list-w: 1120px;   /* services: rail + list, and the hero above them */

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- reset-ish ---------- */
*,*::before,*::after{box-sizing:border-box;}
html{
  font-size: clamp(1em, 0.95em + 0.25vi, 1.2em);
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:"Newsreader",Georgia,"Times New Roman",serif;
  font-variation-settings:"opsz" 11;
  font-size:1.02rem;
  line-height:1.58;
  text-wrap:pretty;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
img{max-width:100%;height:auto;display:block;}
svg{flex:none;max-width:100%;}
a{color:inherit;}

/* ---------- type roles ---------- */
.u-label{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.66rem;
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ink-3);
  font-variation-settings:normal;
}
/* Ticket 0008, "add a little bit of the blue colour somewhere throughout the
   website". Put on the section numbers rather than sprinkled: the site already
   uses blue for numerals — the 01-39 down Services, the clause numbers on the
   legal pages, the count in the discipline rails — so the section numbers were
   the one numeral series still in grey. This makes the rule consistent instead
   of adding a new place blue appears, and it lands on every numbered section of
   Home, About and Contact. The label text stays grey; only the number changes,
   so the amount of blue on any one screen is a few characters. */
.u-label__n{color:var(--blue);}
.band--dark .u-label__n{color:var(--ink-on-dark-2);}
.u-num{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-variant-numeric:tabular-nums;
  font-size:.7rem;
  letter-spacing:.08em;
  color:var(--blue-deep);
}

h1,h2,h3,h4{
  font-weight:400;
  text-wrap:balance;
  margin:0;
}
h1{
  font-variation-settings:"opsz" 72;
  font-size:clamp(2.9rem, 1.6rem + 5.4vi, 6.1rem);
  line-height:1.0;
  letter-spacing:-.025em;
}
h2{
  font-variation-settings:"opsz" 60;
  font-size:clamp(1.9rem, 1.25rem + 2.4vi, 3.2rem);
  line-height:1.13;
  letter-spacing:-.018em;
}
h3{
  font-variation-settings:"opsz" 24;
  font-size:1.42rem;
  line-height:1.24;
  letter-spacing:-.01em;
}
p{margin:0 0 1.05em;}
p:last-child{margin-bottom:0;}
.lede{
  font-size:1.2rem;
  line-height:1.5;
  font-variation-settings:"opsz" 18;
  color:var(--ink-2);
}
.measure{max-width:var(--measure);}
em{font-style:italic;}

/* ---------- layout ---------- */
.shell{
  width:100%;
  max-width:1500px;
  margin-inline:auto;
  padding-inline:var(--gutter);
}
/* Adjacent bands stack their padding, so the max here is half the gap
   you actually see between two sections. The tone change already marks
   the boundary; 264px of empty paper on top of it reads as a hole. */
.band{padding-block:clamp(52px,6.4vw,96px);}
.band--sunk{background:var(--paper-sunk);}
.band--dark{background:var(--paper-deep);color:var(--ink-on-dark);}
.hr{border:0;border-top:1px solid var(--rule);margin:0;}

/* ---------- masthead ---------- */
.masthead{
  position:sticky;top:0;z-index:50;
  /* Opaque, always. An earlier pass caught the same fault at 88% — a headline
     ghosting through the wordmark — and set this to opaque, then handed the
     translucency back via a scroll timeline further down the file. That
     animation is now gone; see the note where it used to live. */
  background:var(--paper);
  border-bottom:1px solid var(--rule-soft);
}
.masthead__in{
  display:flex;align-items:center;gap:clamp(18px,4vw,54px);
  min-height:74px;
}
.brand{display:flex;align-items:center;text-decoration:none;flex:none;}
/* Ticket 0001, 1 Sep. This is now Tim's own artwork rather than our rebuild of
   it — `seed Legal.svg` from the pack he supplied, used whole and unmodified.
   Everything the 27 Aug correction worked out by measuring the vehicle wrap
   turns out to be right in the official file: one weight and one colour across
   seedLegal, ASSIST small and left-aligned under the wordmark rather than
   stretched to its full width. Two things we did not have: the mark carries a
   blue gradient, not a flat fill, and ASSIST is blue rather than grey.
   Sized by height so the file's own 4.3:1 proportions are never distorted. */
.brand__mark{display:block;height:40px;width:auto;flex:none;}
.nav{display:flex;gap:clamp(16px,2.4vw,34px);margin-left:auto;align-items:center;}
.nav a{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.79rem;letter-spacing:.02em;text-decoration:none;
  color:var(--ink-2);position:relative;
}
/* Scoped away from the call button on purpose. `.nav a` is (0,1,1) and
   `.nav__call` is (0,1,0), so this padding was overriding the button's own
   shorthand on every screen size — the phone number has been sitting in a
   34px box since the first build instead of the 39px it was written to be. */
.nav > a:not(.nav__call){padding-block:6px;}
.nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--ink);transform:scaleX(0);transform-origin:left;
  transition:transform .34s var(--ease);
}
.nav a:focus-visible::after{transform:scaleX(1);}
/* The page you are on had no visual mark in the desktop nav at all. It was
   styled in the mobile menu panel (.menu__panel a[aria-current]) and nowhere
   else, so a screen reader was told which page it was on and a sighted visitor
   was not, on a seven page site. Reuses the underline the nav already animates
   in on hover rather than inventing a second device. (0,2,1) so it holds
   against .nav a::after, and .nav__call is unaffected because its ::after is
   display:none. 28 Aug. */
.nav a[aria-current="page"]::after{transform:scaleX(1);}
@media (hover:hover){ .nav a:hover::after{transform:scaleX(1);} }
/* Outline, filling solid on hover. Was solid blue from 27 Aug; both numbers
   went to outline on 3 Sep, option D of four Van put to the channel.

   Why outline rather than two solid blocks. Once NZ joined AU in the bar
   there were two of these, and two filled rectangles put roughly 310px of
   saturated blue in a bone masthead, heavier than anything else above the
   fold and competing with the logo, which is the only other blue object up
   there. Two identical solid blocks also read as a toolbar rather than as a
   phone number. Outline keeps the two numbers equal, which matters on a site
   whose own stat line is "both sides of the Tasman", and leaves the masthead
   built from hairlines like the rest of the page. Prominence does not suffer:
   the bar holds a wordmark, four small links and these, so there is nothing
   for them to get lost behind. Contrast measured at 6.0:1 for blue on paper,
   above AA at this size.

   Written as .nav a.nav__call rather than .nav__call because .nav a is
   (0,1,1) and would otherwise win on colour. That exact collision put this
   button in a 34px box from the first build until 24 Aug. */
.nav a.nav__call{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.79rem;text-decoration:none;
  background:transparent;color:var(--blue);
  border:1px solid var(--blue);padding:9px 17px;
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease);
}
.nav a.nav__call:focus-visible{
  background:var(--blue);color:#fff;border-color:var(--blue);
}
@media (hover:hover){
  .nav a.nav__call:hover{background:var(--blue);color:#fff;border-color:var(--blue);}
}
.nav a.nav__call::after{display:none;}

/* The NZ number in the masthead, 3 Sep (Van's revision 2).
   The country codes are the point, not decoration: two bare numbers next to
   each other tell a visitor nothing about which one to ring, and this site
   sells into two countries. They are set slightly smaller and quieter so the
   number still reads as the object and the code as its label.

   Both buttons carry the same outline treatment as of 3 Sep, so nothing here
   overrides colour any more. The earlier version made AU solid and NZ outline,
   which quietly said AU was the real number and NZ the spare. See the note on
   .nav a.nav__call above for why they are equal now.

   --nz survives as a hook for the width rule below and nothing else. Do not
   add colour to it: `.nav a.nav__call` is (0,2,1) and so is
   `.nav a.nav__call--nz`, so whichever is written last wins, and that is a
   trap rather than a rule. */
.nav__cc{
  font-size:.86em;letter-spacing:.08em;opacity:.72;
  margin-right:7px;
}
/* Below 900 the bar is brand + four links + two buttons and the links start
   colliding with the buttons. NZ drops out of the BAR only — it is still one
   tap away in the menu panel below 720, and on Contact both numbers are set
   at full size. Measured at 1440, 1280, 1024, 960, 900, 860, 768, 390 and 320. */
@media (max-width:900px){
  .nav a.nav__call--nz{display:none;}
}
/* Both numbers in the mobile menu panel, so nothing is lost when the NZ button
   leaves the bar. The panel is only rendered under 720px; above that .menu is
   display:none, so these never appear on a desktop. */
.menu__panel .menu__call{color:var(--blue-deep);}
/* Mobile nav lives in the disclosure below — see MOBILE at the end of this
   sheet. This rule used to simply hide Services, About and Contact under
   720px, which left a seven page site with no way to navigate on a phone
   except by scrolling to the footer. */

/* ---------- hero ----------
   The hero owns the first screen. On any viewport tall enough to hold it,
   the whole composition — eyebrow, headline, aside, image, meta rule —
   resolves above the fold, and the image takes whatever height is left
   rather than pushing the closing rule off-screen. Short screens and
   mobile fall back to natural flow.                                     */
.hero{padding-block:clamp(44px,8vw,104px) 0;}
.hero__eyebrow{display:block;margin-bottom:clamp(26px,4vw,52px);}
.hero__frame{overflow:hidden;}
/* Ticket 0009: the hero is a video now. It behaves exactly as the still did —
   the frame owns the ratio, the media fills it and crops from the centre — so
   `video` gets the same treatment as `img` wherever the hero rules run. The
   nested <img> inside <video> is the fallback for a browser that can play
   neither source. */
.hero__video{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 50%;background:var(--sunk);}
.hero__video img{width:100%;height:100%;object-fit:cover;object-position:50% 50%;}

.hero__head{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:clamp(26px,4vw,48px);
  /* Was `end`. Bottom-aligning the two columns lined the H1's baseline up with
     the button row, which sounds right and measured wrong: the right column is
     307px tall and the H1 only 189, so the H1 was pushed 118px DOWN and the
     eyebrow ended up 143px above the headline it labels, with the standfirst
     starting 107px ABOVE the H1. On a site whose whole structure is "a small
     label, then the big name", the hero was the one place that broke it.
     Every other page hero (.phero__head) already uses start. 28 Aug. */
  align-items:start;
}
@media (min-width:960px){
  /* 1.9/.95 gave the standfirst a 416px column, which wrapped it to FOUR lines
     and made the right column 307px tall against the H1's 189. That height is
     what pushes the photograph down the page. Widening the column to 1.05
     drops the standfirst to three lines, takes 51px off the hero head and
     lifts the picture 50px up the first screen, and the headline still sets on
     two lines at every width from 900 up. Free, measured at 1440 and 1920. */
  .hero__head{grid-template-columns:minmax(0,1.72fr) minmax(0,1.05fr);}
}
.hero h1{font-size:clamp(2.7rem, 1.5rem + 4.6vi, 5.35rem);}
.hero h1 .l{display:block;white-space:nowrap;}
.hero h1 .l--2{padding-left:clamp(0px,5vw,86px);}
@media (max-width:520px){
  .hero h1 .l{white-space:normal;}
  .hero h1 .l--2{padding-left:0;}
}

/* The fit-to-screen hero only engages where the leftover height can still
   hold the photograph. Measured: at 1300x748 the frame was resolving to
   5.06:1 and showing 30% of the team shot — the back row and the tops of
   the front row's heads, cut at the chin. At 1440x900 it was 3.55:1 and
   42%. A two-row group photo needs about 2.2:1 to keep the logo wall and
   all six faces intact, and that only comes free above ~1250px of viewport
   height. Below that the photograph wins and the meta rule goes below the
   fold, which is what the scroll cue is for. */
@media (min-width:900px) and (min-height:1250px){
  .hero{
    min-height:calc(100svh - var(--nav-h));
    max-height:calc(100svh - var(--nav-h));
    display:flex;
    padding-block:clamp(26px,4.2vh,58px) clamp(16px,2.4vh,30px);
  }
  .hero > .shell{
    display:flex;flex-direction:column;
    flex:1;min-height:0;width:100%;
  }
  .hero__eyebrow{margin-bottom:clamp(16px,3.2vh,42px);}
  .hero h1{font-size:min(clamp(2.7rem,1.5rem + 4.6vi,5.35rem), 12.4vh);}
  .hero__figure{
    flex:1 1 0;min-height:0;
    display:flex;flex-direction:column;
    margin-top:clamp(22px,3.6vh,54px);
  }
  .hero__frame{flex:1 1 0;min-height:150px;}
  /* Art direction. The four height-stepped object-positions that used to live
     here (32/24/17%) existed to keep six faces and a logo wall intact in the
     team photograph. That photograph is gone, and a facade has no such
     constraint — it is legible from any horizontal band of itself. Centre, and
     let the crop fall where it falls. Restore the stepped values if a hero with
     people in it ever comes back. */
  .hero__frame img,.hero__frame video{width:100%;height:100%;object-fit:cover;object-position:50% 50%;}
  .hero .metarule{margin-top:auto;padding-top:14px;}
}
/* Laptop and standard desktop. Not height-constrained: the frame carries an
   explicit ratio instead of taking whatever is left over. 2.2:1 puts the crop
   window at roughly 4%-72% of the source, which holds the seedLegal wall, the
   full back row and the seated row down to the chest. */
@media (min-width:900px) and (max-height:1249px){
  .hero{padding-block:clamp(30px,4.2vh,60px) 0;}
  .hero__eyebrow{margin-bottom:clamp(18px,3vh,40px);}
  .hero__figure{margin-top:clamp(28px,4vh,56px);}
  /* 2.2:1 at 13% put the visible window at 4.1% to 72.3% of the source, which
     clipped the top of the wall logo. Tim will notice his own logo cut.
     1.95:1 at 2% opens the window to roughly 0.5% to 77%, so the logo sits
     whole with a sliver of headroom. Measured, not eyeballed. */
  .hero__frame{aspect-ratio:1.95/1;}
  /* Tried and REVERTED on 28 Aug, recorded so nobody tries it again. At
     1440x900 only 346px of the 665px frame is above the fold, so the wet
     street and the car sit below it. Widening the frame to 2.35:1 and pushing
     the crop down does not fix that: the visible band is the TOP of the frame
     either way, and the car lives at 70-88% of the source. The arithmetic says
     no aspect ratio gets it above a 900px fold while the hero head takes 554px.
     What it DID do was re-crop a photograph Tim has specifically said he likes.
     Not worth it. If the whole picture has to be on the first screen, the hero
     head has to give up height, not the picture. */
  /* Was 2% to save the top of the wall logo in the team photograph. The source
     is 1.49:1 and the frame is 1.95:1, so a centred window shows 12% to 88% of
     it, which holds the whole facade and the car. */
  .hero__frame img,.hero__frame video{width:100%;height:100%;object-fit:cover;object-position:50% 50%;}
}

.hero__aside{padding-bottom:.6rem;}
.hero__aside p{
  font-size:1.06rem;line-height:1.52;color:var(--ink-2);
  border-left:1px solid var(--rule);padding-left:20px;max-width:31em;
}
.hero__actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:26px;}

/* ---------- buttons ---------- */
.btn{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.82rem;letter-spacing:.01em;text-decoration:none;
  display:inline-flex;align-items:center;gap:10px;
  padding:13px 24px;border:1px solid var(--ink);color:var(--paper);
  background:var(--ink);
  transition:background .32s var(--ease),border-color .32s var(--ease),color .32s var(--ease);
}
.btn:focus-visible{background:var(--blue-deep);border-color:var(--blue-deep);}
@media (hover:hover){ .btn:hover{background:var(--blue-deep);border-color:var(--blue-deep);} }
.btn--ghost{background:transparent;color:var(--ink);}
.btn--ghost:focus-visible{background:var(--ink);color:var(--paper);border-color:var(--ink);}
@media (hover:hover){ .btn--ghost:hover{background:var(--ink);color:var(--paper);border-color:var(--ink);} }
.btn--light{background:var(--ink-on-dark);border-color:var(--ink-on-dark);color:var(--paper-deep);}
.btn--light:focus-visible{background:#fff;border-color:#fff;color:var(--paper-deep);}
@media (hover:hover){ .btn--light:hover{background:#fff;border-color:#fff;color:var(--paper-deep);} }
.btn__arrow{transition:transform .32s var(--ease);}
@media (hover:hover){ .btn:hover .btn__arrow{transform:translateX(4px);} }

/* ---------- figures (the framed-object treatment) ---------- */
.figure{margin:0;}
.figure img{width:100%;}
.figure figcaption{
  display:flex;gap:14px;align-items:baseline;
  margin-top:12px;
}
.hero__figure{margin-top:clamp(38px,6vw,72px);}

/* ---------- meta rule ---------- */
/* The three figures. Reworked 27 Aug on Tommy's note that the 2014 line did
   not read well and the section cut needed more space.

   It was a single cramped row of number-then-fragment, so the eye read "2014"
   and then had to travel back to assemble "answering since 2014". Now the
   label sits above the figure, which is the site's own signature everywhere
   else: a small label, then the thing itself. The figure also gets a real
   size, because at .7rem it was not a figure, it was another label. */
.metarule{
  display:flex;flex-wrap:wrap;gap:clamp(26px,5vw,72px);
  border-top:1px solid var(--rule);
  padding-top:clamp(20px,2.4vw,30px);
  padding-bottom:clamp(30px,4.4vw,58px);
  margin-top:clamp(46px,6vw,86px);
  align-items:flex-end;
}
.metarule div{display:flex;flex-direction:column;gap:7px;align-items:flex-start;}
/* Three figures under a hairline that runs the full 1296px column, with the
   content stopping at 826. That is 542px of dead paper at 1440, 588 at 1517,
   581 at 1920 — the same fault fixed in four other places on 27 Aug, and this
   was the fifth. It hid because the scroll cue carried `margin-left:auto` and
   sat at the far right, so the rule LOOKED like it had content at both ends.
   Take the cue away and the hole is exposed. It was always there.
   Equal thirds rather than space-between, because Contact's steps and
   assurances rows already use repeat(3,minmax(0,1fr)) and this is the same
   shape of thing. 28 Aug. */
@media (min-width:860px){
  .metarule{
    display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr));
    align-items:end;
  }
}
/* `order:-1` used to pull the label above the figure, which meant the DOM said
   "2014, Answering since" while the screen said "Answering since, 2014". Two
   different reading orders for the same content: WCAG 1.3.2, and it copied out
   as "2014Answering since". Alex, 28 Aug. The markup now carries the real order
   and the CSS does not need to lie about it. */
.metarule .u-num{
  font-family:"Newsreader",Georgia,serif;
  font-size:clamp(1.2rem,.95rem + .75vw,1.6rem);
  font-weight:300;letter-spacing:-.012em;line-height:1;
  font-variation-settings:"opsz" 24;
}
/* The scroll cue is gone, markup and all. It lived inside .metarule, and the
   metarule starts at y=1290 on a 900px-tall laptop, so the one element whose
   entire job is to be seen BEFORE you scroll could only be seen AFTER you had.
   The old comment in this file claimed the metarule falling below the fold was
   "what the scroll cue is for", which cannot be true when the cue is inside it.
   Nothing replaces it: the photograph already runs past the fold on every
   laptop, which says "there is more" without an animated arrow. 28 Aug. */

/* ---------- systems band ---------- */
.systems{display:grid;gap:clamp(28px,5vw,72px);align-items:start;}
@media (min-width:900px){
  .systems{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);}
}
/* The section label spans both columns and leads the section, which is what 02
   and 04 already do. Superseded a 9px optical nudge that lined the label up
   with the heading beside it: that fix was real but it was propping up an
   arrangement that read wrong on a phone. */
.systems__label{grid-column:1 / -1;margin-bottom:clamp(18px,2vw,26px);}
/* Stacked, the heading column has to come first. Otherwise a phone reader gets
   the LEAP/Xero table and five line items before the heading that frames them. */
@media (max-width:899px){
  /* order:-1 alone put the heading above the LABEL as well, which stranded
     "01 We work in your systems" between the fine print and the table it
     belongs to. The label needs to outrank it. */
  .systems__label{order:-2;}
  .systems > div:last-of-type{order:-1;margin-bottom:clamp(26px,5vw,40px);}
}
/* Removed 1 Sep, reported by Van as "this line drags along with scrolling".
   It was a regression of mine. This rule was written when the left column was
   the first child, and it made that column follow the scroll. On 28 Aug the
   section label was promoted to a grid child spanning both columns to fix the
   mobile order — which made the LABEL the first child, so the sticky landed on
   "01 · We work in your systems" instead. A section label that detaches and
   trails down the page past the section it names is worse than no sticky at
   all, and nobody had asked for the original behaviour either. Gone, not
   re-pointed at the column. The print override below is kept: harmless, and it
   documents that this used to stick. */
.stack{border-top:1px solid var(--ink);margin-top:26px;}
.stack__row{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:20px;padding-block:15px;border-bottom:1px solid var(--rule);
}
.stack__name{
  font-family:"Newsreader",Georgia,serif;
  font-variation-settings:"opsz" 40;
  font-size:2rem;line-height:1;letter-spacing:-.02em;
}
.stack__what{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.78rem;color:var(--ink-3);text-align:right;
}
.stack__lead{display:block;margin:30px 0 0;}
.drives{list-style:none;margin:12px 0 0;padding:0;border-top:1px solid var(--rule);}
.drives li{
  font-size:.95rem;color:var(--ink-2);
  padding-block:9px;border-bottom:1px solid var(--rule-soft);
}
.pendingnote{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.7rem;line-height:1.6;color:var(--ink-3);
  margin-top:22px;max-width:30em;
  padding-left:12px;border-left:1px solid var(--rule);
}

/* ---------- service index ----------
   Reused verbatim on the services page at 39 rows, so it has to hold up
   at length: baseline-aligned columns, one affordance per row, no card. */
.index{border-top:1px solid var(--ink);margin-top:clamp(30px,5vw,60px);}
.index__row{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:12px;
  padding-block:clamp(26px,3.4vw,44px);
  border-bottom:1px solid var(--rule);
  transition:background .4s var(--ease);
}
@media (max-width:859px){
  .index__n{grid-row:1;justify-self:start;}
  .index__count{grid-row:1;justify-self:end;}
  .index__title{grid-row:2;}
  .index__blurb{grid-row:3;}
  .index__arrow{display:none;}
}
@media (min-width:860px){
  /* Four children, five tracks: the count was landing at the START of a 1.3fr
     track, so every row died at about 47% under a rule that ran to 100%. That
     reads as a hole, not as space. Four tracks now, and the count is pushed to
     the end of the row, which is the same device the services contents list
     already uses. Reason it was wrong: .78fr for the blurb and 1.3fr for a
     two-word count had the weights the wrong way round. */
  .index__row{
    /* Javonte, 28 Aug: "it doesn't look aligned". It wasn't. Each row is its
       OWN grid, so `auto` sized the first track to that row's own title and the
       blurb started somewhere different on every line: at 1440 it began at 367,
       281, 243 and 282 — four positions spread over 124px, under one rule.
       The count column was doing it too, `auto` giving 96.3px on the two-digit
       rows and 86.9px on the one-digit rows.
       Fixed tracks so the four rows agree. Not fr: the titles are almost the
       same width at every viewport while the container is not, so a proportion
       drifts. These clamps are measured to hold the longest title, "Remote
       Practice Support", without wrapping from 900 to 2560. If a discipline is
       ever renamed to something longer, re-measure. */
    grid-template-columns:clamp(258px,21vw,300px) minmax(0,1fr) clamp(96px,7.5vw,108px) auto;
    gap:clamp(16px,2.4vw,34px);
    align-items:baseline;      /* real alignment, not padding guesswork */
  }
  .index__row .index__count{justify-self:end;}
}
@media (hover:hover){ .index__row:hover{background:color-mix(in srgb, var(--rule-soft) 50%, transparent);} }
.index__row:has(.index__link:focus-visible){background:color-mix(in srgb, var(--rule-soft) 50%, transparent);}

.index__title{margin:0;}
.index__link{text-decoration:none;color:inherit;}
/* the whole row is the target; the link keeps the short accessible name */
.index__link::after{content:"";position:absolute;inset:0;}
.index__link:focus-visible{outline:none;}
.index__row:has(.index__link:focus-visible){outline:2px solid var(--blue);outline-offset:2px;}

.index__blurb{color:var(--ink-2);font-size:.99rem;max-width:38em;margin:0;}
.index__count{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.index__arrow{
  color:var(--ink-3);
  opacity:0;transform:translateX(-6px);
  transition:opacity .3s var(--ease),transform .3s var(--ease);
}
.index__row:hover .index__arrow,
.index__row:has(.index__link:focus-visible) .index__arrow{opacity:1;transform:translateX(0);}
@media (hover:none){ .index__arrow{opacity:1;transform:none;} }

/* ---------- split ---------- */
/* Was align-items:center, which floated the photograph in the middle of the
   text column's height instead of anchoring it. Measured at 1440: on Home 03
   the figure sat 131px below the body's top and 131px above its bottom; on
   About 01 it was 44 and 44; and on Contact the relationship INVERTED, because
   there the picture is taller than the text so the text floated instead.
   Three uses of one component, three different vertical relationships, on a
   site whose whole grammar is aligned tops and hairlines. Top-aligned, the
   image's top edge lands on the section label and the column difference falls
   at the bottom, where it reads as two columns of unequal length rather than
   as something adrift. 28 Aug. */
.split{display:grid;gap:clamp(30px,5vw,74px);align-items:start;}
/* Two columns from 1120, not 900. Between those two widths the columns were
   383–476px, which is not enough for a 60px display headline beside a
   photograph: About 01 went back to three ragged lines and carried 243px of
   dead paper under the image at 900. Stacked, the same section sets its
   headline in one line across the full width. Measured at eleven widths. */
@media (min-width:1120px){
  .split{grid-template-columns:repeat(2,minmax(0,1fr));}
  /* `.split--wide-left` (1.25fr / 1fr) is gone. It gave the photograph the wider
     column and the 60px headline the narrower one, which is backwards: on About
     01 it forced "Firms kept asking for the other ninety per cent." into three
     ragged lines — long, short, long — where equal columns set it in two.
     Measured across all three splits before removing it: About loses a line and
     27px of dead paper, Contact loses 9px, Home gains 10px. Nothing on the site
     was relying on the asymmetry; it was a ratio that existed rather than one
     that was earned. Class removed from the markup too. */
}
.split__body h2{margin-bottom:22px;}

/* ---------- statement ----------
   Deliberately NOT styled as a pull quote. It is our own assertion, not
   something anyone said, and an unattributed italic quote on a page for
   lawyers reads as a testimonial we forgot to credit. Roman, large, with
   a rule above it, so it reads as a claim the site is making. */
/* The hairline belongs to the column, the measure belongs to the text. Keeping
   both on one element tied the rule to a 19em box, which at 1440 stopped 336px
   short of the content beneath it. */
.statement__rule{
  margin-top:22px;
  padding-top:26px;
  border-top:1px solid var(--ink);
}
.statement{
  font-variation-settings:"opsz" 60;
  font-size:clamp(1.75rem, 1.05rem + 2.4vi, 3rem);
  line-height:1.16;
  letter-spacing:-.018em;
  max-width:19em;
  margin:0;
  text-wrap:balance;
}
/* Image offset right; the caption lives in the left margin beside it
   rather than under it, so the void is doing work instead of sitting empty. */
.statement__figure{margin-top:clamp(38px,5vw,72px);}
@media (min-width:900px){
  .statement__figure{
    display:grid;
    grid-template-columns:minmax(0,1fr) 62%;
    column-gap:clamp(24px,3vw,48px);
    align-items:start;
  }
  .statement__figure img{grid-column:2;}
  .statement__figure figcaption{
    grid-column:1;grid-row:1;
    flex-direction:column;align-items:flex-end;
    text-align:right;gap:6px;margin-top:4px;
  }
}

/* ---------- dark CTA ---------- */
/* The section label is the quietest thing on a dark band, not the same weight
   as the body copy beside it. */
.band--dark .u-label{color:var(--ink-on-dark-3);}
.band--dark .hr{border-color:var(--rule-dark);}
.cta{display:grid;gap:clamp(26px,4vw,60px);}
@media (min-width:900px){.cta{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);align-items:end;}}
.cta h2{color:var(--ink-on-dark);}
/* About's CTA headline is two sentences, and `balance` split the first one
   across lines: "You have read who we / are. The next bit is what". `pretty`
   keeps the sentence whole. It is scoped to this one heading because applied
   to every .cta h2 it made Home's four-word-per-line balance lopsided. The
   hyphenated number is protected separately with .nb — without that, `pretty`
   broke "thirty-/nine" on Services. */
.cta__h2--pretty{text-wrap:pretty;}
.cta__lines{display:flex;flex-direction:column;gap:2px;}
.cta__line{
  display:flex;justify-content:space-between;gap:24px;align-items:baseline;
  border-bottom:1px solid var(--rule-dark);padding-block:15px;
  text-decoration:none;color:var(--ink-on-dark);
  transition:padding-left .34s var(--ease),border-color .34s var(--ease);
}
.cta__line:focus-visible{padding-left:10px;border-color:var(--ink-on-dark-2);}
@media (hover:hover){ .cta__line:hover{padding-left:10px;border-color:var(--ink-on-dark-2);} }
.cta__line b{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-weight:400;font-size:1.02rem;font-variant-numeric:tabular-nums;
}

/* ---------- footer ---------- */
/* The CTA band and the footer are the same ink, so without this rule they
   read as one undifferentiated black slab. */
.foot{
  background:var(--paper-deep);color:var(--ink-on-dark-2);
  padding-block:36px 54px;
  border-top:1px solid var(--rule-dark);
}
.foot__cols{display:flex;flex-wrap:wrap;gap:14px 40px;}
/* SPECIFICITY, FIFTH TIME ON THIS BUILD. This rule is (0,1,1) and so is the
   `.foot a` rule below it, so `.foot a` won on source order and the legal links
   rendered in the SAME grey as everything else — the dimmer treatment never
   applied, and the hover below it changed the colour to the one it already was.
   `.foot .foot__links--legal a` is (0,2,1) and holds.
   The colour has changed too: #6E747E measures 3.85 against the deep ground and
   fails AA for small text, so the rule was broken and would have been wrong if
   it had worked. Before writing an override, grep for the base selector. */
.foot .foot__links--legal a{color:var(--ink-on-dark-3);}
/* Two separate statements — what we do and do not do, then who the entity is —
   were joined by a <br>, which gives no separation at all, so they read as one
   run-on block of grey. */
.foot__fine--2{margin-top:.9em;}
/* .foot__in is a two-child flex row. Splitting the fine print into two
   paragraphs gave it a THIRD child, which wrapped onto its own line and put the
   entity statement under the links on the left. Caught in the render, not on
   the page. The two paragraphs live in one block so the row still has two
   children. */
.foot__legal{max-width:46em;}
@media (hover:hover){ .foot .foot__links--legal a:hover{color:var(--ink-on-dark-2);} }
.foot__in{display:flex;flex-wrap:wrap;gap:26px;justify-content:space-between;align-items:flex-start;}
.foot a{color:var(--ink-on-dark-2);text-decoration:none;font-family:"Familjen Grotesk",system-ui,sans-serif;font-size:.78rem;}
@media (hover:hover){ .foot a:hover{color:var(--ink-on-dark);} }
.foot__links{display:flex;gap:22px;flex-wrap:wrap;}
.foot__fine{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.68rem;line-height:1.7;color:#808690;max-width:38em;
}
/* The parent company link moved out of the footer nav, where it was a bare
   "Seed" sitting among four internal page links and quietly left the site, and
   onto the entity sentence that explains what Seed is. It has to be written at
   (0,2,1): `.foot a` is (0,1,1) and sets font-size .78rem, which would render
   this link LARGER than the .68rem fine print around it. Sixth time specificity
   has bitten on this build — grep the base selector before writing an override. */
.foot .foot__fine a{
  font-size:inherit;color:var(--ink-on-dark-2);
  text-decoration:underline;text-decoration-thickness:1px;
  text-decoration-color:var(--rule-dark);text-underline-offset:3px;
  transition:color .3s var(--ease),text-decoration-color .3s var(--ease);
}
.foot .foot__fine a:focus-visible{color:var(--ink-on-dark);text-decoration-color:currentColor;}
@media (hover:hover){
  .foot .foot__fine a:hover{color:var(--ink-on-dark);text-decoration-color:currentColor;}
}

/* The `masthead-settle` scroll animation was removed on 1 Sep. It ramped the
   bar from 72% paper to opaque over the first 140px, on the stated premise
   that "nothing large ever passes under a see-through bar". Measured at
   1512x860, that premise is false. Content enters the 75px bar at y=30 and
   the range does not close until y=140, so for about 110 of those 140px
   something is underneath it:

     y=40   eyebrow under the bar at 80% alpha
     y=80   eyebrow at 88%
     y=100  eyebrow AND the 82px "We drive LEAP." headline at 92%
     y=120  the headline at 96%

   Reported by Javonte from a screenshot: the eyebrow line sliced in half with
   a smear beside the wordmark. There is no scroll position where the bar can
   be translucent and empty — at y=0, the only moment nothing is behind it,
   translucency renders identically to opaque. The effect was invisible when
   it was safe and a defect whenever it showed.

   `backdrop-filter` went with it. It ran at every scroll position including
   fully opaque, where it blurs nothing and still costs a compositing pass —
   and while the bar was translucent it turned a faint ghost into a smear,
   which is what made it read as a rendering fault rather than as frost.

   An opaque bar with a hairline is also simply the house language: this site
   has no gradients, no shadows and no radius anywhere else. */

/* ---------- focus ---------- */
:focus-visible{outline:2px solid var(--blue);outline-offset:3px;}

/* ---------- motion: opt-in, never the default state ---------- */
.rv{opacity:1;transform:none;}

@media (prefers-reduced-motion: no-preference){
  @keyframes rv-in{
    from{opacity:0;transform:translateY(16px);}
    to  {opacity:1;transform:translateY(0);}
  }
  @supports (animation-timeline: view()){
    .rv{
      animation:rv-in .8s var(--ease) both;
      animation-timeline:view();
      animation-range:entry 4% cover 26%;
    }
  }
  /* hero runs on load, not on scroll */
  .hero .rv{animation:rv-in .95s var(--ease) both;animation-timeline:auto;animation-range:normal;}
  .hero .rv-1{animation-delay:.05s;}
  .hero .rv-2{animation-delay:.14s;}
  .hero .rv-3{animation-delay:.23s;}
  .hero .rv-4{animation-delay:.34s;}
  .hero .rv-5{animation-delay:.46s;}
}

/* page transitions when the other pages land */
@view-transition{navigation:auto;}
@media (prefers-reduced-motion: reduce){
  @view-transition{navigation:none;}
  html{scroll-behavior:auto;}
}
::view-transition-old(root){animation:120ms ease-out both fade-out;}
::view-transition-new(root){animation:280ms var(--ease) both fade-in;}
@keyframes fade-out{to{opacity:0;}}
@keyframes fade-in{from{opacity:0;}}

/* ============================================================
   SERVICES PAGE
   ============================================================ */

/* ---------- page hero (smaller sibling of the homepage hero) ---------- */
.phero{padding-block:clamp(40px,5vw,68px) clamp(20px,2.4vw,32px);}
.phero__head{display:grid;gap:clamp(24px,3.4vw,52px);margin-top:clamp(18px,2.2vw,30px);align-items:start;}
/* One measure for the whole page: headline block, contents table, and the
   discipline rails below all hang off the same two edges. */
/* --list-w is the SERVICES page column: the rail plus the list, and the hero
   above them. It was being applied to every .phero__head, so on About and
   Contact the hero stopped at 1192 while every band beneath it ran to 1368 —
   the page's own top 176px narrower than the rest of it, at 1440 and 1920
   alike. Measured on 28 Aug across all four pages. Scoped to the page that
   actually has discipline columns to line up with. */
.phero__head{max-width:none;}
body:has(.disc) .phero__head{max-width:var(--list-w);}
@media (min-width:960px){
  .phero__head{grid-template-columns:minmax(0,1.28fr) minmax(0,1fr);}
}
.phero h1{
  font-variation-settings:"opsz" 72;
  font-size:clamp(2.3rem,1.4rem + 3.1vi,3.9rem);
  line-height:1.02;letter-spacing:-.025em;
}
/* The standfirst used to sit in the right column beside the headline, which
   left the headline's own column empty underneath it — a third of the first
   screen holding nothing. Under the headline it fills that, and the right
   column becomes one thing (the contents) instead of two. */
.phero__stand{
  font-size:1.1rem;line-height:1.55;color:var(--ink-2);
  font-variation-settings:"opsz" 18;
  max-width:30em;margin-top:clamp(20px,2.4vw,30px);
}
.phero__aside > .u-label{display:block;margin-bottom:14px;}

/* ---------- discipline jump nav ---------- */
/* Sits in the hero's right column, under the standfirst. Below the
   headline it cost 178px of vertical space and pushed the list — the whole
   point of the page — off the first screen. */
.jump{
  display:flex;flex-direction:column;
  border-top:1px solid var(--ink);
  margin-top:0;
}
/* Stacked, not inline: "Remote Practice Support" wraps beside its count
   and drags every other cell taller with it. */
.jump__item{
  display:flex;align-items:baseline;gap:14px;
  padding:8px 0;text-decoration:none;
  border-bottom:1px solid var(--rule-soft);
  transition:padding-left .34s var(--ease);
}
.jump__item:focus-visible{padding-left:8px;}
@media (hover:hover){ .jump__item:hover{padding-left:8px;} }

.jump__item > span:nth-child(2){
  font-family:"Newsreader",Georgia,serif;
  font-variation-settings:"opsz" 20;
  font-size:1.02rem;letter-spacing:-.01em;line-height:1.25;
}
.jump__n{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.62rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;margin-left:auto;
  font-variant-numeric:tabular-nums;
}

/* ---------- disciplines ----------
   Four chapters, not one list of thirty-nine. Each discipline takes a
   full-bleed band and the two grounds alternate, so the eye gets a boundary
   every twelve rows instead of one unbroken field of bone. The discipline
   itself sits in a rail on the left and stays there while its own services
   scroll past it. That is what the wide screen is for — carrying structure,
   not stretching a single row across the whole of it. */
.disc{padding-block:clamp(46px,5.4vw,86px);scroll-margin-top:var(--nav-h);}
.disc:first-of-type{padding-top:clamp(18px,2.4vw,34px);}
/* A hairline this pale disappears against the sunk ground, so the bands
   carry their own rule value rather than a global one. */
.disc--sunk{background:var(--paper-sunk);--rule-soft:#D8D2C4;--rule:#CBC4B4;}
/* The deeper ground costs contrast: ink-3 at 16.7px landed on 4.61:1
   against it, over the AA line by a rounding error. Darkened on the sunk
   bands only, which puts it back at 5.07:1. */
.band--sunk,.disc--sunk{--ink-3:#585D66;}

.disc__col{display:grid;gap:clamp(26px,3.4vw,44px);max-width:var(--list-w);}
@media (min-width:960px){
  .disc__col{
    grid-template-columns:minmax(0,.64fr) minmax(0,1fr);
    gap:clamp(38px,4.6vw,92px);
  }
  /* Pinned to the top of the viewport, not to the flow: through thirteen
     rows the discipline you are reading stays named and stays large. */
  .disc__rail{
    position:sticky;
    top:calc(var(--nav-h) + clamp(26px,4vh,54px));
    align-self:start;
  }
}
.disc__num{display:block;}
.disc__name{
  font-variation-settings:"opsz" 48;
  font-size:clamp(1.8rem,1.25rem + 1.9vi,2.85rem);
  line-height:1.05;letter-spacing:-.022em;
  margin:12px 0 0;text-wrap:balance;
}
.disc__count{
  display:block;margin-top:15px;
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.disc__blurb{
  color:var(--ink-2);font-size:1rem;line-height:1.55;
  font-variation-settings:"opsz" 16;
  max-width:25em;
  margin:22px 0 0;padding-top:20px;
  border-top:1px solid var(--rule);
}

/* ---------- the index, in list mode ----------
   The note sits under its name rather than across the page from it. Set
   side by side they were separated by a gap wider than most of the names,
   and the eye had to cross it thirty-nine times. Stacked, a service is one
   object: a name, and a line about it. */
.index--svc{border-top:1px solid var(--ink);margin-top:0;}
.index__row--svc{
  padding-block:clamp(14px,1.6vw,20px);
  border-bottom-color:var(--rule-soft);
}
@media (min-width:860px){
  .index__row--svc{
    grid-template-columns:auto minmax(0,1fr);
    column-gap:clamp(14px,1.7vw,26px);
    row-gap:5px;
    align-items:baseline;
  }
  .index__row--svc .index__n{grid-column:1;grid-row:1;}
  .index__row--svc .index__title{grid-column:2;grid-row:1;}
  .index__row--svc .index__blurb{grid-column:2;grid-row:2;}
}
.index__row--svc:hover{background:transparent;}
.index__row--svc .index__title{
  font-variation-settings:"opsz" 20;
  font-size:1.14rem;line-height:1.3;
}
/* The note is annotation, not a second column of body copy. At .97rem in
   ink-2 it sat three pixels and one step of grey from the name, which over
   thirty-nine rows is not a hierarchy — it reads as two columns of prose.
   The column is the measure, so no em cap on top of it. */
.index__row--svc .index__blurb{
  font-size:.87rem;line-height:1.5;
  color:var(--ink-3);max-width:none;
}
.index__row--svc:last-child{border-bottom:1px solid var(--ink);}

/* Service rows carry no reveal animation on purpose. Thirty-nine rows
   animating one by one is noise, and the transform each one needs creates
   a stacking context that paints over the sticky rail. */
.index__row--svc{transform:none;animation:none;opacity:1;}

/* ============================================================
   CONTACT PAGE
   ============================================================ */
.contact{display:grid;gap:clamp(40px,5vw,80px);align-items:start;}
@media (min-width:940px){
  .contact{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);}
}
/* The aside is 776px tall. Stuck to a 748px laptop viewport its bottom third
   is unreachable — it pins at the top and the rest is simply cut off, which
   on this page is the New Zealand number. Sticky only where the column fits
   on screen; below that it scrolls with the form like any other column. */
@media (min-width:940px) and (min-height:900px){
  .contact__aside{position:sticky;top:calc(var(--nav-h) + 34px);}
}
.contact__lines{margin-top:18px;}
.contact__lines .cta__line{
  border-color:var(--rule);color:var(--ink);
}
.contact__lines .cta__line:focus-visible{border-color:var(--ink);}
@media (hover:hover){ .contact__lines .cta__line:hover{border-color:var(--ink);} }

/* ---------- form ----------
   Posts to Netlify Forms, so it captures leads from the first deploy
   rather than sitting inert like every form on the Seed build did. */
.form{margin-top:clamp(26px,3vw,40px);display:flex;flex-direction:column;gap:20px;}
/* Shown only when the embedded form never reports its height. Styled as a
   card so it reads as deliberate content rather than a broken page. */
.form__fallback{margin:0;padding:1.1rem 1.2rem;border:1px solid var(--rule-soft);border-radius:14px;background:var(--paper);font-weight:600;color:var(--ink);line-height:1.5;}
.form__fallback a{color:var(--ink);text-underline-offset:3px;}
.form__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}
.form__row{display:grid;gap:20px;}
@media (min-width:560px){ .form__row{grid-template-columns:repeat(2,minmax(0,1fr));} }

.field{display:flex;flex-direction:column;gap:8px;}
.field__label{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3);
}
.field input,.field select,.field textarea{
  font-family:"Newsreader",Georgia,serif;
  font-size:1.02rem;color:var(--ink);
  background:transparent;
  border:0;border-bottom:1px solid var(--rule);
  padding:9px 0 11px;
  border-radius:0;            /* iOS rounds inputs by default */
  appearance:none;
  transition:border-color .3s var(--ease);
  /* A form control's intrinsic width is not zero and it is not the column's.
     An <input> sizes to its `size` attribute and a <select> sizes to its
     LONGEST OPTION, and both carry min-width:auto, so either can push a grid
     or flex column wider than the viewport and there is no visible clue which
     one did it. Pinning min-width:0 lets the column govern instead. */
  min-width:0;
  width:100%;
}
.field textarea{resize:vertical;min-height:7em;line-height:1.55;}
.field select{cursor:pointer;}
/* Contact overflowed 35px at a 320px viewport: scrollWidth 355 against 320.
   Measured rather than guessed - every element in the column reported 335px
   wide, which looked like a container fault. It was not. The <select>'s
   min-content was 335px on its own, and zeroing it took scrollWidth from 355
   to exactly 320.
   The cause was a copy change, not CSS. Its longest option is "Remote practice
   support (LEAP, Xero and MYOB)", and that string grew when MYOB was added on
   ticket 00012. A select silently resizes its whole column to fit its longest
   option, so a three-word copy edit moved the layout on a page nobody was
   looking at. Anything added to this list should be checked at 320. */
@media (hover:hover){ .field input:hover,.field select:hover,.field textarea:hover{border-color:var(--ink-3);} }
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--ink);border-bottom-width:1px;
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--blue);outline-offset:4px;
}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-3);opacity:1;}
.field input:user-invalid,.field textarea:user-invalid{border-color:var(--flag,#A93520);}

.form__submit{align-self:flex-start;margin-top:6px;cursor:pointer;font:inherit;
  font-family:"Familjen Grotesk",system-ui,sans-serif;font-size:.82rem;}
.form__note{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.72rem;line-height:1.65;color:var(--ink-3);max-width:34em;margin:0;
}
.form__note a{color:var(--blue-deep);}

/* ---------- numbered steps (contact) ----------
   A real sequence, so it is numbered. Uses the same tabular blue numerals
   as every other index on the site rather than the browser's list markers. */
ol.steps{list-style:none;counter-reset:s;margin:16px 0 0;padding:0;border-top:1px solid var(--rule);}
ol.steps li{
  counter-increment:s;position:relative;
  padding:15px 0 15px 40px;border-bottom:1px solid var(--rule-soft);
}
ol.steps li::before{
  content:counter(s,decimal-leading-zero);
  position:absolute;left:0;top:19px;
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-variant-numeric:tabular-nums;
  font-size:.7rem;letter-spacing:.08em;color:var(--blue-deep);
}
ol.steps strong{font-weight:400;font-size:1.06rem;display:block;line-height:1.35;}
ol.steps p{margin:4px 0 0;font-size:.95rem;color:var(--ink-2);}

/* ============================================================
   LEGAL / PROSE PAGES
   ============================================================ */
/* measure only — the centring belongs to .shell, not to the column */
.prose{max-width:38em;margin-inline:0;}
/* Section headings on the legal pages are now .clause__h, set with their
   clause number and their own rule — see the LEGAL PAGES block below. The
   old bare rule here out-specified it (0,1,1 beats 0,1,0) and drew a second
   hairline above every heading. */
.prose p{color:var(--ink-2);}
.prose strong{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.85em;font-weight:500;letter-spacing:.01em;
  color:var(--blue-deep);
  background:color-mix(in srgb, var(--blue) 8%, transparent);
  padding:2px 6px;
}
.prose em{font-style:italic;}
.prose__meta{display:flex;gap:10px;align-items:baseline;margin:0;}

/* A build-time banner. Deliberately loud: these pages carry legal weight
   and must not ship on someone assuming they were reviewed. */
.draftnote{
  background:var(--paper-deep);color:var(--ink-on-dark);
  padding:16px 0;
}
.draftnote__tag{
  display:inline-block;
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-deep);background:#E0A33A;
  padding:4px 9px;margin-bottom:9px;
}
.draftnote p{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.78rem;line-height:1.6;color:var(--ink-on-dark-2);
  max-width:62em;margin:0;
}
.draftnote > *{
  width:100%;max-width:1500px;margin-inline:auto;
  padding-inline:var(--gutter);
}

/* ============================================================
   PRINT
   A services list for law firms gets printed and circulated —
   partners' meetings, procurement packs, a PDF attached to an email.
   Without these rules the page prints seven pages with two solid black
   bands, sticky elements fighting pagination, and rows split across
   page breaks.
   ============================================================ */
@media print{
  @page{ margin:18mm 16mm; }

  html{font-size:11pt;}
  body{
    background:#fff;color:#000;
    -webkit-print-color-adjust:economy;print-color-adjust:economy;
  }

  /* Sticky positioning and pagination do not mix — a stuck element can
     repeat or float over content on every page. */
  .masthead,.disc__rail,.contact__aside,.systems > :first-child{
    position:static !important;
  }
  .masthead{border-bottom:1px solid #000;backdrop-filter:none;background:#fff;}

  /* Ink. The dark bands carry the contact details, so they invert rather
     than disappear. */
  .band--dark,.foot,.band--sunk,.draftnote{background:#fff !important;}
  .band--dark,.band--dark *,.foot,.foot *,.draftnote,.draftnote *{color:#000 !important;}
  .draftnote{border:1.5pt solid #000;padding:8pt 10pt;margin-bottom:10pt;}
  .draftnote > *{padding-inline:0;}
  .draftnote__tag{background:#000 !important;color:#fff !important;}
  .cta__line,.foot{border-color:#999 !important;}

  /* Screen-only furniture. The phone number stays — it is the single most
     useful thing on a printed page. */
  .nav a:not(.nav__call),.menu,.jump,.form,.btn,.index__arrow{display:none !important;}
  .nav a.nav__call{border:0;padding:0;font-size:1em;}

  /* Nothing splits mid-item. */
  .index__row,ol.steps li,.stack__row,.drives li,.cta__line,.figure{break-inside:avoid;}
  h1,h2,h3,.disc__rail,.u-label{break-after:avoid;}
  .disc{break-inside:auto;}
  .band--dark{break-before:auto;}

  /* Heroes are decoration in print; the list is the content. */
  .hero__figure,.statement__figure{display:none;}
  .hero{min-height:0 !important;max-height:none !important;display:block !important;}
  .hero,.phero,.band,.disc{padding-block:0 12pt !important;}

  /* Reveal animations must never leave printed content invisible. */
  .rv{opacity:1 !important;transform:none !important;animation:none !important;}

  a{text-decoration:none;color:#000;}

  /* An A4 page is ~794 CSS px, below the 860px breakpoint, so the list was
     falling back to the mobile stack — three lines per service and half the
     page width unused. Force the table layout: service on the left, what it
     means on the right, which is the form a printed list wants. */
  .disc__col{display:block !important;}
  .index__row--svc{
    grid-template-columns:auto minmax(0,1fr) minmax(0,1.45fr) !important;
    column-gap:12pt;row-gap:0;
    align-items:baseline;
    padding-block:5.5pt !important;
  }
  .index__n,.index__title,.index__blurb{grid-row:auto !important;justify-self:auto !important;}
  .index__row--svc .index__title{font-size:1em;}
  .index__row--svc .index__blurb{max-width:none;font-size:.92em;}
  .disc__blurb{max-width:none;font-size:1em;margin-block:6pt 8pt;}
  .disc__name{font-size:1.5em;}
  .phero h1,.hero h1{font-size:2.2em;}
  .phero__stand{font-size:1em;}
}


/* ============================================================
   RULES  (About)
   These four are the page's argument — the promise a firm is
   actually buying, including the professional-indemnity boundary
   in rule 04. They were running through the services-index
   component, which set them at 21px: the identical size as
   "Document scanning and data entry", item 06 of 39. Same weight
   for the most important sentence on the site and the most
   mundane. Four items can afford room that thirty-nine cannot,
   so they read as declarations, not inventory.
   ============================================================ */
.rules{border-top:1px solid var(--ink);margin-top:clamp(30px,4vw,56px);}
.rules__item{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  padding-block:clamp(30px,3.8vw,50px);
  border-bottom:1px solid var(--rule);
}
@media (min-width:820px){
  .rules__item{
    grid-template-columns:auto minmax(0,1fr);
    column-gap:clamp(26px,4vw,60px);
  }
  .rules__n{grid-row:1 / span 2;padding-top:.62em;}
}
.rules__name{
  font-variation-settings:"opsz" 40;
  font-size:clamp(1.55rem,1.1rem + 1.7vi,2.35rem);
  line-height:1.13;letter-spacing:-.018em;font-weight:400;
  margin:0;text-wrap:balance;
}
.rules__body{
  color:var(--ink-2);
  font-size:1.06rem;line-height:1.56;
  max-width:34em;margin:13px 0 0;
  text-wrap:pretty;
}
.rules__item:last-child{border-bottom:1px solid var(--ink);}

/* Each rule ran as a number beside a heading stacked over a 34em body, so the
   right half of every row sat empty beneath a hairline that ran the full width
   — four times over, which is what made this section read as unfinished.
   Three columns from 1040px: the number, the declaration, the reason. Same
   signature, and the row now occupies the width its own rule claims. Held to
   1040 because below that the third column stops being a column and starts
   being a gutter. */
@media (min-width:1040px){
  .rules__item{
    grid-template-columns:auto minmax(0,.9fr) minmax(0,1fr);
    align-items:baseline;
  }
  .rules__n{grid-row:1;padding-top:0;}
  .rules__name{grid-column:2;}
  .rules__body{grid-column:3;margin-top:0;max-width:36em;}
}

/* The fix above only ever applied above 1040. Below it the two-column layout
   still had the original fault: the body is capped at a 36em measure while the
   row's hairline ran the full band, so at 1039 the rule overhung its own content
   by 248px — four times over, under a heading that also stops at the measure.
   Same fault this review has removed from six other places, surviving in the
   one component whose comment says it was fixed.
   The block is now sized to its content rather than to the band: the measure
   moves off the paragraph and onto the grid column, so the row's max-content is
   number + gap + measure, and `width:fit-content` makes the rules and the
   borders stop there. Overhang across 320 to 1039: 248px becomes 0 to 5px, and
   the line length is unchanged at ~79 characters. */
@media (max-width:1039px){
  .rules{width:fit-content;max-width:100%;}
  .rules__item{grid-template-columns:auto minmax(0,36em);}
  .rules__body{max-width:none;}
}
@media (max-width:819px){
  .rules__item{grid-template-columns:minmax(0,36em);}
}

@media print{
  .rules__item{break-inside:avoid;padding-block:7pt;}
  .rules__name{font-size:1.25em;}
  .rules__body{font-size:.95em;margin-top:4pt;}
}


/* ============================================================
   WHERE WE ARE  (About)
   The headline claims local people in local time zones, and the
   section used to prove it with a photograph of a parked car and
   two phone numbers set at 12px. 543px of the row was empty. The
   two offices ARE the proof, so they are now the content: numbers
   at reading size, callable, with the timezone against each.
   ============================================================ */
.where{display:grid;gap:clamp(30px,4vw,64px);margin-top:clamp(32px,4vw,56px);align-items:start;}
@media (min-width:900px){
  .where{grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);}
}
.offices{display:flex;flex-direction:column;border-top:1px solid var(--ink);}
.office{
  display:grid;gap:5px;
  padding-block:clamp(16px,2vw,22px);
  border-bottom:1px solid var(--rule);
  text-decoration:none;
  transition:padding-left .34s var(--ease);
}
.office:focus-visible{padding-left:9px;}
@media (hover:hover){ .office:hover{padding-left:9px;} }
.office__num{
  font-family:"Newsreader",Georgia,serif;
  font-variation-settings:"opsz" 32;
  font-size:clamp(1.35rem,1.05rem + 1.1vi,1.85rem);
  line-height:1.15;letter-spacing:-.015em;
  font-variant-numeric:tabular-nums;
  color:var(--ink);
}
.office__num--mail{font-size:clamp(1.05rem,.9rem + .6vi,1.35rem);letter-spacing:-.01em;}
.office__tz{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.74rem;color:var(--ink-3);
}
/* Used to stop a phrase breaking where a break reads as an error: "thirty-nine"
   splitting at its hyphen, which it did in the About CTA standfirst.
   The time zone line was the other case — right-aligned it broke as "Australian
   eastern time · your / business day". That one was solved in the copy instead:
   "· your business day" came off both rows, because the claim is already made
   in full on Contact 05 and in About 04's own heading. One line each now. */
.nb{white-space:nowrap;}
/* Each office row is a hairline over a left-aligned stack, so the rule ran to
   the container while the content stopped at its longest line: 214px of
   overhang on About at 1512, 408px at 768, and 521px on Contact at 900, where
   the block goes full width. Four pages carried it. Rather than shrink the
   block away from its column, the row now uses the width — number left, time
   zone right on the same baseline, which is the same structure as .cta__line
   and .index__row. Overhang is 0 from 560px up on all four pages, with at
   least 20px between the number and the time zone at the tightest width.
   Two things this went wrong on first, both worth keeping:
   1. The number column was `1fr` and the time zone `auto`, so the phone number
      became the flexible track and wrapped to two lines ("+61 2 9071 / 7708")
      at every width. The number is the content; the time zone is what flexes.
   2. A viewport media query was wrong here, because the block's width does not
      track the viewport: on About at 1512 the column is 528px, but at 900 it is
      317px, and at 900 on Contact it is 810px. A viewport rule squeezed the
      time zone to four lines in the narrow case. This is a container query, so
      it responds to the column the block is actually in. 430px is the number
      plus the time zone plus the gap. 430 was right while the time zone read
      "Australian eastern time · your business day"; with that shortened to
      "Australian eastern time" the two halves need only 315px, so the row
      holds together down to a 330px container, which includes a 320px phone. */
.offices{container-type:inline-size;}
@container (min-width:330px){
  .office{
    grid-template-columns:auto minmax(0,1fr);
    column-gap:clamp(20px,3vw,40px);
    align-items:baseline;
  }
  .office__place{grid-column:1 / -1;}
  .office__num{grid-column:1;white-space:nowrap;}
  .office__tz{grid-column:2;justify-self:end;text-align:right;}
}
.where__figure{margin:0;}

@media print{
  .where{grid-template-columns:minmax(0,1fr) minmax(0,1fr) !important;}
  .office{break-inside:avoid;padding-block:5pt;}
  .office__num{font-size:1.15em;}
}


/* ============================================================
   CONTACT — form messaging and assurances
   ============================================================ */
.form__status{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.8rem;color:var(--flag,#A93520);margin:0;
}
.form__status:empty{display:none;}

/* Was the word "required" set in the same grey and near enough the same
   size as the label beside it, so every label row carried two competing
   pieces of metadata. A marker in the flag colour already used for form
   errors says the same thing without joining the sentence. */
.field__req{
  color:#A93520;font-weight:500;
  font-size:1.15em;line-height:1;margin-left:.3em;
  vertical-align:-.05em;
}
/* Sits on the section label row, not above the first field. Below the rule
   it pushed the form's first label 35px lower than the offices label opposite
   it, so the two columns started on different lines despite sharing a rule. */
.contact__labelrow{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:20px;flex-wrap:wrap;
  min-height:1.5em;          /* both columns get the identical box, so the
                                rules below them land on the same pixel */
}
.form__legend{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.7rem;letter-spacing:.06em;color:var(--ink-3);
  margin:0;white-space:nowrap;
}
.form__legend .field__req{margin:0 .3em 0 0;}
.field__hint,.field__err{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.72rem;line-height:1.5;
}
.field__hint{color:var(--ink-3);}
/* Persistent, not a native bubble that vanishes on the next click. */
.field__err{color:#A93520;}
.field__err:empty{display:none;}
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"]{border-bottom-color:#A93520;}

/* The three things a firm principal weighs before letting a supplier
   inside their practice management system. Sits under the send button
   because that is the moment the doubt lands. */
.assurances{
  margin-top:clamp(34px,4vw,52px);
  padding-top:clamp(22px,2.6vw,30px);
  border-top:1px solid var(--ink);
  display:flex;flex-direction:column;
}
.assurance{
  display:grid;gap:6px;
  padding-block:clamp(14px,1.8vw,20px);
  border-bottom:1px solid var(--rule-soft);
}
@media (min-width:640px){
  .assurance{grid-template-columns:minmax(0,.34fr) minmax(0,1fr);column-gap:clamp(20px,3vw,40px);align-items:baseline;}
}
.assurance p{
  margin:0;font-size:.97rem;line-height:1.55;color:var(--ink-2);max-width:34em;
}
.assurances__more{
  margin:16px 0 0;
  font-family:"Familjen Grotesk",system-ui,sans-serif;font-size:.76rem;
}
.assurances__more a{color:var(--blue-deep);}

@media print{
  .assurance{break-inside:avoid;padding-block:5pt;}
  .field__hint,.field__err,.form__status{display:none;}
}


/* ============================================================
   LEGAL PAGES  (Privacy, Terms)
   These were the only two pages on the site set as one unbroken
   column of prose on one flat ground — a Word document wearing
   the brand. They are also the two pages a firm's principal will
   read most carefully, because reading documents like these is
   their job. So they get the same structural devices as the rest
   of the site rather than an exemption from them: numbered
   clauses, a contents rail that stays with you, and a body column
   that no longer leaves 700px of empty paper down the right of
   every screen.

   Deliberately no reveal animation. These are reference
   documents. Same reasoning as the 39 service rows — a clause
   that fades in is a clause you cannot cite.
   ============================================================ */

.legal{display:grid;gap:clamp(30px,4vw,52px);align-items:start;max-width:var(--list-w);}
@media (min-width:960px){
  .legal{grid-template-columns:minmax(0,.52fr) minmax(0,1fr);gap:clamp(44px,5.4vw,96px);}
  /* Same device as the discipline rail on Services: pinned to the
     viewport, not to the flow, so through nine clauses you always know
     where you are and can leave for any other clause in one click. */
  .legal__rail{align-self:start;}
}
@media (max-width:959px){
  /* On a phone a sticky contents column is a wall in front of the
     document. It becomes a short index at the top instead. */
  .legal__rail{max-width:34em;}
}

/* Both columns open with an eyebrow, and both then draw a hairline. Given
   two different bits of content (a label; a label plus a date chip) they
   landed 20px apart, which on a site built out of hairlines is the one
   misalignment you cannot afford. One explicit row height for both fixes
   it at every root size the clamp produces. */
.legal__eyebrow,.legal__meta{
  display:flex;align-items:center;gap:10px;flex-wrap:nowrap;
  height:26px;margin:0 0 14px;
}
.legal__toc{list-style:none;margin:0;padding:0;border-top:1px solid var(--ink);}
/* Below 960 the contents list drops out of its sticky rail and goes full width,
   and Privacy's rows are number-plus-title with nothing on the right, so every
   rule ran 335px past its own text. Terms does not have this, because its rows
   carry a TO DRAFT flag pushed right, which fills them. Sized to its content in
   the stacked range instead. */
@media (max-width:959px){ .legal__toc{width:fit-content;max-width:100%;} }
.legal__toc a{
  display:flex;align-items:baseline;gap:13px;
  padding:9px 0;text-decoration:none;
  border-bottom:1px solid var(--rule-soft);
  transition:padding-left .34s var(--ease);
}
.legal__toc a:focus-visible{padding-left:8px;}
@media (hover:hover){ .legal__toc a:hover{padding-left:8px;} }
.legal__toc-t{
  font-family:"Newsreader",Georgia,serif;
  font-variation-settings:"opsz" 20;
  font-size:.99rem;letter-spacing:-.01em;line-height:1.3;
  color:var(--ink);
}
/* Marks a clause that is still a hole. It belongs in the contents as
   much as in the body — the whole point is that nobody can scroll past
   this document believing it is finished. */
.legal__toc-flag{
  margin-left:auto;flex:none;
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.56rem;letter-spacing:.14em;text-transform:uppercase;
  color:#6A4A05;background:#F6E4BE;padding:3px 6px;
}
/* A running count of what is still missing, held next to the contents
   rather than only inline in the body. Nine clauses can look complete
   from the rail; "six unresolved" cannot. Deletes itself at launch
   along with the banner. */
.legal__unresolved{
  display:flex;align-items:baseline;gap:9px;
  margin:16px 0 0;padding-top:14px;
  border-top:1px solid var(--rule);
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.68rem;line-height:1.5;color:var(--ink-3);
}
.legal__unresolved b{
  font-weight:500;color:#6A4A05;background:#F6E4BE;
  padding:2px 7px;flex:none;
}

@media (min-width:960px) and (min-height:700px){
  .legal__rail{position:sticky;top:calc(var(--nav-h) + clamp(24px,4vh,48px));}
}

/* ---------- clauses ---------- */
.clause{
  padding-top:clamp(20px,2.4vw,28px);
  margin-top:clamp(30px,3.6vw,46px);
  border-top:1px solid var(--rule);
  scroll-margin-top:calc(var(--nav-h) + 22px);
}
.clause:first-of-type{margin-top:0;}
.clause__h{
  display:flex;align-items:baseline;gap:clamp(12px,1.6vw,20px);
  margin:0 0 14px;
  /* The section heading was set at 1.42rem — smaller than a rule name on
     About and barely above a service row. On a page built of nothing but
     headings and paragraphs, the heading is the only structure there is. */
  font-variation-settings:"opsz" 32;
  font-size:clamp(1.5rem,1.15rem + 1.1vi,2rem);
  line-height:1.14;letter-spacing:-.018em;font-weight:400;
  text-wrap:balance;
}
.clause__n{flex:none;position:relative;top:-.15em;}
.clause p{color:var(--ink-2);}
.clause p:last-child{margin-bottom:0;}
/* Landing on a clause from the contents should confirm the arrival. */
.clause:target{border-top-color:var(--ink);}

/* A clause whose body is nothing but an unanswered question. Three of the
   nine on Terms are exactly that, and set as ordinary emphasis they read,
   at a skim, like sections that have been filled in. */
/* Marked by recolouring the hairline the clause already has, not by adding
   a second one. A left border indented the clause and broke the column the
   blue numerals stand in — and that column is a signature of the site.
   The rule above an unfinished clause is amber. Nothing moves. */
.clause--todo{border-top-color:#E0A33A;}

/* ---------- unresolved content ----------
   Was running through .prose strong — blue ink on a blue tint, the same
   treatment the site uses for emphasis. A hole is not emphasis. Keyed to
   the amber of the Not-for-launch tag so every unfinished thing on these
   two pages is the same colour, and so it is obvious what has to be gone
   before launch. */
.todo{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.78em;font-weight:500;letter-spacing:.015em;
  color:#6A4A05;background:#F6E4BE;
  box-shadow:inset 0 -2px 0 #E0A33A;
  /* Several of these are mid-sentence, so a full-stop follows immediately.
     Generous side padding pushed the stop clear of the word and left it
     floating in the line. Tight, and the sentence still reads as a sentence. */
  padding:2px 4px;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;
}

/* ---------- closing block ---------- */
/* Both pages previously ran out of prose and hit the footer. Every other
   page on the site steps down through a band first. This one also does
   something useful: it answers "who do I raise this with", which is the
   question a document like this leaves you holding. */
.legal__close{display:grid;gap:clamp(26px,3.4vw,56px);align-items:start;max-width:var(--list-w);}
@media (min-width:900px){
  .legal__close{grid-template-columns:minmax(0,.9fr) minmax(0,1fr);}
}
.legal__close h2{margin-top:16px;max-width:14em;}
.legal__close .measure{margin-top:18px;color:var(--ink-2);}

@media print{
  /* A printed contents for a legal document is worth having, but a stuck
     column is not — it repeats or floats over the text on every page. */
  .legal,.legal__close{display:block !important;}
  .legal__rail{position:static !important;margin-bottom:14pt;}
  .legal__toc a{padding:2pt 0;}
  .clause{break-inside:auto;padding-top:8pt;margin-top:10pt;}
  .clause__h{font-size:1.25em;margin-bottom:6pt;}
  .clause--todo{border-top:1.5pt solid #000;}
  .todo{box-shadow:none;border:1pt solid #000;background:#fff !important;color:#000 !important;}
  .legal__toc-flag{background:#fff !important;color:#000 !important;border:.75pt solid #000;}
}


/* ============================================================
   THANK YOU
   The only page a converted enquirer ever sees, and the one that
   had never been designed: a headline, one paragraph with both
   phone numbers buried inside it, and a ghost button. The exact
   fault already fixed on Contact — the two most useful things on
   the page set smaller than the prose around them — was still
   sitting here untouched.
   ============================================================ */
.ty{display:grid;gap:clamp(34px,4.4vw,72px);align-items:start;max-width:var(--list-w);}
@media (min-width:900px){
  .ty{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);}
}
.ty__onward{max-width:var(--list-w);}
.ty__onward .cta__line{
  border-color:var(--rule);color:var(--ink);
}
.ty__onward .cta__line:focus-visible{border-color:var(--ink);}
@media (hover:hover){ .ty__onward .cta__line:hover{border-color:var(--ink);} }
.ty__onward .cta__line b{
  font-family:"Newsreader",Georgia,serif;
  font-variation-settings:"opsz" 24;
  font-size:1.2rem;letter-spacing:-.012em;line-height:1.3;
}
.ty__onward .cta__line span:last-child{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:.8rem;color:var(--ink-3);text-align:right;
}
.ty__lines{display:flex;flex-direction:column;gap:2px;margin-top:16px;border-top:1px solid var(--ink);}
/* Title and note fight for one line on a phone and both wrap into a ragged
   two-column tangle. Stacked, the line is a title with a note under it. */
@media (max-width:560px){
  .ty__onward .cta__line{flex-direction:column;align-items:flex-start;gap:3px;}
  .ty__onward .cta__line span:last-child{text-align:left;}
}

@media print{
  .ty{display:block !important;}
  .ty__onward{display:none;}
}


/* ============================================================
   MOBILE
   Two systemic faults, both invisible on a desktop.

   1. No navigation. Under 720px the three nav links were set to
      display:none and nothing replaced them. The only things in
      the masthead were the logo and the phone number, so a phone
      visitor could not reach Services, About or Contact without
      scrolling to the footer of whatever page they landed on.

   2. The type scale collapsed. html font-size is clamped between
      1em and 1.2em, so the root is ~18.8px on a desktop and 16px
      on a phone. Every small role is set in rem, so they all shrank
      with it while body copy stayed comfortable: labels went 12.4px
      to 10.7px, and ASSIST under the wordmark went to 8.6px. A floor
      in px keeps the desktop sizes untouched and stops the small
      roles falling off the bottom on a phone.
   ============================================================ */

/* ---------- the disclosure ---------- */
/* Desktop: inert scaffolding. display:contents dissolves the details and
   the panel, so the three links lay out as direct flex children of .nav
   exactly as they did before, with no duplicated markup. */
/* The desktop and mobile navs are two separate sets of links, and exactly one
   of them is ever in the document. That is deliberate.

   The first version had one set of links inside the <details> and used
   display:contents on desktop to dissolve the disclosure so they would lay
   out as ordinary nav children. That works in some engines and not others —
   a browser that hides closed <details> content via ::details-content keeps
   the links hidden no matter what display the author sets, and the result is
   a desktop masthead with no navigation in it at all. Which is what shipped.

   Three duplicated anchors is a smaller price than a nav whose correctness
   depends on how a given browser implements a closed disclosure. */
@media (min-width:721px){
  .menu{display:none;}
}
@media (max-width:720px){
  .nav > a:not(.nav__call){display:none;}
  .menu{display:block;position:relative;}
  .menu__btn{
    list-style:none;cursor:pointer;user-select:none;
    font-family:"Familjen Grotesk",system-ui,sans-serif;
    font-size:max(13px,.79rem);color:var(--ink);
    display:flex;align-items:center;gap:9px;
    padding:14px 2px;                 /* 44px tall target */
  }
  .menu__btn::-webkit-details-marker{display:none;}
  .menu__btn::after{
    content:"";width:8px;height:8px;flex:none;
    border-right:1px solid currentColor;border-bottom:1px solid currentColor;
    transform:translateY(-2px) rotate(45deg);
    transition:transform .3s var(--ease);
  }
  .menu[open] .menu__btn::after{transform:translateY(1px) rotate(225deg);}
  /* Open/closed is stated explicitly in both directions rather than left to
     the UA. Setting display on the panel unconditionally overrode the
     browser's own rule for hiding closed <details> content, so the menu sat
     permanently open over the top of every mobile page. */
  .menu__panel{
    position:absolute;right:0;top:calc(100% + 8px);
    min-width:190px;z-index:60;
    background:var(--paper);
    border:1px solid var(--rule);
    flex-direction:column;
  }
  .menu:not([open]) .menu__panel{display:none;}
  .menu[open] .menu__panel{display:flex;}
  .menu__panel a{
    padding:15px 18px;font-size:max(14px,.86rem);
    border-bottom:1px solid var(--rule-soft);
  }
  .menu__panel a:last-child{border-bottom:0;}
  .menu__panel a::after{display:none;}
  .menu__panel a[aria-current="page"]{color:var(--blue-deep);}
  /* The masthead is three things on a narrow screen. Tighten the gap and the
     button so brand + Menu + number still fit at 360 without wrapping. */
  .masthead__in{gap:12px;}
  .nav{gap:6px;}
  .nav a.nav__call{padding:15px 13px;white-space:nowrap;}
}
/* At 360 the bar is brand + Menu + the number, and the number was wrapping
   to two lines inside its own button. Everything gives a little so it stays
   on one line: the number is the only conversion action in a mobile
   masthead and it should not look broken. */
/* Below ~355 there is no arrangement of brand + Menu + a full phone number
   that fits one row without shrinking something past legibility. Two rows,
   and nothing has to give. */
@media (max-width:355px){
  .masthead__in{flex-wrap:wrap;gap:0 9px;padding-block:5px;min-height:0;}
  .nav{margin-left:0;width:100%;justify-content:space-between;}
}
@media (max-width:420px){
  .masthead__in{gap:9px;}
  .brand__mark{height:32px;}
  .nav a.nav__call{font-size:max(12px,.72rem);padding:15px 11px;letter-spacing:-.01em;}
}

/* ---------- small-type floor ---------- */
@media (max-width:860px){
  .u-label{font-size:max(11.5px,.66rem);}
  .u-num{font-size:max(12px,.7rem);}
  .draftnote__tag{font-size:max(10.5px,.6rem);}
  .draftnote p{font-size:max(13px,.78rem);}
  .foot a{font-size:max(13px,.78rem);}
  .foot__fine{font-size:max(11.6px,.68rem);}
  .field__label{font-size:max(11.5px,.68rem);}
  .field__hint,.field__err,.form__note,.form__status{font-size:max(12.4px,.72rem);}
  .index__count,.disc__count{font-size:max(11.5px,.66rem);}
  .jump__n{font-size:max(11px,.62rem);}
  .stack__what{font-size:max(12.8px,.78rem);}
  .pendingnote,.legal__unresolved{font-size:max(12px,.7rem);}
  .legal__toc-flag{font-size:max(10px,.56rem);}
  .assurances__more{font-size:max(12.8px,.76rem);}
  .index__row--svc .index__blurb{font-size:max(13.6px,.87rem);}
  .ty__onward .cta__line span:last-child{font-size:max(13px,.8rem);}
}

/* ---------- tap targets ---------- */
/* Footer links were 20px boxes sitting in a row. The jump list on Services
   was 38px. Both are thumb targets on the pages where they matter most. */
@media (max-width:860px){
  .foot__links{gap:6px 20px;}
  .foot__links a{padding-block:11px;}
  .foot__cols{gap:6px 34px;}
  .jump__item{padding:12px 0;}
  .brand{padding-block:6px;}
}


/* Tablet width still shows the inline nav, and at 28px those are thumb
   targets on a device with no cursor. */
@media (max-width:900px){
  .nav > a:not(.nav__call){padding-block:12px;}
  .nav a.nav__call{padding-block:14px;}
}
@media (max-width:860px){
  .legal__toc a{padding:11px 0;}

}


/* ============================================================
   CONTACT — restructure
   The page was one .band containing everything: the numbers, the
   steps, the form and the assurances, all on one unbroken field
   of paper about 1400px deep. Every other page on the site breaks
   itself into alternating bands; this one never did, which is why
   it read as words starting on a page rather than as sections.

   Four changes:
   1. Four bands with alternating grounds, numbered 01-05 like the
      rules on About and the disciplines on Services. The site's
      structural signature is a label, a number, a name, a rule —
      Contact had two 10px labels doing all of it.
   2. The steps and the assurances came out of the columns and
      became full-width bands of three. They were stacked inside
      narrow columns, which is what left ~700px of empty paper down
      the left of the page once the short column ran out.
   3. The two columns now open the same way — label, heading of the
      same size, content. Before, the left opened with a 10px label
      and the right with a 57px display headline, so they read as a
      footnote and a page rather than as two ways to reach us.
   4. The h2 said "Tell us what is stacking up." The standfirst
      300px above it said "Tell us what is stacking up." Cut.
   ============================================================ */

/* Column headings. The old h2 ran at the full page scale — clamp up to
   3.2rem, 57px at this shell width — beside a form. A column heading is
   not a page headline. */
.contact__h{
  font-variation-settings:"opsz" 40;
  font-size:clamp(1.5rem,1.15rem + 1.2vi,2.05rem);
  line-height:1.1;letter-spacing:-.02em;
  margin:14px 0 0;
}
/* Both columns open on the same hairline. The offices carry an ink rule and
   the form opened with the small "* Required" line at the identical height,
   so at a glance the left column looked like a section and the right looked
   like a caption. Same rule, same y, and they read as two doors. */
.contact__aside .offices,
.contact__form .form{
  margin-top:clamp(22px,2.6vw,32px);
  border-top:1px solid var(--ink);
}
.contact__form .form{padding-top:clamp(18px,2vw,24px);}

/* The select was the one control that did not look like a control: its
   default option rendered in Newsreader at body size and full ink, so
   "Select one" read as something a visitor had already typed. Greyed while
   nothing is chosen, like the textarea placeholder beside it. */
.field select:has(option[value=""]:checked){color:var(--ink-3);}

/* A page hero is a promise; on Contact it is furniture between the visitor
   and the phone number they came for. The band below carries its own top
   padding, and stacking both put the first number most of a screen down. */
.phero + .band{padding-top:clamp(28px,3.2vw,48px);}

/* Band headings for 03/04/05. Smaller than a page h1, larger than a column
   heading, consistent across the three. */
.contact__h2{
  font-variation-settings:"opsz" 48;
  font-size:clamp(1.7rem,1.2rem + 1.7vi,2.5rem);
  line-height:1.12;letter-spacing:-.02em;
  margin:16px 0 0;max-width:18em;
}
.contact__p{margin-top:16px;color:var(--ink-2);}

/* ---------- steps, in a row ----------
   Three items stacked in a 0.85fr column is a list. Three items across the
   shell is a sequence, which is what they are. */
ol.steps--row{border-top:0;margin-top:clamp(28px,3.4vw,44px);}
@media (min-width:820px){
  /* --list-w capped these at 1120 while the form and the offices above them ran
     to the full 1296, so Contact had two different right edges about 180px
     apart. The rule's own comment says "three items across the shell"; they now
     actually are. */
  .steps--row{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:clamp(24px,3vw,52px);
  }
  /* Selectors matched to the base rules they override. `ol.steps li` is
     (0,1,2) and `.steps--row li` is (0,1,1), so the row version was losing
     and the 40px left indent for the absolute numeral stayed applied. */
  ol.steps--row li{
    padding:18px 0 0;border-bottom:0;
    border-top:1px solid var(--rule);
  }
  ol.steps--row li::before{
    position:static;display:block;margin-bottom:11px;top:auto;
  }
  ol.steps--row strong{font-size:1.14rem;}
}
@media (max-width:819px){
  ol.steps--row{border-top:1px solid var(--rule);}
}

/* ---------- assurances, in a row ---------- */
.assurances--row{
  border-top:0;
  margin-top:clamp(28px,3.4vw,44px);padding-top:0;
}
@media (max-width:819px){
  .assurances--row{border-top:1px solid var(--ink);}
}
@media (min-width:820px){
  .assurances--row{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:clamp(24px,3vw,52px);
  }
  .assurances--row .assurance{
    display:block;padding:18px 0 0;border-bottom:0;
    border-top:1px solid var(--rule);
  }
  .assurances--row .assurance .u-label{display:block;margin-bottom:10px;}
  .assurances--row .assurance p{max-width:none;}
}

/* The aside is short now — offices only — so it can travel with the form on
   any screen tall enough to hold it, rather than needing 900px of viewport. */
@media (min-width:940px) and (min-height:760px){
  .contact__aside{position:sticky;top:calc(var(--nav-h) + 34px);}
}

/* ---------- link treatment ----------
   These two were the only persistently underlined links on the site, and
   they sat in browser-default underline. Everything else uses a hairline.
   Same idea here: visibly a link, in the site's own language. */
.form__note a,.assurances__more a{
  text-decoration:none;
  border-bottom:1px solid color-mix(in srgb, var(--blue-deep) 40%, transparent);
  padding-bottom:1px;
  transition:border-color .3s var(--ease);
}
.form__note a:focus-visible,.assurances__more a:focus-visible{
  border-bottom-color:var(--blue-deep);
}
@media (hover:hover){
  .form__note a:hover,.assurances__more a:hover{border-bottom-color:var(--blue-deep);}
}
.assurances__more{margin-top:clamp(22px,2.6vw,30px);}

@media print{
  .steps--row,.assurances--row{display:block !important;}
  .contact__h,.contact__h2{font-size:1.3em;}
}

/* ---------- service accordion (26 Aug) -------------------------------
   Tommy's brief: each of the 39 becomes an accordion, the existing
   one-liner stays visible as the summary. Built with <details> rather
   than JS so it works with scripting off and is announced natively.

   State is set EXPLICITLY in both directions. Setting display on the
   panel without a :not([open]) rule overrides the UA rule that hides
   closed content, which is exactly how the mobile menu shipped stuck
   open on 24 Aug. Do not reduce this to a single rule.

   --svc-num is the width of the number column. The summary grid and
   the panel indent both read from it, so the panel aligns under the
   service name rather than approximately near it. Measured, not guessed. */
:root{ --svc-num:0.95rem; --svc-gap:clamp(14px,1.7vw,26px); }

.svc{ border-bottom:1px solid var(--rule-soft); }
.svc__summary{
  border-bottom:0;
  cursor:pointer;
  list-style:none;
}
.svc__summary::-webkit-details-marker{ display:none; }
.svc__summary::marker{ content:""; }
.svc__summary:focus-visible{ outline:2px solid var(--blue); outline-offset:2px; }

.svc__toggle{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:max(11px,.66rem); letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-3); white-space:nowrap;
  transition:color .3s var(--ease);
}
/* Alex, 27 Aug: on a phone there is nothing saying these rows open. The blue he
   saw on one row of thirty-nine was the sticky :hover bug, not an affordance.
   His two options were all-blue or a thin arrow; the arrow wins, because
   thirty-nine blue labels down one page would spend the 2% blue coverage that
   is doing most of the work of making this site look expensive.
   Text in ::before so the caret can sit after it, which reads better on the
   right-aligned desktop column. */
.svc__toggle::before{ content:"What this covers"; }
.svc[open] .svc__toggle::before{ content:"Close"; }
.svc__toggle::after{
  content:""; display:inline-block; width:5px; height:5px;
  border-right:1px solid currentColor; border-bottom:1px solid currentColor;
  transform:translateY(-2px) rotate(45deg);
  margin-left:10px;
  transition:transform .3s var(--ease);
}
.svc[open] .svc__toggle::after{ transform:translateY(1px) rotate(225deg); }
.svc[open] .svc__toggle{ color:var(--blue); }
@media (hover:hover){ .svc__summary:hover .svc__toggle{ color:var(--blue); } }

.svc:not([open]) .svc__panel{ display:none; }
.svc[open] .svc__panel{ display:block; padding-bottom:clamp(18px,2.2vw,28px); }
.svc__panel p{
  color:var(--ink-2); font-size:.95rem; line-height:1.62;
  max-width:58ch; margin:0;
}
.svc__panel p + p{ margin-top:.85em; }

@media (min-width:860px){
  .index__row--svc{ grid-template-columns:var(--svc-num) minmax(0,1fr); }
  .svc__summary{ grid-template-columns:var(--svc-num) minmax(0,1fr) auto; }
  .svc__summary .index__n{ grid-column:1; grid-row:1; }
  .svc__summary .index__title{ grid-column:2; grid-row:1; }
  .svc__summary .index__blurb{ grid-column:2; grid-row:2; }
  .svc__summary .svc__toggle{ grid-column:3; grid-row:1; justify-self:end; }
  .svc__panel{ margin-left:calc(var(--svc-num) + var(--svc-gap)); }
}
@media (max-width:859px){
  .svc__summary .svc__toggle{ justify-self:start; margin-top:2px; }
}
@media print{
  .svc__panel{ display:block !important; }
  .svc__toggle{ display:none; }
}

/* The closing line of Home section 03 is a claim in the firm's own voice,
   not another paragraph of explanation. Set slightly larger and in full ink
   so it reads as the point the section has been building to. */
.home__pull{
  font-size:1.06em; line-height:1.5; color:var(--ink);
  padding-top:16px; border-top:1px solid var(--rule);
}

/* Home 03 only, added 2 Sep. That closing line used to sit at the bottom of the
   text column, where it left this section 195 to 343px of empty paper beside the
   picture. Measured against the other two splits, which run -70 to +136, so Home
   was the outlier by three times. The cause was not a small picture: at 1512 this
   figure is the TALLEST of the three at 457px. The section just carries far more
   copy, 651px against About's 441 and Contact's 317.
   So the line moved rather than the layout stretching. It is the THIRD child of
   the grid, which is what makes both cases work: below 1120 the section stacks and
   it lands last, after the headline and the body, where a conclusion belongs. From
   1120 it is placed in column 1 under the figure instead.
   The body spanning both rows is the load-bearing part. Without it, row 1 stretches
   to the text's height and the line floats far below the picture.
   Do not "simplify" this by nesting the paragraph inside the figure. That was tried
   first. It measures well on a desktop and is wrong on a phone, because the figure
   moves as one block and the punchline then reads out before the section label. */
@media (min-width:1120px){
  .split--pull{row-gap:24px;}
  .split--pull > .figure{grid-row:1;grid-column:1;}
  .split--pull > .home__pull{grid-row:2;grid-column:1;}
  .split--pull > .split__body{grid-row:1 / span 2;grid-column:2;}
}

/* ---------- real people (27 Aug) --------------------------------------
   Tommy asked for staff headshots on the hero and a human presence on
   services, and Tim said to name everyone on About. These are the four
   Seed Legal paralegals, photographed, from Seed's own team page. They
   are the first real faces on this site: everything before them was
   generated, which is why three images had to come off last week.

   Source frames are only about 210x300, so they are used small and
   circular. If better photography arrives these swap straight in.

   28 Aug: recut as `face-*-288.webp`. The four originals were shot in one
   session against the same backdrop, but they were framed loosely and
   differently — face widths of 86, 92, 97 and 106px, and face centres 45px
   apart vertically. Every crop is now built from a detected face box, to one
   rule: the face is half the circle's diameter, and the crop centre sits
   0.22 of a face-height below the face centre (0.16 was tested first and
   clipped the top of Loretta's hair; 0.26 started showing too much chest). So all four heads are the
   same size at the same height, which is what a row of portraits is for.
   The cost is honest: the crops are tighter than the frame, so the source
   pixels per portrait fall to 172-212 and the 288px asset is a 1.36x to
   1.67x upscale. At 144px display that is invisible on a photograph, and a
   row of mismatched head sizes was not. New filenames, per the caching rule. */
.faces{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:0 14px;
  margin-top:clamp(20px,2.4vw,30px);
}
.faces__f{
  width:clamp(38px,3.4vw,46px);aspect-ratio:1;
  border-radius:50%;object-fit:cover;display:block;
  border:2px solid var(--paper);
  margin-right:-12px;                 /* a row, slightly overlapped, not a grid */
  background:var(--sunk);
}
.faces__f:last-of-type{margin-right:0;}
.faces__cap{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:max(11.5px,.68rem);letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);margin-left:20px;
}
.band--sunk .faces__f{border-color:var(--sunk);}
.faces--svc{margin-top:clamp(24px,3vw,36px);}

/* Alex, 27 Aug: centre the circles on mobile "so it looks balanced". Agreed,
   and only here. The four circles are a decorative group, not part of the
   reading column, and flush left they leave about 180px of empty paper to
   their right under a full-width standfirst.
   The figure captions he asked about in the same note are deliberately NOT
   centred: they are .u-label, the same component as every section label on
   the site, and centring one instance of it would make the same component
   behave two different ways on one page. */
@media (max-width:640px){
  .faces{justify-content:center;}
  .faces__cap{flex-basis:100%;text-align:center;margin-left:0;margin-top:12px;}
}

/* The About team block. Names and roles are facts off Seed's own team
   page, so they carry no claim beyond who works here. */
.team{
  list-style:none;margin:clamp(30px,4vw,48px) 0 0;padding:0;
  display:grid;gap:clamp(24px,2.6vw,40px);
  grid-template-columns:repeat(4,minmax(0,1fr));
  /* Width, third and final answer. It was --list-w (borrowed off Services for
     no reason), then the full band (four 116px circles 2.8x their own diameter
     apart — four separate people, not a team), then 1090 to pull them together.
     1090 was the right answer for 116px portraits and the wrong one for these.
     The recut crops carry 144px, and at the full band width that is 324px
     centre-to-centre: 2.25x diameter, tighter than the 2.4x the 1090 version
     achieved at 116px. Bigger portraits buy the width back. So: full band,
     and the ratio is measured rather than assumed. */
}
/* Never three-across: auto-fit used to give 3 columns between roughly 560 and
   700px wide, which left one person orphaned on a second row. Four, then two.
   The switch moved from 719 to 859 when the portraits grew to 144px: at 760 a
   four-across row put 100px circles 177px apart, 1.8x diameter, with the longest
   role breaking to three lines. Two-across holds the rhythm instead. */
@media (max-width:859px){
  .team{grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 20px;}
}
/* Five across from 1100px. The grid was four because the team was four, one
   clean row. It is ten now, and ten across four is 4/4/2 with a two-person
   orphan row that reads as an accident. Ten across five is 5/5. Ten divides by
   five and by two, which is why those are the two counts here and why nothing
   in between is worth having. Added 3 Sep with the six new people. */
@media (min-width:1100px){
  .team{grid-template-columns:repeat(5,minmax(0,1fr));}
}
.team__m{display:flex;flex-direction:column;align-items:flex-start;gap:4px;}
.team__f{
  width:clamp(88px,10vw,144px);aspect-ratio:1;
  border-radius:50%;object-fit:cover;display:block;
  margin-bottom:14px;background:var(--sunk);
}
.team__name{
  font-family:"Newsreader",Georgia,serif;font-weight:300;
  font-size:clamp(1.05rem,.95rem + .3vw,1.24rem);line-height:1.2;
  font-variation-settings:"opsz" 20;
}
.team__role{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:max(11.5px,.68rem);letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3);line-height:1.45;
}
@media (max-width:520px){
  .faces__cap{margin-left:0;flex-basis:100%;margin-top:12px;}
}
@media print{ .faces{display:none;} .team__f{width:70px;} }


/* Section 04's figure used to float right of a mostly empty column, which
   read as a hole once the copy block landed above it. Statement stays full
   width; the copy and the image then sit as a deliberate two-column row. */
.statement__split{display:grid;gap:clamp(28px,4vw,56px);margin-top:clamp(30px,4vw,52px);}
@media (min-width:900px){
  .statement__split{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);align-items:start;}
  .statement__split .statement__figure{display:block;margin-top:0;}
  .statement__split .statement__figure img{grid-column:auto;}
  .statement__split .statement__figure figcaption{
    grid-column:auto;grid-row:auto;flex-direction:row;align-items:baseline;
    text-align:left;margin-top:11px;
  }
}

/* The vehicle band was here and is gone: Tim ruled on 27 Aug that the car
   belongs on the Seed reception site, not the legal one. See the comment where
   the band used to sit in contact.html.

   Recording a mistake of mine that shipped in between, because it is the kind
   that hides: the comment above these rules was edited on 27 Aug and left TWO
   closing `*​/` with loose prose between them. That is invalid CSS. The parser
   discarded the block silently and nothing looked broken, because `.figure img`
   already carried the only declaration that mattered. **A stylesheet edit is
   not verified by the page still looking right.** The brace/comment balance is
   now checked mechanically before every deploy. */

/* ---------- LEAP and Xero (28 Aug) ------------------------------------
   Tommy supplied the official artwork and said to use it. Placement rules are
   Alex's, and the reasoning for each is in the comment in index.html.

   Sizing: the two files have different internal padding, so matching by box
   height would make one look much bigger than the other. LEAP's box is
   576.64x169.94 and includes a square icon taller than its own letters; Xero's
   is 103x29 and is letters only. The heights below were set by rendering both
   and matching the LETTERFORMS, not the boxes.

   Neither file is recoloured, cropped or redrawn. If either needs to change,
   replace the file, do not restyle it here. */
.marks{
  display:flex;align-items:center;
  gap:clamp(28px,3.6vw,52px);
  margin-top:clamp(30px,3.6vw,44px);
  /* Clear space. Both brand guidelines ask for room around the mark, and the
     usual measure is at least the height of the mark itself. LEAP renders at
     38px here, so 30px above and 22px below was under it on both sides. 40 and
     34 clears it and reads better anyway. If either mark is ever resized, this
     spacing moves with it. */
  padding-top:clamp(28px,3vw,40px);
  border-top:1px solid var(--rule);
  flex-wrap:wrap;
}
.marks__m{display:block;width:auto;}
.marks__m--leap{height:clamp(30px,3.4vw,38px);}
.marks__m--xero{height:clamp(19px,2.1vw,24px);}
/* MYOB, 3 Sep. Same rule as the other two: sized on letterforms, not on the box.
   "myob" is lowercase so the matched measurement is X-HEIGHT, exactly as Xero's
   all-lowercase wordmark was matched to LEAP's caps.
   Measured at 4x on the knocked-out file: x-height is 278px of its 526px height,
   so an x-height of 24.5px means a rendered height of 46px. The clamp below is
   Xero's clamp multiplied by 46/24, so the three stay locked together at every
   width rather than drifting apart on the way down.
   No nudge is needed: the mark's baseline sits at 75.3% of its own height, which
   happens to put it within 0.3px of Xero's baseline under align-items:center.
   Verified, not assumed. If any of the three is resized, re-measure all three. */
.marks__m--myob{height:clamp(37px,4.1vw,46px);}
.marks__note{
  margin-top:clamp(24px,2.6vw,34px);
  color:var(--ink-2);font-size:.97rem;line-height:1.55;max-width:34em;
}
.marks__fine{
  margin-top:11px;
  color:var(--ink-3);font-size:max(11.5px,.72rem);line-height:1.5;max-width:40em;
}
@media print{ .marks__m{height:22pt;} }

/* ---------- discipline dividers (28 Aug) ------------------------------
   Full-column photography between the four disciplines. The band's own
   padding is halved: these sit between two sections that already carry
   generous padding, and the full amount three times over reads as a gap
   rather than a break. Same flush-both-gutters treatment as every other
   figure, so the right edge lands on the site's own line. */
.divider{padding-block:clamp(26px,3.2vw,48px);}
/* Held to --list-w, which is the column EVERYTHING else on this page uses: the
   hero, the contents list, the discipline rail and all 39 service rows all stop
   at 1192 on a 1440 screen. When I added these on 28 Aug they ran to the full
   shell at 1368, so the two photographs stuck out 176px past every other
   element on the page. My own version of the fault I spent the morning fixing
   elsewhere. If --list-w ever changes, these follow it. */
.divider__fig{max-width:var(--list-w);}
.divider__fig img{
  width:100%;height:auto;display:block;
  /* The divider used to fill a laptop screen edge to edge: 749px of section on
     an 860px window. Between two dense lists that stops reading as a breath and
     starts reading as the end of the page — there is nothing after it in view to
     say otherwise. Capped so the top of the next discipline stays on screen.
     No effect below 900px, where the image is only ~195px tall anyway.

     The anchor was 68% until 1 Sep, and the reason given was sound at the time:
     "the file on the table is the subject; the ceiling and the shelves are not".
     Both dividers were object photography then — an open volume on a table, a
     file during a meeting. Ticket 0005 replaced them with PEOPLE, and nobody
     came back to the crop. 68% takes the overflow off the TOP, so it was
     removing 71px at 1456 wide, 86px at 1512 and 109px at 1280 — measured — and
     the top of a head sits about 77px down in divider 1 and 54px down in
     divider 2. Both were being scalped at every width. Javonte spotted it.

     22% now. At the worst measured case, 1280 wide with 160px of overflow, that
     is 35px off the top, which clears both heads with room. The remainder comes
     off the bottom, which is floor and desk edge in both frames.

     The rule, since this is the second time a comment has outlived the thing it
     described: if the SUBJECT of a divider image ever changes, re-derive this
     number. It is not a taste setting, it is a function of where the heads are. */
  max-height:min(520px,58vh);
  object-fit:cover;object-position:50% 22%;
}
@media print{ .divider{display:none;} }

/* ---------- discipline rail: where you are, and the way out (28 Aug) --------
   Services is 7,300px tall and the contents list lives only at the very top.
   Once you are inside a discipline there is no indication of position and no
   way to reach the other three without scrolling back. The rail is already
   sticky and the paper beside a thirteen-row list is empty, so this costs
   nothing and the page stops being a one-way corridor. */
.disc__pos{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:max(11px,.64rem);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);
  margin:clamp(26px,3vw,38px) 0 0;
  padding-top:clamp(14px,1.6vw,18px);
  border-top:1px solid var(--rule);
  font-variant-numeric:tabular-nums;
}
.disc__more{display:flex;flex-direction:column;gap:9px;margin-top:13px;}
.disc__more a{
  font-family:"Familjen Grotesk",system-ui,sans-serif;
  font-size:max(12.5px,.76rem);
  color:var(--ink-2);text-decoration:none;
  transition:color .3s var(--ease);
  /* Numbered. Without the numbers this list sat under "03 of 04" as three
     unqualified names and read like the contents of the discipline you were
     already in, rather than the way out of it. 01 / 02 / 04 under a 03 says
     what it is without a second micro-label. */
  display:grid;grid-template-columns:1.9em minmax(0,1fr);align-items:baseline;
}
.disc__more-n{color:var(--blue);font-size:max(11px,.68rem);}
.disc__more a:focus-visible{color:var(--ink);}
@media (hover:hover){ .disc__more a:hover{color:var(--ink);} }
@media print{ .disc__pos,.disc__more{display:none;} }
/* Only where the rail is actually a rail. Below 960 the columns stack, so this
   would sit between the intro and the first service and push the list 130px
   down the phone — paying for wayfinding at the one point in the section where
   nobody needs it yet. The contents list at the top of the page covers mobile. */
@media (max-width:959px){ .disc__pos,.disc__more{display:none;} }
