/* ==========================================================================
   Liberty Law — design tokens and shared primitives.
   Loaded once; every widget stylesheet depends on this, so sections stay
   consistent however they are combined on a page.
   ========================================================================== */

/* Self-hosted, latin subset, only the four weights the design uses. Avoids a
   render-blocking third-party stylesheet and the layout shift that came with
   loading it asynchronously. */
@font-face{font-family:'Alexandria';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/alexandria-400.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Alexandria';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/alexandria-500.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Alexandria';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/alexandria-600.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Alexandria';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/alexandria-700.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  --lls-red:#B91818;
  --lls-red-dark:#8E1212;
  --lls-red-on-photo:#D42222;   /* #B91818 is only 2.8:1 over the hero scrim */
  --lls-red-on-dark:#F0908A;    /* brand red is unreadable on near-black */
  --lls-ink:#121214;
  --lls-body:#5A5A5A;           /* 6.9:1 on white, 6.3:1 on mist */
  --lls-line:#E6E6E9;
  --lls-paper:#FFFFFF;
  --lls-mist:#F4F4F6;
  --lls-dark:#141416;
  --lls-gold:#7A6008;           /* 6.0:1 on white; Google amber alone is 1.7:1 */

  --lls-font:'Alexandria',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  --lls-head:88px;              /* header widget overrides this per breakpoint */
  --lls-shell:1350px;
  --lls-gutter:clamp(1.25rem,4vw,3.75rem);
  --lls-gap:1.5rem;
}

/* Every widget root. Scoped so the plugin never restyles the whole page. */
.lls{
  font-family:var(--lls-font);font-weight:400;font-size:17px;line-height:1.75;
  color:var(--lls-body);-webkit-font-smoothing:antialiased;
}
.lls *,.lls *::before,.lls *::after{box-sizing:border-box}
.lls :where(img){max-width:100%;display:block}
/* :where() keeps this reset at one class of specificity. Written as
   `.lls p` it scores (0,1,1) and silently outranks every component class
   that sets a margin — the gaps vanish and the CSS still looks correct. */
.lls :where(h1,h2,h3,h4,p,figure,blockquote,ul,ol,dl,dd){margin:0}
.lls :where(ul,ol){padding:0;list-style:none}
.lls :where(a){color:inherit}
.lls :focus-visible{outline:3px solid var(--lls-ink);outline-offset:2px;box-shadow:0 0 0 6px rgba(255,255,255,.9)}
.lls--dark :focus-visible,.lls--red :focus-visible{outline-color:#fff;box-shadow:0 0 0 6px rgba(18,18,20,.85)}

.lls__shell{max-width:var(--lls-shell);margin-inline:auto;padding-inline:var(--lls-gutter)}
.lls__band{padding-block:clamp(4rem,8vw,7.5rem)}
.lls--mist{background:var(--lls-mist)}
.lls--dark{background:var(--lls-dark);color:rgba(255,255,255,.72)}
.lls--red{background:var(--lls-red);color:#fff}

/* The brand rule that opens a section. */
.lls-rule{display:block;width:64px;height:5px;background:var(--lls-red);margin:0 0 1.75rem;border:0}
.lls-rule--light{background:#fff}

.lls__h2{
  color:var(--lls-ink);font-weight:700;letter-spacing:-.025em;line-height:1.08;
  font-size:clamp(2.1rem,4.2vw,3.5rem);text-wrap:balance;
}
.lls--dark .lls__h2,.lls--red .lls__h2{color:#fff}
.lls__lede{font-size:clamp(1.0625rem,1.5vw,1.25rem);line-height:1.65;color:var(--lls-ink);font-weight:400}
.lls--dark .lls__lede{color:rgba(255,255,255,.82)}
.lls--red .lls__lede{color:rgba(255,255,255,.88)}

/* Section header: heading wide, intro baseline-aligned beside it. */
.lls__head{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(1.5rem,4vw,4rem);align-items:end}
.lls__head .lls__lede{padding-bottom:.4rem}

/* Pills */
.lls-pill{
  display:inline-flex;align-items:center;gap:.9rem;border-radius:999px;
  font-size:.9375rem;font-weight:600;text-decoration:none;
  padding:1.0625rem 2rem;background:var(--lls-red);color:#fff;border:2px solid var(--lls-red);
  transition:background .25s ease,border-color .25s ease,color .25s ease;
}
/* Hover and focus states on a <button> are scoped with .lls to reach (0,2,0).
   Hello Elementor's reset paints every button magenta via `button:hover,
   button:focus` at (0,1,1), which beats a single class — so a pill that is a
   real button (the callback form's) turns pink the moment it is hovered. */
.lls .lls-pill:hover,.lls .lls-pill:focus{background:var(--lls-red-dark);border-color:var(--lls-red-dark);color:#fff}
.lls-pill svg{flex:none;transition:transform .3s cubic-bezier(.2,.7,.25,1)}
.lls-pill:hover svg{transform:translateX(5px)}
.lls-pill--ghost{background:transparent;color:var(--lls-ink);border-color:var(--lls-line)}
.lls .lls-pill--ghost:hover,.lls .lls-pill--ghost:focus{background:var(--lls-ink);border-color:var(--lls-ink);color:#fff}
/* Ink on ink is an invisible button. A ghost pill on a dark or red band
   inverts, so any widget can sit on any ground without being rewired. */
.lls--dark .lls-pill--ghost,.lls--red .lls-pill--ghost{color:#fff;border-color:rgba(255,255,255,.4)}
.lls--dark .lls-pill--ghost:hover,.lls--red .lls-pill--ghost:hover{background:#fff;border-color:#fff;color:var(--lls-ink)}
.lls-pill--light{background:#fff;color:var(--lls-red);border-color:#fff}
.lls-pill--light:hover{background:var(--lls-ink);border-color:var(--lls-ink);color:#fff}

/* Horizontal snap rail, shared by the services, media and team widgets.
   --lls-vw is set from clientWidth so the right-edge bleed does not overshoot
   by the scrollbar width on Windows and Linux. */
.lls-rail{
  display:flex;align-items:stretch;gap:var(--lls-gap);
  /* overflow-x:auto alone makes overflow-y compute to auto too, so a lifted card
     (hover translateY) let the rail scroll up and down inside its frame. Lock the
     vertical axis; padding-top leaves room for the lift so it is not clipped. */
  overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none;
  margin-right:calc(50% - var(--lls-vw,100vw) / 2);padding-top:.5rem;padding-bottom:.5rem;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
}
.lls-rail::-webkit-scrollbar{display:none}
.lls-rail>*{flex:0 0 var(--lls-card);scroll-snap-align:start}
.lls-railnav{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:clamp(2rem,3vw,2.75rem)}

/* ---------------------------------------------------------------------------
   Mobile scroll-stacking deck — the swipe rail becomes a vertical deck on a
   phone. Each card pins under the header; as the next rises to cover it, the
   card behind recedes. The pin offset is defined here and read back by
   assets/js/stack.js, so there is no constant to keep in sync on the JS side.

   Driven by JS rather than `animation-timeline`, deliberately: the pure-CSS
   technique slices one view timeline into equal parts per card, which assumes
   every card is the same height. These are not — the copy lengths differ — so
   the slices would drift out of step with where the cards actually are. The
   script measures the covering card instead. (Safari only shipped
   scroll-driven animations in 26, so it would have needed this fallback
   anyway, and two implementations would not have matched.)
   --------------------------------------------------------------------------- */
/* inherits:true is load-bearing — the dimming veil is a ::before, and a
   pseudo-element only sees a custom property if it inherits from its
   originating element. With inherits:false the veil sat permanently at the
   initial 0 and never appeared. */
@property --lls-p{syntax:"<number>";inherits:true;initial-value:0}
.lls-stack{--lls-stack-top:calc(var(--lls-head,88px) + 12px)}
/* The admin bar is fixed above the header, so the pin must clear both. */
body.admin-bar .lls-stack{--lls-stack-top:calc(var(--lls-head,88px) + 12px + var(--wp-admin--admin-bar--height,32px))}
@media screen and (max-width:600px){
  /* Below 600px WordPress makes the bar position:absolute — it scrolls away. */
  body.admin-bar .lls-stack{--lls-stack-top:calc(var(--lls-head,88px) + 12px)}
}

@media (max-width:767px){
  .lls-stack .lls-rail{
    display:block;overflow:visible;scroll-snap-type:none;
    margin-right:0;padding-bottom:0;   /* drop the right-edge bleed */
  }
  /* Two classes on the section, not one: the reveal primitive's
     `.lls-rise.is-in{transform:none}` is also (0,2,0) and sits later in this
     file, so it was winning and flattening the whole effect — the progress was
     being published correctly and nothing moved. At (0,3,0) the stack owns
     transform and opacity while it is decked, which is what should happen. */
  .lls.lls-stack .lls-rail>*{
    width:auto;flex:none;position:sticky;top:var(--lls-stack-top);
    /* A clear gap between cards as each one rises — at the plain 1.5rem gap
       the next card read as stuck to the one before. stack.js measures card
       tops, not the gap, so this does not change the timing. */
    margin-bottom:clamp(2.5rem,10vw,3.5rem);
    /* Scale toward the top edge so the pinned edge never moves. */
    transform-origin:top center;
    will-change:transform,opacity;
    /* A transition here would lag the scroll-linked transform. */
    transition:none;

    /* --lls-p is how far the next card has risen to cover this one, 0..1.
       The script sets only that; every visual below is derived from it, so
       the look lives in one place. Three cues together read as depth where
       a shrink alone reads as a shrink: the card slips back (scale), drifts
       up (translate) and falls into shadow (the veil below). */
    --lls-p:0;
    transform:
      translateY(calc(var(--lls-p) * -10px))
      scale(calc(1 - var(--lls-p) * .06));
    /* Solid for the first ~72%, then away quickly. Fading from the very
       start is what made it look like a dissolve rather than a card: at the
       midpoint you could see the section straight through it. */
    opacity:clamp(0,calc((1 - var(--lls-p)) / .28),1);
  }

  /* The receding card dims. Done with an overlay rather than a filter so it
     stays a compositor-only opacity change — a filter would repaint the whole
     card every frame. */
  .lls.lls-stack .lls-rail>*::before{
    content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
    background:#0B0B0D;border-radius:inherit;
    opacity:calc(var(--lls-p) * .3);
  }

  @media (prefers-reduced-motion:reduce){
    /* The movement goes; the fade and the dim stay, because without them a
       card taller than the one covering it peeks out below. */
    .lls.lls-stack .lls-rail>*{transform:none}
  }
  /* Arrows step a horizontal rail; there is no longer one to step. */
  .lls-stack .lls-railnav .lls-arrows{display:none}
  .lls-stack .lls-railnav{justify-content:center}
}
.lls-arrows{display:flex;gap:.75rem;margin-left:auto}
.lls-arrow{
  width:52px;height:52px;border-radius:999px;background:#fff;border:1px solid var(--lls-line);
  color:var(--lls-ink);display:grid;place-items:center;cursor:pointer;
  transition:background .25s ease,color .25s ease,border-color .25s ease;
}
.lls .lls-arrow:hover,.lls .lls-arrow:focus{background:var(--lls-ink);border-color:var(--lls-ink);color:#fff}
.lls-arrow[disabled]{opacity:.35;cursor:default}
.lls-arrow[disabled]:hover{background:#fff;color:var(--lls-ink);border-color:var(--lls-line)}
.lls--dark .lls-arrow{background:transparent;border-color:rgba(255,255,255,.28);color:#fff}
.lls--dark .lls-arrow:hover{background:#fff;border-color:#fff;color:var(--lls-ink)}
.lls--dark .lls-arrow[disabled]:hover{background:transparent;color:#fff;border-color:rgba(255,255,255,.28)}

/* Rotating headline: lines share one grid cell so the block sizes to the
   tallest and never reflows; visibility (not opacity alone) keeps the
   inactive lines out of the accessibility tree. */
.lls-rotator{display:grid}
.lls-rotator__line{
  grid-area:1/1;align-self:end;
  opacity:0;visibility:hidden;transform:translateY(.3em);
  transition:opacity .65s ease,transform .65s cubic-bezier(.2,.7,.25,1),visibility 0s linear .65s;
}
.lls-rotator__line.is-on{opacity:1;visibility:visible;transform:none;transition-delay:0s,0s,0s}

/* Scroll reveal */
.lls-rise{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.25,1)}
.lls-rise.is-in{opacity:1;transform:none}
.lls-rise--1{transition-delay:.08s}
.lls-rise--2{transition-delay:.16s}
.lls-rise--3{transition-delay:.24s}

/* Elementor's editor renders widgets without a scroll event, so never hide
   content from the person editing the page. */
.elementor-editor-active .lls-rise{opacity:1;transform:none}
.elementor-editor-active .lls-rotator__line{position:relative}

/* Small uppercase label with a red bar — names a section ("Path one") where
   the brand rule alone would not say which part of the page you are in. */
.lls p.lls-tag{display:flex;align-items:center;gap:.9rem;font-size:.75rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--lls-red);line-height:1.4;margin-bottom:1.5rem}
.lls-tag::before{content:"";flex:none;width:40px;height:3px;background:var(--lls-red)}
.lls--dark p.lls-tag{color:var(--lls-red-on-dark)}
.lls--dark .lls-tag::before{background:var(--lls-red-on-dark)}
/* A short list led by red dashes. */
.lls-dashes{display:grid;gap:.75rem;margin-top:1.75rem}
.lls-dashes li{display:flex;gap:1rem;align-items:flex-start;color:var(--lls-ink);font-size:1rem;line-height:1.5}
.lls-dashes li::before{content:"";flex:none;width:16px;height:2px;margin-top:.7em;background:var(--lls-red)}

@media (prefers-reduced-motion:reduce){
  .lls-rise{opacity:1;transform:none;transition:none}
  .lls-rotator__line{transition:none}
}

@media (max-width:900px){
  .lls__head{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:640px){
  .lls{font-size:16px}
  :root{--lls-gap:1rem}
  .lls-arrow{width:46px;height:46px}
}
