/* ==========================================================================
   Oakes Consulting — site stylesheet

   Extracted from index.njk on 2026-09-02. It had grown to 326 lines inlined
   in the home page, which was fine for one page and would have meant five
   drifting copies once the interior pages existed.

   The .dirB- prefix is a fossil of the exploration this design won as
   "direction B". Left alone on purpose: renaming every selector across every
   page is a large diff with no user-visible benefit, and the risk of a missed
   selector is real. It is a name, and the name is documented here.

   Colour was measured, never estimated:
     paper #F4F5F6 on black #0B0D0F = 17.83
     muted #9AA1A8 on black         =  7.45   AA / AAA
     gold  #C9A227 on black         =  8.05   AA / AAA
     steel #4A88B5 on black         =  5.08   AA
   On the light section ground #F4F5F6:
     ink   #16181A = 16.31   muted #565D63 = 6.12   gold #8A6B21 = 4.57
   Gold FAILS AA for body text on any light ground. On light it is rules and
   display type only; on the dark ground the restriction lifts.
   ========================================================================== */

/* ==========================================================================
   Direction B — dark and serious
   ========================================================================== */

/* The browser's default 8px body margin was never reset. It inset every
   content column by 8px while the fixed header, which resolves against the
   viewport rather than the body box, ignored it. That is where the 8px
   mismatch between the logo and the body content came from below 1400px.
   Resetting it moves all content 8px left and puts both on the same origin. */
body { margin: 0; }

.dirB {
  --black:    #0B0D0F;
  --black-2:  #14171A;   /* raised card on the dark ground */
  --paper:    #F4F5F6;
  --ink:      #16181A;

  --muted:      #9AA1A8;  /* on dark  */
  --muted-lite: #565D63;  /* on light */

  /* Gold clears AAA on the dark ground at 8.05, so on dark it may be text.
     In the light section it drops to 4.57 at the deepened value and fails
     entirely at the bright one, so light-section gold is the deep cut and is
     still kept off small print. */
  --gold:      #C9A227;
  --gold-deep: #8A6B21;
  --steel:     #4A88B5;

  --hair:      rgba(244, 245, 246, 0.14);
  /* Interactive borders, which are held to a different standard than the
     decorative hairlines above. WCAG 1.4.11 wants 3.0 for the boundary of a UI
     component. At the --hair value a ghost button's edge measured 1.42 on the
     page ground and 1.53 over the hero tree, failing by more than half. At .45
     it measures 4.24 and 3.94. Deliberately short of the label's own colour:
     a full-white edge measures 13.41 over the tree and makes the secondary
     button read as loud as the solid one beside it. */
  --control-edge: rgba(244, 245, 246, 0.45);
  --hair-lite: rgba(22, 24, 26, 0.14);

  --font-display: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: clamp(1.25rem, 5vw, 4.5rem);
  --gap: clamp(4rem, 9vw, 9rem);

  background: var(--black);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 17px; line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

.dirB *, .dirB *::before, .dirB *::after { box-sizing: border-box; }
.dirB :where(p, h1, h2, h3, ul, li) { margin: 0; }
.dirB ul { list-style: none; padding: 0; }

.dirB__wrap { max-width: 1400px; margin: 0 auto; padding-inline: var(--pad); }

.dirB h1, .dirB h2, .dirB h3 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.dirB .mono {
  font-family: var(--font-mono);
  font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}

/* ---------- header ---------- */
/* Fixed, not absolute. An absolutely positioned header scrolls away with the
   page and has no way to come back, which is the whole reason the hide-and-
   return behaviour did nothing here. Interior pages override to sticky below,
   so the bar still holds its own space in the flow there. */
.dirB-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 5;
  border-bottom: 1px solid transparent;
  transition: transform .32s var(--ease-out, cubic-bezier(0,0,.2,1)),
              background-color .32s var(--ease-out, cubic-bezier(0,0,.2,1)),
              border-color .32s var(--ease-out, cubic-bezier(0,0,.2,1));
}
/* Both applied by main.js. The controller only ever toggles a class and never
   writes an inline style, so if the script fails to load the header stays a
   perfectly usable static one rather than a hidden one. */
.dirB-head.is-hidden { transform: translateY(-100%); }
.dirB-head.is-stuck {
  background: var(--black);
  border-bottom-color: var(--hair);
}
/* max-width:none puts the logo on the left screen edge and the nav on the
   right, instead of inside the 1400px content column. The wrap's own
   padding-inline still keeps both off the glass. This is the same pattern the
   church site uses. It deliberately breaks alignment with the headline below,
   which is a decision rather than an oversight: see the note on .dirB-hero. */
.dirB-head__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 2rem; padding-block: 26px;
  max-width: none;
}
.dirB-head__mark {
  display: flex; align-items: center; gap: 11px;
  color: var(--paper); text-decoration: none;
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; letter-spacing: -0.01em; white-space: nowrap;
}
.dirB-head__mark img { width: 30px; height: auto; display: block; opacity: .95; }
.dirB-head nav { display: flex; gap: clamp(1.25rem, 2.6vw, 2.25rem); }
.dirB-head nav a {
  color: var(--muted); text-decoration: none; font-size: 14px;
  transition: color .15s;
}
.dirB-head nav a:hover { color: var(--paper); }

/* See the note in direction A: below 760 the nav overflows the viewport. */
@media (max-width: 760px) {
  .dirB-head__in { flex-direction: column; align-items: flex-start; gap: 10px; }
  .dirB-head nav { flex-wrap: wrap; gap: .75rem 1.25rem; }
}

/* ---------- hero ---------- */
/* A full viewport. Type at a scale the rejected build never went near, and the
   engraving used as texture at the edge rather than as a picture in a box. */
.dirB-hero {
  position: relative; overflow: hidden;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-block: clamp(7rem, 14vh, 10rem) clamp(3rem, 7vh, 5rem);
}
.dirB-hero__oak {
  position: absolute; right: -4%; bottom: -7%; width: min(1250px, 92%);
  opacity: .16; pointer-events: none;
  /* Fading the plate into the ground stops it reading as a pasted-in image. */
  -webkit-mask-image: linear-gradient(to top, transparent 2%, #000 46%),
                      linear-gradient(to left, #000 55%, transparent 96%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to top, transparent 2%, #000 46%),
                      linear-gradient(to left, #000 55%, transparent 96%);
          mask-composite: intersect;
}
.dirB-hero__oak img { width: 100%; height: auto; display: block; }

/* Mobile. The percentage offsets above resolve against the HERO, not the tree,
   so on a phone the hero is still ~844px tall while the tree has shrunk to
   ~194px: bottom:-18% then clipped 152px of a 194px image and left 22% of it
   showing. The bottom fade compounded it, dissolving the trunk as well.
   So on small screens the tree sits higher, runs wider, and keeps more of
   itself: measured back up to roughly 80% visible. */
@media (max-width: 760px) {
  .dirB-hero__oak {
    right: -20%;
    bottom: -3%;
    width: min(760px, 132%);
    opacity: .19;
    -webkit-mask-image: linear-gradient(to top, transparent 1%, #000 30%),
                        linear-gradient(to left, #000 62%, transparent 99%);
            mask-image: linear-gradient(to top, transparent 1%, #000 30%),
                        linear-gradient(to left, #000 62%, transparent 99%);
  }
}
/* width:100% matters. The hero is a column flex container, and .dirB__wrap
   carries `margin: 0 auto`. On a flex item those auto margins shrink the box
   to fit its contents instead of filling the 1400px column, which parked the
   whole hero 171px right of the grid line every section heading sits on.
   Stretching it puts the hero back on the same left edge as the body of the
   page. The header is deliberately not on that line any more: it was pushed
   out to the screen edges on 2026-09-03, so the logo sits left of this. */
.dirB-hero > .dirB__wrap { position: relative; z-index: 2; width: 100%; }

.dirB-hero h1 {
  font-size: clamp(2.9rem, 7.6vw, 6.6rem);
  /* Breaks the headline as "The work has outgrown / the way it is run."
     Measured in Archivo 600 at the capped size: the first line needs 18.22ch,
     and pulling "the" up onto it would need 21.03ch. Anything inside that
     window produces the break; 19.5ch sits near the middle so a fallback
     font's metrics cannot tip it either way. Both bounds scale with the font,
     so the break holds as the clamp shrinks. Measured: two lines down to a
     540px viewport, and at 530px and below the first line no longer fits the
     column and wraps further on its own, which is correct. */
  max-width: 19.5ch;
  margin-top: clamp(1.5rem, 3vh, 2.25rem);
}
.dirB-hero__lede {
  margin-top: clamp(1.5rem, 3vh, 2.25rem);
  max-width: 50ch; font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  color: var(--muted); line-height: 1.55;
}

.dirB-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: clamp(2rem, 4vh, 2.75rem); }
.dirB-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 26px; border-radius: 2px;
  background: var(--paper); color: var(--black);
  font-size: 14px; font-weight: 500; text-decoration: none;
  border: 1px solid var(--paper);
  transition: background .18s, color .18s, border-color .18s;
}
/* Hover softens each button rather than inverting it.

   The old behaviour swapped them: the solid one went transparent and the ghost
   went solid, so moving between the two looked like they traded identities.

   They cannot share a hover background, which was the obvious fix. A black
   label and a white label pass AA on opposite sides of the range and cross
   through the failing zone: at .45 white a black label measures 4.24 and a
   white one 4.21, and both need 4.5. There is no value that serves both.

   So each keeps its own label colour and moves a short distance instead. The
   solid one dims slightly, the ghost one lifts slightly, and neither becomes
   the other. Measured: black on .88 is 13.79, white on .14 is well past 5.94. */
.dirB-btn:hover {
  background: rgba(244, 245, 246, .88);
  border-color: rgba(244, 245, 246, .88);
  color: var(--black);
}
.dirB-btn--ghost { background: transparent; color: var(--paper); border-color: var(--control-edge); }
.dirB-btn--ghost:hover {
  background: rgba(244, 245, 246, .14);
  border-color: rgba(244, 245, 246, .7);
  color: var(--paper);
}

/* ---------- section furniture ---------- */
.dirB-sec { padding-block: var(--gap); }
/* Section numbers were removed on 2026-09-03. They numbered things that were
   not a sequence, the scheme had already broken (engagement.njk opened on an
   orphaned "05"), and the mono/caps/zero-padded-number stack is the loudest
   generated-looking element on a page. The eyebrow label stays: it says what
   the section is. The .01-.04 on the service cards also stay, because the copy
   states they are listed in the order they happen, so those numbers inform. */
.dirB-secmark {
  display: flex; align-items: baseline;
  padding-bottom: 16px; margin-bottom: clamp(2.25rem, 4.5vw, 3.5rem);
  border-bottom: 1px solid var(--hair);
}
.dirB-lite .dirB-secmark { border-bottom-color: var(--hair-lite); }
.dirB-lite .dirB-secmark .mono { color: var(--muted-lite); }

.dirB h2 { font-size: clamp(1.85rem, 3.7vw, 3.1rem); max-width: 21ch; }
/* A wider measure for headings meant to land on one line. "Four things. Most
   people need one of them." measures 33.4ch, against the 21ch global cap that
   was wrapping it. Scoped as a modifier rather than raising that cap: at 35ch
   ten other headings across four pages reflow, and several of them read better
   on two lines. Still a max-width, so narrow viewports wrap normally. */
.dirB h2.dirB-h2--wide { max-width: 35ch; }
.dirB h3 { font-size: clamp(1.25rem, 1.9vw, 1.6rem); letter-spacing: -0.02em; }
.dirB .lede { font-size: clamp(1rem, 1.3vw, 1.18rem); color: var(--muted); max-width: 54ch; line-height: 1.55; }
.dirB-lite .lede { color: var(--muted-lite); }
.dirB .body { max-width: 62ch; }
.dirB .body p + p { margin-top: 1.1em; }

/* ---------- capabilities: the unequal editorial grid, on dark ---------- */
/* Ryan's call, 2026-09-02: keep direction C's unequal grid here rather than
   the Palantir-style ruled list, because the different-sized panels "add some
   really interesting context." He also liked the pop the ruled list had on
   hover, so that behaviour is carried across rather than dropped.
   Four equal boxes is the single most template-looking arrangement there is;
   the 4/2 - 2/4 split is what makes it read as designed. */
.dirB-grid {
  display: grid; gap: 1px; background: var(--hair);
  grid-template-columns: 1fr;
  border-block: 1px solid var(--hair);
}
@media (min-width: 820px) {
  .dirB-grid { grid-template-columns: repeat(6, 1fr); }
  .dirB-grid > article:nth-child(1) { grid-column: span 4; }
  .dirB-grid > article:nth-child(2) { grid-column: span 2; }
  .dirB-grid > article:nth-child(3) { grid-column: span 2; }
  .dirB-grid > article:nth-child(4) { grid-column: span 4; }
}
.dirB-grid > article {
  position: relative;
  background: var(--black);
  padding: clamp(1.75rem, 3.2vw, 2.75rem);
  display: flex; flex-direction: column; gap: 12px;
  min-height: clamp(200px, 21vw, 280px);
  transition: background .22s ease;
}
/* The pop. A lift with transform would open hairline seams in a 1px-gap grid,
   so it is a gold rule wiping in from the left plus a lift in the ground. */
.dirB-grid > article::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.dirB-grid > article:hover { background: var(--black-2); }
.dirB-grid > article:hover::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .dirB-grid > article::before { transition: none; }
  /* Keep the bar put rather than sliding it. Hiding it entirely would take
     the nav away from someone who asked for less motion, not more. */
  .dirB-head { transition: none; }
  .dirB-head.is-hidden { transform: none; }
}
.dirB-grid .n { color: var(--gold); }
.dirB-grid p { color: var(--muted); max-width: 46ch; }

/* ---------- the light section ---------- */
/* The single inversion in the page. */
.dirB-lite {
  background: var(--paper); color: var(--ink);
  padding-block: var(--gap);
}
.dirB-lite h2, .dirB-lite h3 { color: var(--ink); }
.dirB-lite .body p { color: #33383D; }
.dirB-lite strong { font-weight: 600; color: var(--ink); }

.dirB-split { display: grid; gap: clamp(2rem, 5vw, 5rem); grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .dirB-split { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); }
}

.dirB-quote {
  border-left: 3px solid var(--gold-deep);
  padding-left: clamp(1.1rem, 2.2vw, 1.75rem);
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.dirB-quote p {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.15rem, 1.9vw, 1.5rem); line-height: 1.28;
  letter-spacing: -0.02em; color: var(--ink);
}
.dirB-quote cite {
  display: block; margin-top: 12px; font-style: normal;
  font-family: var(--font-mono); font-size: 11.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted-lite);
}

/* ---------- the wallpaper band ---------- */
/* Ryan liked the cropped tree behind direction A's closing band: "it's almost
   like wallpaper kind of-ish." Zoomed further here so it reads as canopy
   texture rather than as a small picture of a tree, which keeps it distinct
   from the whole silhouette used in the hero.
   The art is a background-image rather than an <img> so it can be scaled and
   positioned into the canopy without a wrapper doing transform gymnastics. */
.dirB-wall { position: relative; overflow: hidden; }
.dirB-wall__art {
  position: absolute; inset: 0; pointer-events: none;
  background-image: url("/assets/img/oak-white-1600.png");
  background-repeat: no-repeat;
  background-size: 210% auto;
  background-position: 50% 34%;   /* sits in the canopy, not on the trunk */
  opacity: .085;
  /* Feathered so it dissolves into the ground instead of ending on a hard
     rectangle edge. */
  -webkit-mask-image: radial-gradient(125% 105% at 50% 42%, #000 26%, transparent 76%);
          mask-image: radial-gradient(125% 105% at 50% 42%, #000 26%, transparent 76%);
}
.dirB-wall > .dirB__wrap { position: relative; z-index: 2; }

/* The blue band was tried here and rejected: Ryan's call 2026-09-02 is the
   black band, not blue. The variant and its toggle are gone rather than left
   commented out. If it is ever revisited, the finding worth keeping is that
   direction C's #1B3A57 does NOT survive on a dark ground — muted text lands
   at 4.49, under AA — and #16324C was the cut that did. */

/* ---------- stat-free proof strip ---------- */
/* Deliberately NOT counts. Counts measure what was built rather than what
   changed, and the brief rules specifics off the home page entirely. These are
   commitments, which are checkable and do not go stale. */
.dirB-commit { display: grid; gap: 1px; background: var(--hair); grid-template-columns: 1fr; }
@media (min-width: 760px) { .dirB-commit { grid-template-columns: repeat(3, 1fr); } }
.dirB-commit > div { background: var(--black); padding: clamp(1.5rem, 3vw, 2.25rem); }
.dirB-commit h3 { margin-bottom: 10px; }
.dirB-commit p { color: var(--muted); font-size: 15px; }

/* ---------- portrait ----------
   The placeholder rules that lived here are gone. Every shaped block they drew
   has been filled or cut: the portrait is a real photograph, and the diagram
   slot was removed rather than filled. See the commit for why.

   The portrait sits in the LIGHT section, not the dark one. Its own
   backdrop is a near-black charcoal, so it lands as a dark plate on the
   pale ground, which echoes the dark bands above and below rather than
   looking dropped in. Source is 928px wide, so 900 is effectively native;
   there is no real 2x to offer until a higher-resolution shot exists. */
.dirB-portrait { width: 100%; height: auto; display: block; aspect-ratio: 4/5; object-fit: cover; }

/* ---------- two-up close ---------- */
/* ---------- the page's final block ----------
   Replaced the two-up closer on 2026-09-03. That version put "Start a
   conversation" beside "See how an engagement runs", which split attention at
   the exact moment the page is asking for a decision, and spent half the
   closing on a link already sitting in the nav of every page. A page should
   end on the one thing you want someone to do. */
.dirB-final {
  border-top: 1px solid var(--hair);
  padding-block: clamp(4rem, 9vw, 7.5rem);
  text-align: center;
}
.dirB-final__rule {
  width: 64px; height: 2px; background: var(--gold);
  margin: 0 auto clamp(1.75rem, 3.5vw, 2.5rem);
}
.dirB-final h2 {
  font-size: clamp(1.9rem, 4.2vw, 3.2rem);
  max-width: 18ch; margin-inline: auto;
}
.dirB-final p {
  margin: clamp(1.25rem, 2.5vw, 1.75rem) auto 0;
  max-width: min(44rem, 92%);
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  line-height: 1.6; color: var(--muted);
}
.dirB-final .dirB-actions { justify-content: center; }

/* ---------- footer ---------- */
/* ---------- footer ----------
   Rebuilt 2026-09-03. It was three unlabelled items in a single flex row, which
   read as a stray line of text rather than a footer, and gave the page no
   ending. Now: labelled columns, then the wordmark at scale as the closing
   note, then the legal bar. The wordmark does the job the tree does elsewhere
   without repeating the tree, which by this point in a page has already
   appeared three times. */
.dirB-foot {
  border-top: 1px solid var(--hair);
  padding-top: clamp(3rem, 6vw, 4.5rem);
  /* Guard. The wordmark is sized in vw against a nowrap string, so a font
     substitution or a metric change could push it past the viewport and give
     the whole document a horizontal scrollbar. Clipping here means the worst
     case is a cropped letter rather than a broken page. */
  overflow-x: clip;
}

.dirB-foot__cols {
  display: grid; gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: 1fr;
}
@media (min-width: 700px) {
  .dirB-foot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.dirB-foot__cols h2 {
  font-family: var(--font-mono); font-weight: 500;
  font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 1rem;
}
.dirB-foot__cols ul { display: grid; gap: .55rem; }
.dirB-foot__cols li, .dirB-foot__cols p { font-size: 15px; color: var(--muted); }
.dirB-foot a {
  color: var(--paper); text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color .15s;
}
.dirB-foot a:hover { border-bottom-color: var(--paper); }

/* The wordmark, set to fill the measure. Low contrast on purpose: it is the
   page signing off, not another heading competing for attention. */
.dirB-foot__mark {
  /* Sits last, and outside the text column: at 12.2vw it filled that column to
     the pixel at every width, so the only way to grow it is to let it run to
     the viewport edges instead. Padding rather than margin at the foot so the
     descender on the g has somewhere to go, since line-height 0.9 crops it
     against a hard edge. */
  margin-top: clamp(2.25rem, 4.5vw, 3.5rem);
  padding-inline: clamp(.5rem, 1vw, 1rem);
  padding-bottom: clamp(1rem, 2vw, 1.75rem);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.8rem, 12.4vw, 15.5rem);
  line-height: .9; letter-spacing: -.05em;
  text-align: center;
  /* letter-spacing applies after the LAST character as well, so with a negative
     value the text box ends short of where the glyphs do and centring leaves
     the word sitting left: measured 55px against 70px at 1440. .05em cancels
     that trailing gap; the rest closes the residual left/right side bearings on
     the O and the g. Expressed in em so it holds at every size. */
  text-indent: .067em;
  color: rgba(244, 245, 246, .085);
  user-select: none; white-space: nowrap;
}

/* The copyright sits under the contact details rather than in a bar of its
   own, so the footer carries three columns and a wordmark instead of three
   columns, a bar and a wordmark. */
.dirB-foot__legal { margin-top: 1.5rem; font-size: 13px; color: var(--muted); }


/* ==========================================================================
   Print. A dark page otherwise comes out as a black rectangle or gets its
   backgrounds stripped by the browser. One of the few real costs of going
   dark, and cheap to answer.
   ========================================================================== */
@media print {
  .dirB, .dirB-lite, .dirB-wall { background:#fff !important; color:#111 !important; }
  .dirB h1, .dirB h2, .dirB h3, .dirB .mono, .dirB p, .dirB a { color:#111 !important; }
  .dirB-hero { min-height:auto !important; }
  .dirB-hero__oak, .dirB-wall__art, .dirswitch { display:none !important; }
  .dirB-grid, .dirB-commit { background:#ccc !important; }
  .dirB-grid > article, .dirB-commit > div { background:#fff !important; }
}

/* ==========================================================================
   Interior pages

   The home page opens on a full-viewport hero. Interior pages must not: a
   reader who clicked "What we do" wants the answer, not another curtain. They
   open on a compact masthead instead, sized so the first real content is
   visible without scrolling on a laptop.
   ========================================================================== */

/* The header is fixed over the home hero. Interior pages have no hero to sit
   over, so it holds its own space in the flow instead. Sticky rather than
   static: it still needs to hide and return on scroll, and sticky occupies
   flow space the way static did, so nothing below it shifts. The class name
   is kept because four templates set it. */
.dirB-head--static { position: sticky; top: 0; }

.dirB-masthead {
  padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--hair);
}
.dirB-masthead h1 {
  font-size: clamp(2.3rem, 5.4vw, 4.2rem);
  max-width: 17ch;
  margin-top: clamp(1rem, 2vw, 1.5rem);
}
/* Opt in where a headline is short enough to hold one line and reads better
   for it. The 17ch default exists to stop long headlines running the full
   1400px measure; a short one does not need protecting from that. Below the
   breakpoint it wraps naturally, because it has to. */
.dirB-masthead--full h1 { max-width: none; }
.dirB-masthead .lede {
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  max-width: 58ch;
}

/* A capability block: the category, what it means, and the named pieces of
   work that sit under it. The taxonomy research is explicit that the top layer
   carries every audience and the layer beneath it carries the proof. */
.dirB-cap {
  display: grid; gap: clamp(1rem, 2.5vw, 2.5rem);
  grid-template-columns: 1fr;
  padding-block: clamp(2.25rem, 4.5vw, 3.5rem);
  border-bottom: 1px solid var(--hair);
}
@media (min-width: 900px) {
  /* The heading column is held at a fixed measure rather than 1fr. As 1fr it
     took half the row while the headings only filled 290px of it, so the gap
     read as an accident. */
  .dirB-cap { grid-template-columns: 4.5rem minmax(0, 20rem) minmax(0, 1fr); align-items: start; }
}
.dirB-cap__n { color: var(--gold); }
/* No ch measure here. ch is font-size relative, and at this size 18ch is only
   about 290px, which broke "Process and policy design" across two lines while
   630px of column sat empty beside it. The column width is the constraint. */
.dirB-cap h2 { font-size: clamp(1.5rem, 2.5vw, 2rem); }
.dirB-cap p { color: var(--muted); }

.dirB-under { margin-top: 1.25rem; }
.dirB-under li {
  padding-block: 9px; border-top: 1px solid var(--hair);
  font-size: 15px; color: var(--paper);
}
.dirB-under li:first-child { border-top: 0; }

/* Numbered stages, for the engagement arc. Distinct from the capability list
   on purpose: this one IS a sequence and is allowed to look like one. */
.dirB-stage {
  display: grid; gap: clamp(.75rem, 2vw, 2.5rem);
  grid-template-columns: 1fr;
  padding-block: clamp(2rem, 4vw, 3rem);
  border-bottom: 1px solid var(--hair);
  position: relative;
}
@media (min-width: 900px) {
  .dirB-stage { grid-template-columns: 8.5rem minmax(0, 1fr); }
}
/* Word labels, not numerals. The capability list already uses .01-.04, and two
   different numbered fours on one site (both ending in "handover") is exactly
   the collision this wording avoids. */
.dirB-stage__n {
  font-family: var(--font-mono);
  font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold); padding-top: .55rem; white-space: nowrap;
}
.dirB-stage h2 { font-size: clamp(1.4rem, 2.4vw, 1.95rem); margin-bottom: .75rem; }
.dirB-stage p { color: var(--muted); max-width: 62ch; }
.dirB-stage p + p { margin-top: .9em; }

/* A quiet callout for things that need to be said plainly: how pricing works,
   what is deliberately not claimed. */
.dirB-note {
  border-left: 2px solid var(--gold);
  padding: clamp(1rem, 2vw, 1.5rem) clamp(1.1rem, 2.2vw, 1.75rem);
  background: var(--black-2);
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.dirB-lite .dirB-note { background: #E9EBED; border-left-color: var(--gold-deep); }
.dirB-note h3 { font-size: 1.05rem; margin-bottom: .5rem; }
.dirB-note p { color: var(--muted); font-size: 15px; }
.dirB-note p + p { margin-top: .75em; }
.dirB-lite .dirB-note p { color: var(--muted-lite); }

/* Closing call to action on interior pages. */
/* An onward link. Steel measures 5.08 on the dark ground and 6.63 on the light
   one, so it clears AA on both and needs no per-ground variant. */
.dirB-more {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: 1.5rem;
  color: var(--steel); text-decoration: none; font-weight: 500;
  border-bottom: 1px solid rgba(74,136,181,.35);
}
.dirB-lite .dirB-more { color: #2B5B7E; border-bottom-color: rgba(43,91,126,.35); }
.dirB-more span { transition: transform .2s ease; }
.dirB-more:hover span { transform: translateX(5px); }
@media (prefers-reduced-motion: reduce) { .dirB-more span { transition: none; } }

.dirB-end {
  padding-block: clamp(3.5rem, 7vw, 6rem);
  border-top: 1px solid var(--hair);
  display: grid; gap: clamp(1.25rem, 3vw, 2.5rem); grid-template-columns: 1fr;
}
@media (min-width: 860px) { .dirB-end { grid-template-columns: minmax(0,1fr) minmax(0,1fr); align-items: end; } }
/* The wrappers must fill their grid column. .dirB__wrap carries margin: 0 auto,
   and a grid item with auto side margins does NOT stretch: the margins absorb
   the free space and centre it at its content width instead. The heading is
   capped at 15ch, so its wrapper shrank to 274px and centred while the wrapper
   below it filled 375px, leaving the heading sitting 50px in from everything
   else. Measured on the About page at 390px wide. */
.dirB-end > .dirB__wrap { width: 100%; }
.dirB-end h2 { font-size: clamp(1.7rem, 3.2vw, 2.6rem); max-width: 15ch; }

/* ==========================================================================
   Scripture band

   Isaiah 61:3 set apart rather than paraphrased inside a paragraph. The oak
   engraving sits behind it because the verse is literally about oaks, which
   ties the verse, the firm's name and the mark into one moment instead of
   three separate references.

   Measured on the raised panel #14171A: paper 16.48, gold 7.44, muted 6.89.
   All clear AA, and gold clears AAA, so the emphasis may be gold here. On a
   LIGHT ground it could not be, which is the standing rule.
   ========================================================================== */
.dirB-scripture {
  position: relative; overflow: hidden;
  background: var(--black-2);
  border-block: 1px solid var(--hair);
  padding-block: clamp(3.5rem, 8vw, 6.5rem);
  text-align: center;
}
.dirB-scripture__art {
  position: absolute; inset: 0; pointer-events: none;
  background-image: url("/assets/img/oak-white-1600.png");
  background-repeat: no-repeat;
  background-size: 165% auto;
  background-position: 50% 42%;
  opacity: .07;
  -webkit-mask-image: radial-gradient(115% 100% at 50% 45%, #000 22%, transparent 72%);
          mask-image: radial-gradient(115% 100% at 50% 45%, #000 22%, transparent 72%);
}
.dirB-scripture > .dirB__wrap { position: relative; z-index: 2; }

.dirB-scripture blockquote {
  margin: 0 auto;
  /* Deliberately not a ch measure. ch scales with font size, and at this
     display size it produces a line far longer than it looks in the rule. */
  max-width: min(44rem, 92%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.35rem, 2.9vw, 2.35rem);
  line-height: 1.32;
  letter-spacing: -.02em;
  color: var(--paper);
}
/* The two phrases his story turns on. */
.dirB-scripture blockquote em {
  font-style: normal;
  color: var(--gold);
}
.dirB-scripture cite {
  display: block; margin-top: clamp(1.5rem, 3vw, 2.25rem);
  font-family: var(--font-mono); font-style: normal;
  font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold);
}
/* A hairline pair above and below the reference, the printer's device from the
   engraved direction, kept as the one ornament on the site. */
.dirB-scripture cite::before,
.dirB-scripture cite::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: clamp(1.5rem, 4vw, 3rem); height: 1px;
  background: currentColor; opacity: .5;
}
.dirB-scripture cite::before { margin-right: 1rem; }
.dirB-scripture cite::after  { margin-left: 1rem; }

.dirB-scripture__after {
  position: relative; z-index: 2;
  max-width: min(40rem, 92%); margin: clamp(2.25rem, 4.5vw, 3.25rem) auto 0;
  color: var(--muted); font-size: 1.02rem; line-height: 1.6;
}
