/* ==========================================================
   ht-law / components.css
   Layer 2. Same code every build.
   No literal colour, font name or pixel value in this file.
   ========================================================== */

/* ==========================================================
   BUTTONS
   ========================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-12);
  padding: var(--sp-16) var(--sp-28);
  font-family: var(--font-utility);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-meta);
  border-radius: var(--radius);
  cursor: pointer;
  transition:
    border-color     var(--dur-fast) var(--ease),
    background-color var(--dur-fast) var(--ease),
    color            var(--dur-fast) var(--ease);
  user-select: none;
  white-space: nowrap;
}

/* Inline SVG rather than a font glyph, per the kit's icon rule.
   It also survives a font that does not carry U+2192: Google's
   Figtree subset ships U+2191 and U+2193 but not the rightwards
   arrow, so the entity fell back to a system face on every button. */
.btn > .arrow {
  display: inline-block;
  width: 1.15em;
  height: 0.92em;
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease);
}

.btn:hover > .arrow { transform: translateX(var(--nudge)); }

.btn--block {
  width: 100%;
  justify-content: center;
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  border: var(--border) solid var(--accent);
}

.btn-primary:hover,
.btn-primary:active {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

/* A secondary button has to look like a control while it is just
   sitting there, because a hover cue is no help to someone deciding
   whether a thing is clickable at all.

   The outline does that work, and it stays transparent on purpose.
   A tinted fill would have to pick a background to sit on, and this
   button can land on --paper or on a --surface panel depending on
   where a clone puts it. The accent variant below can afford a fill
   because it only ever sits on the accent. */
.btn-secondary {
  background: transparent;
  color: var(--ink);
  border: var(--border) solid var(--btn-line);
}

.btn-secondary:hover {
  background: var(--surface);
  border-color: var(--ink);
}

.btn-secondary:active { border-color: var(--ink-line-press); }

/* On the accent field the two buttons invert. */
.on-accent .btn-primary {
  background: var(--accent-ink);
  color: var(--accent);
  border-color: var(--accent-ink);
}

.on-accent .btn-primary:hover {
  background: var(--accent-fill-hover);
  border-color: var(--accent-fill-hover);
  color: var(--accent);
}

.on-accent .btn-primary:active {
  background: var(--accent-fill-press);
  border-color: var(--accent-fill-press);
  color: var(--accent);
}

.on-accent .btn-secondary {
  background: var(--accent-btn-fill);
  color: var(--accent-ink);
  border-color: var(--accent-line);
}

.on-accent .btn-secondary:hover {
  background: var(--accent-fill-press);
  border-color: var(--accent-ink);
  color: var(--accent);
}

.on-accent .btn-secondary:active { border-color: var(--accent-line-press); }

/* ==========================================================
   HEADER · NAV · DRAWER
   ========================================================== */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.site-nav {
  padding: var(--sp-24) var(--gutter-wide);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--accent);
  border-bottom: var(--border) solid var(--accent-rule-soft);
  transition:
    padding      var(--dur-base) var(--ease),
    box-shadow   var(--dur-base) var(--ease),
    background   var(--dur-base) var(--ease),
    border-color var(--dur-base) var(--ease);
}

/* ─ .site-nav--over ─────────────────────────────────────────
   The home page only, and only while it is over the hero with
   the drawer shut.

   FX/FACET made the home hero a pale field, so the navy bar
   that works on every other page would sit as a hard slab
   across the top of it. Over the hero the bar goes transparent
   and its type flips to ink.

   Two states take it back to the ordinary navy bar, and both
   are conditions rather than new classes, so there is no second
   state machine to keep in step:

     .is-scrolled   nav.js already stamps this, and on this page
                    it fires one header-height before the hero
                    leaves, so the bar is opaque by the time real
                    content is behind it
     html.is-locked the drawer is open. The drawer panel is navy
                    and continues straight down from the bar, so
                    a transparent bar would leave a pale strip
                    above a navy sheet, and the drawer's own
                    links would inherit ink on navy

   Everything below is scoped to both. That means the scrolled
   bar and the open drawer are the ordinary component on all
   eight pages and nothing has to be restated.

   background and border-color are in the transition list on
   .site-nav so the flip fades rather than cutting.
   ────────────────────────────────────────────────────────── */

html:not(.is-locked) .site-nav--over:not(.is-scrolled) {
  background: transparent;
  border-bottom-color: transparent;
}

html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-logo { color: var(--ink); }

html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links a { color: var(--muted); }

html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links a:hover,
html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links a.is-active { color: var(--ink); }

/* Inverted against the scrolled bar: navy fill on the pale
   field, where the navy bar carries a white fill. */
html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links .nav-cta,
html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links .nav-cta.is-active {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-links .nav-cta:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--accent-ink);
}

html:not(.is-locked) .site-nav--over:not(.is-scrolled) .nav-hamburger span {
  background: var(--ink);
}

/* base.css gives every .site-nav descendant a white focus ring,
   which is correct on the navy bar and invisible here. */
html:not(.is-locked) .site-nav--over:not(.is-scrolled)
  :where(a, button, [tabindex]):focus-visible { outline-color: var(--accent); }

.site-nav.is-scrolled {
  padding: var(--sp-16) var(--gutter-wide);
  box-shadow: var(--shadow-nav);
  border-bottom-color: transparent;
}

.nav-logo {
  font-size: var(--step-nav);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  color: var(--accent-ink);
}

.nav-links {
  display: flex;
  gap: var(--sp-36);
}

.nav-links a {
  font-size: var(--step-utility);
  font-weight: var(--weight-medium);
  color: var(--accent-ink-body);
  transition: color var(--dur-link) var(--ease);
}

.nav-links a:hover,
.nav-links a.is-active { color: var(--accent-ink); }

.nav-links .nav-cta,
.nav-links .nav-cta.is-active {
  padding: var(--sp-9) var(--sp-18);
  background: var(--accent-ink);
  color: var(--accent);
  border: var(--border) solid var(--accent-ink);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-meta);
  transition:
    background   var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease);
}

.nav-links .nav-cta:hover {
  background: var(--accent-fill-hover);
  border-color: var(--accent-fill-hover);
  color: var(--accent);
}

.nav-links .nav-cta:active {
  background: var(--accent-fill-press);
  border-color: var(--accent-fill-press);
}

.nav-hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  gap: var(--sp-6);
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--sp-8);
  margin-right: calc(var(--sp-8) * -1);
  z-index: 101;
  opacity: 0.85;
  transition: opacity var(--dur-fast) var(--ease);
}

.nav-hamburger:hover { opacity: 1; }

.nav-hamburger span {
  display: block;
  height: var(--border);
  background: var(--accent-ink);
  transition:
    transform var(--dur-fast) var(--ease),
    opacity   var(--dur-fast) var(--ease),
    width     var(--dur-fast) var(--ease);
}

.nav-hamburger span:nth-child(1) { width: var(--sp-22); }
.nav-hamburger span:nth-child(2) { width: var(--sp-14); }
.nav-hamburger span:nth-child(3) { width: var(--sp-22); }

.nav-hamburger.is-open span:nth-child(1) {
  width: var(--sp-20);
  transform: translateY(var(--hamburger-shift)) rotate(45deg);
}

.nav-hamburger.is-open span:nth-child(2) {
  opacity: 0;
  width: 0;
}

.nav-hamburger.is-open span:nth-child(3) {
  width: var(--sp-20);
  transform: translateY(calc(var(--hamburger-shift) * -1)) rotate(-45deg);
}

/* Scroll lock. Compensating for the scrollbar keeps the fixed
   header from shifting when the drawer opens on a pointer
   device with a classic scrollbar. */
html.is-locked,
html.is-locked body { overflow: hidden; }

html.is-locked body { padding-right: var(--scrollbar-w, 0); }

/* ==========================================================
   EYEBROW · SECTION HEAD
   ========================================================== */

.eyebrow {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
}

.eyebrow--offset { padding-top: var(--sp-12); }

.section-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-48);
  align-items: baseline;
  margin-bottom: var(--sp-96);
}

.section-head--wide {
  grid-template-columns: 1fr 2fr;
  align-items: stretch;
  margin-bottom: var(--sp-144);
}

.section-head--tall  { margin-bottom: var(--sp-144); }
.section-head--short { margin-bottom: var(--sp-80); }

.section-head__title {
  font-size: var(--step-3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-heading);
  color: var(--ink);
  margin: 0;
}

.section-head__title--measure { max-width: var(--measure-wide); }

/* ==========================================================
   PAGE HERO
   ========================================================== */

.page-hero {
  padding: var(--sp-180) var(--gutter) var(--sp-120);
  border-bottom: var(--border) solid var(--rule);
}

.page-hero__inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

.page-hero__inner--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-64);
  align-items: end;
}

.page-hero__aside { text-align: right; }

.page-hero__eyebrow {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--sp-40);
}

.page-hero__h1 {
  font-size: var(--step-4);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-tight);
  color: var(--ink);
  margin: 0 0 var(--sp-64);
}

.page-hero__desc {
  max-width: var(--measure-lead);
  font-size: var(--step-1);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  margin-bottom: var(--sp-56);
}

.page-hero__actions {
  display: flex;
  gap: var(--sp-16);
  flex-wrap: wrap;
}

/* Accent variant. Used on the services and how-we-help heroes. */
.page-hero--accent {
  background: var(--accent);
  border-bottom: none;
}

.page-hero--accent .page-hero__eyebrow { color: var(--accent-ink-soft); }
.page-hero--accent .page-hero__h1      { color: var(--accent-ink); }

.page-hero--accent .page-hero__desc {
  color: var(--accent-ink-body);
  max-width: none;
  margin-bottom: var(--sp-24);
}

.page-hero--accent .page-hero__desc:last-child { margin-bottom: 0; }

/* ==========================================================
   CARD ROW  (practice areas)
   ========================================================== */

.cap-row {
  display: grid;
  grid-template-columns: var(--sp-120) 1fr 1fr;
  gap: var(--sp-48);
  align-items: baseline;
  padding: var(--sp-40) 0;
  border-top: var(--border) solid var(--rule);
  position: relative;

  /* Bled out sideways so the hover fill has air around the text.
     The padding and the negative margin cancel, so the content box
     and the three grid columns do not move. */
  padding-inline: var(--sp-24);
  margin-inline: calc(var(--sp-24) * -1);

  /* The sweep paints inside this box, so the row owns a stacking
     context and nothing escapes it. */
  isolation: isolate;
}

/* ─ FX/WIPE ─────────────────────────────────────────────────
   ACTIONS family · Quiet tier · HOVER.

   The kit's FX/WIPE is a solid block that rises from the bottom with
   the text inverting. This is the same effect turned on its side,
   travelling left to right, which suits a row far better than a
   column: it runs along the direction the row is read in.

   Only scaleX moves, so it stays inside the kit's rule 4. It sits on
   a pseudo-element rather than on the row's own background, which has
   the side benefit of removing the collision with FX/RISE entirely:
   .rise owns the `transition` shorthand on .cap-row, and a
   pseudo-element carries its own.

   The negative top inset takes the sweep over the row's hairline rule,
   so the rule is filled by the colour rather than left as a grey line
   across the top of a solid block. */
.cap-row::before {
  content: "";
  position: absolute;
  inset: calc(var(--border) * -1) 0 0 0;
  z-index: 0;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-sweep) var(--ease-sweep);
}

/* The last row closes the list with a rule underneath as well. */
.cap-row--last::before {
  inset: calc(var(--border) * -1) 0 calc(var(--border) * -1) 0;
}

/* Keyboard focus always fills, on any device. Hover only where there is
   a pointer that can actually hover: on a touch screen :hover latches
   after a tap and the row would be left mid-sweep with no way to clear
   it. The row is still a link there, it just does not animate. */
.cap-row:has(.cap-row__link:focus-visible)::before { transform: scaleX(1); }

@media (hover: hover) {
  .cap-row:hover::before { transform: scaleX(1); }
}

/* Raised above the sweep with `isolation`, not `position: relative`.
   Both make a stacking context, but only position would also make
   these the containing block for .cap-row__link::after, which is
   anchored to the row and is what makes the whole row clickable. The
   overlay would shrink to the width of the heading and the row would
   quietly stop being a link. */
.cap-row__num,
.cap-row__title,
.cap-row__blurb { isolation: isolate; }

/* Each row goes through to its own section on the services page.

   The link sits inside the heading rather than wrapping the row, so
   the three-column grid, the heading level and role="listitem" all
   survive. The overlay is what makes the whole row the target: one
   link per row, its text the practice area name, and no second
   tab stop.

   The overlay also carries the focus ring, so a keyboard lands on a
   ring around the row rather than around a few words inside it. */
.cap-row__link {
  color: inherit;
  /* No transition of its own. It inherits from the heading, and a
     transition here would animate towards a value that is itself still
     animating, so the link would trail its own heading. */
}

.cap-row__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* The text inverts on a much faster clock than the sweep, and each
   column waits for the sweep's leading edge to reach it. Switching them
   all together would put white text on a still-white right-hand side
   for the best part of a third of a second.

   Leaving is the mirror: no delay at all, so the row clears at once
   rather than unpicking itself column by column. That is why the
   delays live on the hover rule and the zero lives on the base rule. */
.cap-row__num,
.cap-row__title,
.cap-row__blurb {
  transition: color var(--dur-invert) var(--ease);
  transition-delay: 0s;
}

.cap-row:has(.cap-row__link:focus-visible) .cap-row__num {
  color: var(--accent-ink);
  transition-delay: var(--delay-invert-1);
}

.cap-row:has(.cap-row__link:focus-visible) .cap-row__title {
  color: var(--accent-ink);
  transition-delay: var(--delay-invert-2);
}

.cap-row:has(.cap-row__link:focus-visible) .cap-row__blurb {
  color: var(--accent-ink-body);
  transition-delay: var(--delay-invert-3);
}

@media (hover: hover) {
  .cap-row:hover .cap-row__num {
    color: var(--accent-ink);
    transition-delay: var(--delay-invert-1);
  }

  .cap-row:hover .cap-row__title {
    color: var(--accent-ink);
    transition-delay: var(--delay-invert-2);
  }

  .cap-row:hover .cap-row__blurb {
    color: var(--accent-ink-body);
    transition-delay: var(--delay-invert-3);
  }
}

.cap-row__link:focus-visible { outline: none; }

/* White, because by the time this shows the row underneath is accent
   and an accent ring would be invisible on it. */
.cap-row__link:focus-visible::after {
  outline: calc(var(--border) * 3) solid var(--accent-ink);
  outline-offset: calc(var(--border) * -3);
}

.cap-row--last   { border-bottom: var(--border) solid var(--rule); }
/* The offset has to absorb the bleed, or the row shifts. */
.cap-row--offset { margin-left: calc(var(--cap-offset) - var(--sp-24)); }

/* The row still fills and still inverts, it just arrives rather than
   travelling. State without motion, which is the point of the setting. */
@media (prefers-reduced-motion: reduce) {
  .cap-row::before,
  .cap-row__num,
  .cap-row__title,
  .cap-row__blurb { transition: none; }
}

.cap-row__num {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
}

.cap-row__title {
  font-size: var(--step-row);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-heading);
  line-height: var(--lh-heading);
  color: var(--ink);
}

.cap-row__blurb {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  max-width: var(--measure-sm);
}

/* ==========================================================
   STEP LIST  (principles)
   ========================================================== */

.principle {
  padding-top: var(--sp-24);
  border-top: var(--border) solid var(--rule);
  min-height: var(--sp-280);
}

.principle__numeral {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-32);
}

.principle__title {
  font-size: var(--step-2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-heading);
  line-height: var(--lh-title);
  color: var(--ink);
  margin-bottom: var(--sp-16);
}

.principle__body {
  font-size: var(--step-utility);
  font-weight: var(--weight-light);
  line-height: var(--lh-prose);
  color: var(--muted);
}

/* ==========================================================
   TESTIMONIALS
   ========================================================== */

.testimonials__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-48);
  border-top: var(--border) solid var(--rule);
  padding-top: var(--sp-56);
}

/* Third slot. See md/SPEC.md before enabling. */
.testimonials__grid--3 { grid-template-columns: repeat(3, 1fr); }

.testimonial {
  display: flex;
  flex-direction: column;
  gap: var(--sp-32);
  margin: 0;
  padding: 0;
}

.testimonial__text {
  font-size: var(--step-0);
  line-height: var(--lh-body);
  color: var(--ink);
}

.testimonial__author {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: var(--sp-4);
}

.testimonial__source {
  font-size: var(--step--2);
  color: var(--muted);
  letter-spacing: var(--track-meta);
}

/* ==========================================================
   CTA BAND  (closing)
   ========================================================== */

.closing__eyebrow {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--sp-40);
}

.closing__heading {
  font-size: var(--step-4);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-tight);
  color: var(--ink);
  margin-bottom: var(--sp-56);
}

.closing .btn { padding: var(--sp-20) var(--sp-36); }

.closing__contacts {
  display: flex;
  justify-content: center;
  gap: var(--sp-80);
  margin-bottom: var(--sp-56);
  flex-wrap: wrap;
}

.closing__contact-item { text-align: left; }

.closing__contact-label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--sp-10);
}

.closing__contact-value {
  font-size: var(--step-1);
  font-weight: var(--weight-light);
  line-height: var(--lh-prose);
  color: var(--ink);
}

.closing__contact-value a { transition: color var(--dur-fast) var(--ease); }
.closing__contact-value a:hover { color: var(--accent); }

.closing__contact-note {
  font-size: var(--step--2);
  font-weight: var(--weight-regular);
  color: var(--muted);
  margin-top: var(--sp-6);
  letter-spacing: var(--track-meta);
}

/* ==========================================================
   SERVICE SECTIONS
   ========================================================== */

.service-index__item {
  padding: var(--sp-28) var(--sp-24) var(--sp-28) 0;
  border-top: var(--border) solid var(--rule);
}

.service-index__num {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-10);
}

/* Underlined on purpose. Eight rows of unstyled text under a
   number read as a contents page, not as somewhere to click. The
   underline is the one cue nobody has to learn. */
.service-index__link {
  font-size: var(--step--1);
  font-weight: var(--weight-regular);
  color: var(--ink);
  line-height: var(--lh-list);
  transition:
    color var(--dur-fast) var(--ease),
    text-decoration-color var(--dur-fast) var(--ease);
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-8);
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: var(--sp-4);
}

.service-index__link:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

.service-index__link .arrow {
  width: 1em;
  height: 0.8em;
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease);
}

.service-index__link:hover .arrow { transform: translateX(var(--nudge)); }

.service__meta {
  display: flex;
  align-items: baseline;
  gap: var(--sp-32);
  margin-bottom: var(--sp-40);
}

.service__num,
.service__meta-label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
}

.service__num        { color: var(--accent); }
.service__meta-label { color: var(--muted); }

.service__rule {
  height: var(--border);
  background: var(--rule-strong);
  border: 0;
  margin: 0 0 var(--sp-64);
}

.service__body {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: var(--sp-96);
  align-items: start;
}

/* Marks the column a sticky heading lives in.

   position: sticky travels inside its containing block, and in a
   grid with align-items: start that block shrink-wraps the heading,
   leaving nowhere to travel. Stretching the column to the row height
   is what makes sticky do anything at all. Both places that use a
   sticky heading need it, so it is one class rather than two. */
.sticky-col { align-self: stretch; }

.service__title {
  font-size: var(--step-3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-heading);
  color: var(--ink);
  margin: 0 0 var(--sp-24);
}

.service__intro {
  font-size: var(--step-1);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--ink);
  margin-bottom: var(--sp-32);
}

.service__desc {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  margin-bottom: var(--sp-48);
}

.service__list-label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0;
}

.service__list-label--spaced { margin-top: var(--sp-48); }

.service__offences {
  list-style: none;
  margin: 0;
  padding: 0;
}

.service__offences--measure { max-width: var(--measure); }

.service__offences li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-18);
  padding: var(--sp-14) 0;
  border-top: var(--border) solid var(--rule);
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-list);
  color: var(--muted);
}

/* One accent marker per item. The li is already a flex row with a
   --sp-18 gap, so the square drops into it without touching the text
   metrics. Decorative, so it is an empty ::before rather than a
   character: nothing is announced to a screen reader, which already
   gets the list semantics from role="list". */
.service__offences li::before {
  content: "";
  flex: none;
  width: var(--marker-size);
  height: var(--marker-size);
  background: var(--accent);
  /* Centred on the first line rather than on the whole item. The row
     is flex-start so a wrapping item keeps its marker beside the line
     it belongs to; this offset then puts it on that line's optical
     centre. On a single-line item it lands exactly where align-items:
     center used to put it. */
  margin-top: calc((1em * var(--lh-list) - var(--marker-size)) / 2);
}

.service__offences li:last-child { border-bottom: var(--border) solid var(--rule); }

.service__footnote {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  margin-top: var(--sp-32);
  padding-top: var(--sp-24);
  border-top: var(--border) solid var(--rule);
}

/* The list already closes itself with a rule on its last item, so a
   footnote directly after one drew a second line a stroke below the
   first. The spacing is kept, only the duplicate line goes. The rule
   stays on the base class because a footnote that does not follow a
   list still needs something to separate it. */
.service__offences + .service__footnote { border-top: none; }

/* ==========================================================
   HOW WE HELP  ·  type grid, Q&A, funding
   ========================================================== */

/* The block closes itself. This used to be the job of the fifth item's
   --full modifier, which spanned both columns and carried the only
   bottom rule; with four items in an even 2x2 there is no such item, and
   nothing below the block draws a rule either. On the container it holds
   at every band, two columns or one. */
.la-types {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0;
  border-bottom: var(--border) solid var(--rule);
}

.la-type {
  padding: var(--sp-48) var(--sp-48) var(--sp-48) 0;
  border-top: var(--border) solid var(--rule);
}

.la-type:nth-child(even) {
  padding-left: var(--sp-48);
  padding-right: 0;
  border-left: var(--border) solid var(--rule);
}

.la-type__numeral {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-28);
}

.la-type__title {
  font-size: var(--step-2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-heading);
  line-height: var(--lh-block);
  color: var(--ink);
  margin: 0 0 var(--sp-16);
}

.la-type__body {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
}

.qa-row {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: var(--sp-64);
  padding: var(--sp-48) 0;
  border-top: var(--border) solid var(--rule);
}

.qa-row:last-child { border-bottom: var(--border) solid var(--rule); }

.qa-row__q {
  font-size: var(--step-question);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-heading);
  line-height: var(--lh-block);
  color: var(--ink);
  margin: 0;
}

.qa-row__a {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
}

.la-eligibility__intro,
.la-fees__intro {
  font-size: var(--step-1);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
}

.la-eligibility__intro { margin-bottom: var(--sp-32); }

.la-eligibility__desc {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
}

.la-eligibility__desc + .la-eligibility__desc { margin-top: var(--sp-24); }

.la-fees__detail-label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0;
}

/* ==========================================================
   CONTACT CARDS
   ========================================================== */

.contact-card { padding: var(--sp-80) 0; }

.contact-card + .contact-card {
  padding-left: var(--sp-64);
  border-left: var(--border) solid var(--rule);
  margin-left: 0;
}

.contact-card__label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--sp-28);
}

.contact-card__value {
  font-size: var(--step-contact);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-heading);
  color: var(--ink);
}

.contact-card--phone .contact-card__value { font-size: var(--step-4); }

.contact-card__value a { transition: color var(--dur-fast) var(--ease); }
.contact-card__value a:hover { color: var(--accent); }

.contact-card__note {
  margin-top: var(--sp-16);
  font-size: var(--step--2);
  font-weight: var(--weight-regular);
  color: var(--muted);
  letter-spacing: var(--track-meta);
}

/* ==========================================================
   CONTACT FORM
   ========================================================== */

.contact-form-intro__heading {
  font-size: var(--step-3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-heading);
  color: var(--ink);
  margin: 0 0 var(--sp-32);
}

.contact-form-intro__body {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  margin-bottom: var(--sp-24);
}

.contact-form-intro__note {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
  padding-top: var(--sp-24);
  border-top: var(--border) solid var(--rule);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-10);
  margin-bottom: var(--sp-20);
}

.form-group label {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--muted);
}

.form-group input,
.form-group select,
.form-group textarea {
  display: block;
  width: 100%;
  background: var(--paper);
  /* --rule-field, not --rule. At 1.26:1 the source's field
     boundary was invisible. See md/README.md. */
  border: var(--border) solid var(--rule-field);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  padding: var(--sp-16) var(--sp-20);
  border-radius: var(--radius);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease);
  -webkit-appearance: none;
  appearance: none;
}

.form-group input::placeholder,
.form-group textarea::placeholder {
  color: var(--muted);
  opacity: var(--placeholder-alpha);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus { border-color: var(--accent); }

.form-group input:focus-visible,
.form-group select:focus-visible,
.form-group textarea:focus-visible {
  outline: calc(var(--border) * 3) solid var(--accent);
  outline-offset: calc(var(--border) * 2);
}

.form-group input[aria-invalid="true"],
.form-group select[aria-invalid="true"],
.form-group textarea[aria-invalid="true"] { border-color: var(--accent-hover); }

.form-error {
  font-size: var(--step--1);
  font-weight: var(--weight-regular);
  color: var(--accent-hover);
}

.form-error:empty { display: none; }

/* Chevron as a mask, so the colour comes from --accent rather
   than being baked into a data URI. */
.form-group select {
  cursor: pointer;
  padding-right: var(--sp-48);
  background-image: none;
}

.select-wrap { position: relative; }

.select-wrap::after {
  content: "";
  position: absolute;
  right: var(--sp-20);
  top: 50%;
  width: var(--chevron-w);
  height: var(--chevron-h);
  transform: translateY(-50%);
  background-color: var(--accent);
  -webkit-mask-image: var(--chevron);
          mask-image: var(--chevron);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: contain;
          mask-size: contain;
  pointer-events: none;
}

.form-group select option {
  background: var(--paper);
  color: var(--ink);
}

.form-group textarea {
  min-height: var(--sp-160);
  resize: none;
  line-height: var(--lh-body);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-20);
}

.form-submit {
  margin-top: var(--sp-12);
  display: flex;
  align-items: center;
  gap: var(--sp-24);
  flex-wrap: wrap;
}

.form-submit__note {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  color: var(--muted);
}

/* Honeypot. Off-canvas rather than display:none, so a bot
   that filters on display still fills it. */
.form-hp {
  position: absolute;
  left: var(--offscreen);
  width: var(--border);
  height: var(--border);
  overflow: hidden;
}

.form-status {
  font-size: var(--step--1);
  font-weight: var(--weight-regular);
  line-height: var(--lh-body);
  color: var(--ink);
  padding-top: var(--sp-16);
}

.form-status:empty { display: none; }

/* ==========================================================
   FOOTER

   Three tiers, separated by hairlines.

     1  the mark and the firm line, beside the four facts a
        visitor needs to make contact, set two by two
     2  the link lists: practice areas, firm, areas served
     3  the legal baseline

   The tiers are the structure. Tier 1 answers "who is this and
   how do I reach them", which on a defence site is the only
   question that matters at 2am, so it sits above the fold of
   the footer and gets the space. Tier 2 is browsing. Tier 3 is
   the small print.

   The five-column grid this replaces gave the address, the two
   phone numbers and the email the same weight as a list of place
   names, in a column narrower than the address needed.
   ========================================================== */

.site-footer {
  padding: var(--sp-120) var(--gutter-wide) var(--sp-48);
  background: var(--accent);
  border-top: none;
}

.site-footer__inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

/* ─ tier 1 · the mark and the facts ───────────────────────── */

.footer__top {
  display: grid;
  align-items: start;
}

/* Full display scale, not the old --step-2, and the same step the
   hero H1 uses. It is also the mark FX/THRESHOLD holds on screen
   while the panel is up, so setting it this large closes the loop:
   the thing that opened the session is the thing that ends the
   page.

   The size is doing structural work, not decoration. A monogram is
   two to four characters, so at anything smaller it cannot hold
   the left half of tier 1 on its own and the row reads as a block
   of facts on the right with a gap beside it. */
.footer__brand-name {
  font-size: var(--step-4);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-display);
  line-height: var(--lh-tight);
  color: var(--accent-ink);
  margin-bottom: var(--sp-32);
}

.footer__brand-desc {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  line-height: var(--lh-prose);
  color: var(--accent-ink-muted);
  max-width: var(--measure-brand);
}

.footer__facts { display: grid; }

/* One label per fact, where the old layout had a single "Contact"
   heading over an unlabelled list. Four cells in a grid need
   naming or they read as four loose values, and on this site one
   of the two numbers is the out-of-hours line, which is not
   something to leave a visitor to infer from the digits. */
.footer__fact-value {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  line-height: var(--lh-stack);
  color: var(--accent-ink-strong);
}

.footer__fact-value a {
  color: var(--accent-ink-strong);
  transition: color var(--dur-link) var(--ease);
}

.footer__fact-value a:hover { color: var(--accent-ink); }

/* ─ tier 2 · the link lists ───────────────────────────────── */

.footer__grid {
  display: grid;
  border-top: var(--border) solid var(--accent-rule);
}

.footer__col-heading {
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--accent-ink-dim);
  margin-bottom: var(--sp-24);
}

.footer__col-links {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}

.footer__col-links a {
  font-size: var(--step--1);
  font-weight: var(--weight-light);
  color: var(--accent-ink-strong);
  transition: color var(--dur-link) var(--ease);
}

.footer__col-links a:hover { color: var(--accent-ink); }

/* Areas served is seven items against four and six in the columns
   beside it, so on its own it ran half again as long as the row it
   sits in. It takes two tracks and splits into two, which levels
   the row and fills the width that tier 2 would otherwise leave
   empty on the right.

   Four rows, flowing down then across, so 1 to 4 sit under each
   other and 5 to 7 start the second column. Reading order and DOM
   order stay the same. The row count is fixed rather than derived
   because this template ships exactly seven areas; a clone that
   changes that count adjusts it here. */
.footer__col-links--split {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(4, auto);
  gap: var(--sp-12) var(--sp-32);
}

.footer__area {
  color: var(--accent-ink-strong);
  font-size: var(--step--1);
  font-weight: var(--weight-light);
}

/* ─ tier 3 · the legal baseline ───────────────────────────── */

.footer__base {
  border-top: var(--border) solid var(--accent-rule);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-24);
  flex-wrap: wrap;
}

.footer__copy,
.footer__legal,
.footer__credit {
  font-size: var(--step--2);
  font-weight: var(--weight-regular);
  color: var(--accent-ink-dim);
  letter-spacing: var(--track-meta);
}

/* The credit sits right, the legal links take the centre.

   All three take an equal share rather than only the middle one
   growing. Growing just the middle centres it in the gap between the
   other two, and since the copyright is much longer than the credit
   that gap is not the middle of the row: it left the links 49px off.
   Equal thirds put the centre column's centre on the row's centre
   whatever the text either side does. */
.footer__copy   { flex: 1 1 0; min-width: 0; }
.footer__credit { flex: 1 1 0; min-width: 0; text-align: right; }

.footer__legal {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  justify-content: center;
  gap: var(--sp-32);
}

.footer__legal a { transition: color var(--dur-link) var(--ease); }
.footer__legal a:hover { color: var(--accent-ink); }

/* Only the address is white. "Designed by" stays at the dim step
   with the rest of the baseline, so the name is the thing that
   carries, not the label in front of it. 12.53:1 against 5.17:1. */
.footer__credit a {
  color: var(--accent-ink);
  text-decoration: underline;
  text-decoration-color: var(--accent-ink-dim);
  text-underline-offset: var(--sp-4);
  transition: text-decoration-color var(--dur-link) var(--ease);
}

/* The underline is not decoration, it is the accessible cue. White
   against the dim label is only 2.42:1, under the 3:1 that colour
   alone has to clear, and the label cannot be dimmed to widen the
   gap because 0.58 is already close to its own AA floor of 0.525.
   So the link carries a non-colour distinction as well, which is
   what WCAG asks for either way. It is already the brightest thing
   on the row, so hover cannot go brighter: the underline solidifies
   instead. */
.footer__credit a:hover { text-decoration-color: var(--accent-ink); }

/* ==========================================================
   STICKY ACTION  (phone and tablet only)
   ========================================================== */

.sticky-call { display: none; }

.sticky-call a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-10);
  width: 100%;
  padding: var(--sp-16);
  background: var(--accent-ink);
  color: var(--accent);
  font-size: var(--step-0);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-tight);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease);
}

.sticky-call a:hover { background: var(--accent-fill-hover); }

/* ==========================================================
   PROSE  (privacy, terms, regulatory)
   ========================================================== */

.prose {
  max-width: var(--measure-lead);
}

.prose h2 {
  font-size: var(--step-2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-heading);
  line-height: var(--lh-block);
  color: var(--ink);
  margin: var(--sp-48) 0 var(--sp-16);
}

.prose h2:first-child { margin-top: 0; }

.prose p,
.prose li {
  font-size: var(--step-0);
  font-weight: var(--weight-light);
  line-height: var(--lh-body);
  color: var(--muted);
}

.prose p + p { margin-top: var(--sp-16); }

.prose ul {
  margin: var(--sp-16) 0 0;
  padding: 0;
}

.prose li {
  padding: var(--sp-14) 0;
  border-top: var(--border) solid var(--rule);
}

.prose li:last-child { border-bottom: var(--border) solid var(--rule); }

.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: var(--sp-4);
}

.prose a:hover { color: var(--accent-hover); }
