/* ==========================================================================
   Munce Legal — restored interactive states
   --------------------------------------------------------------------------
   WHAT THIS FIXES. Framer drives hover on its interactive components from its JS
   runtime, which swaps a `.hover` CLASS (not the native :hover pseudo-class) and
   lets the exported CSS do the rest. That works — the header CTA, the nav dropdown
   and the desktop service cards all respond correctly on this site.

   The defect is narrower than "the runtime is dead": for SOME component variants
   Framer never authored a hover state at all, so there is no `.hover` rule to fire
   and no native :hover to fall back on. Those elements are clickable and give the
   user nothing. Two of them also declare `cursor:unset`, which — because `cursor`
   is an INHERITED property — resolves to `inherit` and cancels the browser's own
   pointer cursor on a real link.

   Verified 2026-09-18 against the still-live original at muncelegal.com.au: the
   original behaves identically, so this is an inherited Framer authoring gap, not a
   migration regression. Rob's call, 2026-09-18: fix it — bringing defective CTAs
   into line with the rest of the site is a defect fix, not a redesign.

   METHOD. Every rule below re-uses the site's OWN design, not an invented one:
   the same design tokens, and where Framer authored a hover for a sibling variant,
   that variant's exact declarations. Values are sourced individually.

   Gate: tools/verify-hover-states.mjs (absolute mode).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Rich-text links
   --------------------------------------------------------------------------
   Framer already ships the rule that colours a link on hover:

     a.framer-text:hover { color: var(--framer-link-hover-text-color-rgb,
                           var(--framer-link-hover-text-color, ...fallbacks... )) }

   It is live on every page and it works — the header phone number shifts navy to
   gold through exactly this path. The variable is simply never GIVEN a value in
   most of the document: measured in about/index.html, --framer-link-hover-text-color
   is defined in only 3 places out of 26 references. Everywhere else the fallback
   chain resolves back to the link's own resting colour, so the hover computes to
   "no change".

   Supplying the site's own accent token as the document-level default fixes every
   such link at once — every link that has no closer definition, which is the large
   majority of them, all sitting on the white page body.

   The 3 places Framer DOES define it locally are handled separately in the next
   block, not by this default. They need naming because their local definitions are
   scoped so they never apply at the widths their elements render at, so the default
   below would reach them and paint all three the same gold — which is precisely the
   regression this file had to undo. Gold is correct as the fallback for body links on
   white; it is wrong for the navy-backdrop nav and footer.

   source: --token-54fa74a0… is the site's gold accent, the first token defined in
   its own token set, and is the value the one working text-link hover resolves to.
   MEASURED 2026-09-18: rgb(0,74,101) -> rgb(185,142,68) on a[href^="tel:"]. */
:root {
  --framer-link-hover-text-color: var(--token-54fa74a0-143a-440b-bb5a-eb8f1b009f3e, #b98e44);
}

/* Three text-style presets are dead for a different reason, and each already carries
   the hover colour Framer designed for it. Their local rules look like this:

     .framer-bmTop .framer-styles-preset-zn3r3q … { --framer-link-hover-text-color: … }

   Two things stop them ever firing. The rule is scoped to an ancestor class, AND the
   whole block sits inside `@media (max-width:809px)` — but the markup those selectors
   match is display:none below 810px. The rule is live only at widths where its element
   is not rendered, and absent at the widths where it is. So the element falls through
   to the document default and the hover computes to the resting colour.

   The fix is therefore NOT to pick a colour. Each preset's own authored value is
   re-stated here, unscoped and unmediated, so it applies at the widths the element is
   actually visible at. No value below is invented — every one is the token Framer
   itself named in that preset's `--framer-link-hover-text-color`.

   This replaces an earlier blanket rule that forced ONE gold across all three. That
   was wrong and measurably harmful: it dropped the navy-backdrop footer links from
   9.69:1 to 3.24:1, and broke the header phone number, which had been working.

   MEASURED 2026-09-18 — backdrop, then this colour against it:
     zn3r3q  header nav + footer "JustFund.com.au"   navy #004a65   #e6c65e   5.82:1 ✓
     f8s117  all footer links + contact info         navy #004a65   #fefefe   9.61:1 ✓
     1jmn1gu header phone                            grey #f0f2f4   #b98e44   2.65:1 ✗
             contact-info band, Prev/Next ×18 pages  white #fefefe  #b98e44   2.97:1 ✗

   The two ✗ rows are Framer's own authored colour and they fail WCAG AA. Rob's call,
   2026-09-18: ship parity with what Framer designed rather than substitute a darker
   tone that exists nowhere in the site's 21-token palette. Recorded as a known
   INHERITED failure — this is not a WCAG pass and must never be logged as one.

   !important is required: the site's generic `a.framer-text:hover` rule resolves
   through the same custom-property chain and would otherwise win at equal specificity.
   source: each colour is the token named in that preset's own rule — see the table. */
a.framer-text.framer-styles-preset-zn3r3q:hover,
a.framer-text.framer-styles-preset-zn3r3q:focus-visible {
  color: var(--token-b162f162-4fbb-42e3-948a-a22ffe09f66d, #e6c65e) !important;
}
a.framer-text.framer-styles-preset-f8s117:hover,
a.framer-text.framer-styles-preset-f8s117:focus-visible {
  color: var(--token-2599792c-cd72-44e1-834a-b0e24aeeacae, #fefefe) !important;
}
a.framer-text.framer-styles-preset-1jmn1gu:hover,
a.framer-text.framer-styles-preset-1jmn1gu:focus-visible {
  color: var(--token-54fa74a0-143a-440b-bb5a-eb8f1b009f3e, #b98e44) !important;
}

/* THE CURRENT-PAGE LINK HAS NOWHERE TO GO.
   Framer gives zn3r3q and f8s117 the SAME token for
   --framer-link-current-text-color and --framer-link-hover-text-color. The design
   intent is clear and good: hovering a nav link previews what the current page looks
   like. But it means the link for the page you are already on cannot change colour —
   it is already wearing the hover colour.

   MEASURED 2026-09-18 (archived probe .probe-archive/_probe-nav.mjs, /about/, 1440x900):
     nav "About"      current=true   rest rgb(230,198,94)  hover rgb(230,198,94)
     nav "Services"   current=null   rest rgb(254,254,254) hover rgb(230,198,94) ✓
     footer "About Us" current=true  rest rgb(254,254,254) — same collision
   The gate correctly failed "About" as clickable-with-no-feedback. Every other nav
   link passes, which is what identifies the current-page link as the special case
   rather than the colour choice as wrong.

   source: judgment — colour is exhausted for these two links, so the remaining
   affordance is the oldest one a link has. Underline costs no contrast (the text
   keeps its measured 5.82:1 / 9.61:1 on navy) and applies to exactly one link per
   group. Scoped to the two presets so it cannot leak into body copy. */
a.framer-text.framer-styles-preset-zn3r3q[data-framer-page-link-current="true"]:hover,
a.framer-text.framer-styles-preset-f8s117[data-framer-page-link-current="true"]:hover,
a.framer-text.framer-styles-preset-zn3r3q[data-framer-page-link-current="true"]:focus-visible,
a.framer-text.framer-styles-preset-f8s117[data-framer-page-link-current="true"]:focus-visible {
  text-decoration: underline !important;
}

/* --------------------------------------------------------------------------
   2. Primary buttons — variants Framer shipped with no hover state
   --------------------------------------------------------------------------
   Component .framer-v6hHe. Framer authored `.hover` rules for nine of its
   variants; `framer-v-1a5hzqh` ("Primary White BG") got none, and
   `framer-v-qfz1ir` ("Primary Small") got `.pressed` but no `.hover`.

   THE HOVER IS PURELY POSITIONAL. Not one `.hover` rule in this entire component
   changes a `color`, on any variant. The effect is an overlay panel (.framer-1gj2sot)
   that sits parked just below the button at rest and slides over it, with the label
   container (.framer-1ubcifu) layered above. Every variant — working and broken —
   parks the overlay at the identical resting position, set by Framer's own base rule
   `.framer-v6hHe .framer-1gj2sot` in the exported stylesheet. Nothing in this file
   changes that resting position, so the broken variants need only the travel rule.

   WHICH SIBLING TO COPY. An earlier attempt mirrored the `ed9mm6` family
   (`bottom:unset;left:unset;top:0%;right:0`) and Rob reported the result did not match
   the CTAs already on the site. It didn't: `ed9mm6` is not the button he was looking
   at. The homepage hero CTA is variant `8eblsl` ("Secondary V2"), and its own rules are
   what this section now reproduces.

   MEASURED 2026-09-18 (archived probe .probe-archive/_probe-cta.mjs, rendered, pointer actually over the
   element — not read off the stylesheet). Overlay offset is measured relative to the
   button's own top edge, so 0 means fully covering:

     hero 8eblsl  /        @1440  rest overlay +64 gold,  label white  → hover 0, white
     1a5hzqh      /about/  @1440  rest overlay +64 gold,  label NAVY   → hover 0, white
     qfz1ir       /about/  @390   rest overlay +64 navy,  label white  → hover 0, white

   The first two rows are now identical in every measured respect — gold panel,
   white label, pointer cursor — which is the whole of Rob's complaint.

   White on the rendered gold rgb(211,175,55) is 2.09:1. The site already ships that
   on every working primary CTA. Rob's call, 2026-09-18: match it. Recorded as a known
   INHERITED failure carried onto one more variant — NOT a WCAG pass, never log it as
   one. (qfz1ir is unaffected: its overlay is navy, so it measures 9.61:1.)

   source: .framer-v6hHe.framer-v-8eblsl.hover .framer-1gj2sot { bottom:0 } and
           .framer-v6hHe.framer-v-8eblsl.hover .framer-1ubcifu { z-index:1 }
           — both in the exported stylesheet, index.html. Verbatim. */

/* !important is required and is not a shortcut here: the cancelling declaration
   .framer-v6hHe.framer-v-1a5hzqh.framer-ed9mm6{cursor:unset} carries the same
   three-class specificity as anything we can write against the same element.
   Nothing animates `cursor`, so this cannot fight the JS runtime.
   source: rule quoted above, about/index.html */
.framer-v6hHe.framer-v-1a5hzqh.framer-ed9mm6,
.framer-v6hHe.framer-v-qfz1ir.framer-ed9mm6 {
  cursor: pointer !important;
}

/* source: judgment — Framer animates this overlay from JS with no CSS transition to
   copy, so a duration had to be chosen. 220ms sits inside the 200–350ms band this
   project already mandates for in-place open/close motion, at the fast end because
   a button hover should feel immediate. Only position is transitioned; nothing
   here animates layout-affecting size. */
.framer-v6hHe.framer-v-1a5hzqh .framer-1gj2sot,
.framer-v6hHe.framer-v-qfz1ir .framer-1gj2sot {
  transition: top .22s ease, bottom .22s ease, left .22s ease, right .22s ease;
}

/* source: .framer-v6hHe.framer-v-8eblsl.hover .framer-1gj2sot { bottom:0 }
           — the homepage hero CTA's own rule, exported stylesheet, index.html.
   Both broken variants rest at the same position as the hero, so this is a direct
   copy rather than a translation: the overlay travels the same distance, same way. */
.framer-v6hHe.framer-v-1a5hzqh:hover .framer-1gj2sot,
.framer-v6hHe.framer-v-qfz1ir:hover .framer-1gj2sot,
.framer-v6hHe.framer-v-1a5hzqh:focus-visible .framer-1gj2sot,
.framer-v6hHe.framer-v-qfz1ir:focus-visible .framer-1gj2sot {
  bottom: 0;
}

/* source: .framer-v6hHe.framer-v-8eblsl.hover .framer-1ubcifu { z-index:1 }
           — same hero rule, same file. Deliberately 1, not 2: the overlay is also
   z-index:1, and the label wins on DOM order because it comes second. That is exactly
   how the hero CTA layers, and copying its value keeps the two identical. */
.framer-v6hHe.framer-v-1a5hzqh:hover .framer-1ubcifu,
.framer-v6hHe.framer-v-qfz1ir:hover .framer-1ubcifu,
.framer-v6hHe.framer-v-1a5hzqh:focus-visible .framer-1ubcifu,
.framer-v6hHe.framer-v-qfz1ir:focus-visible .framer-1ubcifu {
  z-index: 1;
}

/* THE LABEL COLOUR — this is the part that answers Rob's complaint.
   The hero CTA renders gold + WHITE because its label is already white at rest; its
   hover never recolours anything. `1a5hzqh` sits on a white button with a NAVY label,
   so the same positional rule alone gives gold + navy — which is what Rob saw.

   The label reads its colour through the site's own chain: the .framer-1ubcifu wrapper
   declares `--extracted-r6o4lv` inline, and the <p> inside declares
   `--framer-text-color:var(--extracted-r6o4lv, …)` inline. Overriding the wrapper
   property therefore recolours the label through Framer's own plumbing — no new
   selector against the <p>, and no touching of the resting state.

   !important is required only because the wrapper carries the property inline.
   `qfz1ir` gets NO rule here: its label is already white and its overlay is navy, so
   it is correct with the positional rules alone.

   source: --token-2599792c… is the white the hero CTA's own label resolves to
           (--extracted-r6o4lv on .framer-1ubcifu, index.html hero instance). */
.framer-v6hHe.framer-v-1a5hzqh:hover .framer-1ubcifu,
.framer-v6hHe.framer-v-1a5hzqh:focus-visible .framer-1ubcifu {
  --extracted-r6o4lv: var(--token-2599792c-cd72-44e1-834a-b0e24aeeacae, #fefefe) !important;
}

/* --------------------------------------------------------------------------
   3. Footer social icons — variant with only a pressed state
   --------------------------------------------------------------------------
   Component .framer-r00BP. Framer authored `.hover` for variants 175n0zz, bryl70
   and 13uf60t; `framer-v-ndpgml` received only `.pressed`.

   source: .framer-r00BP.framer-v-175n0zz.hover .framer-1ksjodp
           { justify-content:flex-end } — exported stylesheet, about/index.html */
.framer-r00BP.framer-v-ndpgml .framer-1ksjodp {
  transition: justify-content .22s ease; /* source: matches §2, same interaction class */
}
.framer-r00BP.framer-v-ndpgml:hover .framer-1ksjodp,
.framer-r00BP.framer-v-ndpgml:focus-visible .framer-1ksjodp {
  justify-content: flex-end;
}

/* --------------------------------------------------------------------------
   4. Service cards — narrow-breakpoint clone
   --------------------------------------------------------------------------
   Component .framer-l5dpq. The desktop clone (framer-v-1669glx) responds correctly
   via the JS variant swap; the narrow clone (framer-v-4jv5wj) does not respond and
   additionally computes cursor:auto on a real link.

   No CSS hover exists for ANY variant of this component to copy — the desktop
   effect is authored entirely in the runtime — so the treatment below is a
   restrained choice rather than a reproduction, kept to the site's accent token so
   it reads as the same family.

   source: judgment — no sibling CSS hover exists to mirror; colour is the site's
   own gold accent token, same one used in §1. */
.framer-l5dpq.framer-v-4jv5wj {
  cursor: pointer !important;
  transition: background-color .22s ease;
}

/* background-color, not border-color, and !important on both counts.
   First attempt set border-color and the gate reported "variant class swapped but
   NOTHING visibly changed" — correctly. Two reasons it was invisible, both worth
   keeping written down:
     1. The visible 1px border is not the element's own border. It is painted by
        .framer-l5dpq[data-border=true]:after from a --border-color custom property,
        so setting border-color on the element itself changes a property nothing
        renders.
     2. That --border-color is ALREADY the gold accent at rest, so even reaching it
        would have been a no-op.
   The resting background is set INLINE on the element, so a stylesheet rule cannot
   win without !important.

   source: MEASURED — inline style on a[data-framer-name="Mobile"] resolves its
   background to --token-2599792c… #fefefe. #faf7f3 is that white with the site's
   gold accent #b98e44 at 6%, computed channel-wise:
   r 254*.94+185*.06=250, g 254*.94+142*.06=247, b 254*.94+68*.06=243.
   A literal is used rather than color-mix() so the tint does not depend on
   color-mix support in whatever browser the client's clients are on. */
.framer-l5dpq.framer-v-4jv5wj:hover,
.framer-l5dpq.framer-v-4jv5wj:focus-visible {
  background-color: #faf7f3 !important;
}

/* --------------------------------------------------------------------------
   4b. Logo links and icon controls
   --------------------------------------------------------------------------
   Framer authored no hover for any of these, on any variant, so there is nothing
   to mirror. A restrained opacity shift is the house-neutral affordance: it signals
   the element is live without touching brand colour, which matters most here
   because three of the four are the firm's own logo lockup.

   !important is required: the site's entrance animation drives opacity from the JS
   runtime as an inline style, which a plain stylesheet rule cannot outrank. Scoped
   to :hover / :focus-visible only, so the resting reveal animation is untouched.

   source: judgment — no sibling CSS hover exists to copy. 0.72 is a visible but
   quiet shift; MEASURED against the same 220ms timing used throughout this file. */
a.framer-3xdgzj.framer-28d1km,
a.framer-3ukbb.framer-bm2ayg,
a.framer-1elrnw6.framer-bm2ayg,
.framer-f0jjc2 {
  transition: opacity .22s ease;
}
a.framer-3xdgzj.framer-28d1km:hover,
a.framer-3ukbb.framer-bm2ayg:hover,
a.framer-1elrnw6.framer-bm2ayg:hover,
.framer-f0jjc2:hover,
a.framer-3xdgzj.framer-28d1km:focus-visible,
a.framer-3ukbb.framer-bm2ayg:focus-visible,
a.framer-1elrnw6.framer-bm2ayg:focus-visible,
.framer-f0jjc2:focus-visible {
  opacity: .72 !important;
}

/* --------------------------------------------------------------------------
   5. Keyboard focus
   --------------------------------------------------------------------------
   Deliberately NOT gated by verify-hover-states.mjs: asserting :focus-visible needs
   real keyboard modality, which that gate does not drive, and a half-working check is
   worse than none. It has its own gate instead — tools/verify-focus-ring.mjs walks the
   page with Tab, so :focus-visible genuinely matches, and asserts BOTH the 3:1 ring
   contrast and that no ancestor clips the ring. Run it after any change to this
   section; it exits non-zero on either failure.

   Required by the standing rule that every clickable element has hover, focus-visible
   and active states. The hover treatments above are extended to :focus-visible inline;
   this adds the visible ring.

   THREE CORRECTIONS to the first version of this rule, all found by measuring a real
   Tab walk (tools/verify-focus-ring.mjs — keyboard modality, so :focus-visible genuinely
   matches; scripted .focus() would not have proved this).

   1. CLIPPING IS EVERYWHERE, not in two places. The first version used an outward
      ring and patched the two clippers named in the handoff. A Tab walk of /about/
      found ten more: the footer link rows (.framer-htzzlz), the contact band
      (.framer-1iktm3v) and each service card (.framer-14w7z4i, .framer-1i0vtlc,
      .framer-13du9j6). Framer's layout is built from overflow:hidden flex wrappers,
      so ANY outward ring is a list of exceptions that grows every time a section is
      added. A box-shadow ring clips identically — the technique is not the issue.

      So the ring is drawn INSIDE the element's own border box, everywhere, with no
      exception list. An inset ring cannot be clipped by an ancestor because it never
      leaves the element. This is one rule instead of a maintained denylist, and it is
      the reason `outline-offset` is negative below.

   2. THE SELECTOR MISSED ELEMENTS. `a, button, [role=button]` left a focusable nav
      element with the browser's 1px default ring at 1.96:1 on navy. `:focus-visible`
      alone matches whatever the browser actually focuses, so there is nothing to keep
      in sync.

   3. COLOUR. The first version used gold everywhere; gold #b98e44 on white is 2.97:1
      and fails the 3:1 floor. Unlike the inherited colour failures elsewhere in this
      file, this ring is ours, not Framer's, so it gets fixed rather than recorded.

      MEASURED 2026-09-18, ring against the backdrop it actually sits on:
        navy  #004a65 on white #fefefe          9.61:1  ✓
        navy  #004a65 on grey  #f0f2f4 (top bar) 8.63:1  ✓
        white #fefefe on navy  #004a65          13.0:1  ✓
        white #fefefe on the social-icon strip   8.5:1  ✓
      Gold was rejected for the dark areas too: it measures 3.24:1 on the navy footer
      and only 2.84:1 on the social-icon strip, whose 5% white veil lifts the backdrop
      just enough to drop it under the floor. White clears both with room to spare.

   source: WCAG 2.4.11 Focus Appearance — the indicator must be at least a 2px
   perimeter and contrast 3:1 against adjacent colours. 2px inset is that perimeter. */
:focus-visible {
  outline: 2px solid var(--token-a2d7b8ca-eac6-4a53-aec9-921ed3fbf0a5, #004a65);
  outline-offset: -2px;
}

/* Navy backdrops — the header nav, the whole footer, and the social icons. A navy
   ring on navy is invisible, so these take white.
   source: backdrops measured 2026-09-18 — the nav wrapper and the footer both
   resolve to --token-a2d7b8ca… #004a65. Scoped by CONTAINER, not by text preset,
   so non-anchor focusables inside them are covered too.

   THE FOOTER IS MATCHED BY ITS ELEMENT, NOT BY A CLASS, AND THAT IS DELIBERATE.
   This rule previously read `.framer-1tadhzx` — the /about/ footer's section hash.
   Framer regenerates section wrapper hashes PER ROUTE: `framer-1tadhzx` occurs
   twice in about/index.html and ZERO times in the other 25 pages (grepped). So the
   footer ring was navy-on-navy at 1.00:1 — an invisible focus indicator — on 25 of
   26 pages, while the one page the gate was hardcoded to check was the one page the
   selector happened to match. Element and preset classes are stable across routes;
   section wrappers are not. Never scope a site-wide rule to a section hash.
   source: MEASURED 2026-09-18 across all 26 routes — 698 focusables sit on a dark
   backdrop, 520 of them inside <footer>. */
.framer-2luqmz :focus-visible,
.framer-2luqmz:focus-visible,
footer :focus-visible,
footer:focus-visible,
.framer-r00BP:focus-visible,
/* The HEADER logo link. It sits on the navy band but is OUTSIDE .framer-2luqmz (the
   nav list) and outside .framer-1tadhzx (the footer), so the container-scoped rules
   above never reached it and it kept the navy default ring: navy on navy, 1.00:1 —
   an invisible focus indicator on tab stop 4 of every page.
   The two FOOTER logo anchors (.framer-3ukbb.framer-bm2ayg, .framer-1elrnw6.framer-bm2ayg)
   are already covered by .framer-1tadhzx and are deliberately not repeated here.
   source: MEASURED 2026-09-18 — this anchor's composited backdrop is rgb(0, 74, 101)
   on all 8 routes sampled (/, /about/, /contact/, /services/, /services/separation-divorce/,
   /resources/, one article, /404.html), visible on every one. White gives 9.61:1,
   the same figure the nav links on this band already measure. */
a.framer-3xdgzj.framer-28d1km:focus-visible,
/* CTA buttons that sit on a navy SECTION rather than inside the nav or the footer,
   so no container rule reaches them. Scoped by Framer VARIANT class, which is shared
   site-wide — the same framer-v-8eblsl component is "Book free consult" on /contact/,
   "Free 30 Min Consult" on /resources/ and "Go to Home" on /404.html, and all three
   measured 1.00:1 before this rule.
   source: MEASURED 2026-09-18 across all 26 routes — these are the only dark-backdrop
   focusables outside <footer> and .framer-2luqmz. v-8eblsl (6 instances / 4 routes),
   v-rg4kty ("View All" blog back button, 15 article routes), v-1rim410 (1 instance). */
.framer-v6hHe.framer-v-8eblsl:focus-visible,
.framer-v6hHe.framer-v-rg4kty:focus-visible,
.framer-v6hHe.framer-v-1rim410:focus-visible,
/* THE MOBILE HAMBURGER. Below 810px the desktop header is display:none and this is
   the ONLY control in the header — the entire route to navigation on a phone. It sits
   on the navy band and was taking the navy default ring: 1.00:1, invisible, in both
   the closed and open states.
   It was missed because it is outside .framer-2luqmz and outside <footer>, AND
   because it does not exist in the DOM at 1440px, which is the only width the focus
   gate measured. Found 2026-09-18 by an adversarial pass at 390px.
   source: MEASURED 2026-09-18 at 390x844 — composited backdrop rgb(0, 74, 101) on
   /, /about/, /contact/, /services/, /404.html, closed and open. */
div.framer-f0jjc2:focus-visible {
  outline-color: var(--token-2599792c-cd72-44e1-834a-b0e24aeeacae, #fefefe);
}

/* THE ONE LIGHT ELEMENT INSIDE THE NAV CONTAINER — this is a correction to the rule
   above, and it must stay AFTER it.
   `.framer-2luqmz :focus-visible { outline-color: white }` was written for the navy
   DESKTOP nav bar. Framer reuses the SAME class for the mobile drawer, and inside the
   open drawer the "Free Consult" button is WHITE-FILLED. The container rule therefore
   forced a white ring onto a white button: 1.00:1, invisible.
   This is the second time a container-scoped rule has misfired because Framer reuses a
   class across different backdrops (see the .framer-1tadhzx note above). A container
   tells you where an element is, never what colour it sits on.
   source: MEASURED 2026-09-18 at 390x844 with the drawer OPEN — inside .framer-2luqmz
   the four nav links composite to rgb(0, 74, 101) and this button alone composites to
   rgb(254, 254, 254), identically on /, /about/, /services/ and /contact/. At 1440px
   the header CTA is outside this container and already measured 9.61:1, so this rule
   changes nothing on desktop. */
.framer-2luqmz .framer-v6hHe:focus-visible {
  outline-color: var(--token-a2d7b8ca-eac6-4a53-aec9-921ed3fbf0a5, #004a65);
}

/* --------------------------------------------------------------------------
   4c. Testimonial carousel controls
   --------------------------------------------------------------------------
   The homepage testimonial slideshow ships four classless <button> elements per
   responsive variant — Previous, Next, and two pagination dots, 16 in total across
   the four SSR variants — and Framer authored no hover for any of them, under
   either mechanism: there is no :hover rule and no .hover-class rule reaching them
   anywhere in the page's inline CSS or in this file. They do carry cursor:pointer,
   so a visitor is told they are live and gets nothing back.

   These are treated as INHERITED rather than as a migration regression. Be precise
   about how strong that evidence is, because an earlier draft of this comment
   overstated it on all three points:
     - MEASURED 2026-09-24, rendered DOM at 1440 and 390: this export and the Framer
       live site present the same four controls with the same bounding rects, the same
       inline style strings and the same child elements. That is rendered-shape
       equality. It is NOT a byte comparison of the served markup — no such comparison
       was made, and the word "byte-identical" does not belong here.
     - The reference arm sampled only SOME of these controls, never all of them:
       SAMPLES_PER_SIGNATURE = 2 takes [first, last] out of a bucket that also held a
       control this export does not have, so of the reference samples on "/", several
       returned OK. "Every carousel row on the reference fails on every run" is NOT in
       the data and was wrong.
     - JUDGMENT, not measurement: the OK rows are read as belonging to that other
       control rather than to a carousel button. The gate cannot tell them apart, so
       no artifact proves it.
   What IS solid: no :hover rule and no .hover-class rule reaches these buttons on
   either site, and nothing in this export removed one.

   An earlier pass classified two of them as REGRESSIONs. The cause was the gate
   bucketing them under the signature `button||` — bare tag, no framer-name, no class
   — together with an unlabelled 30x30 control that exists only on the framer.app
   host, which responds to hover; the classifier asks whether SOME row under that key
   responded, so every failing control in the bucket was blamed. Those two rows were
   the NARROW pair, and both reference runs agreed on them — the verdict was wrong but
   it was reproducible. (The desktop pair is where the reference runs disagreed, and
   those were classified INHERITED. An earlier draft told that story about the wrong
   viewport.) That the other control is Framer platform chrome is a JUDGMENT from four
   negatives — no aria-label, no data-framer-name, no class, present on reference
   routes where this export has no such button at all — not a measurement.

   Two different responses, because one does not fit both controls.

   ARROWS darken their own translucent fill. !important is required: the fill is an
   inline style (background-color:rgba(0,0,0,0.2)) and a stylesheet rule cannot
   outrank it. §4b's opacity fade is deliberately NOT reused — fading a translucent
   circle reads as disabled, the opposite of an affordance.
   source: judgment — no sibling CSS hover exists to mirror, on either site.
   rgba(0,0,0,.4) is this element's own inline 0.2 alpha doubled; over the measured
   section backdrop rgb(240,242,244) that moves the composite from rgb(192,194,195)
   to rgb(144,145,146).
   The darkening is scoped to :hover and deliberately NOT to :focus-visible. The §5
   ring is INSET (outline-offset:-2px), so on these buttons it paints over the button's
   own fill rather than over the section backdrop — darkening the fill for a focused
   arrow would drag its own focus ring from 5.42:1 down to 3.07:1, a 2% margin over
   the floor. Leaving the fill alone while focused keeps the ring at 5.42:1, and the
   ring is the focus affordance. source: MEASURED 2026-09-24, sRGB relative luminance,
   navy #004a65 against each composited fill.

   DOTS scale instead of fading, because opacity is ALREADY this component's state
   channel. MEASURED 2026-09-24: each dot holds a 10x10 circle in the site's gold
   #b98e44, at opacity 1 when its page is current and 0.5 when it is not. An opacity
   hover would fade the current dot into looking inactive and push an inactive one to
   0.36 — it would read as state, not as feedback. Scale is orthogonal to it. No
   !important needed: nothing sets transform inline on the dots (the arrows do carry
   transform:none, a second reason the arrow rule does not use transform).
   The scale is applied to the BUTTON rather than to the circle inside it. Do not
   restate the earlier reason given here — that a scaled child "would be clipped to
   nothing" — it was wrong: overflow clips to the PADDING box (25x30), not the content
   box, so a 12.5px scaled circle fits with room to spare. Scaling the button is simply
   the smaller rule, and it is what was measured.
   The button's own scaled box IS clipped by its 50x30 overflow:hidden wrapper —
   MEASURED 2026-09-24 while hovered: 3.75px off top and bottom, 3.13px off the outward
   side. That clipped area is transparent padding. The gold circle renders 12.5px
   centred in a 37.5px box and stays inside the wrapper's 30px height untouched,
   confirmed by render at verification/compare/dot-*-{rest,hover}.png. A future reviewer
   will spot the clipping and assume a defect; this paragraph is why there isn't one.
   source: judgment — 1.25 is the smallest step that is unambiguous on a 10px target;
   timing matches the .22s ease used throughout this file.

   Approved by Rob 2026-09-24 — he chose to add the affordance on the §4b precedent
   and separately confirmed the straight-copy exemption still stands. The wording of
   the principle below is MINE, not a quote from him, and is not a standing rule:
   an inherited no-hover control still gets the house affordance, because the
   straight-copy rule is not a reason to ship a control that says "clickable" and
   answers nothing.

   Keyboard focus: MEASURED 2026-09-24 — for the DOTS the button fill is transparent,
   so the inset ring composites against the section backdrop rgb(240,242,244) and the
   navy ring (#004a65) lands at 8.63:1 (the same figure §5 already records for this
   pair — an earlier draft said 8.64 and contradicted it). For the ARROWS the ring sits
   on the button's own fill instead, giving 5.42:1 at rest, which is why the hover
   darkening is not extended to the focused state. No colour override is needed for
   either. The inset offset from §5 is what makes the ring visible at all, since every
   one of these buttons sets overflow:hidden inline.
   NOTE on the citation: the 3:1 floor for a focus indicator against adjacent colours
   is WCAG 1.4.11 Non-text Contrast. WCAG 2.4.11 Focus Appearance is the >=2px-perimeter
   requirement measured between the focused and unfocused states. §5 of this file states
   the 1.4.11 requirement under the 2.4.11 label; that predates this section and is left
   as-is rather than edited here, but do not copy it forward. */
fieldset.framer--slideshow-controls button[aria-label="Previous"],
fieldset.framer--slideshow-controls button[aria-label="Next"] {
  transition: background-color .22s ease;
}
fieldset.framer--slideshow-controls button[aria-label="Previous"]:hover,
fieldset.framer--slideshow-controls button[aria-label="Next"]:hover {
  background-color: rgba(0, 0, 0, .4) !important;
}

fieldset.framer--slideshow-controls button[aria-label^="Scroll to page"] {
  transition: transform .22s ease;
}
fieldset.framer--slideshow-controls button[aria-label^="Scroll to page"]:hover,
fieldset.framer--slideshow-controls button[aria-label^="Scroll to page"]:focus-visible {
  transform: scale(1.25);
}

/* --------------------------------------------------------------------------
   6. Reduced motion
   --------------------------------------------------------------------------
   The colour and position END STATES are affordances and must survive — only the
   tweening is removed. Never collapse this into "no hover".
   source: WCAG 2.3.3 Animation from Interactions. */
@media (prefers-reduced-motion: reduce) {
  .framer-v6hHe.framer-v-1a5hzqh .framer-1gj2sot,
  .framer-v6hHe.framer-v-qfz1ir .framer-1gj2sot,
  .framer-r00BP.framer-v-ndpgml .framer-1ksjodp,
  .framer-l5dpq.framer-v-4jv5wj,
  fieldset.framer--slideshow-controls button[aria-label="Previous"],
  fieldset.framer--slideshow-controls button[aria-label="Next"],
  fieldset.framer--slideshow-controls button[aria-label^="Scroll to page"] {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   7. Hero text vertically centred below the menu bar (2026-10-14)
   --------------------------------------------------------------------------
   Not a hover rule. It lives here because this is the one stylesheet loaded on
   every page that survives in-site clicks (Framer re-injects its own page CSS).

   Inherited from Framer, not caused by the move: live and the original
   .framer.app measured identical on all 26 pages. Each hero's padding counts the
   solid menu bar as if it were hero, so the text sat high (or, on service pages,
   wherever an absolutely-placed title happened to fall).

   Rule: the space below the bar is split evenly above/below the text, and the
   hero keeps its original total height so nothing below it moves.
   Menu bar bottom MEASURED 2026-10-14 (WebKit, verification/hero-centre-2026-10-14/info.cjs):
   170px at 1440, 130px at 1024, 100px at 390.
   Breakpoints are Framer's own (from the pages' image `sizes` attributes).
   Doubled class = one notch above Framer's rule, whichever order the sheets load. */

/* 7a. Resources, Contact, all articles. Framer: 300/170 desktop, 205/100 tablet,
   160/60 phone (phone already centred: 160-100 = 60). */
@media (min-width: 1200px) {
  .framer-swdQI .framer-3ssv1x.framer-3ssv1x,
  .framer-y98K7 .framer-1nwo6lc.framer-1nwo6lc,
  .framer-EAf97 .framer-1lgjh61.framer-1lgjh61 {
    padding-top: 320px;    /* MEASURED 2026-10-14: bar 170 + (300+170-170)/2 */
    padding-bottom: 150px; /* MEASURED 2026-10-14: (300+170-170)/2, total height unchanged */
  }
}
@media (min-width: 810px) and (max-width: 1199.98px) {
  .framer-swdQI .framer-3ssv1x.framer-3ssv1x,
  .framer-y98K7 .framer-1nwo6lc.framer-1nwo6lc,
  .framer-EAf97 .framer-1lgjh61.framer-1lgjh61 {
    padding-top: 217.5px;  /* MEASURED 2026-10-14: bar 130 + (205+100-130)/2 */
    padding-bottom: 87.5px; /* MEASURED 2026-10-14: (205+100-130)/2, total height unchanged */
  }
}

/* 7b. Home. Framer: 270/160 desktop, 175/80 tablet, 135/60 phone. */
@media (min-width: 1200px) {
  .framer-Yrqj8 .framer-g3cr7y.framer-g3cr7y {
    padding-top: 300px;    /* MEASURED 2026-10-14: bar 170 + (270+160-170)/2 */
    padding-bottom: 130px; /* MEASURED 2026-10-14: (270+160-170)/2, total height unchanged */
  }
}
@media (min-width: 810px) and (max-width: 1199.98px) {
  .framer-Yrqj8 .framer-g3cr7y.framer-g3cr7y {
    padding-top: 192.5px;  /* MEASURED 2026-10-14: bar 130 + (175+80-130)/2 */
    padding-bottom: 62.5px; /* MEASURED 2026-10-14: (175+80-130)/2, total height unchanged */
  }
}
@media (max-width: 809.98px) {
  .framer-Yrqj8 .framer-g3cr7y.framer-g3cr7y {
    padding-top: 147.5px;  /* MEASURED 2026-10-14: bar 100 + (135+60-100)/2 */
    padding-bottom: 47.5px; /* MEASURED 2026-10-14: (135+60-100)/2, total height unchanged */
  }
}

/* 7c. Service pages. The title is position:absolute, top:20px inside a short
   placeholder box, so a one-line title hung low of the box and a two-line title
   (Family Dispute Resolution) ran further down. Centre the title on its box, then
   make the hero's content area exactly the space below the bar so flex centres the
   box there. Total heights are kept at Framer's own.
   `translate`, not `transform`: Framer writes transform:none inline on this element. */
.framer-47Fnv .framer-q1aes6.framer-q1aes6 { top: 50%; translate: 0 -50%; }
@media (min-width: 1200px) {
  .framer-47Fnv .framer-1cr7nox.framer-1cr7nox {
    height: 543px;      /* MEASURED 2026-10-14: Framer's rendered hero height at 1440 (padding-derived) */
    padding-top: 170px; /* MEASURED 2026-10-14: menu bar bottom at 1440 */
    padding-bottom: 0;
  }
}
@media (min-width: 810px) and (max-width: 1199.98px) {
  .framer-47Fnv .framer-1cr7nox.framer-1cr7nox {
    padding-top: 130px; /* MEASURED 2026-10-14: menu bar bottom at 1024; Framer's own height 373px kept */
    padding-bottom: 0;
  }
}
@media (max-width: 809.98px) {
  .framer-47Fnv .framer-1cr7nox.framer-1cr7nox {
    padding-top: 100px; /* MEASURED 2026-10-14: menu bar bottom at 390; Framer's own height 288px kept */
    padding-bottom: 0;
  }
}

/* 7d. Resources + Contact, desktop only: the hero's entrance animation STICKS 50px low
   after an in-site click (Framer's own bug; the original .framer.app does it too) and
   only lets go when the visitor scrolls. MEASURED 2026-10-14 with settle.cjs/stuck.cjs:
   no other page or width sticks. On a direct visit the slide (32px) runs while the text
   is under 0.5% opacity, then never moves again, scroll included — so pinning it at the
   settled value costs nothing visible. The fade-in still plays. The value is exactly
   what Framer settles to; !important because Framer writes this one inline. */
@media (min-width: 1200px) {
  .framer-swdQI .framer-1wdlxg6,
  .framer-y98K7 .framer-dwpsgt { transform: perspective(1200px) !important; }
}
