/*
Theme Name: Lugo Law
Theme URI: https://www.lugolaw.com/
Author: Converge Digital
Author URI: https://convergedigitalmarketing.com/
Description: Bilingual block theme for the Law Offices of Alejo Lugo & Associates. Core Gutenberg blocks only. The design system lives in theme.json; this file carries only what theme.json cannot express.
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
Version: 1.69.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lugolaw
Tags: block-theme, full-site-editing, two-columns, custom-colors
*/

/* --------------------------------------------------------------------------
   Everything expressible in theme.json belongs in theme.json. What is left
   here is behaviour and a small set of named utilities, per docs/METHOD.md.
   No per-page CSS, ever.
   -------------------------------------------------------------------------- */

/* Sticky header that inverts on scroll ------------------------------------ */

.wp-site-blocks > header.wp-block-template-part {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--wp--preset--color--white);
  border-bottom: 1px solid var(--wp--preset--color--line);
  transition: background .28s ease, border-color .28s ease, box-shadow .28s ease;
}

/* The admin bar is fixed on desktop, so offset under it while logged in. */
.admin-bar .wp-site-blocks > header.wp-block-template-part { top: 32px; }
@media (max-width: 782px) {
  .admin-bar .wp-site-blocks > header.wp-block-template-part { top: 46px; }
}

.ll-header--scrolled {
  background: var(--wp--preset--color--ink) !important;
  border-bottom-color: #1B3E5C !important;
  box-shadow: 0 10px 30px -18px rgba(7, 22, 38, .7);
}

/* Logo crossfade. Two stacked images, one per header state. */
.ll-mono { position: relative; display: block; width: 60px; height: 60px; flex: none; }
.ll-mono img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block; object-fit: contain;
  transition: opacity .28s ease;
}
.ll-mono .ll-mono__dark { opacity: 0; }
.ll-header--scrolled .ll-mono .ll-mono__light { opacity: 0; }
.ll-header--scrolled .ll-mono .ll-mono__dark  { opacity: 1; }

/* Wordmark, and its inversion in the scrolled state ----------------------- */
.ll-wordmark { display: flex; flex-direction: column; line-height: 1.1; }
.ll-wordmark .ll-wordmark__pre {
  font-size: .68rem; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--wp--preset--color--brand);
}
.ll-wordmark .ll-wordmark__name {
  font-size: 1.06rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--wp--preset--color--brand);
}
.ll-header--scrolled .ll-wordmark__pre  { color: #8FB0CC; }
.ll-header--scrolled .ll-wordmark__name { color: var(--wp--preset--color--white); }
/* Core sets the nav link colour with a doubled class,
   .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content
   { color: inherit }, which outranks any sane selector on the anchor. Because
   the declared value is "inherit", colouring the container is both simpler and
   more robust than trying to outrank it. Hover has to match that specificity. */
.ll-header--scrolled .wp-block-navigation { color: var(--wp--preset--color--white); }
.ll-header--scrolled .wp-block-navigation a.wp-block-navigation-item__content.wp-block-navigation-item__content:hover {
  color: #9CC6EE;
}

/* Headings breathe. Copy length changes between EN and ES, so nothing that
   contains text gets a fixed height. */
h1, h2, h3, .wp-block-heading { text-wrap: balance; }
p { text-wrap: pretty; }

/* Utility bar: office phones left, language right, full bleed ------------- */
.ll-utility { font-size: .82rem; }
.ll-utility a { text-decoration: none; }
.ll-utility a:hover { text-decoration: underline; }

/* Named utilities --------------------------------------------------------- */
.ll-eyebrow {
  font-size: .83rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase;
}
/* The practice page H1 sits in this slot. Once it carries a whole keyword
   phrase rather than one or two words, caps and letter-spacing stop helping:
   the line gets wide, reads as shouting and is measurably slower to scan.
   Sentence case, no tracking, one step up in size. Every other .ll-eyebrow
   keeps its caps, because those really are one and two word labels. */
.ll-phero h1.ll-eyebrow {
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.35;
  margin-bottom: .5rem;
  max-width: 34ch;
}
.ll-card {
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 14px;
  background: var(--wp--preset--color--white);
}
.ll-shadow { box-shadow: 0 18px 40px -28px rgba(7, 22, 38, .45); }

/* Full-bleed hero image sits behind its copy ------------------------------ */
.ll-hero { position: relative; isolation: isolate; }
.ll-hero .ll-hero__media { position: absolute; inset: 0; z-index: -2; }
.ll-hero .ll-hero__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 32%;
}
/* The scrim exists to make the copy legible, not to tint the photograph. It
   stays fully clear across the left of the frame where he is, and only builds
   under the text column on the right. */
.ll-hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg,
    rgba(10,33,56,0)   0%,
    rgba(10,33,56,0)   34%,
    rgba(10,33,56,.42) 45%,
    rgba(10,33,56,.84) 60%,
    rgba(10,33,56,.92) 100%);
}
/* Below the two-column breakpoint the copy sits over the picture, so the scrim
   has to run vertically instead or the text becomes unreadable. */
@media (max-width: 781px) {
  .ll-hero::after {
    background: linear-gradient(180deg,
      rgba(10,33,56,.25) 0%,
      rgba(10,33,56,.55) 42%,
      rgba(10,33,56,.88) 100%);
  }
}

/* Respect a reduced-motion preference ------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .wp-site-blocks > header.wp-block-template-part,
  .ll-mono img { transition: none; }
}

/* Skip link visible on focus ---------------------------------------------- */
.skip-link:focus {
  position: fixed; top: 8px; left: 8px; z-index: 999;
  padding: 12px 18px; border-radius: 8px;
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--ink);
}

/* Brand lockup ------------------------------------------------------------ */
.ll-brand {
  display: flex; align-items: center; gap: 14px;
  text-decoration: none; flex: none;
}
.ll-brand:hover { text-decoration: none; }
/* The header measure, deliberately wider than the 1240px content measure.
   At 1240 the bar has 1176px of usable width inside its own padding and the
   brand, nav and button need 1206px, so the row was overflowing its padding
   and everything sat shoulder to shoulder. One value, changed here, moves the
   header and the mega panel together. */
:root { --ll-header-measure: 1440px; }
/* Sticky offset for anything that has to clear the header. Measured in
   headless Chrome per breakpoint rather than guessed; see .ll-plist__rail. */
:root { --ll-header-h: 156px; }
.ll-headbar { max-width: var(--ll-header-measure); }

/* Utility bar labels ------------------------------------------------------ */
.ll-utility__label {
  color: var(--wp--preset--color--ink-soft);
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  margin-right: .45rem;
}
.ll-utility a { color: var(--wp--preset--color--white); font-weight: 700; }
.ll-langswitch a {
  display: inline-block; padding: .42rem .95rem; border-radius: 8px;
  background: var(--wp--preset--color--sand);
  color: var(--wp--preset--color--ink); font-weight: 700;
}
.ll-langswitch a:hover { background: var(--wp--preset--color--sand-deep); text-decoration: none; }

/* Navigation, and the Practice Areas mega panel --------------------------- */
/* Built on core's navigation-submenu markup rather than a mega-menu plugin.
   The second level becomes the panel's columns; the third level is the link
   list inside each column, forced static so it is always visible.

   Careful with the selectors: WordPress puts the block's className on BOTH the
   <li> and its <ul>, so a bare .ll-mega rule hits the panel as well as the item.
   Everything below is qualified by tag. The extra .wp-block-navigation prefix is
   there to outrank core's own .wp-block-navigation .has-child ... rules. */
.ll-nav .wp-block-navigation-item__content { padding-block: .4rem; }

.ll-nav.wp-block-navigation li.ll-mega { position: static !important; }

.ll-nav.wp-block-navigation li.ll-mega > ul.wp-block-navigation__submenu-container {
  position: absolute;
  left: 0; right: 0; top: 100%;
  /* Core's closed-submenu rule also pins the panel itself to height:0 with
     overflow:hidden, which left it 69px tall (its own padding) and clipped the
     445px columns inside it. Same deliberate override as the level below. */
  height: auto !important;
  overflow: visible !important;
  width: auto !important; min-width: 0 !important; max-height: none !important;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 26px 30px;
  padding: 34px max(32px, calc((100% - var(--ll-header-measure)) / 2 + 32px));
  background: var(--wp--preset--color--white);
  border: 0; border-top: 1px solid var(--wp--preset--color--line);
  border-radius: 0;
  box-shadow: 0 26px 50px -34px rgba(7, 22, 38, .55);
}

/* Each column */
.ll-nav.wp-block-navigation li.ll-mega > ul > li { position: static; width: auto; }
.ll-nav.wp-block-navigation li.ll-mega > ul > li > .wp-block-navigation-item__content {
  font-size: .95rem; font-weight: 800; color: var(--wp--preset--color--ink);
  padding: 0 0 .55rem; border-bottom: 1px solid var(--wp--preset--color--line-2);
  margin-bottom: .5rem; display: block;
}

/* Third level: always shown, stacked inside its column */
.ll-nav.wp-block-navigation li.ll-mega ul ul.wp-block-navigation__submenu-container {
  /* Core hides a closed submenu with
       .wp-block-navigation .has-child:not(.open-on-click):not(:hover):not(:focus-within) .wp-block-navigation__submenu-container
     which is six classes of specificity and sets visibility, height, width and
     overflow. Inside the mega panel these lists are never "closed", so this is a
     deliberate override rather than a specificity race. */
  position: static !important;
  opacity: 1 !important;
  /* MUST be "inherit", not "visible". Core hides the closed panel with
     visibility:hidden, and a hidden element is not hit-testable, but a
     descendant that forces itself visible IS. Forcing these lists visible made
     the whole invisible panel a hover trap sitting over the page, so moving the
     mouse anywhere in the body opened the mega menu. Inheriting means the
     columns appear and disappear with the panel, and vanish from hit testing
     with it too. */
  visibility: inherit !important;
  display: block !important;
  width: auto !important;
  min-width: 0 !important;
  height: auto !important;
  max-height: none !important;
  overflow: visible !important;
  inset: auto !important;
  padding: 0; border: 0; border-radius: 0; box-shadow: none;
  background: transparent; transform: none;
}
.ll-nav.wp-block-navigation li.ll-mega ul ul a {
  padding: .28rem 0; font-size: .92rem; font-weight: 500;
  color: var(--wp--preset--color--ink-2);
}
.ll-nav.wp-block-navigation li.ll-mega ul ul a:hover { color: var(--wp--preset--color--brand); }
.ll-nav.wp-block-navigation li.ll-mega .ll-mega__all a {
  margin-top: .35rem; font-weight: 700; color: var(--wp--preset--color--brand);
}
/* The dropdown chevrons make no sense once the panel is a static grid. */
.ll-nav.wp-block-navigation li.ll-mega ul .wp-block-navigation__submenu-icon { display: none; }

@media (max-width: 1100px) {
  .ll-nav.wp-block-navigation li.ll-mega > ul.wp-block-navigation__submenu-container {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
/* Inside the mobile overlay the panel must flow, not float. */
.wp-block-navigation__responsive-container.is-menu-open li.ll-mega > ul.wp-block-navigation__submenu-container {
  position: static; display: block; padding: 0; box-shadow: none;
  background: transparent; border: 0;
}

/* Breadcrumb -------------------------------------------------------------- */
/* The crumbs are raw HTML inside the constrained layout, so without help they
   take contentSize (760px) and centre, landing 240px right of the H1 below
   them and leaving the paper strip floating short of both edges. The nav
   carries `alignfull` for the strip, and the inner box reproduces core's
   alignwide geometry exactly: root padding on the outside, wideSize centred
   within it. That puts the first crumb on the same vertical as the hero
   eyebrow and H1 at every width. */
.ll-crumbs {
  background: var(--wp--preset--color--paper);
  border-bottom: 1px solid var(--wp--preset--color--line-2);
  font-size: .9rem;
  padding-inline: var(--wp--preset--spacing--40);
}
.ll-crumbs__inner {
  max-width: var(--wp--style--global--wide-size);
  margin-inline: auto;
  padding-block: 14px;
  padding-inline: 0;
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
}
.ll-crumbs a { color: var(--wp--preset--color--brand); text-decoration: none; font-weight: 600; }
.ll-crumbs a:hover { text-decoration: underline; }
.ll-crumbs [aria-hidden="true"] { color: var(--wp--preset--color--sand-deep); }
.ll-crumbs [aria-current="page"] { color: var(--wp--preset--color--ink-soft); }

/* Practice hero ----------------------------------------------------------- */
.ll-phero .wp-block-post-title { margin-top: .35rem; }

/* Child page grid --------------------------------------------------------- */
.ll-childgrid {
  list-style: none; margin: var(--wp--preset--spacing--40) auto 0; padding: 0;
  max-width: var(--wp--style--global--wide-size);
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  background: var(--wp--preset--color--line);
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 14px; overflow: hidden;
}
.ll-childgrid li { margin: 0; background: var(--wp--preset--color--white); }
.ll-childgrid a {
  display: block; padding: 18px 20px; font-weight: 600;
  color: var(--wp--preset--color--ink); text-decoration: none;
}
/* Hover is scoped to devices that actually have a pointer. On a touch screen
   :hover latches after a tap and the card stays highlighted, which reads as a
   selected state that never clears. Touch gets :active instead. */
@media (hover: hover) {
  .ll-childgrid a:hover {
    background: var(--wp--preset--color--brand-pale);
    color: var(--wp--preset--color--brand);
  }
}
.ll-childgrid a:active {
  background: var(--wp--preset--color--brand-pale);
  color: var(--wp--preset--color--brand);
}
.ll-childgrid a:focus-visible {
  outline: 3px solid var(--wp--preset--color--brand-lift);
  outline-offset: -3px;
}
/* A chevron makes each row read as a destination rather than a bullet, and it
   is the only affordance a touch device gets, since it cannot hover. */
.ll-childgrid a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.ll-childgrid a::after {
  content: ""; flex: none; width: 7px; height: 7px;
  border-right: 2px solid var(--wp--preset--color--sand-deep);
  border-bottom: 2px solid var(--wp--preset--color--sand-deep);
  transform: rotate(-45deg);
  transition: border-color .15s ease, transform .15s ease;
}
@media (hover: hover) {
  .ll-childgrid a:hover::after { border-color: var(--wp--preset--color--brand); transform: rotate(-45deg) translate(2px, 2px); }
}

/* Footer ------------------------------------------------------------------ */
/* Closing CTA across the bottom of the mega panel (lugolaw_mega_cta).
   Spans the whole grid rather than taking a sixth column, because the five
   columns are already the width they want to be and squeezing them to make
   room for a card would cost more than the card gains. */
.ll-nav.wp-block-navigation li.ll-mega > ul > li.ll-megacta {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .75rem 1.5rem;
  margin-top: .5rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--wp--preset--color--line);
  width: auto;
}
.ll-megacta p { margin: 0; }
.ll-megacta__t { font-size: .92rem; line-height: 1.4; }
.ll-megacta__t strong { color: var(--wp--preset--color--ink); }
.ll-megacta__t span { color: var(--wp--preset--color--ink-soft); }
.ll-megacta__a { display: flex; align-items: center; gap: .6rem; }
.ll-nav.wp-block-navigation li.ll-mega .ll-megacta__call {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .55rem .95rem; border-radius: 999px;
  background: var(--wp--preset--color--brand-pale);
  color: var(--wp--preset--color--brand);
  font-weight: 800; font-size: .9rem; text-decoration: none; white-space: nowrap;
}
.ll-nav.wp-block-navigation li.ll-mega .ll-megacta__call:hover {
  background: var(--wp--preset--color--brand); color: var(--wp--preset--color--white);
}
.ll-nav.wp-block-navigation li.ll-mega .ll-megacta__btn {
  padding: .62rem 1.15rem; border-radius: 10px;
  background: var(--wp--preset--color--brand);
  color: var(--wp--preset--color--white);
  font-weight: 800; font-size: .9rem; text-decoration: none; white-space: nowrap;
}
.ll-nav.wp-block-navigation li.ll-mega .ll-megacta__btn:hover {
  background: var(--wp--preset--color--ink);
}
/* The closing CTA belongs to the desktop panel. In the overlay it rendered as
   a wide two-button block that ran off the screen, and the header already has
   a consultation button two inches above it. */
.wp-block-navigation__responsive-container.is-menu-open li.ll-megacta,
.ll-nav .wp-block-navigation__responsive-container.is-menu-open li.ll-megacta { display: none !important; }

/* ==========================================================================
   Header, across the breakpoints.

   The inline nav runs down to 1024px. An earlier pass pushed the overlay up to
   1200 instead, which put a hamburger on small laptops: easier to write, worse
   to use, and the wrong trade. What actually did not fit was the brand lockup,
   so the brand is what gives way, in steps, and the nav stays.

   Three tiers above 1024, because the row is genuinely tighter at 1024 than at
   1440 and one set of sizes cannot serve both.
   ========================================================================== */

/* The nav block is overlayMenu "always", so core keeps the overlay at every
   width and always shows the button. Above 1024 that is undone here, which is
   exactly what core does for its own 600px breakpoint. */
@media (min-width: 1024px) {
  .ll-nav .wp-block-navigation__responsive-container.hidden-by-default:not(.is-menu-open) {
    display: block;
    width: 100%;
    position: relative;
    z-index: auto;
    background-color: inherit;
    padding: 0;
  }
  .ll-nav .wp-block-navigation__responsive-container.hidden-by-default:not(.is-menu-open) .wp-block-navigation__responsive-container-close { display: none; }
  .ll-nav .wp-block-navigation__responsive-container-open.always-shown { display: none; }
}

/* 1024 to 1199: the tight tier. Mark only, no wordmark, compact nav. */
@media (min-width: 1024px) and (max-width: 1199px) {
  .ll-brand .ll-wordmark { display: none; }
  .ll-mono { width: 44px; height: 44px; }
  .ll-nav .wp-block-navigation__container { gap: .95rem !important; }
  .ll-nav .wp-block-navigation-item__content { font-size: .88rem; }
  .ll-headbar { gap: var(--wp--preset--spacing--30) !important; padding-inline: var(--wp--preset--spacing--30); }
  .ll-headbar > .wp-block-group { gap: var(--wp--preset--spacing--30) !important; }
  .ll-headcta .wp-block-button__link {
    font-size: .8rem;
    padding: .7rem 1rem !important;
  }
}

/* 1200 to 1439: the wordmark comes back, sizes still trimmed. */
@media (min-width: 1200px) and (max-width: 1439px) {
  .ll-mono { width: 48px; height: 48px; }
  .ll-wordmark .ll-wordmark__pre  { font-size: .58rem; }
  .ll-wordmark .ll-wordmark__name { font-size: .88rem; }
  .ll-nav .wp-block-navigation__container { gap: 1.05rem !important; }
  .ll-nav .wp-block-navigation-item__content { font-size: .9rem; }
  .ll-headbar { gap: var(--wp--preset--spacing--30) !important; }
  .ll-headbar > .wp-block-group { gap: var(--wp--preset--spacing--30) !important; }
  .ll-headcta .wp-block-button__link { font-size: .84rem; padding: .74rem 1.1rem !important; }
}

/* 1440 and up: full size, room to breathe. */
@media (min-width: 1440px) {
  .ll-mono { width: 56px; height: 56px; }
  .ll-nav .wp-block-navigation__container { gap: 1.6rem !important; }
}

/* Never wrap the firm's name to two lines; show it whole or not at all. */
.ll-wordmark .ll-wordmark__name,
.ll-wordmark .ll-wordmark__pre { white-space: nowrap; }

/* --------------------------------------------------------------------------
   Below 1024: the overlay.
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .ll-headbar { flex-wrap: nowrap; gap: var(--wp--preset--spacing--30); padding-block: .7rem; }
  .ll-headbar > .wp-block-group { flex-wrap: nowrap; gap: var(--wp--preset--spacing--30); }
  .ll-nav, .ll-headcta { flex: 0 0 auto; }
  .ll-headcta .wp-block-button,
  .ll-headcta .wp-block-button__link { white-space: nowrap; flex: 0 0 auto; }
  .ll-headcta .wp-block-button__link { font-size: .82rem; padding: .72rem 1.05rem !important; }
  .ll-brand { min-width: 0; flex: 0 1 auto; }
  .ll-mono { width: 44px; height: 44px; }
  .ll-wordmark .ll-wordmark__pre  { font-size: .56rem; }
  .ll-wordmark .ll-wordmark__name { font-size: .84rem; }
}
@media (max-width: 720px) {
  .ll-brand .ll-wordmark { display: none; }
  .ll-mono { width: 42px; height: 42px; }
}

/* The burger: three bars, and big enough to hit. Core ships a two-bar glyph at
   24px which reads as an equals sign. */
.ll-nav .wp-block-navigation__responsive-container-open {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.ll-nav .wp-block-navigation__responsive-container-open svg { display: none; }
.ll-nav .wp-block-navigation__responsive-container-open::before {
  content: "";
  width: 26px; height: 2px;
  background: currentColor;
  box-shadow: 0 -8px 0 currentColor, 0 8px 0 currentColor;
}
.ll-nav .wp-block-navigation__responsive-container-close {
  width: 44px; height: 44px;
}
.ll-nav .wp-block-navigation__responsive-container-close svg { width: 26px; height: 26px; }

/* The overlay itself. Left aligned, because a right-aligned list of links on a
   phone is a thumb reaching across the screen for every tap, and because the
   nav block carries justifyContent "right" for the desktop row, which the
   overlay inherits and which pushed the practice-area headings off the right
   edge of the screen. Every list inside the overlay, not just the top one. */
.ll-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.ll-nav .wp-block-navigation__responsive-container.is-menu-open ul,
.ll-nav .wp-block-navigation__responsive-container.is-menu-open li {
  align-items: flex-start !important;
  justify-content: flex-start !important;
  text-align: left !important;
}
.ll-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > li { width: 100%; }
.ll-nav .wp-block-navigation__responsive-container.is-menu-open ul.wp-block-navigation__container { gap: .15rem; width: 100%; }
.ll-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  padding: .6rem 0; font-size: 1.05rem; font-weight: 700;
}

/* The mega panel collapses to its five section headings inside the overlay.
   The desktop rule that forces the third level open carries !important, so it
   was firing here too and the menu loaded with all 54 practice pages expanded
   above everything else. A phone menu is not a sitemap. */
.wp-block-navigation__responsive-container.is-menu-open li.ll-mega ul ul.wp-block-navigation__submenu-container { display: none !important; }
.wp-block-navigation__responsive-container.is-menu-open li.ll-mega > ul.wp-block-navigation__submenu-container {
  position: static; display: block; padding: 0 0 0 .9rem; box-shadow: none;
  background: transparent; border: 0; grid-template-columns: none;
}
.wp-block-navigation__responsive-container.is-menu-open li.ll-mega > ul > li > .wp-block-navigation-item__content {
  font-size: .95rem; font-weight: 600; padding: .45rem 0; border: 0; margin: 0;
}

/* Homepage: why hire us ----------------------------------------------------
   A photograph of the attorney against a numbered list, not four equal boxes.
   Four identical cards give the eye nothing to rank and no reason to stop; a
   portrait does both, and the band is the one place on the homepage where the
   person being hired can be looked at. The section above it already carries
   the team photograph on the right, so this one sits on the left. */
.ll-why__split {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: var(--wp--preset--spacing--60);
  align-items: start;
  margin-top: var(--wp--preset--spacing--50);
}
.ll-why__split > * { margin-block: 0 !important; }
.ll-why__media { position: relative; }
.ll-why__media figure { margin: 0; }
.ll-why__media img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 14%;
  border-radius: 18px;
}
.ll-why__cap {
  margin: .95rem 0 0 !important;
  font-size: .83rem;
  line-height: 1.5;
  color: var(--wp--preset--color--ink-soft);
}
.ll-why__cap strong { color: var(--wp--preset--color--ink); font-weight: 700; }

.ll-why__list { counter-reset: llwhy; border-top: 1px solid var(--wp--preset--color--line); }
.ll-why__list > * { margin-block: 0 !important; }
.ll-why__item {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 1.1rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--wp--preset--color--line);
}
/* The counter is the whole ornament. A generated grid item needs no markup,
   so the numbering cannot drift from the list it is numbering. */
/* The counter occupies the narrow column for the whole item. Without the
   explicit placement the heading takes column two and the paragraph falls
   back into column one, which is 2.6rem wide: every line breaks after one
   word. Auto-placement is the bug, so both tracks are assigned by hand. */
.ll-why__item > * { grid-column: 2; }
.ll-why__item::before {
  grid-column: 1;
  grid-row: 1 / -1;
  counter-increment: llwhy;
  content: counter(llwhy, decimal-leading-zero);
  font-size: .9rem;
  font-weight: 800;
  line-height: 1.75;
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
  color: var(--wp--preset--color--brand);
}
.ll-why__item h3 { margin: 0 0 .3rem !important; }
.ll-why__item p  { margin: 0 !important; }
.ll-why__cta { margin-top: var(--wp--preset--spacing--40) !important; }
.ll-why__cta .wp-block-button__link { font-size: .95rem; }

@media (max-width: 1100px) {
  .ll-why__split { gap: var(--wp--preset--spacing--50); }
}
@media (max-width: 880px) {
  .ll-why__split { grid-template-columns: 1fr; }
  .ll-why__media { max-width: 340px; }
  .ll-why__media img { aspect-ratio: 1 / 1; }
}

/* Homepage: credentials band (patterns/home-credentials.php) ---------------
   Four stated facts, not a logo wall. Hairlines rather than cards: the band
   is a reference strip between two loud sections and should read as quiet. */
.ll-creds { border-block: 1px solid var(--wp--preset--color--line); }
.ll-creds__inner { max-width: var(--wp--style--global--wide-size); margin-inline: auto; }
.ll-creds__eyebrow {
  margin: 0 0 var(--wp--preset--spacing--30);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--wp--preset--color--brand);
}
.ll-creds__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--40);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ll-creds__item {
  margin: 0;
  padding-left: var(--wp--preset--spacing--30);
  border-left: 1px solid var(--wp--preset--color--line-2);
}
.ll-creds__item:first-child { padding-left: 0; border-left: 0; }
.ll-creds__mark { display: block; color: var(--wp--preset--color--brand); margin-bottom: .7rem; }
.ll-creds__mark svg { display: block; }
.ll-creds__label {
  display: block;
  font-weight: 700;
  font-size: .98rem;
  line-height: 1.35;
  color: var(--wp--preset--color--ink);
  text-wrap: balance;
}
.ll-creds__sub {
  display: block;
  margin-top: .3rem;
  font-size: .85rem;
  line-height: 1.45;
  color: var(--wp--preset--color--ink-soft);
}
@media (max-width: 900px) {
  .ll-creds__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--wp--preset--spacing--40); }
  .ll-creds__item:nth-child(odd) { padding-left: 0; border-left: 0; }
}
@media (max-width: 520px) {
  .ll-creds__grid { grid-template-columns: 1fr; }
  .ll-creds__item { padding-left: 0; border-left: 0; }
}

/* Homepage: the full practice list.
   All 73 practice pages, which is the point of the band: the navigation is a
   curated 41 and is discounted as boilerplate anyway, so this is where the
   rest of the site actually gets linked from. One row per branch rather than
   five equal columns, because the branches are 17, 25, 17, 6 and 8 and a
   five-column grid built on the longest one leaves three columns of air. */
/* Sticky rail on the left, the branches scrolling past it on the right. The
   same editorial device the ProDigital rebuild uses: the heading and the ask
   stay in view for the whole of a band that is 1,500px tall, so the call to
   action is never scrolled off while someone reads a directory. */
.ll-plist__layout {
  display: grid;
  grid-template-columns: minmax(0, 0.74fr) minmax(0, 1.26fr);
  gap: var(--wp--preset--spacing--70);
  align-items: start;
}
.ll-plist__layout > * { margin-block: 0 !important; }
.ll-plist__rail {
  position: sticky;
  /* Clear of the sticky header, whose height is measured, not guessed. */
  top: calc(var(--ll-header-h, 124px) + var(--wp--preset--spacing--40));
}
.ll-plist__rail > * { margin-block: 0 0 !important; }
.ll-plist__rail h2 { margin: .35rem 0 1rem !important; }
.ll-plist__rail p { margin: 0 0 var(--wp--preset--spacing--30) !important; }
/* Both buttons take the rail's width so the stack reads as one control
   group rather than two differently sized pills. */
.ll-plist__cta { margin-top: var(--wp--preset--spacing--30) !important; flex-direction: column; align-items: stretch; max-width: 17rem; }
.ll-plist__cta .wp-block-button { width: 100%; }
.ll-plist__cta .wp-block-button__link { display: block; width: 100%; text-align: center; font-size: .95rem; }

.ll-plist__branch {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: var(--wp--preset--spacing--40);
  padding: var(--wp--preset--spacing--40) 0;
  border-top: 1px solid var(--wp--preset--color--line);
}
.ll-plist__branch > * { margin-block: 0 !important; }
.ll-plist__branches > * { margin-block: 0 !important; }
.ll-plist__branches > :first-child { padding-top: 0; border-top: 0; }
.ll-plist__branches > :last-child { padding-bottom: 0; }
.ll-plist__h {
  margin: 0 !important;
  font-weight: 800;
  font-size: 1.0625rem;
  line-height: 1.3;
}
.ll-plist__h a { color: var(--wp--preset--color--ink); text-decoration: none; }
.ll-plist__h a:hover { color: var(--wp--preset--color--brand); text-decoration: underline; }
.ll-plist__count {
  display: block;
  margin-top: .3rem;
  font-size: .82rem;
  font-weight: 500;
  color: var(--wp--preset--color--ink-soft);
  font-variant-numeric: tabular-nums;
}
/* Multi-column flow rather than a grid: the columns balance themselves, so a
   branch of 6 and a branch of 25 both fill their row without a per-branch
   rule. break-inside keeps a link from splitting across a column boundary. */
.ll-plist__ul {
  list-style: none;
  margin: 0 !important;
  padding-left: 0 !important;
  columns: 2;
  column-gap: var(--wp--preset--spacing--40);
}
.ll-plist__ul li { margin: 0 0 .5rem; break-inside: avoid; }
.ll-plist__ul a {
  color: var(--wp--preset--color--ink-2);
  text-decoration: none;
  font-size: .92rem;
  line-height: 1.4;
}
.ll-plist__ul a:hover { color: var(--wp--preset--color--brand); text-decoration: underline; }

@media (max-width: 1100px) {
  .ll-plist__layout { gap: var(--wp--preset--spacing--50); }
  .ll-plist__branch { grid-template-columns: minmax(0, 9rem) minmax(0, 1fr); }
}
@media (max-width: 960px) {
  /* Below this the rail has nothing to stay beside: it stacks above the list
     and sticky is switched off, because a sticky block in a single column
     pins itself over the content it is introducing. */
  .ll-plist__layout { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--50); }
  .ll-plist__rail { position: static; }
  .ll-plist__branch { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--30); }
  .ll-plist__ul { columns: 2; }
}
@media (max-width: 520px) { .ll-plist__ul { columns: 1; } }

/* Homepage: resources band ------------------------------------------------
   Was "From the blog", which names the publishing mechanism rather than what
   is in it. Every post has a featured image and it was being thrown away. */
.ll-homeblog__grid,
.ll-postcards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--40);
  margin-top: var(--wp--preset--spacing--50);
  list-style: none;
  padding-left: 0 !important;
}
.ll-homeblog__grid > li,
.ll-postcards > li {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--wp--preset--color--white);
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 16px;
  overflow: hidden;
  margin: 0;
  transition: box-shadow .28s ease, transform .28s ease;
}
.ll-homeblog__grid > li::before,
.ll-postcards > li::before {
  content: "";
  position: absolute; inset: 0 0 auto 0; height: 3px; z-index: 2;
  background: var(--wp--preset--color--accent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .34s cubic-bezier(.22,.61,.36,1);
}
.ll-homeblog__grid > li:hover,
.ll-homeblog__grid > li:focus-within,
.ll-postcards > li:hover,
.ll-postcards > li:focus-within { box-shadow: 0 26px 50px -30px rgba(7, 22, 38, .55); transform: translateY(-4px); }
.ll-homeblog__grid > li:hover::before,
.ll-homeblog__grid > li:focus-within::before,
.ll-postcards > li:hover::before,
.ll-postcards > li:focus-within::before { transform: scaleX(1); }
.ll-homeblog__grid .wp-block-post-featured-image,
.ll-postcards .wp-block-post-featured-image { margin: 0; }
.ll-homeblog__grid .wp-block-post-featured-image img,
.ll-postcards .wp-block-post-featured-image img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: 0;
  transition: transform .4s ease;
}
.ll-homeblog__grid > li:hover .wp-block-post-featured-image img,
.ll-postcards > li:hover .wp-block-post-featured-image img { transform: scale(1.04); }
.ll-homeblog__body,
.ll-postcards__body { padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40) var(--wp--preset--spacing--40); }
.ll-homeblog__body > *,
.ll-postcards__body > * { margin-block: 0 !important; }
.ll-homeblog__grid h3 { margin: 0 0 .5rem !important; line-height: 1.3; }
.ll-homeblog__grid h3 a { color: var(--wp--preset--color--ink); text-decoration: none; }
.ll-homeblog__grid h3 a:hover { color: var(--wp--preset--color--brand); }
.ll-homeblog__grid .wp-block-post-excerpt { margin: 0; }
.ll-homeblog__grid .wp-block-post-excerpt__excerpt { margin: 0 0 .9rem; }
.ll-homeblog__grid .wp-block-post-excerpt__more-text { margin: auto 0 0; padding-top: var(--wp--preset--spacing--30); }
.ll-homeblog__grid .wp-block-post-excerpt__more-link {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
  text-decoration: none;
}
.ll-homeblog__grid .wp-block-post-excerpt__more-link::after {
  content: "\2192"; font-size: .95rem; letter-spacing: 0;
  transition: transform .28s cubic-bezier(.22,.61,.36,1);
}
.ll-homeblog__grid > li:hover .wp-block-post-excerpt__more-link::after { transform: translateX(5px); }
.ll-homeblog__body { display: flex; flex-direction: column; flex: 1; }
.ll-homeblog__grid .wp-block-post-excerpt { display: flex; flex-direction: column; flex: 1; }
.ll-homeblog__all { margin-top: var(--wp--preset--spacing--40); font-weight: 700; }
.ll-homeblog__all a { color: var(--wp--preset--color--brand); }
@media (max-width: 900px) { .ll-homeblog__grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .ll-homeblog__grid .wp-block-post-featured-image img { transition: none; }
  .ll-homeblog__grid > li:hover .wp-block-post-featured-image img { transform: none; }
}

/* Floating CTA bar (patterns/floating-cta.php + assets/js/floating-cta.js).
   Hidden until the script says otherwise, so no-JS never sees it. Centred on
   the same wide measure as the rest of the page rather than pinned to a
   corner, because a full-width bar at the bottom of a legal site reads as an
   ad. */
.ll-fcta {
  position: fixed;
  z-index: 60;
  left: 50%;
  bottom: 1.15rem;
  width: min(1100px, calc(100vw - 2rem));
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .7rem .7rem .7rem 1.4rem;
  border-radius: 16px;
  /* Navy, not ink, plus a hairline. The first version was ink at .97, which is
     the same colour as the "You need an attorney" band on the home page: the
     bar vanished into it and only its buttons were visible. It has to read as
     a separate object on a light section AND on a dark one, so it is lifted a
     step off ink and given an edge. */
  background: rgba(16, 53, 88, .98);
  border: 1px solid rgba(255, 255, 255, .16);
  color: var(--wp--preset--color--white);
  box-shadow: 0 22px 50px -12px rgba(3, 12, 22, .7), 0 2px 0 rgba(255, 255, 255, .05) inset;
  transform: translate(-50%, calc(100% + 2rem));
  opacity: 0;
  transition: transform .3s ease, opacity .3s ease;
}
.ll-fcta.is-on { transform: translate(-50%, 0); opacity: 1; }
.ll-fcta[hidden] { display: none; }
.ll-fcta p { margin: 0; }
.ll-fcta__text { font-size: .92rem; line-height: 1.35; }
.ll-fcta__text strong { display: block; color: var(--wp--preset--color--white); }
.ll-fcta__text span { color: #A9C2D8; }
.ll-fcta__actions { display: flex; align-items: center; gap: .6rem; }
.ll-fcta__call {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .7rem 1rem; border-radius: 10px;
  border: 1px solid rgba(255,255,255,.3);
  color: var(--wp--preset--color--white); font-weight: 700; text-decoration: none;
  white-space: nowrap;
}
.ll-fcta__call:hover { background: rgba(255,255,255,.1); }
.ll-fcta__btn {
  padding: .78rem 1.25rem; border-radius: 10px;
  background: var(--wp--preset--color--brand-pale);
  color: var(--wp--preset--color--ink);
  font-weight: 800; text-decoration: none; white-space: nowrap;
}
.ll-fcta__btn:hover { background: var(--wp--preset--color--white); }
.ll-fcta__x {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(255,255,255,.14); color: var(--wp--preset--color--white);
  cursor: pointer;
}
.ll-fcta__x:hover { background: rgba(255,255,255,.26); }
.ll-fcta__short { display: none; }

@media (max-width: 860px) {
  .ll-fcta { bottom: .7rem; padding: .55rem; gap: .5rem; }
  .ll-fcta__text { display: none; }
  .ll-fcta__actions { width: 100%; }
  .ll-fcta__call { flex: 0 0 auto; }
  .ll-fcta__btn { flex: 1; text-align: center; }
  .ll-fcta__long { display: none; }
  .ll-fcta__short { display: inline; }
}
@media (prefers-reduced-motion: reduce) { .ll-fcta { transition: none; } }

/* Footer ground.
   The flat ink panel read as cheap next to the rest of the page. This is a
   ramp through the navy family rather than a hue swing: ink deepened at the
   top left, through navy, finishing just short of brand blue at the bottom
   right, so it still reads as this firm's colour and not a gradient for its
   own sake. background-image layers over the block's own background-color,
   which is why the preset class does not need overriding. */
/* Transparent on purpose: the ground is painted by the template-part wrapper
   above, which also covers that wrapper's own padding. Painting it here left a
   band of flat ink wherever the wrapper's padding showed. */
.ll-footer {
  position: relative;
  background-color: transparent !important;
  background-image: none;
}


.ll-footer .ll-wordmark__pre  { color: #8FB0CC; }
.ll-footer .ll-wordmark__name { color: var(--wp--preset--color--white); }
.ll-footer-links { list-style: none; padding-left: 0 !important; }
.ll-footer-links li { margin: 0 0 .7rem; }
.ll-footer-links a {
  color: var(--wp--preset--color--line-2); text-decoration: none; font-size: .97rem;
}
.ll-footer-links a:hover { color: var(--wp--preset--color--white); text-decoration: underline; }
.ll-footer .ll-eyebrow { margin-bottom: 1.1rem; }

/* Button variants --------------------------------------------------------- */
.wp-block-button.is-style-outline > .wp-block-button__link {
  background: transparent; border: 2px solid currentColor;
}
.ll-ctaband .wp-block-button.is-style-outline > .wp-block-button__link { color: var(--wp--preset--color--white); }
.ll-ctaband .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--white); color: var(--wp--preset--color--brand);
}
.wp-block-button.is-style-invert > .wp-block-button__link {
  background: var(--wp--preset--color--white); color: var(--wp--preset--color--brand);
}
.wp-block-button.is-style-invert > .wp-block-button__link:hover {
  background: var(--wp--preset--color--brand-pale); color: var(--wp--preset--color--brand);
}
/* On the sand practice hero an outline button needs real contrast. */
.ll-phero .wp-block-button.is-style-outline > .wp-block-button__link {
  background: var(--wp--preset--color--white);
  border-color: var(--wp--preset--color--white);
  color: var(--wp--preset--color--ink);
}

/* --------------------------------------------------------------------------
   Corrections found against the first live render.
   -------------------------------------------------------------------------- */

/* A constrained-layout group clamps every direct child to contentSize. The
   hero's backdrop is a direct child, so it was being held to 760px instead of
   filling the section. It is decorative and absolutely positioned, so opt it
   out of the layout entirely. */
.ll-hero > .ll-hero__media {
  max-width: none !important;
  width: 100%;
  margin: 0 !important;
}

/* The header template part is not itself a constrained group, so "alignwide"
   has nothing to centre against. Give the header bar the container treatment
   directly, which lines the brand up with the footer and the page content. */
.ll-headbar {
  margin-inline: auto;
  padding-inline: var(--wp--preset--spacing--40);
  width: 100%;
  box-sizing: border-box;
}

/* The brand, nav and CTA are one row on desktop. Without this the group wraps
   as soon as the container gains padding, dropping the nav onto its own line. */
/* 1200, not 1024: at 1024 the brand, the six nav items and the CTA do not fit
   on one line, and forcing nowrap pushed the row 127px past the viewport.
   Below this the header wraps to two rows, which is fine. */
@media (min-width: 1024px) {
  .ll-headbar { flex-wrap: nowrap !important; gap: var(--wp--preset--spacing--40); }
  .ll-headbar > .wp-block-group { flex-wrap: nowrap !important; gap: var(--wp--preset--spacing--40); }
  .ll-nav { flex-wrap: nowrap !important; }
  .ll-nav .wp-block-navigation__container { flex-wrap: nowrap !important; gap: 1.2rem; }
  .ll-nav .wp-block-navigation-item__content { white-space: nowrap; }
  .ll-headcta .wp-block-button__link { white-space: nowrap; }
}

/* The mega panel must span the header, but core makes the nav, its responsive
   container, its dialog and the menu <ul> all position:relative, so the panel
   was anchoring to the 567px menu instead. Neutralise those on desktop only and
   the sticky header becomes the containing block. The mobile overlay keeps its
   positioning, which is what makes the slide-in work. */
@media (min-width: 1024px) {
  .ll-nav,
  .ll-nav .wp-block-navigation__responsive-container:not(.is-menu-open),
  .ll-nav .wp-block-navigation__responsive-dialog,
  .ll-nav ul.wp-block-navigation__container {
    position: static !important;
  }
}

/* Columns align to the top of the panel, and each column is a plain block. */
.ll-nav.wp-block-navigation li.ll-mega > ul.wp-block-navigation__submenu-container { align-items: start; }
.ll-nav.wp-block-navigation li.ll-mega > ul > li { display: block; }
.ll-nav.wp-block-navigation li.ll-mega ul ul > li { display: block; width: auto; }

/* Third-level links are flex items by default, which stops the text wrapping,
   so long labels ran across into the next column. Make them plain blocks. */
.ll-nav.wp-block-navigation li.ll-mega ul ul a.wp-block-navigation-item__content {
  display: block !important;
  white-space: normal !important;
  overflow-wrap: anywhere;
  line-height: 1.35;
}
.ll-nav.wp-block-navigation li.ll-mega ul ul > li { min-width: 0; }

/* --------------------------------------------------------------------------
   Homepage sections
   -------------------------------------------------------------------------- */

.ll-pgrid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--30);
  margin-top: var(--wp--preset--spacing--50);
}
@media (max-width: 1024px) { .ll-pgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px)  { .ll-pgrid { grid-template-columns: 1fr; } }

.ll-pcard {
  position: relative;
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--wp--preset--color--white);
  display: flex; flex-direction: column;
  transition: box-shadow .28s ease, transform .28s ease, border-color .28s ease;
}
/* The accent rule is drawn at full width and scaled from the left on hover,
   so nothing in the card reflows: a border that appears on hover shifts the
   whole card down by its own width. */
.ll-pcard::before {
  content: "";
  position: absolute; inset: 0 0 auto 0; height: 3px; z-index: 2;
  background: var(--wp--preset--color--accent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .34s cubic-bezier(.22,.61,.36,1);
}
.ll-pcard:hover, .ll-pcard:focus-within {
  box-shadow: 0 26px 50px -30px rgba(7, 22, 38, .55);
  transform: translateY(-4px);
  border-color: var(--wp--preset--color--line-2);
}
.ll-pcard:hover::before, .ll-pcard:focus-within::before { transform: scaleX(1); }
.ll-pcard .ll-pcard__media { margin: 0; overflow: hidden; }
.ll-pcard .ll-pcard__media img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 0;
  transition: transform .5s cubic-bezier(.22,.61,.36,1);
}
.ll-pcard:hover .ll-pcard__media img { transform: scale(1.05); }
.ll-pcard__body { flex: 1; display: flex; flex-direction: column; }
/* The card body is a constrained group, so core gives each child
   margin-inline:auto against the content size. A flex item with auto side
   margins does not stretch: it shrinks to its text and centres, which is why
   the card headings were centred over left-aligned copy. */
.ll-pcard__body > * { margin-inline: 0 !important; max-width: none !important; }
.ll-pcard h3 { margin: 0 0 .5rem; }
.ll-pcard h3 a { color: var(--wp--preset--color--ink); text-decoration: none; }
.ll-pcard:hover h3 a { color: var(--wp--preset--color--brand); }
.ll-pcard p { margin: 0; }
/* The whole card is the hit area. The heading keeps the real link so the
   accessible name and the tab order are unchanged; this only widens where a
   pointer may land. */
.ll-pcard h3 a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
/* Reads as a call to action rather than a heading that happens to be blue.
   margin-top:auto pins it to the bottom of the card so the cue line sits on
   one baseline across a row whose blurbs are different lengths. */
.ll-pcard__cue {
  display: inline-flex; align-items: center; gap: .45rem;
  margin: var(--wp--preset--spacing--30) 0 0 !important;
  margin-top: auto !important;
  padding-top: var(--wp--preset--spacing--30);
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
}
.ll-pcard__cue::after {
  content: "\2192";
  font-size: .95rem; letter-spacing: 0;
  transition: transform .28s cubic-bezier(.22,.61,.36,1);
}
.ll-pcard:hover .ll-pcard__cue::after { transform: translateX(5px); }

.ll-office iframe {
  width: 100%; height: 280px; display: block;
  border-radius: 14px; border: 1px solid var(--wp--preset--color--line);
  margin-bottom: var(--wp--preset--spacing--30);
}

.ll-reviews-slot {
  border: 2px dashed var(--wp--preset--color--sand-deep);
  border-radius: 14px;
  padding: var(--wp--preset--spacing--50);
  text-align: center;
  color: var(--wp--preset--color--ink-soft);
  margin-top: var(--wp--preset--spacing--40);
}

/* The mega panel hangs off the bottom of the header, but the list item stops at
   the end of the nav row, leaving the header's own bottom padding as a dead
   strip: the pointer left the item before it reached the panel, so the menu
   closed on the way down. Extend the item's hit area to the header edge and
   pull it back with a matching negative margin so nothing moves visually. */
@media (min-width: 1024px) {
  .ll-nav.wp-block-navigation li.ll-mega { padding-bottom: 18px; margin-bottom: -18px; }
}

/* Footer lockup: identical geometry to the header, reversed for the dark
   ground. It inherits the row layout from .ll-brand; an earlier rule here
   stacked it into a column, which is what made it look like a different mark. */
.ll-footer-brand { flex-direction: row; margin-bottom: 18px; }
.ll-footer-brand .ll-mono--footer { width: 60px; height: 60px; position: relative; flex: none; }
.ll-footer-brand .ll-mono--footer img { width: 100%; height: 100%; display: block; object-fit: contain; position: static; }

/* Belt and braces: a closed panel must never intercept the pointer. */
.ll-nav.wp-block-navigation li.ll-mega > ul.wp-block-navigation__submenu-container { pointer-events: none; }
.ll-nav.wp-block-navigation li.ll-mega:hover > ul.wp-block-navigation__submenu-container,
.ll-nav.wp-block-navigation li.ll-mega:focus-within > ul.wp-block-navigation__submenu-container { pointer-events: auto; }

/* The card grid is a block-layout group, so core still hands its children the
   flow margin, which pushed the first card out of line with the rest. */
.ll-pgrid > * { margin-block: 0 !important; }

/* Utility bar, rebuilt as a language-aware pattern ------------------------ */
.ll-utility__offices { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--30); align-items: center; }
.ll-utility__offices p { margin: 0; font-size: .82rem; }
/* Utility bar. Three siblings now: offices, review strip, language switch.
   On a narrow screen the offices take the first row and the strip and the
   language switch share the second; they could never share one before,
   because the strip lived inside the offices group and they had different
   parents, so they could never land on the same flex line. */
@media (max-width: 1023px) {
  .ll-utility { flex-wrap: wrap; row-gap: .35rem; padding-top: .45rem !important; padding-bottom: .45rem !important; font-size: .76rem; }
  .ll-utility__offices { flex: 1 1 100%; gap: 1rem; flex-wrap: nowrap; }
  .ll-utility__offices p { font-size: .76rem; white-space: nowrap; }
  .ll-utility .ll-ti--strip { transform: scale(.82); transform-origin: left center; margin-right: -3rem; }
  .ll-utility__lang { margin-left: auto; gap: .5rem; }
}
@media (max-width: 620px) {
  .ll-utility__label { letter-spacing: .05em; margin-right: .28rem; font-size: .6rem; }
  .ll-utility__offices p { font-size: .72rem; }
  .ll-utility .ll-ti--strip { transform: scale(.72); margin-right: -4.5rem; }
  .ll-utility__say { display: none; }
}
@media (max-width: 420px) {
  .ll-utility__offices { gap: .6rem; }
  .ll-utility__offices p { font-size: .67rem; }
  .ll-utility__label { font-size: .55rem; margin-right: .2rem; }
}
.ll-utility__lang { display: flex; align-items: center; gap: var(--wp--preset--spacing--30); }

/* Trustindex.
   The loader injects each widget at the position of its own script tag, so
   every placement is wrapped in one of these. The min-heights hold the space
   before the widget arrives, so a lazy-loaded widget does not shove the page
   down when it lands.

   Heights measured from the rendered widgets at 1440px on 2026-09-23:
   strip 44px, badge 123px, slider ~360px, review grid 1693px (EN) / 1534px
   (ES). Re-measure if a widget's layout is changed in the Trustindex
   dashboard, because these are layout-specific.

   The grid is the one compromise. Reserving its full height would leave a
   page-length hole on the rare load failure, and the real height moves with
   the review copy and differs per language, so it reserves 900px: most of the
   shift absorbed, bounded downside. */
.ll-ti { width: 100%; }
.ll-ti--strip { width: auto; min-height: 44px; display: flex; align-items: center; }
.ll-ti--badge { min-height: 123px; }
/* The footer copy runs narrow, so the badge is capped there; in the practice
   hero it fills its column instead. */
.ll-footer .ll-ti--badge { max-width: 240px; margin-top: var(--wp--preset--spacing--40); }
.ll-ti--global { min-height: 360px; }
/* The grid picks its column count by dividing the space it is given by
   data-review-target-width, which Trustindex sets to 300px for this layout.
   At the full 1240px wide size that lands on four columns; capping it at
   1100px lands on three, which is what the page is meant to show. Change the
   target width in the Trustindex dashboard rather than this number if the
   column count needs to move again. */
.ll-ti--testimonials { min-height: 900px; max-width: 1100px; margin-inline: auto; }

/* The strip sits on the dark utility bar, where the bar's own white bold link
   styling would otherwise bleed into the widget's chrome. */
.ll-utility .ll-ti a { color: inherit; font-weight: inherit; }
.ll-utility__say { font-size: .82rem; color: var(--wp--preset--color--line-2); }
a.ll-langswitch {
  display: inline-block; padding: .42rem .95rem; border-radius: 8px;
  background: var(--wp--preset--color--sand);
  color: var(--wp--preset--color--ink); font-weight: 700;
  font-size: .82rem; text-decoration: none;
}
a.ll-langswitch:hover { background: var(--wp--preset--color--sand-deep); text-decoration: none; }

/* Placeholder slot for the Gravity Forms embed, same treatment as the reviews
   slot so an unbuilt component is obvious rather than looking like a blank. */
.ll-form-slot {
  border: 2px dashed var(--wp--preset--color--sand-deep);
  border-radius: 14px;
  padding: var(--wp--preset--spacing--50);
  text-align: center;
  color: var(--wp--preset--color--ink-soft);
}

/* --------------------------------------------------------------------------
   Top-level spacing
   -------------------------------------------------------------------------- */

/* theme.json's blockGap applies between the top-level blocks too, which put a
   24px band of page background between the header and the first section. On a
   page whose first section is coloured that reads as a stray stripe under the
   header. Header, main and footer each own their vertical padding, so they do
   not need a gap between them. */
.wp-site-blocks > * { margin-block-start: 0; }

/* The generic page title band was padded 72px top against 48px bottom, so the
   title sat low in it and the whole band looked taller than it needed to be. */
.ll-pagehead { padding-top: var(--wp--preset--spacing--50) !important; }

/* --------------------------------------------------------------------------
   Interaction states
   --------------------------------------------------------------------------
   Core sets nav link colour with a doubled class:
     .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content
     { color: inherit }
   theme.json's own hover rules are wrapped in :root :where(...), which carries
   almost no specificity, so they never won and hovering a menu item did
   nothing at all. Matching that doubled class is what it takes.
   -------------------------------------------------------------------------- */

/* Hover and focus, white header */
.ll-nav.wp-block-navigation a.wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.ll-nav.wp-block-navigation a.wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible {
  color: var(--wp--preset--color--brand);
}

/* Hover and focus, navy header after scroll */
.ll-header--scrolled .ll-nav.wp-block-navigation a.wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.ll-header--scrolled .ll-nav.wp-block-navigation a.wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible {
  color: #9CC6EE;
}

/* Where you are. The underline carries the meaning, so it does not depend on
   colour alone. */
.ll-nav a[data-ll-state="ll-nav-current"],
.ll-nav a[data-ll-state="ll-nav-ancestor"] {
  color: var(--wp--preset--color--brand) !important;
  box-shadow: inset 0 -2px 0 0 currentColor;
}
.ll-header--scrolled .ll-nav a[data-ll-state="ll-nav-current"],
.ll-header--scrolled .ll-nav a[data-ll-state="ll-nav-ancestor"] {
  color: #9CC6EE !important;
}
/* Inside the mega panel the columns are already headings, so a current child
   just gets weight rather than a rule under it. */
.ll-nav.wp-block-navigation li.ll-mega ul a[data-ll-state] {
  box-shadow: none;
  font-weight: 700;
}

/* Keyboard focus, everywhere. */
a:focus-visible,
.wp-element-button:focus-visible,
.wp-block-button__link:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--wp--preset--color--brand-lift);
  outline-offset: 2px;
}

/* Buttons: every variant gets a visible hover, not just the filled default.
   The outline style previously only had one inside two specific sections. */
.wp-block-button__link,
.wp-element-button {
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  border-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
}
/* On the sand hero the outline button is already white-filled, so it darkens
   instead. */
.ll-phero .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  border-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
}
/* On the blue CTA band it inverts to white. */
.ll-ctaband .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--white);
  border-color: var(--wp--preset--color--white);
  color: var(--wp--preset--color--brand);
}
.ll-headcta .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
}

/* Body links: underline is already there, hover changes colour too. */
.wp-block-post-content a:hover,
.ll-footer-links a:hover,
.ll-crumbs a:hover {
  color: var(--wp--preset--color--brand-lift);
}

/* The language control is a button, so it behaves like one. */
a.ll-langswitch:focus-visible { outline-offset: 2px; }

/* At narrow widths the container is far taller than the photograph is, so cover
   crops horizontally and centring lands on the cabinet with him out of frame.
   Hold the focal point on him instead. */
@media (max-width: 781px) {
  .ll-hero .ll-hero__media img { object-position: 28% center; }
}

/* --------------------------------------------------------------------------
   Section rhythm and button states, second pass
   -------------------------------------------------------------------------- */

/* Full-bleed sections carry their own vertical padding, so the block gap
   between them shows as a 24px stripe of page background. It was visible
   between the firm section and the reviews section, and anywhere else two
   coloured sections meet. */
main > .alignfull,
.wp-block-post-content > .alignfull {
  margin-block-start: 0;
  margin-block-end: 0;
}

/* Buttons: every state changes both the fill and a contrasting ring, so a
   button can never hover into the colour of the surface behind it. The ring is
   a box-shadow rather than a border so nothing shifts by 2px on hover. */
.wp-block-button__link,
.wp-element-button {
  transition: background-color .18s ease, color .18s ease, box-shadow .18s ease;
}

/* Filled, on light ground */
.wp-block-button:not(.is-style-outline):not(.is-style-invert) > .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
  box-shadow: 0 0 0 2px var(--wp--preset--color--brand-lift);
}

/* White button. Hovering to a mid blue made it read as part of the blue band
   behind it, which is what looked like the button disappearing. */
.wp-block-button.is-style-invert > .wp-block-button__link:hover {
  background: var(--wp--preset--color--brand-pale);
  color: var(--wp--preset--color--ink);
  box-shadow: 0 0 0 2px var(--wp--preset--color--white);
}

/* Outline on a dark ground: fills white, keeps a white ring. */
.ll-ctaband .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.ll-hero .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.ll-footer .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--white);
  border-color: var(--wp--preset--color--white);
  color: var(--wp--preset--color--brand);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .45);
}

/* Outline on the sand hero: fills ink. */
.ll-phero .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  border-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
  box-shadow: 0 0 0 2px var(--wp--preset--color--sand-deep);
}

/* Header consultation button */
.ll-headcta .wp-block-button__link:hover {
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--white);
  box-shadow: 0 0 0 2px var(--wp--preset--color--brand-lift);
}

/* Footer: the tan headings read as a different system from the header, which
   uses a muted blue for the same job. Both now share that blue. */
.ll-footer .ll-eyebrow {
  color: #8FB0CC !important;
}
.ll-footer-links a { color: #C9D6E4; }
.ll-footer-links a:hover { color: var(--wp--preset--color--white); }

/* --------------------------------------------------------------------------
   Outline buttons on dark grounds
   --------------------------------------------------------------------------
   The generic outline hover fills with ink. On a section whose background IS
   ink that produced an invisible button: no border, no fill, just white text
   floating on navy. Key the treatment off the surface instead, using the
   background classes WordPress already puts on those sections, so an outline
   button can never fill with the colour behind it.
   -------------------------------------------------------------------------- */
.has-ink-background-color .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.has-navy-background-color .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.has-brand-background-color .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.ll-hero .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.ll-ctaband .wp-block-button.is-style-outline > .wp-block-button__link:hover,
.ll-footer .wp-block-button.is-style-outline > .wp-block-button__link:hover {
  background: var(--wp--preset--color--white) !important;
  border-color: var(--wp--preset--color--white) !important;
  color: var(--wp--preset--color--ink) !important;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .35) !important;
}

/* Same problem in reverse: an invert (white) button on a light section would
   hover to pale blue against near-white. Give it an ink ring there. */
.has-paper-background-color .wp-block-button.is-style-invert > .wp-block-button__link:hover,
.has-paper-2-background-color .wp-block-button.is-style-invert > .wp-block-button__link:hover,
.has-sand-background-color .wp-block-button.is-style-invert > .wp-block-button__link:hover,
.has-sand-2-background-color .wp-block-button.is-style-invert > .wp-block-button__link:hover {
  box-shadow: 0 0 0 2px var(--wp--preset--color--ink) !important;
}

/* --------------------------------------------------------------------------
   Footer, matched to the header
   --------------------------------------------------------------------------
   The footer was running on the warm half of the palette while the header runs
   on the cool half, so the two ends of the page read as different systems. The
   header uses #8FB0CC for secondary text and #9CC6EE for link hover once it
   goes navy. The footer now uses exactly those.
   -------------------------------------------------------------------------- */

.ll-footer .ll-footer-blurb { color: #C4D2E0; }

.ll-footer-links a { color: #C9D6E4; text-decoration: none; }
.ll-footer-links a:hover,
.ll-footer-links a:focus-visible {
  color: #9CC6EE;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Anything else in the footer that still points at the sand ramp. */
.ll-footer .has-line-2-color { color: #C4D2E0 !important; }
.ll-footer .has-sand-deep-color { color: #8FB0CC !important; }
.ll-footer a:not(.wp-block-button__link):hover { color: #9CC6EE; }

/* --------------------------------------------------------------------------
   Mega menu: closing the last of the dead strip
   --------------------------------------------------------------------------
   The panel hangs off the bottom of the header while the menu item ends at the
   bottom of the nav row. Measured on the live page, that left an 8px band where
   the pointer was over neither, so moving down into the menu dropped :hover and
   the panel closed. Intermittent, because a fast diagonal crosses it and a slow
   one does not.

   Rather than guess at padding, pull the panel's box upward so it overlaps the
   item, and push its contents back down by the same amount so nothing moves.
   The hover path is then continuous by construction.
   -------------------------------------------------------------------------- */
@media (min-width: 1024px) {
  .ll-nav.wp-block-navigation li.ll-mega > ul.wp-block-navigation__submenu-container {
    margin-top: -16px;
    padding-top: 50px; /* 34px of design padding plus the 16px pulled up */
  }
  /* And widen the item's own hit area so it meets the panel's new top edge. */
  .ll-nav.wp-block-navigation li.ll-mega { padding-bottom: 26px; margin-bottom: -26px; }
}

/* Legal links sit with the copyright rather than taking a slot in the main
   footer columns. Nobody navigates to them; they only need to be findable. */
.ll-footer-legal {
  margin: .4rem 0 0;
  font-size: .78rem;
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
}
.ll-footer-legal a { color: #8FA4B8; text-decoration: none; }
.ll-footer-legal a:hover { color: #9CC6EE; text-decoration: underline; text-underline-offset: 3px; }
.ll-footer-legal span { color: #47596C; }

/* --------------------------------------------------------------------------
   Footer bottom bar
   --------------------------------------------------------------------------
   Copyright and legal on the left, social on the right, one line. The social
   marks sit at the same visual weight as the copyright: present, findable, and
   not competing with the links above them.
   -------------------------------------------------------------------------- */
.ll-footer-bottom {
  max-width: var(--wp--style--global--wide-size);
  margin: var(--wp--preset--spacing--50) auto 0;
  padding-top: var(--wp--preset--spacing--30);
  border-top: 1px solid #1D3450;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 14px 28px;
}
.ll-footer-bottom__legal { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; }
.ll-footer-copy { margin: 0; font-size: .78rem; color: #6C8097; }
.ll-footer-bottom .ll-footer-legal { margin: 0; }

.ll-social {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: 6px;
  margin-left: auto;
}
.ll-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px;
  color: #7E93A8; text-decoration: none;
  transition: color .16s ease, background-color .16s ease;
}
.ll-social a:hover { color: #9CC6EE; background: rgba(156, 198, 238, .10); }
.ll-social a:focus-visible {
  outline: 2px solid var(--wp--preset--color--brand-lift); outline-offset: 2px;
}
.ll-social svg { display: block; }

@media (max-width: 600px) {
  .ll-footer-bottom { justify-content: flex-start; }
  .ll-social { margin-left: 0; }
}

/* --------------------------------------------------------------------------
   Offices card, pinned above the footer

   The offices sit in a rounded card lifted off the footer's own ink ground in
   navy, so they read as their own object instead of as a fourth band in a run
   of blues. The two offices are divided by a vertical hairline: Riverside and
   Murrieta are two places, and a single gap lets them read as one paragraph.
   -------------------------------------------------------------------------- */
/* The bottom of the page is one continuous ground, not two dark blocks that
   happen to sit next to each other. The ramp is split across the locations
   band and the footer and meets at the same colour, and it runs straight down
   rather than on an angle precisely so the seam matches at every width: with
   an angled gradient the colour along the join depends on how wide the
   viewport is, and the seam reappears. */
.ll-locband {
  background: linear-gradient(to bottom, #04101C 0%, #0A2138 100%);
  color: var(--wp--preset--color--white);
  padding-block: var(--wp--preset--spacing--60) 0;
}
.ll-locband__inner {
  max-width: var(--wp--style--global--wide-size);
  margin-inline: auto;
  padding-inline: var(--wp--preset--spacing--40);
}
.ll-loccard {
  background: var(--wp--preset--color--navy);
  border-radius: 18px;
  padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--50);
}
.ll-loccard__eyebrow {
  margin: 0 0 6px; font-size: .78rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: #9CC6EE;
}
.ll-loccard__h {
  margin: 0 0 var(--wp--preset--spacing--40);
  font-size: clamp(1.4rem, 2.1vw, 1.85rem); font-weight: 800;
  letter-spacing: -.02em; line-height: 1.12;
  color: var(--wp--preset--color--white); text-wrap: balance;
}

/* A vertical hairline, not a gap, so the two offices stay distinct. */
.ll-loccard__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.ll-loccard__cols > .ll-locoffice:first-child { padding-right: var(--wp--preset--spacing--50); }
.ll-loccard__cols > .ll-locoffice:last-child {
  padding-left: var(--wp--preset--spacing--50);
  border-left: 1px solid rgba(156, 198, 238, .22);
}

.ll-locoffice { display: grid; grid-template-columns: 150px 1fr; gap: var(--wp--preset--spacing--30); align-items: start; }
/* The empty bordered strip under every map was a class collision, not a layout
   bug. The contact and location pages have their own office component that
   also uses .ll-office, and its `.ll-office iframe` rule adds a 1.1rem bottom
   margin for a 280px map. That margin leaked into this card, which is why the
   bordered box measured 151.6px around a 132px iframe. This component is now
   .ll-locoffice so the two cannot reach each other. Grid and line-height:0 stay
   as belt and braces against stray line boxes. */
.ll-locoffice__map {
  display: grid;
  line-height: 0;
  border-radius: 10px; overflow: hidden;
  border: 1px solid rgba(156, 198, 238, .28); background: #0F2B47;
}
.ll-locoffice__map iframe { display: block; width: 100%; height: 132px; border: 0; }
.ll-locoffice__body h3 { margin: 0 0 6px; font-size: 1.1rem; font-weight: 800; letter-spacing: -.012em; }
.ll-locoffice__body h3 a { color: var(--wp--preset--color--white); text-decoration: none; }
.ll-locoffice__body h3 a:hover { color: #9CC6EE; }
.ll-locoffice address { font-style: normal; font-size: .92rem; line-height: 1.55; color: #C9D6E4; }
.ll-locoffice__tel { margin: 9px 0 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.ll-locoffice__tel a { color: #9CC6EE; text-decoration: none; }
.ll-locoffice__tel a:hover { text-decoration: underline; text-underline-offset: 3px; }
.ll-locoffice__fax { margin: 3px 0 0; font-size: .84rem; color: #8FA8C0; font-variant-numeric: tabular-nums; }
.ll-locoffice__links { margin: 11px 0 0; font-size: .86rem; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ll-locoffice__links a { color: var(--wp--preset--color--white); font-weight: 700; text-decoration: none; }
.ll-locoffice__links a:hover { color: #9CC6EE; text-decoration: underline; text-underline-offset: 3px; }
.ll-locoffice__sep { color: #46617C; }

.ll-loccard__foot {
  margin-top: var(--wp--preset--spacing--40);
  padding-top: var(--wp--preset--spacing--30);
  border-top: 1px solid rgba(156, 198, 238, .22);
  display: flex; flex-wrap: wrap; gap: 14px var(--wp--preset--spacing--40);
  align-items: center; justify-content: space-between;
}
.ll-loccard__foot p { margin: 0; font-size: 1rem; font-weight: 700; letter-spacing: -.008em; color: #E3ECF5; }
.ll-loccard__cta {
  display: inline-block; background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--brand); font-weight: 800; font-size: .9rem;
  padding: 11px 22px; border-radius: 6px; text-decoration: none;
  border: 2px solid var(--wp--preset--color--white); white-space: nowrap;
}
.ll-loccard__cta:hover {
  background: transparent; color: var(--wp--preset--color--white);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .28);
}

/* The footer's outer template-part wrapper is transparent; its ink comes from
   the group inside it. Padding on that wrapper therefore shows as a stripe of
   page background, which is what put a white band between the two. Give the
   wrapper the same ground instead, so the block stays continuous whatever the
   inner spacing does. */
/* The footer paints itself, on every page. This used to be set only in the
   `.ll-locband + footer` rule below, which meant that on the pages where the
   locations band is deliberately suppressed, the contact page and the two
   location pages, the footer had no ground at all: white text on the page's
   own paper. Those are exactly the pages nobody scrolls during a homepage
   review, which is how it survived.

   Linear only, in every case. A radial glow here was centred at 86% across
   and 12% down the footer, so it began at the footer's top edge and drew a
   hard line across the right-hand side of the seam while the left blended
   cleanly. Any gradient that is not purely vertical reintroduces the seam,
   because the two blocks are different heights. */
footer.wp-block-template-part {
  position: relative;
  background: linear-gradient(to bottom, #04101C 0%, #16457C 100%);
}
/* Where the locations band does run, it has already drawn the top of the ramp
   from #04101C to #0A2138, so the footer picks the ramp up from there and the
   two read as one ground rather than two dark blocks side by side. */
.ll-locband + footer.wp-block-template-part {
  background: linear-gradient(to bottom, #0A2138 0%, #16457C 100%);
  padding-top: 0;
}

@media (max-width: 1000px) {
  .ll-locoffice { grid-template-columns: 124px 1fr; gap: var(--wp--preset--spacing--20); }
  .ll-locoffice__map iframe { height: 118px; }
}
@media (max-width: 782px) {
  .ll-loccard { padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--40); }
  .ll-loccard__cols { grid-template-columns: 1fr; }
  .ll-loccard__cols > .ll-locoffice:first-child {
    padding-right: 0; padding-bottom: var(--wp--preset--spacing--40);
  }
  .ll-loccard__cols > .ll-locoffice:last-child {
    padding-left: 0; padding-top: var(--wp--preset--spacing--40);
    border-left: 0; border-top: 1px solid rgba(156, 198, 238, .22);
  }
  .ll-loccard__foot { justify-content: flex-start; }
}
@media (max-width: 480px) {
  .ll-locoffice { grid-template-columns: 1fr; }
  .ll-locoffice__map iframe { height: 150px; }
  .ll-loccard__cta { width: 100%; text-align: center; }
}

/* Call option under a form ------------------------------------------------ */
/* The second choice on the page, so it is a quieter shape than the submit
   button above it: outlined rather than filled, and preceded by a line that
   gives the reader permission to take it. */
.ll-formcall {
  margin-top: var(--wp--preset--spacing--40);
  padding-top: var(--wp--preset--spacing--40);
  border-top: 1px solid var(--wp--preset--color--line);
  text-align: center;
}
.ll-formcall__lead {
  margin: 0 0 12px;
  font-size: .95rem;
  color: var(--wp--preset--color--ink-soft);
}
.ll-formcall__btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  padding: 14px 20px;
  border: 2px solid var(--wp--preset--color--brand);
  border-radius: 8px;
  background: transparent;
  color: var(--wp--preset--color--brand);
  font-weight: 800; font-size: 1.02rem; letter-spacing: -.01em;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.ll-formcall__btn:hover,
.ll-formcall__btn:focus-visible {
  background: var(--wp--preset--color--brand);
  color: var(--wp--preset--color--white);
}
.ll-formcall__icon {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--wp--preset--color--brand-pale);
  color: var(--wp--preset--color--brand);
}
.ll-formcall__btn:hover .ll-formcall__icon,
.ll-formcall__btn:focus-visible .ll-formcall__icon {
  background: rgba(255, 255, 255, .18);
  color: var(--wp--preset--color--white);
}
.ll-formcall__note {
  margin: 10px 0 0;
  font-size: .82rem;
  color: var(--wp--preset--color--ink-soft);
}

/* Gravity Forms, wearing the theme's clothes ------------------------------ */
/* The colours are NOT set here, and cannot be. Gravity prints an inline style
   block per form, `#gform_wrapper_1[data-form-index="0"].gform-theme`, which
   is an ID plus an attribute plus a class. No rule in this stylesheet can
   out-specify that, and it is not in any CSS file, so grepping Gravity's own
   stylesheets for the declaration finds the wrong one.
   
   That block is generated from Gravity's global style defaults, so the colours
   are set through the `gform_default_styles` filter in functions.php, which is
   the mechanism that writes it. Only layout lives here. */
/* Gravity ships 40px between every field, which on a five field form is 200px
   of dead space and makes it read as five separate questions rather than one
   form. 22px keeps the fields grouped, while the 12px label gap still binds
   each label to its own input. Two classes, because Gravity declares these on
   a single one and ties go to whichever loaded last. */
.gform_wrapper.gform-theme--framework,
.gform_wrapper.gform-theme--api {
  --gf-form-gap-y: 22px;
}

/* rows="10" renders a 192px box, which invites an essay and pushes the submit
   button off a phone screen entirely. */
/* min-height is what pins the textarea, not height: rows="10" resolves to a
   192px minimum, so setting height alone does nothing. Both, or neither. */
.gform_wrapper.gform-theme--framework textarea,
.gform_wrapper.gform-theme--api textarea {
  min-height: 118px;
  height: 118px;
}

/* The band is brand blue, so the form inside it has to invert: pale labels,
   white fields, and a white submit against the blue rather than blue on blue. */
.ll-ctaband .gform_wrapper { max-width: none; margin-inline: 0; text-align: left; }
.ll-ctaband .gform_wrapper .gfield_label,
.ll-ctaband .gform_wrapper legend { color: #DCE9F6; font-size: .86rem; }
.ll-ctaband .gform_wrapper .gfield_required { color: #FFC9B8; }
.ll-ctaband .gform_wrapper.gform-theme--framework,
.ll-ctaband .gform_wrapper.gform-theme--api {
  --gf-form-gap-y: 16px;
}
.ll-ctaband .gform_wrapper.gform-theme--framework textarea {
  min-height: 92px; height: 92px;
}

/* The button is styled directly rather than through Gravity's colour
   variables. Inside the band those variables lose: the inline per-form block
   selected by an ID resets --gf-color-primary to brand blue, which on a brand
   blue band renders the submit button invisible. Declaring background and
   colour on the element itself sidesteps the variable entirely. */
/* !important, deliberately, and the only place in this stylesheet that uses
   it. Gravity routes every control through a chain of its own custom
   properties (--gf-ctrl-* into --gf-local-*) and paints from the local one, so
   a plain declaration loses no matter how specific it is or how late the
   stylesheet loads. Both were tried. On a brand blue band the default leaves a
   brand blue button on a brand blue ground, which is not a styling preference,
   it is an invisible submit button. */
.ll-ctaband .gform_wrapper .gform_button.button,
.ll-ctaband .gform_wrapper .gform-footer .gform_button {
  /* Brass, matching .ll-ctaband__btn on the pages that show buttons instead
     of this form. It was brand-pale with a white ring, chosen when the only
     alternative was white, which read as a fifth field above four white
     inputs. The accent solves that better and makes the two variants of this
     band end on the same colour. */
  background: var(--wp--preset--color--accent-lift) !important;
  border: 0 !important;
  box-shadow: none !important;
  color: var(--wp--preset--color--ink) !important;
  width: 100% !important;
  padding-block: 15px !important;
  border-radius: 8px !important;
  font-weight: 800;
  font-size: 1.04rem;
}
.ll-ctaband .gform_wrapper .gform_button.button:hover {
  background: var(--wp--preset--color--white) !important;
  color: var(--wp--preset--color--ink) !important;
}
.ll-ctaband .gform_wrapper .gform_button.button:focus-visible {
  outline: 3px solid var(--wp--preset--color--accent-lift);
  outline-offset: 3px;
}
.ll-ctaband .gform_confirmation_message {
  color: var(--wp--preset--color--white);
  font-size: 1.05rem; font-weight: 700; text-align: center;
  padding-block: var(--wp--preset--spacing--30);
}
.ll-ctaband__orcall { margin: 14px 0 0; text-align: center; font-size: .88rem; color: #CFE0F2; }
.ll-ctaband__orcall a { color: #fff; font-weight: 800; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.5); }
.ll-ctaband__orcall a:hover { border-bottom-color: #fff; }

.gform_button.button,
.gform-footer .gform_button {
  width: 100%;
  font-family: inherit;
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: -.01em;
  padding-block: 14px;
}
/* The footer is a flex row, which shrink-wraps the button to its text and
   leaves the primary action narrower than the call option beneath it. Block
   layout lets the button take the width it asks for. */
.gform-footer,
.gform_footer {
  margin-top: var(--wp--preset--spacing--30);
  display: block;
}

/* Exit intent prompt ------------------------------------------------------ */
/* The hidden attribute must win. An author rule setting `display` beats the
   user agent's `[hidden] { display: none }`, so declaring `display: grid` here
   left this element rendered on every page: invisible, but covering the whole
   viewport at z-index 9999 and swallowing every click and hover on the site.
   That is what killed the mega menu. */
.ll-exit[hidden] { display: none; }
.ll-exit {
  position: fixed; inset: 0; z-index: 9999;
  display: grid; place-items: center;
  padding: var(--wp--preset--spacing--30);
}
.ll-exit__scrim {
  position: absolute; inset: 0;
  background: rgba(10, 33, 56, .55);
  opacity: 0; transition: opacity .2s ease;
}
.ll-exit.is-open .ll-exit__scrim { opacity: 1; }
.ll-exit__panel {
  position: relative;
  width: min(430px, 100%);
  background: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--white);
  border-radius: 18px;
  padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--40) var(--wp--preset--spacing--40);
  text-align: center;
  box-shadow: 0 30px 70px -20px rgba(10, 33, 56, .6);
  opacity: 0; transform: translateY(10px) scale(.985);
  transition: opacity .2s ease, transform .2s ease;
}
.ll-exit.is-open .ll-exit__panel { opacity: 1; transform: none; }
.ll-exit__x {
  position: absolute; top: 12px; right: 12px;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  color: #C9D6E4; cursor: pointer;
}
.ll-exit__x:hover { background: rgba(255, 255, 255, .2); color: #fff; }
/* theme.json gives every h2 an explicit ink colour, which beats the white
   inherited from the panel, so the title has to say so itself. */
.ll-exit__title {
  margin: 0 0 10px;
  font-size: clamp(1.25rem, 2.4vw, 1.5rem); font-weight: 800;
  letter-spacing: -.02em; line-height: 1.15; text-wrap: balance;
  color: var(--wp--preset--color--white);
}
.ll-exit__body {
  margin: 0 0 var(--wp--preset--spacing--40);
  font-size: .95rem; line-height: 1.55; color: #C9D6E4;
}
.ll-exit__cta,
.ll-exit__call {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  /* Without this the padding and border are added to the 100%, and both
     buttons hang out over the edges of the panel. */
  box-sizing: border-box;
  width: 100%; padding: 13px 20px;
  border-radius: 8px; font-weight: 800; font-size: .98rem;
  text-decoration: none; letter-spacing: -.01em;
}
.ll-exit__cta {
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--brand);
  border: 2px solid var(--wp--preset--color--white);
}
.ll-exit__cta:hover { background: transparent; color: var(--wp--preset--color--white); }
.ll-exit__call {
  margin-top: 10px;
  background: transparent;
  color: var(--wp--preset--color--white);
  border: 2px solid rgba(255, 255, 255, .5);
  font-variant-numeric: tabular-nums;
}
.ll-exit__call:hover { border-color: #fff; background: rgba(255, 255, 255, .1); }

/* The page behind a modal should not scroll. */
.ll-exit-locked, .ll-exit-locked body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .ll-exit__scrim, .ll-exit__panel { transition: none; }
  .ll-exit__panel { transform: none; }
}

/* Consultation modal ------------------------------------------------------ */
/* Same guard as the exit prompt: an author rule setting display beats the
   user agent's [hidden] { display: none }, and without this the panel is a
   full screen click shield on every page. */
.ll-modal[hidden] { display: none; }
.ll-modal {
  position: fixed; inset: 0; z-index: 9998;
  display: grid; place-items: start center;
  padding: var(--wp--preset--spacing--30);
  overflow-y: auto;
}
.ll-modal__scrim {
  position: fixed; inset: 0;
  background: rgba(10, 33, 56, .6);
  opacity: 0; transition: opacity .2s ease;
}
.ll-modal.is-open .ll-modal__scrim { opacity: 1; }
.ll-modal__panel {
  position: relative;
  width: min(460px, 100%);
  /* Top aligned rather than centred, and scrollable, because a centred panel
     is exactly what the phone keyboard breaks: it takes half the screen and
     a centred box has nowhere to go. */
  margin-block: clamp(12px, 5vh, 56px);
  background: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--white);
  border-radius: 18px;
  padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--40) var(--wp--preset--spacing--40);
  box-shadow: 0 30px 70px -20px rgba(10, 33, 56, .65);
  opacity: 0; transform: translateY(10px) scale(.99);
  transition: opacity .2s ease, transform .2s ease;
}
.ll-modal.is-open .ll-modal__panel { opacity: 1; transform: none; }
.ll-modal__x {
  position: absolute; top: 12px; right: 12px;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  color: #C9D6E4; cursor: pointer;
}
.ll-modal__x:hover { background: rgba(255, 255, 255, .2); color: #fff; }
.ll-modal__title {
  margin: 0 0 8px;
  font-size: clamp(1.2rem, 2.4vw, 1.45rem); font-weight: 800;
  letter-spacing: -.02em; line-height: 1.15;
  color: var(--wp--preset--color--white);
}
.ll-modal__body {
  margin: 0 0 var(--wp--preset--spacing--30);
  font-size: .92rem; line-height: 1.5; color: #C9D6E4;
}
.ll-modal__call { margin: 14px 0 0; text-align: center; font-size: .88rem; }
.ll-modal__call a { color: #fff; font-weight: 700; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.45); }

/* The form inside the panel, on navy. */
.ll-modal .gform_wrapper .gfield_label { color: #DCE9F6; font-size: .84rem; }
.ll-modal .gform_wrapper .gfield_required { color: #FFC9B8; }
.ll-modal .gform_wrapper.gform-theme--framework,
.ll-modal .gform_wrapper.gform-theme--api { --gf-form-gap-y: 14px; }
.ll-modal .gform_wrapper.gform-theme--framework textarea { min-height: 84px; height: 84px; }
.ll-modal .gform_wrapper .gform_button.button {
  /* Same reason as the band: Gravity paints from its own local custom
     properties, so a plain declaration never lands. */
  background: var(--wp--preset--color--brand-pale) !important;
  border: 0 !important;
  box-shadow: 0 0 0 2px var(--wp--preset--color--white) !important;
  color: var(--wp--preset--color--ink) !important;
  width: 100% !important;
  padding-block: 14px !important;
  border-radius: 8px !important;
  font-weight: 800;
}
.ll-modal .gform_wrapper .gform_button.button:hover {
  background: var(--wp--preset--color--white) !important;
  color: var(--wp--preset--color--brand) !important;
}
.ll-modal .gform_confirmation_message {
  color: var(--wp--preset--color--white);
  font-size: 1.02rem; font-weight: 700; text-align: center;
  padding-block: var(--wp--preset--spacing--30);
}
.ll-modal.is-done .ll-modal__body,
.ll-modal.is-done .ll-modal__call { display: none; }

.ll-modal-locked, .ll-modal-locked body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .ll-modal__scrim, .ll-modal__panel { transition: none; }
  .ll-modal__panel { transform: none; }
}


/* --------------------------------------------------------------------------
   Accent headline
   A second colour on the words that carry the meaning, so a heading reads as
   a sentence with emphasis rather than one block of ink. Applied with a span
   inside the heading, which core keeps because it is inline formatting.
   -------------------------------------------------------------------------- */
.ll-accent { color: var(--wp--preset--color--accent); }
.has-ink-background-color .ll-accent,
.has-navy-background-color .ll-accent,
.ll-hero .ll-accent,
.ll-ctaband .ll-accent,
.ll-first .ll-accent,
.ll-footer .ll-accent { color: var(--wp--preset--color--accent-lift); }

/* --------------------------------------------------------------------------
   Rating chip
   One component, two shells. The figures come from lugolaw_rating_chip(), so
   the header and the hero cannot drift apart. Drawn rather than embedded:
   Trustindex ships a loader script and a white pill, and a white pill on the
   ink utility strip is what made that strip look cluttered.
   -------------------------------------------------------------------------- */
.ll-ratechip {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  white-space: nowrap;
  line-height: 1.3;
}
.ll-ratechip__stars { display: inline-flex; color: var(--wp--preset--color--accent-lift); }
.ll-ratechip__stars svg { display: block; }
.ll-ratechip__txt strong { font-weight: 800; font-variant-numeric: tabular-nums; }

/* On the ink utility strip: bare, no pill, sized to sit on one line with the
   two office numbers and the language switch. */
.ll-ratechip--strip { font-size: .82rem; gap: .45rem; color: var(--wp--preset--color--white); }
.ll-ratechip--strip .ll-ratechip__txt { color: rgba(255, 255, 255, .88); }

/* On the hero: an outlined pill, so the photograph still reads behind it. */
.ll-ratechip--hero {
  padding: .52rem 1.05rem;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 999px;
  background: rgba(10, 33, 56, .35);
  color: var(--wp--preset--color--white);
  font-size: .9rem;
  gap: .6rem;
}

.ll-herochip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .7rem;
  margin-top: var(--wp--preset--spacing--40);
}
/* The language chip is the one thing on this hero that a Spanish speaker
   scanning an English page is looking for, so it takes the accent rather than
   the same white hairline as the rating. */
.ll-herochip__lang {
  display: inline-flex;
  align-items: center;
  padding: .52rem 1.05rem;
  border: 1px solid rgba(224, 179, 95, .55);
  border-radius: 999px;
  color: var(--wp--preset--color--accent-lift);
  font-size: .9rem;
  font-weight: 700;
  line-height: 1.3;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}
.ll-herochip__lang:hover,
.ll-herochip__lang:focus-visible {
  background: var(--wp--preset--color--accent-lift);
  border-color: var(--wp--preset--color--accent-lift);
  color: var(--wp--preset--color--ink);
}
@media (prefers-reduced-motion: reduce) { .ll-herochip__lang { transition: none; } }
@media (max-width: 620px) {
  /* The stars go, not the figures. On a phone the strip is already three
     things deep and the drawn stars are the widest, least informative part of
     the chip: "4.5" says the same in a fifth of the width. The rating is still
     announced in full through the wrapper's aria-label. */
  .ll-ratechip--strip .ll-ratechip__stars { display: none; }
  .ll-ratechip--strip .ll-ratechip__txt { font-size: .78rem; }
}
@media (max-width: 480px) {
  .ll-ratechip--hero,
  .ll-herochip__lang { font-size: .84rem; padding: .45rem .85rem; }
}

/* --------------------------------------------------------------------------
   Motion
   Every transition above is decoration. Someone who has asked the system for
   reduced motion gets the same colour changes with nothing moving.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ll-pcard,
  .ll-pcard::before,
  .ll-pcard .ll-pcard__media img,
  .ll-pcard__cue::after,
  .ll-homeblog__grid > li,
  .ll-homeblog__grid > li::before,
  .ll-homeblog__grid .wp-block-post-excerpt__more-link::after {
    transition: none !important;
  }
  .ll-pcard:hover { transform: none; }
  .ll-pcard:hover .ll-pcard__media img { transform: none; }
  .ll-pcard:hover .ll-pcard__cue::after { transform: none; }
  .ll-homeblog__grid > li:hover { transform: none; }
  .ll-homeblog__grid > li:hover .wp-block-post-excerpt__more-link::after { transform: none; }
}

/* --------------------------------------------------------------------------
   The first call (patterns/first-call.php)
   Two cards, and the phone mark opens the section instead of dividing them.
   As a dial centred on a full-height hairline between two panels it is the
   signature of the site this was drawn from; at the head of the section it
   says the same thing without borrowing that composition. Everything else is
   pulled left rather than centred, which is how the rest of this page reads.
   -------------------------------------------------------------------------- */
.ll-first__inner { max-width: var(--wp--style--global--wide-size); margin-inline: auto; }

.ll-first__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--wp--preset--spacing--30);
  align-items: center;
}
.ll-first__dial {
  display: grid; place-items: center;
  width: 66px; height: 66px;
  border-radius: 50%;
  background: var(--wp--preset--color--accent);
  color: var(--wp--preset--color--white);
  box-shadow: 0 0 0 8px rgba(140, 94, 16, .12), 0 16px 28px -16px rgba(140, 94, 16, .85);
}
.ll-first__eyebrow {
  margin: 0 0 .3rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
}
.ll-first__h2 {
  margin: 0;
  font-size: clamp(1.9rem, 1.2rem + 2.1vw, 3rem);
  line-height: 1.08;
  letter-spacing: -.02em;
  font-weight: 800;
  color: var(--wp--preset--color--ink);
  text-wrap: balance;
  max-width: 24ch;
}
.ll-first__lede {
  margin: var(--wp--preset--spacing--30) 0 var(--wp--preset--spacing--60);
  max-width: 62ch;
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--wp--preset--color--ink-soft);
}

.ll-first__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--wp--preset--spacing--40);
  align-items: stretch;
}
.ll-first__panel { border-radius: 20px; padding: var(--wp--preset--spacing--50); }
.ll-first__panel ul { list-style: none; margin: 0; padding: 0; }
.ll-first__panel li {
  display: grid;
  grid-template-columns: 1.4rem minmax(0, 1fr);
  gap: .75rem;
  align-items: start;
  margin: 0;
  padding: .72rem 0;
  font-size: .98rem;
  line-height: 1.45;
}
.ll-first__mk { display: block; padding-top: .14rem; }
.ll-first__mk svg { display: block; }
.ll-first__ph {
  display: flex; align-items: center; gap: .8rem;
  margin: 0 0 .6rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
}
.ll-first__ph::after { content: ""; flex: 1; height: 1px; background: currentColor; opacity: .3; }

.ll-first__panel--before {
  background: var(--wp--preset--color--paper);
  border: 1px solid var(--wp--preset--color--line);
  color: var(--wp--preset--color--ink-soft);
}
.ll-first__panel--before .ll-first__ph { color: var(--wp--preset--color--ink-soft); }
.ll-first__panel--before .ll-first__mk { color: var(--wp--preset--color--ink-soft); opacity: .7; }

.ll-first__panel--after {
  background: linear-gradient(165deg, #0A2138 0%, #16457C 118%);
  color: var(--wp--preset--color--white);
  box-shadow: 0 30px 56px -36px rgba(7, 22, 38, .7);
}
.ll-first__panel--after .ll-first__ph { color: var(--wp--preset--color--accent-lift); }
.ll-first__panel--after .ll-first__mk { color: var(--wp--preset--color--accent-lift); }
.ll-first__panel--after li { font-weight: 600; }

.ll-first__cta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--wp--preset--spacing--30);
  margin-top: var(--wp--preset--spacing--50);
}
.ll-first__btn {
  display: inline-block;
  padding: .85rem 1.6rem;
  border-radius: 10px;
  background: var(--wp--preset--color--brand);
  color: var(--wp--preset--color--white);
  font-weight: 700;
  text-decoration: none;
  transition: background .2s ease, transform .2s ease;
}
.ll-first__btn:hover { background: var(--wp--preset--color--ink); color: var(--wp--preset--color--white); transform: translateY(-2px); }
.ll-first__tel {
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--wp--preset--color--accent);
  padding-bottom: 2px;
}
.ll-first__tel:hover { color: var(--wp--preset--color--accent); }

@media (max-width: 1100px) {
  .ll-first__panel { padding: var(--wp--preset--spacing--40); }
}
@media (max-width: 860px) {
  /* The cards stack. Each keeps its own heading, so "before" and "after" are
     still named where the reader is: nothing depends on the two being side by
     side to be understood. */
  .ll-first__grid { grid-template-columns: 1fr; }
  .ll-first__dial { width: 54px; height: 54px; }
  .ll-first__dial svg { width: 22px; height: 22px; }
  .ll-first__h2 { max-width: none; }
}
@media (max-width: 520px) {
  .ll-first__head { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--20); }
}
@media (prefers-reduced-motion: reduce) {
  .ll-first__btn { transition: none; }
  .ll-first__btn:hover { transform: none; }
}



/* --------------------------------------------------------------------------
   Consultation CTA band (patterns/cta-band.php)
   Was a flat slab of brand blue with everything stacked down the middle. A
   centred headline over two buttons on one solid colour is the shape of every
   law firm footer since about 2014, and it also wasted the band: the phone
   number was a button the same size as everything else, when on a page like
   this it is the thing most people act on.

   Now it is asymmetric. The argument sits left and the actions sit right in
   their own panel, which is also where the Gravity form goes on a practice
   page, so both variants have the same silhouette.
   -------------------------------------------------------------------------- */
.ll-ctaband {
  background: linear-gradient(118deg, #0A2138 0%, #15406F 58%, #1A5091 100%);
  color: var(--wp--preset--color--white);
  position: relative;
  overflow: hidden;
}
/* One soft light off the top right, so the field has somewhere to come from
   instead of reading as a printed rectangle. Clipped by the band's own
   overflow, which is why it cannot draw the hard edge the footer glow did. */
.ll-ctaband::before {
  content: "";
  position: absolute;
  top: -40%; right: -10%;
  width: 60%; aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(224, 179, 95, .16) 0%, rgba(224, 179, 95, 0) 62%);
  pointer-events: none;
}
.ll-ctaband__inner {
  position: relative;
  max-width: var(--wp--style--global--wide-size);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: var(--wp--preset--spacing--70);
  align-items: center;
}
.ll-ctaband__eyebrow {
  margin: 0 0 .5rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--wp--preset--color--accent-lift);
}
.ll-ctaband__h2 {
  margin: 0;
  font-size: clamp(2rem, 1.2rem + 2.3vw, 3.2rem);
  line-height: 1.06;
  letter-spacing: -.02em;
  font-weight: 800;
  color: var(--wp--preset--color--white);
  text-wrap: balance;
}
.ll-ctaband__sub {
  margin: var(--wp--preset--spacing--30) 0 0;
  max-width: 44ch;
  font-size: 1.125rem;
  line-height: 1.55;
  color: var(--wp--preset--color--brand-pale);
}

/* The action panel. Translucent rather than a second solid colour, so it
   lifts off the gradient without introducing a third blue. */
.ll-ctaband__act {
  padding: var(--wp--preset--spacing--50);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 20px;
  background: rgba(4, 16, 28, .34);
  backdrop-filter: saturate(140%) blur(3px);
  text-align: center;
}
.ll-ctaband__btn {
  display: block;
  padding: .95rem 1.6rem;
  border-radius: 10px;
  background: var(--wp--preset--color--accent-lift);
  color: var(--wp--preset--color--ink);
  font-weight: 800;
  font-size: 1.04rem;
  text-decoration: none;
  transition: background .2s ease, transform .2s ease;
}
.ll-ctaband__btn:hover,
.ll-ctaband__btn:focus-visible {
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--ink);
  transform: translateY(-2px);
}
/* A rule with the word set into it, rather than a line of text above a line of
   rule. Two pseudo-elements so the word stays centred whatever its length, in
   either language. */
.ll-ctaband__or {
  display: flex; align-items: center; gap: .9rem;
  margin: var(--wp--preset--spacing--30) 0 var(--wp--preset--spacing--20);
  font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(220, 233, 246, .62);
}
.ll-ctaband__or::before,
.ll-ctaband__or::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, .18); }
/* The phone number is set as a number, not as a button. It is the action most
   people on this page take and it should not be the same size as a label. */
.ll-ctaband__tel {
  display: inline-block;
  font-size: clamp(1.5rem, 1.1rem + 1.1vw, 1.95rem);
  font-weight: 800;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  color: var(--wp--preset--color--white);
  text-decoration: none;
  border-bottom: 2px solid rgba(224, 179, 95, .55);
  padding-bottom: 3px;
  transition: color .2s ease, border-color .2s ease;
}
.ll-ctaband__tel:hover,
.ll-ctaband__tel:focus-visible {
  color: var(--wp--preset--color--accent-lift);
  border-bottom-color: var(--wp--preset--color--accent-lift);
}
.ll-ctaband__hours {
  margin: .6rem 0 0;
  font-size: .85rem;
  color: rgba(220, 233, 246, .6);
}

@media (max-width: 1024px) {
  .ll-ctaband__inner { gap: var(--wp--preset--spacing--50); }
  .ll-ctaband__act { padding: var(--wp--preset--spacing--40); }
}
@media (max-width: 860px) {
  .ll-ctaband__inner { grid-template-columns: 1fr; }
  .ll-ctaband__sub { max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ll-ctaband__btn, .ll-ctaband__tel { transition: none; }
  .ll-ctaband__btn:hover { transform: none; }
}


/* --------------------------------------------------------------------------
   Blog archive (templates/index.html, templates/es-blog.html)
   The cards are the homepage component, extended into the rules above rather
   than copied, so the two cannot drift. What is left here is what differs on
   an archive: the column count, the heading level, and a standfirst set to a
   reading measure while the grid below it runs full width.
   -------------------------------------------------------------------------- */
.ll-postcards {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: var(--wp--preset--spacing--60);
}
.ll-postcards__body { display: flex; flex-direction: column; flex: 1; }
.ll-postcards h2 { margin: 0 0 .5rem !important; line-height: 1.25; }
.ll-postcards h2 a { color: var(--wp--preset--color--ink); text-decoration: none; }
.ll-postcards h2 a:hover { color: var(--wp--preset--color--brand); }
.ll-postcards .wp-block-post-excerpt { display: flex; flex-direction: column; flex: 1; margin: 0; }
.ll-postcards .wp-block-post-excerpt__excerpt { margin: 0 0 .9rem; }
.ll-postcards .wp-block-post-excerpt__more-text { margin: auto 0 0; padding-top: var(--wp--preset--spacing--30); }
.ll-postcards .wp-block-post-excerpt__more-link {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
  text-decoration: none;
}
.ll-postcards .wp-block-post-excerpt__more-link::after {
  content: "\2192"; font-size: .95rem; letter-spacing: 0;
  transition: transform .28s cubic-bezier(.22,.61,.36,1);
}
.ll-postcards > li:hover .wp-block-post-excerpt__more-link::after { transform: translateX(5px); }
/* The wrapper keeps the wide track so the standfirst starts on the same left
   edge as the H1 and the cards; the measure is capped on the paragraphs. */
.ll-bloglede > p { max-width: 68ch; }
.ll-bloglede > p + p { margin-top: var(--wp--preset--spacing--20); }
@media (max-width: 1000px) { .ll-postcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 680px)  { .ll-postcards { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .ll-postcards > li,
  .ll-postcards > li::before,
  .ll-postcards .wp-block-post-featured-image img,
  .ll-postcards .wp-block-post-excerpt__more-link::after { transition: none !important; }
  .ll-postcards > li:hover { transform: none; }
  .ll-postcards > li:hover .wp-block-post-featured-image img { transform: none; }
  .ll-postcards > li:hover .wp-block-post-excerpt__more-link::after { transform: none; }
}

/* --------------------------------------------------------------------------
   Offices page (patterns/offices-page.php)
   The locations band is suppressed on this page, which is the whole point of
   it: here the two offices get drawn at full size with their own maps rather
   than squeezed into a strip above the footer.
   -------------------------------------------------------------------------- */
/* The page template puts post-content in a constrained group, which caps every
   child at the 760px content size. The office cards and the courts list want
   the wide measure, so the wrapper takes it back. */
.ll-offpage {
  max-width: var(--wp--style--global--wide-size) !important;
  width: 100%;
  margin-inline: auto !important;
}
.ll-offpage__eyebrow {
  margin: 0 0 .7rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
}
.ll-offpage__lede {
  margin: 0 0 .9rem;
  max-width: 62ch;
  font-size: 1.25rem;
  line-height: 1.55;
  color: var(--wp--preset--color--ink);
}
.ll-offpage__sub {
  margin: 0;
  font-size: 1rem;
  color: var(--wp--preset--color--ink-soft);
}
.ll-offpage__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--40);
  margin-top: var(--wp--preset--spacing--60);
}
.ll-offcard {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 18px;
  overflow: hidden;
  background: var(--wp--preset--color--white);
  transition: box-shadow .28s ease, transform .28s ease;
}
.ll-offcard:hover, .ll-offcard:focus-within {
  box-shadow: 0 26px 50px -30px rgba(7, 22, 38, .5);
  transform: translateY(-3px);
}
.ll-offcard__map iframe {
  display: block; width: 100%; height: 230px; border: 0;
  /* The embed draws on a pale ground that is brighter than the card, so it is
     held back a shade at rest and comes up to full on hover. */
  filter: saturate(.78) contrast(.96);
  transition: filter .35s ease;
}
.ll-offcard:hover .ll-offcard__map iframe { filter: none; }
.ll-offcard__body { padding: var(--wp--preset--spacing--40); }
.ll-offcard__h {
  margin: 0 0 .5rem;
  font-size: 1.6rem; font-weight: 800; letter-spacing: -.01em;
  color: var(--wp--preset--color--ink);
}
.ll-offcard__addr { margin: 0 0 .9rem; color: var(--wp--preset--color--ink-2); line-height: 1.5; }
/* The number is the action on this page, so it is set as a number rather than
   dropped into the address block at body size. */
.ll-offcard__tel {
  display: inline-block;
  font-size: 1.6rem; font-weight: 800; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  color: var(--wp--preset--color--brand);
  text-decoration: none;
  border-bottom: 2px solid var(--wp--preset--color--accent);
  padding-bottom: 2px;
  transition: color .2s ease, border-color .2s ease;
}
.ll-offcard__tel:hover { color: var(--wp--preset--color--accent); }
.ll-offcard__meta {
  display: flex; flex-wrap: wrap; gap: .2rem 1.1rem;
  margin: .9rem 0 0;
  font-size: .85rem;
  color: var(--wp--preset--color--ink-soft);
}
.ll-offcard__links {
  display: flex; flex-wrap: wrap; gap: .4rem 1.4rem;
  margin: var(--wp--preset--spacing--30) 0 0;
  padding-top: var(--wp--preset--spacing--30);
  border-top: 1px solid var(--wp--preset--color--line-2);
}
.ll-offcard__links a {
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
  text-decoration: none;
}
.ll-offcard__links a:hover { text-decoration: underline; text-underline-offset: 4px; }

.ll-offcourts {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--wp--preset--spacing--50);
  margin-top: var(--wp--preset--spacing--70);
  padding-top: var(--wp--preset--spacing--50);
  border-top: 1px solid var(--wp--preset--color--line);
}
.ll-offcourts__h { margin: 0 0 .7rem; font-size: 1.5rem; font-weight: 800; letter-spacing: -.01em; }
.ll-offcourts__say p { margin: 0 0 .8rem; color: var(--wp--preset--color--ink-soft); line-height: 1.6; }
.ll-offcourts__more a {
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent); text-decoration: none;
}
.ll-offcourts__more a:hover { text-decoration: underline; text-underline-offset: 4px; }
.ll-offcourts__list { list-style: none; margin: 0; padding: 0; }
.ll-offcourts__list li {
  display: flex; flex-direction: column; gap: .15rem;
  margin: 0;
  padding: .85rem 0;
  border-bottom: 1px solid var(--wp--preset--color--line-2);
}
.ll-offcourts__list li:first-child { padding-top: 0; }
.ll-offcourts__list strong { font-weight: 700; color: var(--wp--preset--color--ink); }
.ll-offcourts__list span { font-size: .88rem; color: var(--wp--preset--color--ink-soft); }

@media (max-width: 860px) {
  .ll-offpage__grid,
  .ll-offcourts { grid-template-columns: 1fr; }
  .ll-offcourts { gap: var(--wp--preset--spacing--40); }
}
@media (prefers-reduced-motion: reduce) {
  .ll-offcard, .ll-offcard__map iframe { transition: none; }
  .ll-offcard:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   Attorney page (patterns/attorney-page.php)
   A portrait that stays beside the text while it is read, rather than a
   headshot dropped at the top and scrolled past in the first second.
   -------------------------------------------------------------------------- */
.ll-attn {
  max-width: var(--wp--style--global--wide-size) !important;
  width: 100%;
  margin-inline: auto !important;
}
.ll-attn__split {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: var(--wp--preset--spacing--60);
  align-items: start;
  /* The credentials band follows immediately and draws a hairline across the
     top of itself. The portrait is the tallest thing in this block, so with no
     padding here its bottom edge lands exactly on that rule: measured 0px at
     1440. The band's own padding sits inside the rule and does not help. */
  padding-bottom: var(--wp--preset--spacing--60);
}
.ll-attn__media { position: sticky; top: calc(var(--ll-header-h, 156px) + var(--wp--preset--spacing--40)); }
.ll-attn__media img {
  display: block;
  width: 100%;
  /* height:auto is required, not cosmetic. wp_get_attachment_image() emits
     width and height attributes, and with both dimensions definite the
     browser ignores aspect-ratio entirely: the portrait rendered at its full
     1024px height in a 275px column. The homepage portrait does not have this
     problem because it comes from a core image block, which ships its own
     height:auto. */
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 14%;
  border-radius: 18px;
}
.ll-attn__eyebrow {
  margin: 0 0 .4rem;
  font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--wp--preset--color--accent);
}
.ll-attn__role {
  margin: 0 0 var(--wp--preset--spacing--30);
  font-size: 1.05rem; font-weight: 700;
  color: var(--wp--preset--color--ink-2);
}
.ll-attn__standf {
  margin: 0 0 var(--wp--preset--spacing--30);
  font-size: 1.3rem; line-height: 1.5;
  color: var(--wp--preset--color--ink);
  text-wrap: pretty;
}
.ll-attn__bio {
  margin: 0 0 var(--wp--preset--spacing--30);
  line-height: 1.7;
  color: var(--wp--preset--color--ink-soft);
}
.ll-attn__cta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--wp--preset--spacing--30);
  margin: var(--wp--preset--spacing--40) 0 0;
}
.ll-attn__btn {
  display: inline-block;
  padding: .85rem 1.6rem;
  border-radius: 10px;
  background: var(--wp--preset--color--brand);
  color: var(--wp--preset--color--white);
  font-weight: 700;
  text-decoration: none;
  transition: background .2s ease, transform .2s ease;
}
.ll-attn__btn:hover { background: var(--wp--preset--color--ink); color: var(--wp--preset--color--white); transform: translateY(-2px); }
.ll-attn__tel {
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--wp--preset--color--accent);
  padding-bottom: 2px;
}
.ll-attn__tel:hover { color: var(--wp--preset--color--accent); }

.ll-attn__work {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--wp--preset--spacing--50);
  padding-top: var(--wp--preset--spacing--60);
}
.ll-attn__workh h2 { margin: 0 0 .7rem; font-size: 1.5rem; font-weight: 800; letter-spacing: -.01em; }
.ll-attn__workh p { margin: 0 0 .8rem; color: var(--wp--preset--color--ink-soft); line-height: 1.6; }
.ll-attn__firm { margin: var(--wp--preset--spacing--30) 0 0; }
.ll-attn__firm a {
  font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--wp--preset--color--accent); text-decoration: none;
}
.ll-attn__firm a:hover { text-decoration: underline; text-underline-offset: 4px; }
.ll-attn__areas {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--20);
}
.ll-attn__areas li { margin: 0; }
.ll-attn__areas a {
  display: block;
  padding: 1rem 1.1rem;
  border: 1px solid var(--wp--preset--color--line);
  border-radius: 12px;
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--ink);
  font-weight: 700;
  text-decoration: none;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.ll-attn__areas a:hover {
  border-color: var(--wp--preset--color--accent);
  transform: translateY(-2px);
  box-shadow: 0 18px 34px -24px rgba(7, 22, 38, .5);
}

@media (max-width: 900px) {
  .ll-attn__split { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--40); }
  /* Sticky in a single column pins the portrait over the text it belongs to. */
  .ll-attn__media { position: static; max-width: 340px; }
  .ll-attn__media img { aspect-ratio: 1 / 1; }
  .ll-attn__work { grid-template-columns: 1fr; }
}
@media (max-width: 520px) { .ll-attn__areas { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .ll-attn__btn, .ll-attn__areas a { transition: none; }
  .ll-attn__btn:hover, .ll-attn__areas a:hover { transform: none; }
}
