/* RockPoint geo city template - styles
   Extracted from the Dallas prototype (page 1931) on 2026-08-24 so every city
   page shares ONE copy instead of carrying its own 126KB of inline chrome.
   Blocks are concatenated in their original document order; the cascade and the
   execution order are therefore identical to the inline version.
   Edit here, not in a page. */

:root {
  --llp-dark: #101012;
  --llp-dark2: #141416;
  --llp-dark3: #18181a;
  --llp-cream: #f3f1ec;
  --llp-text: #09090b;
  --llp-gold: #CCA967;
  --llp-gold2: #D4A84B;
  --llp-gold-hover: #9a6a00;
  --llp-red: #b3261e;
  --llp-font-heading: var(--font-heading, "Poppins", "Inter", system-ui, sans-serif);
  --llp-font-body: var(--font-body, "Inter", system-ui, sans-serif);
}
.llp-wrap { font-family: var(--llp-font-body); color: var(--llp-text); line-height: 1.7; }
.llp-wrap *, .llp-wrap *::before, .llp-wrap *::after { box-sizing: border-box; }
.llp-wrap section { padding: 90px clamp(20px, 4vw, 60px); }
.llp-wrap .llp-container { max-width: 1320px; margin: 0 auto; }
.ct-inner-content:has(.llp-wrap) { max-width: none !important; padding: 0 !important; }
.llp-wrap, .llp-wrap > section { width: 100%; }
.llp-wrap h1, .llp-wrap h2, .llp-wrap h3, .llp-wrap h4 {
  font-family: var(--llp-font-heading); font-weight: 800; line-height: 1.15; margin: 0 0 .6em;
}
.llp-wrap h2 { font-size: clamp(28px, 3.2vw, 44px); }
.llp-wrap h3 { font-size: clamp(20px, 1.8vw, 26px); }
.llp-wrap p { margin: 0 0 1.1em; }
.llp-wrap a { color: var(--llp-gold); text-decoration: underline; text-underline-offset: 3px; }
.llp-wrap a:hover { color: var(--llp-gold-hover); }
.llp-wrap .llp-eyebrow {
  display: inline-block; font-family: var(--llp-font-heading); font-weight: 700;
  font-size: 13px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--llp-gold); margin-bottom: 16px;
}
.llp-wrap .llp-btn {
  display: inline-block; background: var(--llp-gold); color: var(--llp-text);
  font-family: var(--llp-font-heading); font-weight: 700; font-size: 16px;
  padding: 16px 32px; border-radius: 100vmax; text-decoration: none;
  transition: background .2s ease, transform .2s ease; line-height: 1;
}
.llp-wrap .llp-btn:hover { background: var(--llp-gold-hover); color: #fff; transform: translateY(-1px); }
.llp-wrap .llp-btn--ghost { background: transparent; color: var(--llp-gold); border: 2px solid var(--llp-gold); }
.llp-wrap .llp-btn--ghost:hover { background: var(--llp-gold); color: var(--llp-text); }

/* HERO */
.llp-hero {
  background: var(--llp-dark); color: var(--llp-cream);
  padding: 200px 24px 110px; text-align: left;
  background-image:
    linear-gradient(180deg, rgba(16,16,18,.88) 0%, rgba(16,16,18,.72) 55%, rgba(16,16,18,.96) 100%),
    url("https://geos.rockpointlaw.com/wp-content/uploads/2026/04/rockpoint-law-1-1536x922.png");
  background-size: cover;
  background-position: center;
  border-bottom: 1px solid rgba(204,169,103,.18);
}
.llp-hero h1 { font-size: clamp(36px, 5.5vw, 72px); color: #fff; margin-bottom: 24px; max-width: 18ch; }
.llp-hero h1 em { font-style: italic; color: var(--llp-gold); font-weight: 800; }
.llp-hero .llp-sub { font-size: clamp(16px, 1.2vw, 18px); color: rgba(243,241,236,.85); max-width: 66ch; margin-bottom: 28px; }
.llp-hero .llp-rule { display: none; }
.llp-hero-badges { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 32px; }
.llp-hero-badge { font-size: 13px; color: rgba(243,241,236,.9); border: 1px solid rgba(204,169,103,.35); background: rgba(204,169,103,.06); padding: 9px 16px; border-radius: 100vmax; }
.llp-hero-badge b { color: var(--llp-gold); font-weight: 700; }

/* Generic backgrounds */
.llp-dark { background: var(--llp-dark); color: var(--llp-cream); }
.llp-dark2 { background: var(--llp-dark2); color: var(--llp-cream); }
.llp-dark3 { background: var(--llp-dark3); color: var(--llp-cream); }
.llp-cream { background: var(--llp-cream); color: var(--llp-text); }
.llp-light { background: #fafaf8; color: var(--llp-text); }
.llp-dark h2, .llp-dark h3, .llp-dark2 h2, .llp-dark2 h3, .llp-dark3 h2, .llp-dark3 h3 { color: #fff; }
.llp-dark h2 em, .llp-dark2 h2 em, .llp-dark3 h2 em { font-style: italic; color: var(--llp-gold); }
.llp-cream h2 em, .llp-light h2 em { font-style: italic; color: var(--llp-gold-hover); }

/* 2-col with image */
.llp-2col { display: grid; grid-template-columns: 1.2fr 1fr; gap: 64px; align-items: center; }
.llp-2col--rev { grid-template-columns: 1fr 1.2fr; }
.llp-2col__img {
  background: var(--llp-dark2); aspect-ratio: 4/3; border-radius: 4px;
  background-size: cover; background-position: center;
  box-shadow: 0 12px 40px rgba(0,0,0,.35);
}
@media (max-width: 880px) { .llp-2col, .llp-2col--rev { grid-template-columns: 1fr; gap: 32px; } }

/* Inline CTA band */
.llp-cta-band {
  margin-top: 32px; padding: 28px 32px; background: rgba(204,169,103,.07);
  border-left: 3px solid var(--llp-gold); border-radius: 4px;
}
.llp-cta-band p { margin-bottom: 16px; font-weight: 600; }

/* Cards grid */
.llp-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; margin-top: 40px; }
.llp-card {
  background: var(--llp-dark3); padding: 32px 28px; border-radius: 6px;
  border-top: 3px solid var(--llp-gold); transition: transform .25s ease;
}
.llp-card:hover { transform: translateY(-4px); }
.llp-card h3 { color: #fff; font-size: 19px; margin-bottom: 12px; }
.llp-card p { color: rgba(243,241,236,.78); font-size: 15px; line-height: 1.6; }
.llp-card__icon {
  width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
  background: rgba(204,169,103,.12); border-radius: 10px; margin-bottom: 20px;
  color: var(--llp-gold);
}
.llp-card__icon svg { width: 24px; height: 24px; }
.llp-cards--light .llp-card { background: #fff; border-top-color: var(--llp-gold); box-shadow: 0 4px 24px rgba(0,0,0,.06); }
.llp-cards--light .llp-card h3 { color: var(--llp-text); }
.llp-cards--light .llp-card p { color: rgba(9,9,11,.75); }
.llp-cards--light .llp-card__icon { background: rgba(204,169,103,.18); color: var(--llp-gold-hover); }

/* Process timeline */
.llp-steps { display: grid; gap: 40px; margin-top: 48px; }
.llp-step { display: grid; grid-template-columns: 80px 1fr; gap: 28px; align-items: flex-start; }
.llp-step__num {
  font-family: var(--llp-font-heading); font-weight: 800; font-size: 56px;
  color: var(--llp-gold); line-height: 1; letter-spacing: -.02em;
}
.llp-step__body h3 { color: #fff; font-size: 22px; margin-bottom: 10px; }
.llp-step__body p { color: rgba(243,241,236,.82); }
@media (max-width: 600px) { .llp-step { grid-template-columns: 1fr; gap: 8px; } .llp-step__num { font-size: 44px; } }

/* Comparison table */
.llp-compare { margin-top: 36px; border-radius: 6px; overflow: hidden; box-shadow: 0 6px 28px rgba(0,0,0,.08); }
.llp-compare table { width: 100%; border-collapse: collapse; background: #fff; }
.llp-compare th, .llp-compare td { padding: 18px 22px; text-align: left; border-bottom: 1px solid #eee; font-size: 15px; vertical-align: top; }
.llp-compare th { background: var(--llp-dark); color: #fff; font-family: var(--llp-font-heading); font-weight: 700; font-size: 14px; letter-spacing: .04em; text-transform: uppercase; }
.llp-compare th:last-child { background: var(--llp-gold); color: var(--llp-text); }
.llp-compare td:first-child { color: rgba(9,9,11,.65); }
.llp-compare td:last-child { color: var(--llp-text); font-weight: 600; background: rgba(204,169,103,.08); }
.llp-compare tr:last-child td { border-bottom: 0; }

/* Eligibility 3-col table variant */
.llp-eligtable th:last-child, .llp-eligtable td:last-child { background: #fff; color: var(--llp-text); font-weight: 400; }

/* Checklist */
.llp-checklist { list-style: none; padding: 0; margin: 32px 0; display: grid; gap: 14px; max-width: 760px; }
.llp-checklist li {
  /* was display:flex - flex made <strong> and the text after it separate flex
     items, which collapses the space between them and rendered
     "Replacementwith a comparable new vehicle" (Juan, Loom 2026-08-20).
     Block keeps the inline space; the bullet stays centred because ::before
     is absolutely positioned. */
  position: relative; padding-left: 40px; font-size: 17px;
  display: block; min-height: 30px; line-height: 1.6;
}
.llp-checklist li::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border-radius: 50%; background: var(--llp-gold);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23101012' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-size: 16px 16px; background-position: center; background-repeat: no-repeat;
}

/* Accordion */
.llp-accordion { margin-top: 36px; display: grid; gap: 12px; }
.llp-accordion details {
  background: var(--llp-dark3); border-radius: 6px; border-left: 3px solid var(--llp-gold);
  padding: 0;
}
.llp-accordion[data-light="1"] details { background: #fff; box-shadow: 0 2px 14px rgba(0,0,0,.05); }
.llp-accordion summary {
  cursor: pointer; padding: 20px 28px; font-family: var(--llp-font-heading);
  font-weight: 700; font-size: 17px; color: #fff; list-style: none;
  position: relative; padding-right: 56px;
}
.llp-accordion[data-light="1"] summary { color: var(--llp-text); }
.llp-accordion summary::-webkit-details-marker { display: none; }
.llp-accordion summary::after {
  content: "+"; position: absolute; right: 24px; top: 50%; transform: translateY(-50%);
  font-size: 24px; color: var(--llp-gold); font-weight: 400; transition: transform .25s ease;
}
.llp-accordion details[open] summary::after { content: "\2212"; transform: translateY(-50%) rotate(0); }
.llp-accordion details > div { padding: 0 28px 24px; color: rgba(243,241,236,.82); font-size: 15px; line-height: 1.7; }
.llp-accordion[data-light="1"] details > div { color: rgba(9,9,11,.75); }

/* Final CTA band */
.llp-final-cta {
  background: linear-gradient(135deg, var(--llp-dark) 0%, var(--llp-dark3) 50%, var(--llp-dark) 100%);
  text-align: center; padding: 130px 24px;
  position: relative;
}
.llp-final-cta::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(circle at 50% 50%, rgba(204,169,103,.06) 0%, transparent 60%);
  pointer-events: none;
}
.llp-final-cta h2 { color: #fff; font-size: clamp(28px, 4vw, 48px); margin-bottom: 28px; }
.llp-final-cta h2 em { font-style: italic; color: var(--llp-gold); }
.llp-final-cta .llp-btn { font-size: 18px; padding: 20px 44px; }

/* Disclaimer */
.llp-disclaimer { padding: 50px 24px; background: var(--llp-dark2); color: rgba(243,241,236,.55); font-size: 13px; line-height: 1.65; }
.llp-disclaimer h2 { font-size: 14px; color: rgba(243,241,236,.75); margin-bottom: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.llp-review { color: rgba(243,241,236,.7); font-size: 13px; margin-bottom: 18px; }
.llp-review a { color: var(--llp-gold); }
.llp-adv { color: rgba(243,241,236,.7); font-size: 13px; margin-bottom: 18px; font-weight: 600; }

.llp-lead { font-size: 17px; font-weight: 600; color: inherit; }

.llp-wrap section h2 { position: relative; padding-bottom: 16px; }
/* Juan 2026-08-23: no dash marks. The gold underline under every h2 is gone. */
.llp-wrap section h2::after { content: none; }


/* Community pill list */
.llp-pills { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; padding: 0; }
.llp-pills li {
  list-style: none; padding: 10px 22px; border: 1px solid rgba(204,169,103,.35);
  border-radius: 100vmax; font-weight: 600; font-size: 14px; color: var(--llp-gold);
  background: rgba(204,169,103,.06);
}
.llp-light .llp-pills li, .llp-cream .llp-pills li { color: var(--llp-gold-hover); border-color: rgba(154,106,0,.4); background: rgba(204,169,103,.08); }

/* Speakable answer block */
.llp-answer {
  background: rgba(204,169,103,.09); border-left: 3px solid var(--llp-gold);
  border-radius: 6px; padding: 26px 30px; margin: 8px 0 34px; max-width: 82ch;
}
.llp-answer p { margin: 0; font-size: 17px; color: rgba(243,241,236,.9); }
.llp-cream .llp-answer p, .llp-light .llp-answer p { color: rgba(9,9,11,.85); }

/* Reviews */
.llp-reviews { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:22px; margin-top:12px; }
.llp-rev-card { background:#fff; border-radius:8px; padding:26px 26px 22px; box-shadow:0 4px 24px rgba(0,0,0,.06); border-top:3px solid var(--llp-gold); }
.llp-rev-stars { color:var(--llp-gold); font-size:17px; letter-spacing:2px; margin-bottom:12px; }
.llp-rev-card p { font-size:15px; color:rgba(9,9,11,.8); font-style:italic; }
.llp-rev-card .who { font-style:normal; font-weight:700; font-size:14px; color:var(--llp-text); margin-top:14px; }
.llp-rev-summary { display:flex; align-items:center; gap:20px; flex-wrap:wrap; margin-top:10px; padding:22px 26px; background:#fff; border-radius:8px; box-shadow:0 4px 24px rgba(0,0,0,.06); }
.llp-rev-summary .big { font-family:var(--llp-font-heading); font-weight:800; font-size:44px; color:var(--llp-text); line-height:1; }
.llp-rev-summary .stars { color:var(--llp-gold); font-size:20px; letter-spacing:2px; }
.llp-todo { display:inline-block; background:rgba(179,38,30,.1); color:var(--llp-red); font-size:12px; font-weight:700; padding:3px 9px; border-radius:5px; margin-left:6px; }
.llp-todo-box { background:rgba(179,38,30,.06); border:1px dashed rgba(179,38,30,.4); border-radius:6px; padding:14px 18px; font-size:13px; color:rgba(9,9,11,.7); margin-top:18px; }

/* Team snippet */
.llp-team { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:24px; margin-top:40px; }
.llp-team-card { background:var(--llp-dark3); border-radius:8px; padding:28px 26px; border-top:3px solid var(--llp-gold); }
.llp-team-card h3 { color:#fff; font-size:19px; margin-bottom:4px; }
.llp-team-card .role { color:var(--llp-gold); font-size:13px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; margin-bottom:14px; }
.llp-team-card p { color:rgba(243,241,236,.78); font-size:14.5px; line-height:1.6; }

/* Blog cards */
.llp-blog { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:24px; margin-top:40px; }
.llp-blog-card { background:#fff; border-radius:8px; padding:26px 24px; box-shadow:0 4px 24px rgba(0,0,0,.06); border-left:3px solid var(--llp-gold); display:flex; flex-direction:column; }
.llp-blog-card .kicker { font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--llp-gold-hover); margin-bottom:10px; }
.llp-blog-card h3 { font-size:18px; color:var(--llp-text); margin-bottom:12px; line-height:1.35; }
.llp-blog-card a.more { margin-top:auto; font-weight:700; font-size:14px; text-decoration:none; }

/* Exit-intent popup */
.llp-exit { position:fixed; inset:0; background:rgba(2,8,22,.72); z-index:99999; display:none; align-items:center; justify-content:center; padding:20px; }
.llp-exit.open { display:flex; }
.llp-exit__box { background:var(--llp-dark3); border-top:4px solid var(--llp-gold); border-radius:12px; max-width:440px; width:100%; padding:40px 36px 34px; position:relative; text-align:center; box-shadow:0 30px 80px rgba(0,0,0,.5); }
.llp-exit__box h3 { color:#fff; font-size:26px; margin-bottom:12px; }
.llp-exit__box p { color:rgba(243,241,236,.8); font-size:15px; margin-bottom:22px; }
.llp-exit__box .llp-btn { width:100%; text-align:center; }
.llp-exit__phone { display:block; margin-top:16px; color:var(--llp-gold); font-weight:700; font-size:20px; text-decoration:none; font-family:var(--llp-font-heading); }
.llp-exit__close { position:absolute; top:14px; right:18px; background:none; border:none; color:rgba(243,241,236,.6); font-size:26px; cursor:pointer; line-height:1; }
.llp-exit__close:hover { color:#fff; }
.llp-exit__fine { font-size:11.5px; color:rgba(243,241,236,.45); margin-top:16px; margin-bottom:0; }

/* ── */

/* Hero: Texas art + stepped evaluation form (Juan, Loom 2026-08-20) */
  .llp-hero--tx{position:relative;overflow:hidden;isolation:isolate}
  .llp-hero--tx > .llp-container{position:relative;z-index:1}
  .llp-hero__grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(340px,.85fr);
    gap:clamp(28px,4vw,64px);align-items:center}
  .llp-qual{background:rgba(10,14,24,.55);backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
    border:1px solid rgba(204,169,103,.30);border-radius:18px;padding:28px 28px 24px;
    box-shadow:0 24px 60px rgba(0,0,0,.45)}
  .llp-qual__title{margin:0;font-size:clamp(21px,2.2vw,27px);color:#f4f1ea}
  .llp-qual__sub{margin:6px 0 0;font-size:14px;color:rgba(243,241,236,.72)}
  .llp-qual__dots{display:flex;gap:7px;margin:16px 0 20px}
  .llp-qual__dots i{width:26px;height:3px;border-radius:2px;background:rgba(243,241,236,.22);transition:background .3s}
  .llp-qual__dots i.is-on{background:var(--llp-gold,#cca967)}
  .llp-qual__step{display:none;border:0;padding:0;margin:0}
  .llp-qual__step.is-on{display:block;animation:qualIn .3s ease}
  @keyframes qualIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  .llp-qual legend{font-size:16px;font-weight:600;color:#f4f1ea;margin-bottom:14px;padding:0;line-height:1.4}
  .llp-qual__opts{display:grid;gap:8px;margin-bottom:18px}
  .llp-qual__opts label{display:flex;align-items:center;gap:11px;padding:11px 14px;border-radius:10px;
    background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09);cursor:pointer;
    font-size:15px;color:#f0ede6;transition:background .18s,border-color .18s}
  .llp-qual__opts label:hover{background:rgba(204,169,103,.13);border-color:rgba(204,169,103,.42)}
  .llp-qual__opts input{accent-color:var(--llp-gold,#cca967);width:17px;height:17px;flex-shrink:0}
  .llp-qual input[type=text],.llp-qual input[type=tel],.llp-qual input[type=email]{
    width:100%;padding:12px 14px;margin-bottom:10px;border-radius:10px;font:inherit;font-size:15px;
    background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);color:#f4f1ea}
  .llp-qual input::placeholder{color:rgba(243,241,236,.5)}
  .llp-qual input:focus{outline:2px solid rgba(204,169,103,.6);outline-offset:1px}
  .llp-qual__row{display:flex;align-items:center;gap:12px;justify-content:space-between;flex-wrap:wrap}
  .llp-qual__back{background:none;border:0;color:rgba(243,241,236,.72);font:inherit;font-size:14px;cursor:pointer;padding:8px 2px}
  .llp-qual__back:hover{color:#f4f1ea}
  .llp-qual__fine{font-size:11.5px;line-height:1.5;color:rgba(243,241,236,.62);margin:14px 0 0}
  @media(max-width:980px){.llp-hero__grid{grid-template-columns:minmax(0,1fr)}}
  @media (prefers-reduced-motion:reduce){.llp-qual__step.is-on{animation:none}}

/* ── */

/* "A Dallas example" tooltips - Juan, Loom 2026-08-23: "when I hover over, a
         little tooltip should pop up with that example ... those should pop up as
         tooltips when I hover over each one of these in a nice way." The examples came
         across from the light eligibility table, which this section now replaces.
         Hover, keyboard focus and tap all open it. The in-card copy is hidden ONLY
         after the script has run (html.llp-ex-js), so if the JS ever fails the example
         stays on the page as plain text instead of disappearing. */
      .llp-card__act{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;margin-top:18px}
      /* only this grid: the four cards run to different lengths, so the example
         link and the test button are pushed to a shared baseline. */
      .llp-cards--elig .llp-card{display:flex;flex-direction:column}
      .llp-cards--elig .llp-card__icon{align-self:flex-start}
      .llp-cards--elig .llp-card__act{margin-top:auto;padding-top:16px}
      .llp-ex{display:inline-block;font-size:13.5px;color:var(--llp-gold,#cca967);cursor:help}
      .llp-ex__t{border-bottom:1px dotted currentColor;text-underline-offset:3px}
      .llp-ex:hover .llp-ex__t,.llp-ex:focus-visible .llp-ex__t{color:#fff}
      .llp-ex:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:3px;border-radius:3px}
      .llp-ex__d{display:block;margin-top:6px;max-width:46ch;font-size:14px;line-height:1.55;
        color:rgba(243,241,236,.78)}
      html.llp-ex-js .llp-ex__d{display:none}
      .llp-ex-pop{position:fixed;z-index:9998;width:max-content;
        max-width:min(320px,calc(100vw - 24px));padding:14px 16px;border-radius:12px;
        background:#0e1118;color:#f2efe8;border:1px solid rgba(204,169,103,.4);
        box-shadow:0 18px 44px rgba(0,0,0,.45);font-size:14px;line-height:1.55;pointer-events:none}
      .llp-ex-pop[hidden]{display:none}
      .llp-ex-pop strong{display:block;margin-bottom:5px;color:var(--llp-gold,#cca967);
        font-size:12px;letter-spacing:.7px;text-transform:uppercase}
      @media (max-width:600px){.llp-card__act{gap:10px 12px}}
      /* The test dialog was moved into this dark section when the light
         eligibility table was merged away. ".llp-dark h3" would paint its title
         white on the cream panel, so it is restored here rather than by editing
         the modal's own stylesheet. */
      .llp-dark .llp-testcheck h3{color:#1a1a1a}
      .llp-dark .llp-testcheck label,.llp-dark .llp-testcheck p{color:#1a1a1a}

/* ── */

/* Loom 2026-08-23, Juan: "these all need to be solid yellow. I almost
         scrolled right past them." Primary weight now: solid gold ground, dark
         ink on it (8.3:1), and it lifts on hover so it reads as the action. */
      .llp-test-btn{margin-top:8px;background:var(--llp-gold,#cca967);
        border:1px solid var(--llp-gold,#cca967);color:#141416;
        font:inherit;font-size:13.5px;font-weight:700;padding:9px 20px;border-radius:100vmax;
        cursor:pointer;white-space:nowrap;box-shadow:0 3px 12px rgba(204,169,103,.3);
        transition:filter .2s,transform .2s,box-shadow .2s}
      .llp-test-btn:hover{filter:brightness(1.07);transform:translateY(-1px);
        box-shadow:0 7px 20px rgba(204,169,103,.4)}
      .llp-test-btn:focus-visible{outline:3px solid #fff;outline-offset:2px}
      @media (prefers-reduced-motion:reduce){.llp-test-btn{transition:none}
        .llp-test-btn:hover{transform:none}}
      .llp-modal{position:fixed;inset:0;z-index:9999;display:grid;place-items:center;padding:24px}
      .llp-modal[hidden]{display:none}
      .llp-modal__scrim{position:absolute;inset:0;background:rgba(8,10,16,.62);
        -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:tcFade .2s ease}
      /* Opaque and explicitly coloured: it now floats over the page rather than
         sitting in the section, so it cannot inherit a usable text colour. */
      .llp-testcheck{position:relative;z-index:1;width:min(640px,100%);max-height:min(86vh,900px);
        overflow:auto;margin:0;padding:34px 36px;border-radius:18px;color:#1a1a1a;background:#fbfaf7;
        border:1px solid rgba(204,169,103,.45);box-shadow:0 30px 80px rgba(0,0,0,.42);
        animation:tcPop .24s cubic-bezier(.2,.8,.3,1)}
      @keyframes tcFade{from{opacity:0}to{opacity:1}}
      @keyframes tcPop{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
      /* Lock BOTH html and body: body alone does not hold, the html element keeps
         scrolling. Deliberately no position:fixed here — pinning the body collapses
         the document, and the scroll restore on close lands in the wrong place on a
         page this tall. Not moving the page at all means nothing to restore. */
      html.llp-modal-open,body.llp-modal-open{overflow:hidden}
      @media (max-width:600px){
        .llp-modal{padding:14px}
        .llp-testcheck{padding:26px 22px;max-height:88vh}
      }
      @media (prefers-reduced-motion:reduce){
        .llp-modal__scrim,.llp-testcheck{animation:none}
      }
      .llp-testcheck h3{margin:0 0 6px}
      .llp-testcheck__x{position:absolute;top:12px;right:16px;background:none;border:0;font-size:26px;
        line-height:1;cursor:pointer;color:inherit;opacity:.55}
      .llp-testcheck__x:hover{opacity:1}
      .llp-testcheck label{display:flex;gap:10px;align-items:flex-start;margin:10px 0;font-size:16px;cursor:pointer}
      .llp-testcheck input{margin-top:4px;width:18px;height:18px;accent-color:var(--llp-gold,#cca967);flex-shrink:0}
      .llp-testcheck__out{margin-top:16px;font-weight:700;min-height:1.5em}
      .llp-testcheck__out:not(:empty){margin-top:18px;padding-top:16px;
        border-top:1px solid rgba(17,17,17,.12)}
      .llp-testcheck__fine{font-size:12px;opacity:.7;margin-top:14px;line-height:1.5}

/* ── */

/* Repair-history upload, three steps. EVERY hide rule below is scoped under
     .is-stepped, which only JS adds - if the script never runs the form renders
     as one plain list and still submits. A CSS-only hide waiting on JS made real
     content permanently invisible on this page once; not repeating that. */
  /* Juan, Loom: "this upload your repair orders needs to be very nice and SMALL".
     It was in steps but still a full-width slab. Now a compact card sitting beside
     the CTA rather than under it, at a fraction of the height. */
  /* Juan, 2026-08-23: "move that black CTA to a box container and step one in the
     upload your documents and start your case evaluation for free." The CTA and the
     upload wizard are now one box sitting in the empty column beside the closing
     copy, rather than two stacked blocks below it. */
  .llp-close2col{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,4vw,56px);
    align-items:start;margin-top:clamp(20px,3vh,34px)}
  .llp-startbox{background:linear-gradient(135deg,#1b1b1f,#0d0d0f);color:#f3f1ec;
    border-radius:18px;padding:26px 28px;box-shadow:0 20px 50px rgba(0,0,0,.18)}
  .llp-startbox__kicker{display:block;color:var(--llp-gold,#cca967);font-size:11.5px;
    font-weight:700;letter-spacing:.17em;text-transform:uppercase}
  .llp-startbox h3{margin:8px 0 6px;font-size:clamp(20px,2.1vw,27px);color:#fff;line-height:1.18}
  .llp-startbox > p{margin:0 0 16px;font-size:14.5px;line-height:1.55;color:rgba(243,241,236,.8)}
  .llp-startbox .llp-upload{max-width:none;margin:0;padding:0;background:none;border:0}
  .llp-startbox__alt{display:inline-block;margin-top:14px;font-size:13px;
    color:var(--llp-gold,#cca967);text-decoration:underline;text-underline-offset:3px}
  @media(max-width:900px){
    .llp-close2col{grid-template-columns:1fr}
    .llp-startbox{padding:22px 20px}
  }
  .llp-upload{max-width:520px;margin-left:auto;margin-right:auto;padding:20px 22px;border-radius:14px}
  .llp-upload h3{font-size:17px;margin:0 0 4px;line-height:1.25}
  .llp-upload > p{font-size:13px;line-height:1.45;margin:0 0 12px;opacity:.78}
  .llp-upload.is-stepped .rpl-cf7 label{margin-bottom:8px}
  .llp-upload.is-stepped .rpl-cf7 input[type=text],
  .llp-upload.is-stepped .rpl-cf7 input[type=email],
  .llp-upload.is-stepped .rpl-cf7 input[type=tel]{padding:7px 10px;font-size:13.5px}
  .llp-upload.is-stepped .rpl-cf7 textarea{height:60px}
  .llp-upload .llp-wiz__bar{margin-bottom:10px}
  @media(max-width:700px){.llp-upload{max-width:none;padding:18px 16px}}
  .llp-upload .rpl-cf7 > p{margin:0}
  .llp-upload.is-stepped .rpl-cf7 > p > br{display:none}
  .llp-upload.is-stepped .llp-wiz__step{display:none}
  .llp-upload.is-stepped .llp-wiz__step.is-on{display:block}
  .llp-upload.is-stepped .rpl-cf7 label{display:block;margin:0 0 10px;font-size:12.5px;
    color:rgba(243,241,236,.9)}
  .llp-upload.is-stepped .rpl-cf7 input[type=text],
  .llp-upload.is-stepped .rpl-cf7 input[type=email],
  .llp-upload.is-stepped .rpl-cf7 input[type=tel],
  .llp-upload.is-stepped .rpl-cf7 textarea{margin-top:4px;padding:8px 11px;font-size:14px;
    border-radius:8px}
  /* CF7 ships rows=10 on the textarea, so a min-height alone does not shrink it */
  .llp-upload.is-stepped .rpl-cf7 textarea{min-height:0;height:72px;resize:vertical}
  .llp-wiz__head{display:flex;align-items:center;gap:12px;margin:0 0 14px}
  .llp-wiz__bar{flex:1;height:4px;border-radius:100vmax;background:rgba(243,241,236,.14);
    overflow:hidden}
  .llp-wiz__bar > i{display:block;height:100%;width:33.33%;border-radius:100vmax;
    background:var(--llp-gold,#cca967);transition:width .28s ease}
  .llp-wiz__count{font-size:11.5px;font-weight:700;letter-spacing:.06em;
    text-transform:uppercase;color:rgba(243,241,236,.62);white-space:nowrap}
  .llp-wiz__legend{margin:0 0 10px;font-size:13px;font-weight:700;color:var(--llp-gold,#cca967)}
  .llp-wiz__nav{display:flex;gap:10px;align-items:center;margin-top:6px}
  .llp-wiz__btn{font:inherit;font-size:14px;font-weight:700;padding:10px 22px;
    border-radius:100vmax;cursor:pointer;border:1px solid rgba(204,169,103,.5);
    background:none;color:rgba(243,241,236,.9);transition:background .2s,border-color .2s}
  .llp-wiz__btn:hover{background:rgba(204,169,103,.16);border-color:var(--llp-gold,#cca967)}
  .llp-wiz__btn--next{background:var(--llp-gold,#cca967);border-color:var(--llp-gold,#cca967);
    color:#141416}
  .llp-wiz__btn--next:hover{filter:brightness(1.07);background:var(--llp-gold,#cca967)}
  .llp-upload.is-stepped .rpl-cf7 .submit_btn{display:none}
  .llp-upload.is-stepped[data-wiz="2"] .rpl-cf7 .submit_btn{display:inline-block;width:auto;
    margin:0}
  .llp-upload.is-stepped[data-wiz="0"] .llp-wiz__btn--back{display:none}
  .llp-upload.is-stepped[data-wiz="2"] .llp-wiz__btn--next{display:none}
  @media (prefers-reduced-motion:reduce){.llp-wiz__bar > i{transition:none}}

/* ── */

/* Vehicle stage - Juan, Loom 2026-08-20: hover a category and see that vehicle
     on the stand behind the cards, auto-rotating like a character select. */
  .llp-vehstage{position:relative;overflow:hidden;isolation:isolate}
  .llp-vehstage__bg{position:absolute;inset:0;z-index:0}
  .llp-vehstage__bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    object-position:center 55%;opacity:0;transform:scale(1.04);
    transition:opacity .7s ease, transform 6s ease-out}
  .llp-vehstage__bg img.is-on{opacity:.85;transform:scale(1)}
  .llp-vehstage__veil{position:absolute;inset:0;
    background:linear-gradient(180deg,rgba(6,8,14,.88) 0%,rgba(6,8,14,.30) 38%,rgba(6,8,14,.34) 62%,rgba(6,8,14,.92) 100%)}
  .llp-vehstage{padding-top:clamp(56px,7vh,96px);padding-bottom:clamp(56px,7vh,96px)}
  .llp-vehstage__cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
  .llp-vehstage .llp-vehcard{background:rgba(10,12,18,.62);backdrop-filter:blur(3px);
    -webkit-backdrop-filter:blur(3px);border:1px solid rgba(204,169,103,.22)}
  .llp-vehstage .llp-vehcard h3{margin-bottom:8px}
  .llp-vehstage .llp-vehcard p{font-size:14.5px;line-height:1.6}
  @media(max-width:1100px){.llp-vehstage__cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
  @media(max-width:620px){.llp-vehstage__cards{grid-template-columns:minmax(0,1fr)}}
  .llp-vehstage__inner{position:relative;z-index:1}
  .llp-vehstage__nav{display:flex;align-items:center;gap:12px}
  .llp-vehstage__cards{flex:1}
  .llp-vehstage__arrow{flex:0 0 auto;width:42px;height:42px;border-radius:50%;cursor:pointer;
    background:rgba(255,255,255,.05);border:1px solid rgba(204,169,103,.35);color:#f3f1ec;
    font-size:22px;line-height:1;transition:background .2s,border-color .2s}
  .llp-vehstage__arrow:hover{background:rgba(204,169,103,.2);border-color:var(--llp-gold,#cca967)}
  .llp-vehcard{cursor:pointer;transition:transform .3s ease,border-color .3s ease,background .3s ease}
  .llp-vehcard.is-active{border-color:rgba(204,169,103,.65);background:rgba(204,169,103,.10);transform:translateY(-4px)}
  .llp-vehcard:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:3px}
  /* the old rule here was `@media(max-width:860px){.llp-vehstage__arrow{display:none}}`
     - the arrows existed and worked, they were simply hidden on the one device that
     had no other way to move the rail. They come back below, on their own row. */
  @media (prefers-reduced-motion:reduce){.llp-vehstage__bg img{transition:opacity .01s}}

/* ── */

/* Comparison toggle - Juan, Loom 2026-08-20: an engagement point, not a static table.
     Loom 2026-08-23: the four scenarios move out of stacked bars into a 2x2 grid on the
     left with one of them shown big on the right, taking turns. The top On your own /
     With RockPoint switch stays. */
  .llp-cmp{margin-top:28px;max-width:820px}
  .llp-cmp__switch{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:0;
    background:rgba(17,17,17,.06);border-radius:100vmax;padding:5px;margin-bottom:26px}
  .llp-cmp__tab{position:relative;z-index:1;background:none;border:0;cursor:pointer;font:inherit;
    font-weight:700;letter-spacing:.2px;padding:13px 18px;border-radius:100vmax;color:#4a4a4a;
    transition:color .28s ease}
  .llp-cmp__tab.is-on{color:#111}
  .llp-cmp__thumb{position:absolute;top:5px;left:5px;width:calc(50% - 5px);height:calc(100% - 10px);
    border-radius:100vmax;background:#fff;box-shadow:0 3px 14px rgba(0,0,0,.14);
    transition:transform .32s cubic-bezier(.4,0,.2,1),background .32s ease}
  .llp-cmp[data-side="with"] .llp-cmp__thumb{transform:translateX(100%);background:var(--llp-gold,#cca967)}
  .llp-cmp__ico{flex:0 0 26px;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
    font-size:15px;font-weight:700;margin-top:1px}
  .llp-cmp__ico--x{background:rgba(190,40,40,.12);color:#a32020}
  .llp-cmp__ico--v{background:rgba(204,169,103,.22);color:#8a6b2f}

  /* --- the four scenarios ------------------------------------------------
     Baseline (no JS) is a plain stack: all eight cards and all eight detail
     panels are in the document and readable. Every rule that HIDES anything
     sits under .is-live, a class only the script adds, so a script that never
     runs can no longer make real copy disappear. */
  .llp-cmp__stage{margin-top:2px}
  .llp-cmp__grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-content:start}
  .llp-cmp__card{display:flex;flex-direction:column;padding:0;margin:0;text-align:left;font:inherit;
    color:inherit;cursor:pointer;background:#fff;border:1px solid rgba(17,17,17,.11);
    border-radius:14px;overflow:hidden;
    transition:border-color .25s ease,box-shadow .25s ease,transform .25s ease}
  .llp-cmp__cardimg{display:block;position:relative;aspect-ratio:16/9;background:#e7e4dd;overflow:hidden}
  .llp-cmp__cardimg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    opacity:.85;transition:opacity .25s ease}
  .llp-cmp__cardt{display:block;flex:1 1 auto;padding:13px 15px 15px;font-size:14px;line-height:1.42;
    font-weight:600;color:#3a3a3d}
  .llp-cmp__cardt .llp-cmp__ico{display:inline-grid;width:21px;height:21px;font-size:12px;
    vertical-align:-5px;margin:0 8px 0 0}
  .llp-cmp__card:hover{border-color:rgba(204,169,103,.75);transform:translateY(-2px);
    box-shadow:0 10px 24px rgba(0,0,0,.1)}
  .llp-cmp__card:hover .llp-cmp__cardimg img,
  .llp-cmp__card.is-active .llp-cmp__cardimg img{opacity:1}
  .llp-cmp__card.is-active{border-color:var(--llp-gold,#cca967);
    box-shadow:0 0 0 2px rgba(204,169,103,.4),0 12px 26px rgba(0,0,0,.11)}
  .llp-cmp__card.is-active .llp-cmp__cardt{color:#141416}
  .llp-cmp__card:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:3px}

  .llp-cmp__feature{position:relative}
  .llp-cmp__feat{background:#fff;border:1px solid rgba(17,17,17,.11);border-radius:16px;
    overflow:hidden;margin:0 0 16px}
  .llp-cmp__featimg{position:relative;aspect-ratio:16/9;background:#e7e4dd;overflow:hidden}
  .llp-cmp__featimg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  .llp-cmp__featbody{padding:20px 24px 24px}
  .llp-cmp__featmeta{display:flex;align-items:baseline;justify-content:space-between;gap:14px}
  .llp-cmp__featk{color:#8a6b2f;font-size:12px;font-weight:700;letter-spacing:.16em;text-transform:uppercase}
  .llp-cmp__featn{color:#9a9a9a;font-size:12px;font-weight:700;letter-spacing:.1em;flex:none}
  .llp-cmp__feath{margin:10px 0 11px;font-size:clamp(19px,1.7vw,25px);line-height:1.2;
    font-weight:800;color:#141416}
  .llp-cmp__feat p{margin:0;font-size:16px;line-height:1.65;color:#4b4b4b}
  .llp-cmp__prog{display:none}

  /* --- live layout: only applied once the script has run ---------------- */
  .llp-cmp__stage.is-live{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);
    gap:20px;align-items:start}
  .llp-cmp__stage.is-live .llp-cmp__feat{display:none;margin:0}
  .llp-cmp__stage.is-live .llp-cmp__feat.is-on{display:block;animation:cmpFeatIn .42s ease}
  .llp-cmp[data-side="alone"] .llp-cmp__stage.is-live [data-cmp-set="with"]{display:none}
  .llp-cmp[data-side="with"] .llp-cmp__stage.is-live [data-cmp-set="alone"]{display:none}
  .llp-cmp__stage.is-live .llp-cmp__prog{display:block;position:absolute;top:0;left:0;right:0;height:3px;
    z-index:3;background:var(--llp-gold,#cca967);border-radius:0 3px 3px 0;
    transform:scaleX(0);transform-origin:left center;pointer-events:none}
  @keyframes cmpFeatIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

  @media (max-width:900px){
    .llp-cmp__stage.is-live{grid-template-columns:1fr;gap:16px}
    .llp-cmp__stage.is-live .llp-cmp__feature{order:-1}
    .llp-cmp__featbody{padding:18px 18px 20px}
    .llp-cmp__cardt{font-size:13px;padding:11px 12px 13px}
    .llp-cmp__feat p{font-size:15.5px}
  }
  /* No auto-rotation for anyone who asked for less motion: the grid steps aside
     and all four scenarios of the active side are simply shown, in full. */
  @media (prefers-reduced-motion:reduce){
    .llp-cmp__thumb,.llp-cmp__card,.llp-cmp__cardimg img,.llp-cmp__feat{transition:none;animation:none}
    .llp-cmp__stage.is-live{grid-template-columns:1fr}
    .llp-cmp__stage.is-live .llp-cmp__grid{display:none}
    .llp-cmp__stage.is-live .llp-cmp__feat{display:block;margin:0 0 18px}
    .llp-cmp__stage.is-live .llp-cmp__prog{display:none}
  }

/* ── */

/* Juan, Loom 2026-08-20: the FAQ was a wall. Show three, reveal the rest on request. */
      .llp-accordion[data-faq-collapse="1"] > details:nth-of-type(n+4){display:none}
      .llp-faq-more-wrap{text-align:center;margin-top:28px}
      .llp-faq-more{background:none;border:1px solid var(--llp-gold,#cca967);color:inherit;
        font:inherit;font-weight:600;letter-spacing:.3px;padding:13px 30px;border-radius:100vmax;
        cursor:pointer;transition:background .2s,color .2s}
      .llp-faq-more:hover{background:var(--llp-gold,#cca967);color:#111}
      .llp-faq-more:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:3px}

/* ── */

/* Glossary tooltips - Juan, Loom 2026-08-20: "I should be able to hover over it
     and there should be a tooltip that explains what the agency decision is.
     That's how we provide value." */
  .llp-gloss{position:relative;cursor:help}
  .llp-gloss__t{border-bottom:1px dotted currentColor;text-underline-offset:3px}
  .llp-gloss:hover .llp-gloss__t,.llp-gloss:focus-visible .llp-gloss__t{color:var(--llp-gold-hover,#b8935a)}
  .llp-gloss:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:2px;border-radius:3px}
  .llp-gloss-pop{position:absolute;z-index:9999;max-width:340px;padding:14px 16px;border-radius:12px;
    background:#0e1118;color:#f2efe8;border:1px solid rgba(204,169,103,.4);
    box-shadow:0 18px 44px rgba(0,0,0,.45);font-size:14px;line-height:1.55;pointer-events:auto}
  .llp-gloss-pop strong{display:block;margin-bottom:5px;color:var(--llp-gold,#cca967);
    font-size:12px;letter-spacing:.7px;text-transform:uppercase}
  .llp-gloss-pop__more{display:inline-block;margin-top:9px;font-size:12.5px;color:var(--llp-gold,#cca967)}

/* ── */

/* Section imagery - Juan, Loom 2026-08-20. Each one earns its place: the Austin
     agency, the "you can do this from your couch in Dallas" reassurance, and the
     paperwork behind a repurchase. */
  .llp-secfig{margin:34px 0 0;border-radius:16px;overflow:hidden;position:relative;
    border:1px solid rgba(204,169,103,.22)}
  .llp-secfig img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:16/7}
  .llp-secfig figcaption{position:absolute;left:0;right:0;bottom:0;padding:26px 22px 14px;
    font-size:13.5px;color:#f3f1ec;
    background:linear-gradient(180deg,transparent,rgba(6,8,14,.88))}
  .llp-homecard{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:clamp(20px,3vw,40px);
    align-items:center;margin-top:38px;padding:0;border-radius:18px;overflow:hidden;
    background:rgba(204,169,103,.07);border:1px solid rgba(204,169,103,.22)}
  .llp-homecard__media img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:4/3}
  .llp-homecard__copy{padding:clamp(20px,2.4vw,34px) clamp(20px,2.4vw,34px) clamp(20px,2.4vw,34px) 0}
  .llp-homecard__copy h3{margin:0 0 10px}
  .llp-homecard__copy p{margin:0 0 12px;line-height:1.68}
  @media(max-width:820px){
    .llp-homecard{grid-template-columns:minmax(0,1fr)}
    .llp-homecard__copy{padding:0 22px 24px}
  }

/* ── */

/* One mark per process step - Juan, Loom 2026-08-20: "there should be an image
     that goes along with each one", DIY feel. Line art rather than photographs so
     the seven read as one set and cost the page nothing in weight. */
  .llp-step__num{display:flex;flex-direction:column;align-items:flex-start;gap:14px}
  /* The step grid's first track is 80px, which clipped a 104px thumbnail off the
     left edge. Widen the track to fit the picture instead of overflowing it. */
  .llp-step{grid-template-columns:118px 1fr}
  .llp-step__pic{display:block;width:112px;height:84px;object-fit:cover;border-radius:10px;
    border:1px solid rgba(204,169,103,.28);box-shadow:0 8px 22px rgba(0,0,0,.35)}
  @media(max-width:700px){
    .llp-step{grid-template-columns:84px 1fr}
    .llp-step__pic{width:78px;height:58px}
  }

/* ── */

/* Loom 2, 2026-08-22: the Texas map belongs here beside the short answer, with the
     Google Business map and our reviews underneath it, and a light touch of Americana
     behind the section - "very lightly and tastefully, so it doesn't disrupt the
     current aesthetic". */
  .llp-cream:has(.llp-2col__side){position:relative;isolation:isolate}
  /* Juan: "I can barely see the flag... it looks like blotches". The blotching WAS
     mix-blend-mode:multiply, which drags the gold to olive and the charcoal to mud.
     The new art is authored on the exact section cream, so at normal blend its own
     ground is invisible and no rectangle edge shows. Mask keeps it off the copy. */
  .llp-cream:has(.llp-2col__side){overflow:hidden}
  .llp-cream:has(.llp-2col__side)::before{content:"";position:absolute;inset:0;z-index:-1;
    /* centred, not right: with cover the state sits left of the art's centre, so
       anchoring right pushed Texas itself behind the copy scrim and only stripes
       showed. Centre puts the state in the open span beside the copy column. */
    /* Speed 2026-09-06: this used to hardcode the Texas artwork on a selector that
       matches on EVERY city page, so a non-Texas sibling would have painted Texas.
       The art is now a per-state custom property set on the body (body class comes
       from rpl-geo-page-config.php). A state with no artwork resolves to `none` and
       the section simply carries no art -- never another state's map. */
    background-image:var(--rpl-geo-art,none);
    background-repeat:no-repeat;background-position:80% 45%;background-size:228% auto;
    opacity:.58;pointer-events:none}
  /* One line per state that has map artwork. Add a state here, not above. */
  body.rpl-geo-state--tx{--rpl-geo-art:url('/wp-content/uploads/geo-vehicles/txart_ink.webp')}
  /* Georgia, added 2026-09-07. Outline traced from a real Georgia boundary polygon so the
     state shape is geographically correct, and deliberately carries NO location pin: the
     Texas art marks the Dallas office and RockPoint has no Georgia premises. */
  body.rpl-geo-state--ga{--rpl-geo-art:url('/wp-content/uploads/geo-vehicles/gaart_ink.webp')}
  /* Masking the art off the copy column hid the state itself, because with cover
     the state sits left of centre. So the art stays bold and spans the section,
     and the copy column gets its own cream field instead. Legibility is solved
     locally rather than by weakening the artwork Juan asked to be bolder. */
  .llp-cream:has(.llp-2col__side) .llp-2col > div:first-child{position:relative;isolation:isolate}
  .llp-cream:has(.llp-2col__side) .llp-2col > div:first-child::before{content:"";position:absolute;
    z-index:-1;inset:-28px -60px -28px -40px;pointer-events:none;
    background:linear-gradient(90deg,rgba(243,241,236,.94) 0%,rgba(243,241,236,.90) 55%,rgba(243,241,236,.66) 82%,rgba(243,241,236,0) 100%)}
  @media(max-width:860px){
    /* One column on a phone makes this section very tall, so the state is anchored
       to the bottom edge rather than to a height-dependent percentage. */
    .llp-cream:has(.llp-2col__side)::before{opacity:.34;background-size:300% auto;
      background-position:81% 100%}
    /* one column on a phone, so the scrim would sit over the whole thing */
    .llp-cream:has(.llp-2col__side) .llp-2col > div:first-child::before{
      background:linear-gradient(180deg,rgba(243,241,236,.95) 0%,rgba(243,241,236,.92) 78%,rgba(243,241,236,0) 100%);inset:-20px -20px}
  }
  /* Rock texture so the black sections are not flat black. The tile's mean colour
     IS #141416, so it cannot shift the section tone. */
  .llp-dark,.llp-dark3{position:relative;isolation:isolate}
  .llp-dark::before,.llp-dark3::before{content:"";position:absolute;inset:0;z-index:-1;
    pointer-events:none;background:#141416 url('/wp-content/uploads/geo-vehicles/rock_fine.webp') repeat;
    background-size:440px 440px}
  /* Courthouse behind the Filing From Dallas section, black kept as an overlay.
     Photo on the section's own ::before with inset:0 and a vertical mask, so it
     dissolves into the neighbouring sections instead of ending on a hard edge. */
  .llp-dark2{position:relative;isolation:isolate;overflow:hidden}
  .llp-dark2::before{content:"";position:absolute;inset:0;z-index:-2;pointer-events:none;
    background:url('/wp-content/uploads/geo-vehicles/court_classical.webp') no-repeat center bottom / cover;
    -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 89%,transparent 100%);
            mask-image:linear-gradient(180deg,transparent 0,#000 7%,#000 89%,transparent 100%)}
  .llp-dark2::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
    background:
      linear-gradient(180deg,rgba(16,16,18,.74) 0%,rgba(16,16,18,.80) 55%,rgba(16,16,18,.94) 100%),
      linear-gradient(90deg,rgba(16,16,18,.55) 0%,rgba(16,16,18,0) 62%)}
  .llp-2col__side{display:flex;flex-direction:column;gap:18px}
  /* No panel, no border, no dark card. The map's own field is the cream, and
     multiply blending drops whatever is left so it bleeds into the section. */
  .llp-txmap{margin:0 0 -8px;background:none;border:0}
  .llp-txmap img{display:block;width:100%;height:auto;mix-blend-mode:multiply;
    -webkit-mask-image:radial-gradient(ellipse 74% 72% at 52% 50%, #000 58%, transparent 92%);
    mask-image:radial-gradient(ellipse 74% 72% at 52% 50%, #000 58%, transparent 92%)}
  .llp-txmap figcaption{padding:2px 2px 0;font-size:12.5px;color:#6a6a6a;
    letter-spacing:.2px;text-align:center}
  .llp-gbp{border-radius:14px;overflow:hidden;border:1px solid rgba(17,17,17,.12);background:#fff}
  .llp-gbp iframe{display:block;width:100%;height:200px;border:0}
  .llp-gbp__meta{padding:13px 15px;display:flex;flex-direction:column;gap:3px}
  .llp-gbp__meta strong{font-size:14.5px}
  .llp-gbp__addr{font-size:12.5px;color:#5b5b5b;line-height:1.45}
  .llp-gbp__rating{font-size:13px;color:#3c3c3c;margin-top:4px}
  .llp-gbp__rating .llp-gbp__stars{color:#c9a227;letter-spacing:1px}
  @media(max-width:860px){.llp-gbp iframe{height:170px}}

/* ── */

/* Loom 2: the test buttons get their own column on the right, not tucked under
     the test name. "Last column, it should add an additional column, so we have
     four columns." */
  /* The added header cell must wear the same dark band as the other three. */
  .llp-elig-act{white-space:nowrap;text-align:right;vertical-align:middle}
  thead .llp-elig-act{background:var(--llp-dark,#0a0d16);color:#f3f1ec}
  .llp-elig-act .llp-test-btn{margin-top:0}
  @media(max-width:820px){.llp-elig-act{text-align:left}}

/* ── */

.llp-byline{padding:26px 0}
  .llp-byline .llp-review{margin:0;font-size:13.5px;line-height:1.6;color:#4a4a4a}

/* ── */

/* Loom (older): "this right here... looks small and weak. We need a bolder call to
     action." And the comparison section wants "one representative image of what it
     would look like without a Lemon Law attorney, and one with RockPoint". */
  .llp-bigcta{margin-top:56px;padding:44px 40px;border-radius:20px;text-align:center;
    background:linear-gradient(135deg,#1b1b1f 0%,#0d0d0f 100%);
    border:1px solid rgba(204,169,103,.34)}
  .llp-bigcta p{color:#fff;font-size:clamp(19px,2.2vw,26px);line-height:1.45;margin:0 0 24px;
    font-family:var(--llp-font-heading,inherit);font-weight:700}
  .llp-btn--big{font-size:clamp(16px,1.6vw,19px);padding:20px 44px}

  .llp-cmp{max-width:none}
  .llp-cmp__figure{position:relative;margin:0 0 26px;border-radius:16px;overflow:hidden;
    aspect-ratio:16/7;background:#0d1018}
  .llp-cmp__figure img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
    opacity:0;transition:opacity .45s ease}
  .llp-cmp__figure img.is-on{opacity:1}
  .llp-cmp__panel li{font-size:clamp(17px,1.5vw,19px)}
  .llp-cmp__q{padding:18px 20px}
  .llp-cmp__tab{font-size:clamp(15px,1.4vw,17px)}
  /* --- explainer text laid over each comparison image (Juan, 23 Aug) --- */
  .llp-cmpov{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .45s ease;z-index:2}
  .llp-cmpov.is-on{opacity:1}
  .llp-cmpov::before{content:"";position:absolute;inset:0;z-index:0}
  /* the subject sits centre-right in the "alone" shot, so the scrim weights left */
  .llp-cmpov--alone::before{background:linear-gradient(100deg,rgba(8,10,16,.88) 0%,rgba(8,10,16,.66) 28%,rgba(8,10,16,.18) 52%,rgba(8,10,16,0) 66%)}
  /* the "with" shot is emptiest along the lower-left table */
  .llp-cmpov--with::before{background:linear-gradient(22deg,rgba(8,10,16,.9) 0%,rgba(8,10,16,.58) 36%,rgba(8,10,16,.1) 62%,rgba(8,10,16,0) 74%)}
  .llp-cmpov__box{position:absolute;left:5%;max-width:38%;z-index:1}
  .llp-cmpov--alone .llp-cmpov__box{top:50%;transform:translateY(-50%)}
  .llp-cmpov--with .llp-cmpov__box{bottom:9%}
  .llp-cmpov__k{display:block;color:var(--llp-gold,#cca967);font-size:clamp(11px,.85vw,13px);
    font-weight:700;letter-spacing:.17em;text-transform:uppercase}
  .llp-cmpov__h{margin:10px 0 10px;color:#fff;font-size:clamp(19px,2.1vw,31px);font-weight:800;line-height:1.14}
  .llp-cmpov__p{margin:0;color:rgba(255,255,255,.84);font-size:clamp(13px,1.1vw,16px);line-height:1.5;max-width:34ch}
  .llp-cmpov__pin{position:absolute;z-index:1;display:inline-flex;align-items:center;gap:9px;
    color:#fff;font-size:13px;font-weight:600;line-height:1;white-space:nowrap;
    background:rgba(10,12,18,.58);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
    border:1px solid rgba(255,255,255,.2);padding:8px 13px;border-radius:999px}
  .llp-cmpov__pin::before{content:"";flex:0 0 7px;width:7px;height:7px;border-radius:50%;background:var(--llp-gold,#cca967)}
  /* pins would crowd a small photo; the box carries the message there */
  @media (max-width:900px){
    .llp-cmpov__pin{display:none}
    .llp-cmpov__box{max-width:62%}
    .llp-cmpov--alone::before{background:linear-gradient(100deg,rgba(8,10,16,.92) 0%,rgba(8,10,16,.74) 42%,rgba(8,10,16,.2) 70%,rgba(8,10,16,0) 84%)}
  }
  /* a 16/7 letterbox is too short to hold copy on a phone */
  @media (max-width:700px){
    .llp-cmp__figure{aspect-ratio:4/3}
    .llp-cmpov__box{max-width:84%;left:6%}
    .llp-cmpov--alone .llp-cmpov__box{top:auto;bottom:8%;transform:none}
  }
  @media (prefers-reduced-motion:reduce){.llp-cmpov{transition:none}}
  @media (prefers-reduced-motion:reduce){.llp-cmp__figure img{transition:none}}

/* ── */

/* Loom 2026-08-23, Juan: "should be on a gentle, slow slide or glide ... and
     then boom, it should rotate. The next slide should be the first card, and it
     should just keep infinitely rotating." A marquee, not a paged carousel.
     Base state is a plain scrollable row; the animation only switches on once JS
     has cloned the run, so nothing is unreachable if the script never runs. */
  .llp-why{position:relative;margin-top:44px}
  .llp-why__viewport{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
    scrollbar-width:none}
  .llp-why__viewport::-webkit-scrollbar{display:none}
  .llp-why__track{display:flex;gap:22px;width:max-content}
  .llp-why__card{flex:0 0 clamp(255px,25vw,330px);box-sizing:border-box}
  .llp-why.is-glide .llp-why__viewport{overflow:hidden;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%)}
  .llp-why.is-glide .llp-why__track{will-change:transform;
    animation:llpWhyGlide var(--why-dur,66s) linear infinite}
  .llp-why.is-glide:hover .llp-why__track,
  .llp-why.is-glide:focus-within .llp-why__track{animation-play-state:paused}
  @keyframes llpWhyGlide{
    from{transform:translate3d(0,0,0)}
    to{transform:translate3d(calc(var(--why-run,0px) * -1),0,0)}
  }
  @media (prefers-reduced-motion:reduce){
    /* no motion, and every card still reachable by scrolling */
    .llp-why.is-glide .llp-why__viewport{overflow-x:auto;
      -webkit-mask-image:none;mask-image:none}
    .llp-why.is-glide .llp-why__track{animation:none;transform:none}
    .llp-why.is-glide .llp-why__clone{display:none}
  }

/* ── */

/* ── Scroll motion ──────────────────────────────────────────────────────────
     Gold accents that travel as you scroll and pass beneath the lighter sections,
     and a drifting emblem. All of it sits behind the content and none of it moves
     when the visitor has asked for reduced motion. */
  [data-parallax]{position:relative;overflow:hidden;isolation:isolate}
  .llp-splash{position:absolute;z-index:-1;pointer-events:none;display:block;
    background:radial-gradient(closest-side, rgba(204,169,103,.42), rgba(204,169,103,0) 72%);
    will-change:transform}
  .llp-splash--rise{left:-8%;bottom:-38%;width:66vw;height:66vw;max-width:900px;max-height:900px;
    transform:translate3d(0, calc(var(--sy,0) * -1px), 0)}
  .llp-splash--diagonal{left:-14%;top:-18%;width:58vw;height:58vw;max-width:760px;max-height:760px;
    background:radial-gradient(closest-side, rgba(204,169,103,.34), rgba(204,169,103,0) 70%);
    transform:translate3d(calc(var(--sy,0) * 0.9px), calc(var(--sy,0) * 0.55px), 0)}
  .llp-emblem{position:absolute;right:-90px;top:0;width:320px;height:320px;z-index:-1;opacity:.05;
    pointer-events:none;background:url('/wp-content/uploads/2025/12/Rockpoint-Law-Logo-white.webp')
    no-repeat center / contain;
    transform:translate3d(0, calc(var(--sy,0) * -0.35px), 0) rotate(calc(var(--sy,0) * 0.02deg))}
  @media (prefers-reduced-motion:reduce){
    .llp-splash,.llp-emblem{transform:none !important}
  }
  @media(max-width:700px){.llp-emblem{display:none}}

/* ── */

/* ── The process, read sideways ────────────────────────────────────────────
     Juan asked for this specifically: the number oversized, and as you scroll the
     steps travel horizontally - one leaves to the left, the next arrives from the
     right - until the last one lets you go and the page carries on down. Below the
     tablet breakpoint, or with reduced motion, it is a plain vertical list again. */
    /* 72vh per step rather than 92 — the effect still reads and the page is
     about a thousand pixels shorter for it. */
  /* The process section is light now, so its type and framing have to invert. */
  .llp-cream .llp-hstep__copy h3{color:#141416}
  .llp-cream .llp-hstep__copy p{color:#4a4a4a}
  .llp-cream .llp-hstep__num{opacity:.85}
  .llp-cream .llp-hstep__pic{border-color:rgba(17,17,17,.12);box-shadow:0 14px 34px rgba(0,0,0,.16)}
  .llp-cream .llp-hscroll__bar{background:rgba(17,17,17,.12)}
  /* Persuasive close between the last step and the CTA. Matched to the section
     intro paragraph above the steps (same 76ch measure) so the copy column reads
     as one column top to bottom. .llp-bigcta already carries a 56px top margin,
     which supplies the separation from the button block. */
  .llp-steps-close{max-width:76ch;margin:clamp(18px,3vw,30px) 0 0}
  .llp-steps-close p{font-size:clamp(16px,1.5vw,19px);line-height:1.75;color:#4a4a4a;
    margin:0 0 15px}
  .llp-steps-close p:last-child{margin-bottom:0}

  /* Outcomes: pinned while the cards advance one at a time, so they are big
     enough to actually read. Same mechanic as the process section. */
  /* same pin-below-the-header fix as the process section - this block uses the
     identical mechanic, so its kicker and cards slid under the nav in exactly the
     same way */
  .llp-osc{position:relative;height:calc(var(--steps,5) * 62vh);margin-top:20px;
    --llp-pin-top:142px}
  /* Same lead-in gap fix as the process section. Tallest measured content here is
     the kicker plus a card, 338px, so the floor clears it comfortably. */
  .llp-osc__sticky{position:sticky;top:var(--llp-pin-top,142px);
    height:max(400px,min(62vh,calc(100vh - var(--llp-pin-top,142px))));overflow:hidden;
    display:flex;flex-direction:column;justify-content:center;justify-content:safe center}
  .llp-osc__kicker{display:block;padding:0 clamp(20px,5vw,70px);margin-bottom:clamp(16px,3vh,34px)}
  .llp-osc__track{display:flex;width:calc(var(--steps,5) * 100%);
    transform:translate3d(calc(var(--px,0) * -1%),0,0);will-change:transform}
  .llp-ocard{flex:0 0 calc(100% / var(--steps,5));display:grid;
    grid-template-columns:minmax(0,auto) minmax(0,1fr);gap:clamp(24px,4vw,60px);
    align-items:center;padding:0 clamp(20px,5vw,70px)}
  .llp-ocard__img{display:none}
  @media(min-width:1100px){
    .llp-ocard{grid-template-columns:minmax(0,auto) minmax(0,300px) minmax(0,1fr)}
    /* mix-blend-mode:multiply used to sit on this rule, but it never actually ran.
       .llp-osc__track carries a transform for the carousel, and a transform opens a
       new stacking context - so the image had no cream backdrop to blend with and
       painted its own near-white field straight over the section. Measured on the
       rendered page: the plate came back rgb(246,245,244) against a rgb(243,241,236)
       section, i.e. a pale rectangle exactly where the art was meant to dissolve.
       The multiply-onto-cream is now baked into the WebP files themselves, so what
       ships is deterministic instead of depending on a blend that a stacking context
       can silently switch off. The mask stays, to feather the last few pixels. */
    .llp-ocard__img{display:block;width:100%;height:auto;
      -webkit-mask-image:radial-gradient(ellipse 70% 70% at 50% 52%,#000 52%,transparent 100%);
      mask-image:radial-gradient(ellipse 70% 70% at 50% 52%,#000 52%,transparent 100%)}
  }
  .llp-ocard__n{font-family:var(--llp-font-heading,inherit);font-weight:800;line-height:.82;
    font-size:clamp(96px,16vw,230px);color:var(--llp-gold,#cca967);opacity:.85;letter-spacing:-.04em}
  .llp-ocard h3{font-size:clamp(26px,3vw,44px);margin:0 0 16px;color:#141416;line-height:1.12}
  .llp-ocard p{font-size:clamp(16px,1.5vw,21px);line-height:1.7;color:#4a4a4a;max-width:58ch;margin:0}
  .llp-osc__bar{position:absolute;left:clamp(20px,5vw,70px);right:clamp(20px,5vw,70px);
    bottom:8vh;height:2px;background:rgba(17,17,17,.12);border-radius:2px}
  .llp-osc__bar span{display:block;height:100%;width:0;border-radius:2px;
    background:var(--llp-gold,#cca967);transition:width .12s linear}
  /* Juan, 2026-08-25: "These also should be in horizontal step format." Same
     treatment as the process steps directly above - this block used to unwind the
     mechanic below 860 (height:auto, static sticky, block track, transform:none)
     so the outcomes fell into a plain vertical list of text with no imagery at all.
     The pin, the track and the same DWELL-0.55 park-travel-park curve now run here
     too, driven by --px instead of --hx.
     Everything is inside the query: the desktop pin offset, the 3-column card and
     the >=1100px media rule are untouched. */
  @media(max-width:860px){
    /* matched to the process steps so both pinned sections read the same under the
       thumb - about three fast flicks end to end. svh (with a vh fallback) so a
       collapsing URL bar cannot resize the spacer mid-travel. */
    .llp-osc{height:calc(var(--steps,5) * 58vh);
      height:calc(var(--steps,5) * 58svh);margin-top:8px}
    .llp-osc__sticky{top:var(--llp-pin-top,152px);
      height:calc(100vh - var(--llp-pin-top,152px) - 10px);
      height:calc(100svh - var(--llp-pin-top,152px) - 10px);
      padding-bottom:30px}
    .llp-osc__kicker{padding:0}
    /* one column, read top to bottom: gold number, heading, the one short line,
       then that outcome's own loop underneath. DOM order is num / video / copy,
       so the rows are assigned explicitly rather than by source order. */
    /* align-content:START, not center. The five loops do not share an aspect ratio,
       so their boxes are not the same height; centring each card's block would slide
       the number and heading up and down as the track travelled. Starting them all at
       the same y keeps the text rock-steady and lets only the artwork's bottom edge
       differ, which reads as natural. */
    .llp-ocard{grid-template-columns:minmax(0,1fr);
      grid-template-rows:auto auto auto;
      gap:11px;align-content:start;align-items:start;padding:0}
    .llp-ocard__n{grid-row:1;font-size:clamp(50px,14vw,64px);line-height:.84}
    .llp-ocard > div{grid-row:2;min-width:0}
    /* The copy here is far shorter than the process steps - card 02 is four words -
       so the visual gets the room that buys: ~38svh, roughly twice the height the
       step images got.
       object-fit:contain, NOT cover. These five loops do not share an aspect ratio
       (out1/3/4 are 640x640, out2/5 are 800x436), and cover would crop the square
       ones into the radial mask that is meant to dissolve their edges. contain
       keeps every loop whole and keeps all five cards the SAME height, so nothing
       jumps vertically as the track travels. The letterbox it leaves is invisible:
       the art is already multiplied onto cream and masked, so it floats on the
       section rather than sitting in a visible box. */
    /* The box must HUG the artwork, or the radial mask cannot do its job. A fixed
       height plus object-fit:contain looked right on the square loops and wrong on
       the wide ones (out2/out5, 800x436): the mask feathers the ELEMENT box, so with
       a 350x320 box around 350x190 of video the feather fell outside the picture
       entirely and card 05 showed a hard pale rectangle on the cream - the same
       failure the desktop comment above describes.
       Constraining the WIDTH and letting height follow the aspect makes the element
       box exactly the picture box for every clip, square or wide, so the mask
       dissolves the real edges in both cases.
       The cap is in svh because it is vertical room, not width, that limits us here:
       the square loops are as tall as they are wide. */
    .llp-ocard__img{display:block;grid-row:3;justify-self:center;
      width:min(100%,42svh);height:auto;
      -webkit-mask-image:radial-gradient(ellipse 70% 70% at 50% 52%,#000 52%,transparent 100%);
      mask-image:radial-gradient(ellipse 70% 70% at 50% 52%,#000 52%,transparent 100%)}
    .llp-ocard h3{font-size:clamp(22px,6vw,28px);margin:0 0 7px;line-height:1.15}
    .llp-ocard p{font-size:15.5px;line-height:1.6;max-width:none}
    /* the gold line survives, full width of the pinned box */
    .llp-osc__bar{left:0;right:0;bottom:10px}
  }
  /* Landscape phones and any short viewport: no room to pin, so it unwinds to the
     static stack exactly as it did before. transform:none makes a stale --px from
     before a rotation harmless. */
  @media(max-width:860px) and (max-height:520px){
    .llp-osc{height:auto;margin-top:8px}
    .llp-osc__sticky{position:static;height:auto;display:block;padding-bottom:0}
    .llp-osc__track{display:block;width:100%;transform:none}
    .llp-ocard{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;padding:0 0 34px}
    .llp-ocard__n{font-size:64px}
    .llp-ocard__img{display:none}
    .llp-osc__bar{display:none}
  }
  @media(prefers-reduced-motion:reduce){
    .llp-osc{height:auto}
    .llp-osc__sticky{position:static;height:auto;display:block}
    .llp-osc__track{display:block;width:100%;transform:none}
    .llp-ocard{grid-template-columns:minmax(0,1fr);padding:0 0 34px}
  }
  /* Repair-history upload and the appointment request. Forms are Contact Form 7,
     so submissions are stored in Flamingo and emailed, not thrown away. */
  .llp-upload{margin-top:18px;padding:24px 26px;border-radius:16px;
    background:linear-gradient(135deg,#1b1b1f 0%,#0d0d0f 100%);
    border:1px solid rgba(204,169,103,.26)}
  .llp-upload h3{margin:0 0 6px;font-size:clamp(19px,1.8vw,23px);color:#fff}
  .llp-upload p{margin:0 0 14px;color:rgba(243,241,236,.82);font-size:14.5px}
  .llp-upload .rpl-cf7 label{color:rgba(243,241,236,.9)}
  .llp-upload .rpl-cf7 input[type=file]{color:rgba(243,241,236,.9)}
  /* Loom 2026-08-23, Juan: the appointment box towered over the CTA beside it.
     Both columns now share a height, and the form runs two fields to a row with
     the optional note folded into a reveal. CF7 wraps the whole field list in a
     single wpautop <p>, so the grid goes on that <p> and the <br> separators are
     dropped; nothing is hidden, so it still works if the reveal script fails. */
  .llp-booksplit{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:stretch;margin-top:36px}
  .llp-booksplit > .llp-cta-band{display:flex;flex-direction:column;justify-content:center}
  .llp-book{padding:20px 22px;border-radius:16px;background:rgba(204,169,103,.08);
    border:1px solid rgba(204,169,103,.26)}
  .llp-book h3{margin:0 0 4px;font-size:clamp(17px,1.5vw,21px);color:#fff}
  .llp-book p{margin:0 0 12px;color:rgba(243,241,236,.82);font-size:13.5px;line-height:1.45}
  .llp-book .rpl-cf7 > p{display:grid;grid-template-columns:1fr 1fr;gap:9px 12px;
    align-items:start;margin:0}
  .llp-book .rpl-cf7 > p > br{display:none}
  .llp-book .rpl-cf7 label{margin:0;font-size:11.5px;letter-spacing:.01em}
  /* CF7 renders the meeting-type radios as nested labels, so the row ordering is
     pinned to direct children of the wpautop paragraph only. */
  .llp-book .rpl-cf7 > p > label:nth-of-type(1){order:1}
  .llp-book .rpl-cf7 > p > label:nth-of-type(2){order:2}
  .llp-book .rpl-cf7 > p > label:nth-of-type(3){order:3}
  .llp-book .rpl-cf7 > p > label:nth-of-type(4){order:6}
  .llp-book .rpl-cf7 > p > label:nth-of-type(5){order:4}
  .llp-book .rpl-cf7 > p > label:nth-of-type(6){order:5}
  .llp-book .rpl-cf7 > p > label:nth-of-type(7){order:7}
  .llp-book .rpl-cf7 input[type=text],.llp-book .rpl-cf7 input[type=email],
  .llp-book .rpl-cf7 input[type=tel],.llp-book .rpl-cf7 input[type=date],
  .llp-book .rpl-cf7 select,.llp-book .rpl-cf7 textarea{margin-top:4px;padding:7px 10px;
    font-size:13.5px;border-radius:8px}
  .llp-book .rpl-cf7 textarea{min-height:0;height:60px;resize:vertical}
  .llp-book .rpl-cf7 .wpcf7-radio{gap:6px 12px;margin-top:4px;font-size:12.5px}
  .llp-book .rpl-cf7 > p > label:has(textarea),
  .llp-book .rpl-cf7 > p > .llp-book__more,
  .llp-book .rpl-cf7 > p > input[type=submit],
  .llp-book .rpl-cf7 > p > .wpcf7-spinner{grid-column:1 / -1}
  .llp-book .rpl-cf7 > p > .llp-book__more{order:7}
  .llp-book .rpl-cf7 > p > input[type=submit]{order:8}
  .llp-book .rpl-cf7 > p > .wpcf7-spinner{order:9;justify-self:center}
  .llp-book .rpl-cf7 .submit_btn{margin-top:2px;padding:10px 20px;font-size:14px;width:100%}
  .llp-book__more{margin:0}
  .llp-book__more > summary{cursor:pointer;font-size:12px;font-weight:700;list-style:none;
    color:var(--llp-gold,#cca967);padding:4px 0}
  .llp-book__more > summary::-webkit-details-marker{display:none}
  .llp-book__more > summary::before{content:"+ ";font-weight:800}
  /* SPEED 2026-09-11: "\2212 " - CSS consumes the space that TERMINATES a hex escape,
     so the open state rendered the minus hard against the label ("-Which circuit...")
     while the closed "+ " was fine. \20 is an explicit space that survives. */
  .llp-book__more[open] > summary::before{content:"\2212\20"}
  .llp-book__more > label{display:block;margin-top:2px}
  @media(max-width:620px){.llp-book .rpl-cf7 > p{grid-template-columns:1fr}}
  .rpl-cf7 label{display:block;margin-bottom:12px;font-size:14px;font-weight:600}
  .rpl-cf7 input[type=text],.rpl-cf7 input[type=email],.rpl-cf7 input[type=tel],
  .rpl-cf7 input[type=date],.rpl-cf7 select,.rpl-cf7 textarea{display:block;width:100%;
    margin-top:6px;padding:11px 13px;border-radius:9px;border:1px solid rgba(17,17,17,.18);
    background:#fff;color:#141416;font:inherit;font-weight:400}
  .rpl-cf7 textarea{min-height:88px;resize:vertical}
  .rpl-cf7 input[type=file]{display:block;width:100%;margin-top:6px;font-size:14px}
  .rpl-cf7 .wpcf7-radio{display:flex;flex-wrap:wrap;gap:14px;margin-top:6px;font-weight:400}
  .rpl-cf7 .submit_btn{margin-top:6px;background:var(--llp-gold,#cca967);color:#141416;border:0;
    font:inherit;font-weight:700;padding:12px 22px;border-radius:100vmax;cursor:pointer}
  .rpl-cf7 .submit_btn:hover{filter:brightness(1.06)}
  .llp-book .rpl-cf7 label{color:rgba(243,241,236,.9)}
  @media(max-width:900px){.llp-booksplit{grid-template-columns:1fr}}
  /* Juan, Loom 2026-08-23: "On the ground in Dallas... this would have to show
     again our offices and our Google Business again." Same components as the
     brief section above, restyled for a dark background. The address here is the
     one already published elsewhere on this page - no new claim is made. */
  .llp-ground-gbp{margin-top:30px}
  /* Juan: the Google map, the testimonials and the consultation CTA belong in the
     RIGHT column underneath the Dallas photo, not stacked under the body copy on the
     left. The photo moves to the top of that column, so the two columns now start
     level - hence align-items:start rather than the centring inherited from .llp-2col.
     Even columns because the right one now carries a map and review cards and needs
     the room; the copy still measures comfortably at that width. */
  .llp-2col--ground{grid-template-columns:1fr 1fr;align-items:start}
  .llp-ground-side{display:flex;flex-direction:column;min-width:0}
  .llp-ground-side .llp-ground-gbp{margin-top:26px}
  @media(max-width:880px){.llp-2col--ground{grid-template-columns:1fr}}
  .llp-gbp--dark{background:rgba(243,241,236,.06);border:1px solid rgba(243,241,236,.14);
    border-radius:14px;overflow:hidden}
  .llp-gbp--dark .llp-gbp__meta{padding:14px 16px}
  .llp-gbp--dark .llp-gbp__meta strong{color:#fff;display:block}
  .llp-gbp--dark .llp-gbp__addr{color:rgba(243,241,236,.78);display:block;font-size:14px;margin-top:2px}
  .llp-gbp--dark .llp-gbp__rating{color:var(--llp-gold,#cca967);display:block;font-size:14px;margin-top:6px}
  .llp-ground-gbp .rpl-rvw{background:rgba(243,241,236,.07);border-color:rgba(243,241,236,.14)}
  .llp-ground-gbp .rpl-rvw blockquote{color:rgba(243,241,236,.86)}
  .llp-ground-gbp .rpl-rvw figcaption{color:rgba(243,241,236,.6)}
  /* Juan, 2026-08-23: "the same little stone anonymous character running in the
     direction of the scroll... and stands still looking at you when you stop."
     He walks the progress line, faces the way you are travelling, and settles
     back into the idle loop the moment you stop. Decorative only, so aria-hidden.
     Later the same day: the two-still flipbook became two short clips. Each clip
     is the character (300x420) stacked on top of its own black/white matte
     (300x420), and a small WebGL shader recombines them into real alpha at draw
     time. That is deliberate - Safari refuses VP9-with-alpha and this box cannot
     build HEVC-with-alpha, so a packed matte is what keeps iOS working. Do not
     "improve" it into an alpha codec.
     Still no mix-blend-mode anywhere near this: the sticky wrapper and the
     translated track each open their own stacking context, so a blend mode never
     reaches the section behind it - it silently does nothing here. */
  .llp-runner{position:absolute;left:clamp(20px,5vw,70px);right:clamp(20px,5vw,70px);
    bottom:calc(var(--llp-bar-bottom,20px) + 2px);height:0;pointer-events:none;z-index:2}
  /* The still sprite is the floor of this feature: it is visible by DEFAULT and is
     only hidden once the compositor has actually painted a moving frame. Nothing
     here is hidden while waiting on JS, so a script or WebGL or autoplay failure
     leaves a sensible standing figure on the page rather than a hole. */
  .llp-runner__still,.llp-runner__gl{position:absolute;bottom:-3px;left:0;
    height:var(--llp-runner-h,200px);width:auto;aspect-ratio:300/420;
    transform-origin:bottom center;will-change:transform;
    filter:drop-shadow(0 6px 10px rgba(17,17,17,.16))}
  .llp-runner__gl{opacity:0;transition:opacity .25s ease}
  .llp-runner.is-live .llp-runner__gl{opacity:1}
  .llp-runner.is-live .llp-runner__still{opacity:0}
  /* the <video>s are texture sources only, never painted. Kept at 1px rather than
     display:none so the decoder keeps producing frames for texImage2D. */
  .llp-runner__src{position:absolute;bottom:0;left:0;width:1px;height:1px;
    opacity:0;pointer-events:none}
  @media(max-width:860px){.llp-runner{display:none}}
  @media(prefers-reduced-motion:reduce){
    /* no compositor, no crossfade, no playback - he simply stands there */
    .llp-runner__gl,.llp-runner__src{display:none}
    .llp-runner__still{opacity:1}
  }
  .llp-hscroll{position:relative;height:calc(var(--steps,5) * 72vh);
    /* Juan, 2026-08-24: "underneath the menu there needs to be some space where it
       locks into place and starts going horizontally ... otherwise the titles and
       the texts are getting covered by the menu as it scrolls horizontally".
       The pinned box used to park at top:0, i.e. UNDERNEATH the sticky header, so
       every step title slid beneath the nav as the track moved. It now locks below
       the header with a clear band between the two. The value is the measured header
       height plus that band and is re-measured by the script on every frame, so it
       follows the header at any width; the 142px here is only the pre-script
       fallback (114px header + 28px band). */
    --llp-pin-top:142px;
    /* reserved band under the cards that the gold line and the figure live in.
       Trimmed by the height the pin now gives up to the header, so the card area
       itself stays the size it was and no step gets clipped. */
    --llp-runner-lane:clamp(120px,calc(26vh - 40px),250px);
    --llp-bar-bottom:clamp(14px,2.4vh,26px);
    --llp-runner-h:clamp(120px,21vh,200px)}
  /* The pinned box used to be a full 100vh with the track centred inside it, which
     parked ~265px of dead cream between the intro copy and the first step on the way
     in - the gap Juan asked to close. Shrinking the pinned box (rather than dragging
     the track up with a negative margin) keeps the track centred, so the composition
     still balances once the section pins. The clamp floor sits above the tallest step
     measured across the sticky range (419px at 1400w, 400px at 1100w) so the track can
     never be clipped, and `safe center` makes the browser fall back to flex-start
     instead of cropping the top if a step ever does outgrow the box. */
  .llp-hscroll__sticky{position:sticky;top:var(--llp-pin-top,142px);
    /* fits the space left under the header; the 560px floor still wins on very short
       windows so the tallest step can never be clipped */
    height:max(560px,min(88vh,calc(100vh - var(--llp-pin-top,142px))));overflow:hidden;
    display:flex;flex-direction:column;justify-content:center;justify-content:safe center;
    padding-bottom:var(--llp-runner-lane)}
  .llp-hscroll__track{display:flex;width:calc(var(--steps,5) * 100%);
    transform:translate3d(calc(var(--hx,0) * -1%),0,0);will-change:transform}
  .llp-hstep{flex:0 0 calc(100% / var(--steps,5));display:grid;
    grid-template-columns:minmax(0,auto) minmax(0,1fr);gap:clamp(24px,4vw,60px);
    align-items:center;padding:0 clamp(20px,5vw,70px)}
  .llp-hstep__num{font-family:var(--llp-font-heading,inherit);font-weight:800;line-height:.82;
    font-size:clamp(96px,16vw,240px);color:var(--llp-gold,#cca967);opacity:.9;letter-spacing:-.04em}
  .llp-hstep__media{display:none}
  .llp-hstep__copy h3{font-size:clamp(24px,3vw,42px);color:#fff;margin:0 0 16px}
  .llp-hstep__copy p{font-size:clamp(16px,1.5vw,20px);line-height:1.7;
    color:rgba(243,241,236,.84);max-width:62ch;margin:0}
  .llp-hscroll__bar{position:absolute;left:clamp(20px,5vw,70px);right:clamp(20px,5vw,70px);
    bottom:var(--llp-bar-bottom);height:2px;background:rgba(204,169,103,.18);border-radius:2px}
  .llp-hscroll__bar span{display:block;height:100%;width:0;border-radius:2px;
    background:var(--llp-gold,#cca967);transition:width .12s linear}
  @media(min-width:1100px){
    .llp-hstep{grid-template-columns:minmax(0,auto) minmax(0,260px) minmax(0,1fr)}
    .llp-hstep__media{display:block}
    .llp-hstep__pic{display:block;width:100%;height:auto;border-radius:14px;
      border:1px solid rgba(204,169,103,.28);box-shadow:0 18px 40px rgba(0,0,0,.45)}
  }
  /* Juan, 2026-08-25: "This doesn't have my beautiful animation with the character
     horizontal movement" - on a phone. The block that used to live here unwound the
     whole mechanic below 860 (height:auto, static sticky, block track, transform:none),
     so the steps fell into a plain vertical list and nothing travelled.
     The pin, the track and the park-travel-park curve now run on mobile too. What does
     NOT come with them is the marble figure: Juan, same day, "Just the steps with the
     little image we did for each, not the character walking, that won't ship in mobile."
     So .llp-runner keeps its display:none below 860 and the runner script keeps its own
     width bail - four mp4s through a WebGL compositor is not a thing to hand a phone.
     With no figure down here the reserved lane under the cards is dead space at exactly
     the width where vertical space is scarcest, so it is zeroed and handed back to the
     step; only the gold line keeps a small band of its own.
     Nothing in this block may leak upwards: every declaration is inside the query, and
     the desktop pin offset, dwell curve and 3-column step layout are untouched. */
  @media(max-width:860px){
    /* shorter than the desktop 72vh/step so the section is ~2 flicks end to end
       rather than a corridor you have to work your way out of. svh (with a vh
       fallback) so a collapsing URL bar cannot resize the spacer mid-travel. */
    .llp-hscroll{height:calc(var(--steps,5) * 58vh);
      height:calc(var(--steps,5) * 58svh);
      --llp-runner-lane:0px;              /* no figure on mobile - reclaim the band */
      --llp-bar-bottom:9px}
    /* exactly the room left under the sticky header, less a hairline of breathing
       space. No 560px floor here: on a short phone that floor would push the box
       past the fold and crop a step. Short viewports unwind instead - see below. */
    .llp-hscroll__sticky{top:var(--llp-pin-top,152px);
      height:calc(100vh - var(--llp-pin-top,152px) - 10px);
      height:calc(100svh - var(--llp-pin-top,152px) - 10px);
      padding-bottom:26px}
    /* the container already supplies the page gutter, so the step adds none */
    /* Juan, 2026-08-25: "We should see the step and text and below that the nice
       character image representative of that step. For each step." One column,
       read top to bottom: numeral, heading, paragraph, then that step's own marble
       vignette closing the card. The DOM order is num / media / copy, so the rows
       are assigned explicitly rather than relying on source order. */
    .llp-hstep{grid-template-columns:minmax(0,1fr);
      grid-template-rows:auto auto auto;
      gap:11px;align-content:center;align-items:start;padding:0}
    .llp-hstep__num{grid-row:1;font-size:clamp(50px,14vw,64px);line-height:.86;margin:0}
    .llp-hstep__copy{grid-row:2;min-width:0}
    /* the image was OFF below 1100px - base .llp-hstep__media is display:none and
       only the >=1100 query switched it on, which is why a phone showed a wall of
       text and nothing else. It is switched back on here and sized for a narrow
       column: full bleed of the card, cropped to a strip so a tall vignette cannot
       eat the height budget. svh, so a collapsing URL bar cannot change the fit. */
    .llp-hstep__media{display:block;grid-row:3;min-width:0;min-height:0}
    .llp-hstep__pic{display:block;width:100%;aspect-ratio:16/9;
      max-height:clamp(132px,23svh,197px);object-fit:cover;object-position:center 40%;
      border-radius:12px;
      border:1px solid rgba(204,169,103,.28);box-shadow:0 12px 26px rgba(0,0,0,.4)}
    /* sized against the LONGEST step, not the shortest: 15px/1.6 keeps step 01 and
       step 05 (the two ~480-character paragraphs, both longer than step 04) inside
       the pinned box with the image still under them. Nothing scrolls inside the
       card - an inner scroller here would fight the page scroll. */
    .llp-hstep__copy h3{font-size:clamp(20px,5.4vw,25px);margin:0 0 9px;line-height:1.25}
    .llp-hstep__copy p{font-size:15.5px;line-height:1.62;max-width:none}
    /* the gold line survives; it is the only progress cue left once the figure
       is gone, so it runs the full width of the pinned box instead of inset */
    .llp-hscroll__bar{left:0;right:0}
  }
  /* Landscape phones and any short viewport: a pinned box needs vertical room it
     does not have here, so the mechanic unwinds to the plain vertical list it used
     to be at every mobile size. transform:none matters - it makes a stale --hx from
     before a rotation harmless. */
  @media(max-width:860px) and (max-height:520px){
    .llp-hscroll{height:auto}
    .llp-hscroll__sticky{position:static;height:auto;display:block;padding-bottom:0}
    .llp-hscroll__track{display:block;width:100%;transform:none}
    .llp-hstep{display:grid;grid-template-columns:minmax(0,1fr);gap:14px;
      padding:0 0 46px}
    .llp-hstep__num{font-size:72px}
    .llp-hstep__media{display:none}
    .llp-hscroll__bar{display:none}
  }
  @media (prefers-reduced-motion:reduce){
    .llp-hscroll{height:auto}
    /* the lane stays: he is still drawn standing on the line down here, so the
       band under the last card has to stay reserved or his head covers it */
    .llp-hscroll__sticky{position:static;height:auto;padding-bottom:var(--llp-runner-lane)}
    .llp-hscroll__track{display:block;width:100%;transform:none}
    .llp-hstep{padding-bottom:46px}
  }

/* ── */

/* "Can we do a little search box where people can start typing questions and then
     one of these will appear?" The FAQs all stay in the markup and in the FAQPage
     schema either way - filtering only hides them visually. */
  .llp-faq-search{position:relative;margin:0 0 22px;max-width:560px}
  .llp-faq-search input{width:100%;padding:15px 18px;border-radius:100vmax;font:inherit;font-size:16px;
    border:1px solid rgba(17,17,17,.16);background:#fff;color:inherit}
  .llp-faq-search input:focus{outline:2px solid var(--llp-gold,#cca967);outline-offset:1px;
    border-color:transparent}
  .llp-faq-search__count{display:block;margin:9px 4px 0;font-size:13px;color:#6a6a6a;min-height:1.2em}
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
    clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ── */

/* "This is way too long. We need to find opportunities to condense... but while
     keeping everything that we need. I don't want to lose anything that's great to
     have." So nothing is removed - the vertical rhythm is tightened instead. */
  .llp-cream,.llp-light,.llp-dark3,.llp-dark2,.llp-disclaimer{padding-top:clamp(48px,6vh,86px);
    padding-bottom:clamp(48px,6vh,86px)}
  .llp-final-cta{padding-top:clamp(64px,8vh,96px);padding-bottom:clamp(64px,8vh,96px)}
  .llp-2col{gap:clamp(24px,3.4vw,52px)}
  .llp-steps,.llp-cards{margin-top:clamp(26px,3vh,40px)}
  .llp-cta-band{margin-top:clamp(24px,3vh,36px)}
  .llp-secfig{margin-top:clamp(22px,3vh,32px)}
  .llp-homecard{margin-top:clamp(24px,3vh,34px)}
  .llp-byline{padding-top:18px;padding-bottom:18px}

  /* ── the outcomes track ── */
  /* The box must be bounded by its column, or there is no overflow to travel
     through and the track never moves. */
  /* min-width:0 is the bit that matters: as a grid/flex item the box was being
     sized by its own max-content track (1722px), so there was no overflow left
     to scroll through. */
  .llp-outcomes{margin:30px 0 0;overflow:hidden;width:100%;max-width:100%;min-width:0;
    /* Feather both edges so the cards look like they are travelling past a window
       rather than being chopped off by one. */
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 46px,#000 calc(100% - 46px),transparent 100%);
    mask-image:linear-gradient(to right,transparent 0,#000 46px,#000 calc(100% - 46px),transparent 100%)}
  .llp-2col > *{min-width:0}
  .llp-outcomes__track{display:flex;gap:18px;list-style:none;padding:0;margin:0;
    transform:translate3d(calc(var(--ox,0) * -1px),0,0);will-change:transform}
  .llp-outcome{flex:0 0 min(330px, 78vw);box-sizing:border-box;padding:24px 24px 26px;
    border-radius:16px;background:rgba(17,17,17,.04);border:1px solid rgba(204,169,103,.24)}
  .llp-outcome h4{margin:0 0 9px;font-size:18px}
  .llp-outcome p{margin:0;font-size:15.5px;line-height:1.65;color:#4a4a4a}
  @media (prefers-reduced-motion:reduce){
    .llp-outcomes__track{transform:none;flex-wrap:wrap}
    .llp-outcome{flex-basis:min(330px,100%)}
  }
/* ── */

/* Comparison feature: the caption sits ON the picture (Juan, 2026-08-24)
   "can we put the text on the image when its in the big frame?"
   The kicker, the headline and the paragraph used to sit in a white block
   underneath the big frame, so the card read as two stacked objects. They now
   overlay the foot of the photograph itself.
   Legibility is handled in the frame, not by dimming the whole picture: the text
   sits on a bottom-up scrim that reaches 94% black at the very bottom and is
   fully clear across the top two-thirds, so the image still reads while the copy
   keeps its contrast. The frame also gets taller (4/3.05 rather than 16/9) so the
   caption occupies about a third of it instead of half.
   Under 721px the caption goes back UNDER the image: at phone width the longest
   paragraph is taller than the frame itself, so overlaying there would bury the
   picture completely and put small light text over a busy photo. */
@media(min-width:721px){
  .llp-cmp__feat{position:relative;isolation:isolate}
  .llp-cmp__feat .llp-cmp__featimg{aspect-ratio:4/3.05}
  .llp-cmp__feat .llp-cmp__featimg::after{content:'';position:absolute;inset:0;
    pointer-events:none;z-index:1;
    background:linear-gradient(180deg,
      rgba(8,9,11,0) 30%,rgba(8,9,11,.34) 50%,
      rgba(8,9,11,.78) 74%,rgba(8,9,11,.94) 100%)}
  .llp-cmp__feat .llp-cmp__featbody{position:absolute;left:0;right:0;bottom:0;z-index:2;
    padding:0 clamp(18px,2.2vw,30px) clamp(18px,2vw,26px)}
  .llp-cmp__feat .llp-cmp__featk{color:var(--llp-gold,#cca967)}
  .llp-cmp__feat .llp-cmp__featn{color:rgba(255,255,255,.7)}
  .llp-cmp__feat .llp-cmp__feath{color:#fff;margin:9px 0 10px;
    text-shadow:0 1px 16px rgba(0,0,0,.55)}
  .llp-cmp__feat .llp-cmp__featbody p{color:rgba(255,255,255,.9);
    text-shadow:0 1px 14px rgba(0,0,0,.6)}
}

/* ── */

/* "put the video on top of the rock without the black background that is on top
   of the rock" (Juan, 2026-08-24).
   The team-video block ships from the theme with a hard black panel
   (.rpl-video-section{background:#09090b}). On a geo page that block is relocated
   INTO an .llp-dark section, and .llp-dark already paints the rock tile on its own
   ::before - so the panel was laying flat black over the rock and reading as a box
   dropped on the page. Clearing the panel lets the section's rock run straight
   through behind the video. Scoped to the relocated wrapper so the block keeps its
   black panel anywhere else it is used. */
.rpl-home-blocks .rpl-video-section{background:transparent}

/* Juan, 2026-08-24: "too much space between the bottom of these two columns, can
   we make the right side image container smaller so it lines up with the 2 cards
   on the left". The taller 4:3 frame I set for the caption overshot the card grid
   by about 75px. Rather than pick another fixed ratio that only lines up at one
   window width, the right column now simply STRETCHES to whatever height the left
   grid is: the stage stretches instead of top-aligning, the frame becomes a flex
   column, and the picture takes the remaining space. The image is object-fit:cover
   already, so it crops rather than distorts, and the two columns end on the same
   line at every width. The caption keeps its own scrim and stays pinned to the
   bottom of the frame. */
@media(min-width:721px){
  .llp-cmp__stage.is-live{align-items:stretch}
  .llp-cmp__stage.is-live .llp-cmp__feature{display:flex;flex-direction:column}
  .llp-cmp__stage.is-live .llp-cmp__feat.is-on{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
  .llp-cmp__feat .llp-cmp__featimg{aspect-ratio:auto;flex:1 1 auto;min-height:0}
  /* the copy has less room in a shorter frame, so the block is tightened a touch */
  .llp-cmp__feat .llp-cmp__feath{margin:7px 0 8px}
  .llp-cmp__feat .llp-cmp__featbody{padding-bottom:clamp(16px,1.6vw,22px)}
}

/* ── */

/* Horizontal vehicle-case lead band (Juan, 2026-08-24).
   Sits at the foot of the local/office section, on the rock. Two rows of four on a
   desktop so it reads as a wide band rather than a tall stack; it collapses to two
   columns on a tablet and one on a phone.
   The fields are deliberately lighter than the section behind them - Juan's note on
   the contact form was that near-invisible outlines do not read as a form at all -
   and the focus state is the gold the rest of the site uses. */
.rplf-band{margin:34px 0 0;padding:clamp(22px,2.6vw,34px) clamp(20px,2.4vw,32px) clamp(18px,2vw,26px);
  border-radius:18px;position:relative;isolation:isolate;
  background:rgba(255,255,255,.045);
  border:1px solid rgba(225,180,58,.30);
  box-shadow:0 22px 60px rgba(0,0,0,.34)}
.rplf-band__head{margin:0 0 clamp(16px,1.8vw,22px)}
.rplf-band__kicker{display:block;color:var(--llp-gold,#cca967);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;margin-bottom:9px}
.rplf-band__h{margin:0 0 7px;color:#fff;font-weight:800;line-height:1.15;
  font-size:clamp(21px,2.3vw,31px)}
.rplf-band__sub{margin:0;color:rgba(243,241,236,.72);font-size:15.5px;line-height:1.6}

.rplf__grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
  gap:clamp(10px,1.1vw,16px);align-items:end}
.rplf__f{margin:0;min-width:0}
.rplf__f--make{grid-column:span 3}
.rplf__f--model{grid-column:span 3}
.rplf__f--year{grid-column:span 2}
.rplf__f--name{grid-column:span 4}
.rplf__f--phone{grid-column:span 3}
.rplf__f--email{grid-column:span 3}
.rplf__f--msg{grid-column:span 4}
.rplf__f--submit{grid-column:span 2}

.rplf__f label{display:block;margin:0 0 6px;color:rgba(243,241,236,.80);
  font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
.rplf__f input[type=text],.rplf__f input[type=tel],.rplf__f input[type=email],
.rplf__f select,.rplf__f textarea{
  width:100%;box-sizing:border-box;display:block;
  background:rgba(9,9,11,.55);color:#fff;
  border:1px solid rgba(243,241,236,.34);border-radius:10px;
  padding:12px 13px;font-size:15.5px;line-height:1.35;font-family:inherit;
  transition:border-color .16s ease, box-shadow .16s ease, background-color .16s ease}
.rplf__f textarea{resize:vertical;min-height:46px}
.rplf__f select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:34px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23cca967' stroke-width='2' fill='none'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center}
.rplf__f ::placeholder{color:rgba(243,241,236,.42)}
.rplf__f input:not([type=submit]):hover,.rplf__f select:hover,.rplf__f textarea:hover{border-color:rgba(243,241,236,.52)}
.rplf__f input:not([type=submit]):focus,.rplf__f select:focus,.rplf__f textarea:focus{outline:none;
  border-color:var(--llp-gold,#cca967);background:rgba(9,9,11,.72);
  box-shadow:0 0 0 3px rgba(225,180,58,.22)}

.rplf__btn{width:100%;cursor:pointer;border:0;border-radius:10px;
  padding:13px 16px;font-family:inherit;font-size:15.5px;font-weight:800;letter-spacing:.01em;
  color:#141416;background:var(--llp-gold,#cca967);
  transition:transform .14s ease, box-shadow .14s ease, filter .14s ease}
.rplf__btn:hover{filter:brightness(1.06);box-shadow:0 10px 26px rgba(204,169,103,.32)}
.rplf__btn:active{transform:translateY(1px)}
.rplf__btn:focus-visible{outline:2px solid #fff;outline-offset:3px}

.rplf__fine{margin:14px 0 0;color:rgba(243,241,236,.52);font-size:12.5px;line-height:1.55}

/* CF7 chrome: its wrappers must not break the grid */
.rplf-band .wpcf7-form-control-wrap{display:block}
.rplf-band .wpcf7-not-valid-tip{color:#ffb4a8;font-size:12px;margin-top:5px}
.rplf-band .wpcf7-response-output{margin:14px 0 0;padding:11px 14px;border-radius:10px;
  border:1px solid rgba(243,241,236,.28);color:rgba(243,241,236,.9);font-size:14px}
.rplf-band .wpcf7-spinner{margin:0 0 0 8px}

@media(max-width:1024px){
  .rplf__f--make,.rplf__f--model,.rplf__f--name,.rplf__f--phone,
  .rplf__f--email,.rplf__f--msg{grid-column:span 6}
  .rplf__f--year{grid-column:span 6}
  .rplf__f--submit{grid-column:span 6}
}
@media(max-width:640px){
  .rplf__grid{grid-template-columns:1fr}
  .rplf__f--make,.rplf__f--model,.rplf__f--year,.rplf__f--name,.rplf__f--phone,
  .rplf__f--email,.rplf__f--msg,.rplf__f--submit{grid-column:1 / -1}
}

/* the message box matches the inputs so every cell in a row is the same height and
   the labels line up across the band; it still grows if someone wants to write more */
.rplf__f--msg textarea{height:46px;min-height:46px}
.rplf__f--msg textarea:focus{height:92px}
/* CF7's own paragraph handling can still leave a stray break in the markup */
.rplf__f br{display:none}

/* ── */

/* Juan, 2026-08-24: "I want the check my case button to be a square and large, so
   accommodate the fields to leave that last column alone for the square button."
   The band is now two columns: every field lives in the left column, and the right
   column belongs to the button alone.
   The square is not a hardcoded pixel size - the button is height:100% of the row
   with aspect-ratio 1, so its width is always exactly its height. It stays a true
   square at every width, and it grows or shrinks with the field block rather than
   drifting out of proportion. */
.rplf__grid{display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(14px,1.6vw,22px);align-items:stretch}
.rplf__fields{display:grid;grid-template-columns:repeat(9,minmax(0,1fr));
  gap:clamp(10px,1.1vw,16px);align-content:end;min-width:0}
.rplf__f--make,.rplf__f--model,.rplf__f--year,
.rplf__f--name,.rplf__f--phone,.rplf__f--email{grid-column:span 3}
.rplf__f--msg{grid-column:1 / -1}
.rplf__action{display:flex;min-width:0}
.rplf__f--submit{margin:0;display:flex;height:100%}
.rplf__f--submit .wpcf7-form-control-wrap{display:flex;height:100%}
.rplf__btn{height:100%;width:auto;aspect-ratio:1;min-width:150px;
  border-radius:18px;padding:16px;white-space:normal;line-height:1.25;
  font-size:clamp(17px,1.5vw,22px)}

@media(max-width:1024px){
  .rplf__f--make,.rplf__f--model,.rplf__f--year,
  .rplf__f--name,.rplf__f--phone,.rplf__f--email{grid-column:span 3}
  .rplf__btn{min-width:130px;font-size:17px;border-radius:16px}
}
@media(max-width:640px){
  /* a square is wrong on a phone - the button goes full width like a normal CTA */
  .rplf__grid{grid-template-columns:1fr}
  .rplf__fields{grid-template-columns:1fr}
  .rplf__f--make,.rplf__f--model,.rplf__f--year,.rplf__f--name,
  .rplf__f--phone,.rplf__f--email,.rplf__f--msg{grid-column:1 / -1}
  .rplf__btn{height:auto;width:100%;aspect-ratio:auto;border-radius:12px;
    padding:15px 18px;font-size:16.5px}
}

/* the square is large, so the label scales with it rather than sitting small and
   lost in the middle of it */
.rplf__btn{font-size:clamp(20px,2.1vw,29px);letter-spacing:-.01em}
@media(max-width:640px){.rplf__btn{font-size:16.5px;letter-spacing:0}}

@media(max-width:640px){
  /* the flex chain that makes the desktop square work also stops the button
     stretching here, so the phone layout unwinds it back to plain blocks */
  .rplf__action{display:block;width:100%}
  .rplf__f--submit{display:block;height:auto;width:100%}
  .rplf__f--submit .wpcf7-form-control-wrap{display:block;height:auto;width:100%}
  .rplf__btn{width:100%;min-width:0}
}

/* ── */

/* Juan, 2026-08-24: "too big, i need this whole section tighter and more compact.
   too much space between fields, the field names can go inside of the field."
   The labels now live in the placeholder, and the <label> elements are hidden
   VISUALLY ONLY - they stay in the markup and stay readable to a screen reader,
   because a form of unlabelled boxes is unusable to anyone not looking at it.
   Everything else here is just air coming out: padding, gaps, heading size and
   field height all come down. The square button follows automatically, since its
   size is derived from the height of the field block rather than set. */
.rplf__f label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

.rplf-band{margin:26px 0 0;padding:clamp(16px,1.7vw,22px) clamp(16px,1.7vw,22px) clamp(14px,1.4vw,18px);
  border-radius:14px}
.rplf-band__head{margin:0 0 clamp(11px,1.2vw,15px)}
.rplf-band__kicker{font-size:11px;letter-spacing:.15em;margin-bottom:5px}
.rplf-band__h{font-size:clamp(19px,1.75vw,25px);margin:0 0 4px}
.rplf-band__sub{font-size:14.5px;line-height:1.5}

.rplf__grid{gap:clamp(10px,1.1vw,14px)}
.rplf__fields{gap:clamp(8px,0.75vw,11px)}
.rplf__f input[type=text],.rplf__f input[type=tel],.rplf__f input[type=email],
.rplf__f select,.rplf__f textarea{padding:10px 12px;font-size:14.8px;border-radius:8px}
.rplf__f--msg textarea{height:41px;min-height:41px}
.rplf__f--msg textarea:focus{height:76px}
.rplf__btn{border-radius:14px;font-size:clamp(18px,1.7vw,24px)}
.rplf__fine{margin:10px 0 0;font-size:11.5px}

@media(max-width:640px){
  .rplf-band{padding:18px 16px 16px}
  .rplf__f input[type=text],.rplf__f input[type=tel],.rplf__f input[type=email],
  .rplf__f select,.rplf__f textarea{padding:12px 13px;font-size:16px}
  .rplf__btn{font-size:16.5px}
}

/* ── */

/* Juan, 2026-08-24: "make that a stone slate button, really sexy 3D, with a little
   underlay of LED light but the golden colour in the background, so that when I
   click on it it looks like it's actually going inside like a button."

   Three parts:
   1. FACE - the same rock the section is cut from, over a top-lit slate gradient,
      so the button reads as a piece of the same stone rather than a coloured box.
   2. LED - a gold glow on the wrapper, sitting BEHIND the slab and bleeding out
      past its edges. It lives on the wrapper because the button is an <input>,
      and replaced elements do not render ::before/::after.
   3. TRAVEL - the slab sits on a 10px extruded base. On press it drops the full
      10px, the base collapses to 1px, the inner shadow floods, and the LED flares.
      That is what makes it read as going INTO the housing rather than just dimming. */
.rplf__f--submit{position:relative;isolation:isolate}
.rplf__f--submit::before{content:'';position:absolute;
  inset:4px -6px 2px -6px;z-index:0;pointer-events:none;border-radius:20px;
  background:radial-gradient(58% 62% at 50% 62%,
    rgba(225,180,58,.95) 0%, rgba(225,180,58,.55) 42%,
    rgba(225,180,58,.18) 68%, rgba(225,180,58,0) 82%);
  filter:blur(9px);opacity:.8;
  transition:opacity .16s ease, filter .16s ease}

.rplf__btn{position:relative;z-index:1;
  appearance:none;-webkit-appearance:none;
  color:#f4f2ec;text-shadow:0 1px 2px rgba(0,0,0,.75);
  border:1px solid rgba(255,255,255,.11);
  background-color:#2c2c31;
  background-image:
    linear-gradient(180deg, rgba(255,255,255,.13) 0%, rgba(255,255,255,.02) 38%, rgba(255,255,255,0) 62%),
    url('/wp-content/uploads/geo-vehicles/rock_slab.webp'),
    linear-gradient(180deg,#3d3d43 0%,#2c2c31 54%,#1f1f24 100%);
  background-size:auto, 280px 280px, auto;
  background-repeat:no-repeat, repeat, no-repeat;
  background-blend-mode:normal, soft-light, normal;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.24),
    inset 0 -1px 0 rgba(0,0,0,.55),
    inset 0 14px 30px rgba(255,255,255,.045),
    0 10px 0 #121216,
    0 14px 24px rgba(0,0,0,.55),
    0 0 30px 2px rgba(225,180,58,.26);
  transition:transform .09s cubic-bezier(.4,.0,.2,1),
             box-shadow .12s ease, filter .12s ease;
  will-change:transform}

.rplf__btn:hover{filter:brightness(1.05);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.30),
    inset 0 -1px 0 rgba(0,0,0,.55),
    inset 0 14px 30px rgba(255,255,255,.06),
    0 10px 0 #121216,
    0 16px 28px rgba(0,0,0,.6),
    0 0 42px 5px rgba(225,180,58,.42)}
.rplf__f--submit:hover::before{opacity:1;filter:blur(11px)}

/* pressed: the slab travels the full height of its own base */
.rplf__btn:active{transform:translateY(10px);
  box-shadow:
    inset 0 3px 12px rgba(0,0,0,.8),
    inset 0 -1px 0 rgba(255,255,255,.05),
    inset 0 -8px 18px rgba(0,0,0,.45),
    0 1px 0 #121216,
    0 2px 5px rgba(0,0,0,.5),
    0 0 46px 7px rgba(225,180,58,.6)}
.rplf__f--submit:active::before{opacity:1;filter:blur(13px)}

.rplf__btn:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:4px}

@media(prefers-reduced-motion:reduce){
  .rplf__btn{transition:none}
  .rplf__btn:active{transform:none}
}
@media(max-width:640px){
  /* shallower travel on a phone so the button never jumps under a thumb */
  .rplf__btn{box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(0,0,0,.55),
    0 6px 0 #121216,
    0 8px 16px rgba(0,0,0,.5),
    0 0 24px 2px rgba(225,180,58,.26)}
  .rplf__btn:active{transform:translateY(6px);
    box-shadow:
      inset 0 3px 10px rgba(0,0,0,.8),
      0 1px 0 #121216,
      0 2px 5px rgba(0,0,0,.5),
      0 0 34px 5px rgba(225,180,58,.55)}
}

/* ── */

/* REMOVED 2026-08-25. This moved the WHOLE PICTURE - the figure, the car and the
   plinth all drifting as one. Juan: "the whole thing is moving, i didnt want that.
   i wanted little gifs with these little guys waving and the other one with the car
   going up and down on the lift." He wants motion INSIDE the frame, which is an
   asset problem, not a CSS one. Being replaced with per-card generated loops. */

/* ── */

/* Juan, 2026-08-25: "button is looking cheap and not real stone slate. and the
   font you chose is not our font found elsewhere on the site. put the CHECK / MY
   CASE letters engraved in the stone. And the words are what illuminate."

   Three fixes:
   A. REAL SLATE. The texture was being washed out under a soft-light blend at
      280px, which is why it read as a grey plastic box. It is now an overlay
      blend at 150px over a darker, cooler base, with a cut edge instead of a
      soft one: hard 1px light lip on top, dark under-edge, and an inner vignette
      so the middle of the slab is not a flat field.
   B. OUR FONT. The input was falling back to the browser's default UI face. It
      now takes --font-heading, the Poppins the headings on this page use.
   C. ENGRAVED, SELF-LIT LETTERING. A browser will not let you layer effects on
      the text inside an <input>, so the input keeps the click and the lettering
      moves to its own layer directly over the slab. The letters are cut in - a
      hard black shadow above the stroke reads as the depth of the cut, a faint
      light lip below reads as the bottom edge catching the room - and the gold
      now comes OUT of the letters rather than glowing from behind the slab. */

/* the behind-slab glow drops back to a faint ambient - the words do the lighting */
.rplf__f--submit::before{inset:8px 0 4px;filter:blur(14px);opacity:.34}

.rplf__btn{
  font-family:var(--llp-font-heading, var(--font-heading, "Poppins", system-ui, sans-serif));
  color:transparent;                 /* the input's own text stays hidden */
  text-shadow:none;
  border-radius:10px;
  border:1px solid rgba(255,255,255,.07);
  background-color:#26262b;
  background-image:
    linear-gradient(180deg, rgba(255,255,255,.10) 0%, rgba(255,255,255,0) 30%),
    radial-gradient(120% 90% at 50% 42%, rgba(0,0,0,0) 38%, rgba(0,0,0,.42) 100%),
    url('/wp-content/uploads/geo-vehicles/rock_slab.webp'),
    linear-gradient(180deg,#35353b 0%,#26262b 50%,#191a1e 100%);
  background-size:auto, auto, 150px 150px, auto;
  background-repeat:no-repeat, no-repeat, repeat, no-repeat;
  background-blend-mode:normal, multiply, overlay, normal;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.30),
    inset 0 2px 1px rgba(255,255,255,.06),
    inset 0 -2px 0 rgba(0,0,0,.75),
    inset 0 0 22px rgba(0,0,0,.35),
    0 9px 0 #0f1013,
    0 13px 22px rgba(0,0,0,.62),
    0 0 18px 1px rgba(225,180,58,.14)}

/* the lettering layer: cut into the slab, lit from inside the cut */
.rplf__f--submit::after{
  content:"CHECK\A MY CASE";
  white-space:pre-line;
  position:absolute;inset:0;z-index:2;pointer-events:none;
  display:flex;align-items:center;justify-content:center;text-align:center;
  font-family:var(--llp-font-heading, var(--font-heading, "Poppins", system-ui, sans-serif));
  font-weight:800;letter-spacing:.055em;line-height:1.12;
  font-size:clamp(17px,1.75vw,25px);
  color:#f2cf7d;
  text-shadow:
    0 -1px 1px rgba(0,0,0,.95),
    0 -2px 3px rgba(0,0,0,.7),
    0 1px 0 rgba(255,255,255,.13),
    0 0 9px rgba(225,180,58,.75),
    0 0 22px rgba(225,180,58,.45),
    0 0 44px rgba(225,180,58,.22);
  transition:transform .09s cubic-bezier(.4,0,.2,1), text-shadow .12s ease, color .12s ease}

.rplf__f--submit:hover::after{color:#f8dd9a;
  text-shadow:
    0 -1px 1px rgba(0,0,0,.95),
    0 -2px 3px rgba(0,0,0,.7),
    0 1px 0 rgba(255,255,255,.16),
    0 0 12px rgba(225,180,58,.95),
    0 0 30px rgba(225,180,58,.6),
    0 0 60px rgba(225,180,58,.3)}

/* pressed: slab and lettering travel together, and the cut flares */
.rplf__f--submit:active::after{transform:translateY(9px);color:#ffe9b0;
  text-shadow:
    0 -1px 1px rgba(0,0,0,.95),
    0 -2px 4px rgba(0,0,0,.8),
    0 1px 0 rgba(255,255,255,.10),
    0 0 16px rgba(225,180,58,1),
    0 0 40px rgba(225,180,58,.72),
    0 0 78px rgba(225,180,58,.4)}
.rplf__btn:active{transform:translateY(9px);
  box-shadow:
    inset 0 3px 12px rgba(0,0,0,.85),
    inset 0 -1px 0 rgba(255,255,255,.05),
    inset 0 0 26px rgba(0,0,0,.5),
    0 1px 0 #0f1013,
    0 2px 5px rgba(0,0,0,.5),
    0 0 24px 2px rgba(225,180,58,.3)}

@media(max-width:640px){
  .rplf__f--submit::after{font-size:16px;letter-spacing:.05em}
  .rplf__f--submit:active::after{transform:translateY(6px)}
}

/* ── */

/* The booking section's left panel (Juan, 2026-08-25). It used to hold a second
   gold button, "Talk Through Your Options", sitting beside "Request This Time".
   Two equal CTAs in one section split the intent and the weaker one wins some of
   the clicks, so the button is gone and the panel now does the job of getting
   someone INTO the form on the right: what to bring, who they will actually speak
   to, and how the meeting can happen. No competing link out of the section. */
.llp-bookaside{border-left:3px solid var(--llp-gold,#cca967);
  background:rgba(204,169,103,.08);border-radius:0 14px 14px 0;
  padding:clamp(20px,2.4vw,30px) clamp(20px,2.2vw,30px);
  display:flex;flex-direction:column;justify-content:center;height:100%;
  box-sizing:border-box}
.llp-bookaside__lead{margin:0 0 clamp(14px,1.6vw,20px);color:#fff;font-weight:700;
  font-size:clamp(16px,1.35vw,19px);line-height:1.45}
.llp-bookaside__list{list-style:none;margin:0;padding:0;display:grid;
  gap:clamp(10px,1.1vw,14px)}
.llp-bookaside__list li{position:relative;padding-left:26px;
  color:rgba(243,241,236,.82);font-size:15px;line-height:1.6}
/* a small gold tick, drawn rather than an image, so it costs nothing */
.llp-bookaside__list li::before{content:"";position:absolute;left:2px;top:.42em;
  width:9px;height:5px;border-left:2px solid var(--llp-gold,#cca967);
  border-bottom:2px solid var(--llp-gold,#cca967);transform:rotate(-45deg)}
.llp-bookaside__note{margin:clamp(16px,1.8vw,22px) 0 0;
  color:rgba(243,241,236,.55);font-size:13.5px;line-height:1.5}
@media(max-width:900px){
  .llp-bookaside{border-radius:0 12px 12px 0;height:auto}
}
/* the closing line was sitting on top of the last bullet - give it room */
.llp-bookaside__note{margin-top:clamp(20px,2.2vw,28px);padding-top:clamp(14px,1.5vw,18px);
  border-top:1px solid rgba(204,169,103,.18)}

/* ── */

/* Juan, 2026-08-25: "the text is not centered or cool like i imagined it. i need
   the whole button face done in nano banana as i described it to you."

   The face is now a generated photograph of a slate tile with CHECK MY CASE cut
   into it and gold light coming out of the carved channels - the thing he actually
   described, rather than CSS type sitting on a grey box.

   It also removes a real bug. The CSS lettering was centred on the COLUMN, not on
   the button, and the button is narrower than its column, so the words drifted
   right and hung off the edge. Baked into the face, that cannot happen: the text
   is centred in the image to within 6px of 1024, measured.

   ACCESSIBILITY: the words are now pixels, so the <input>'s own value carries the
   accessible name. It stays in the DOM and is announced normally; it is only
   painted transparent. Never remove that value. */
.rplf__f--submit::after{content:none}          /* the CSS lettering layer is retired */
.rplf__f--submit::before{opacity:.22;filter:blur(16px)}  /* the face lights itself now */

.rplf__btn{
  color:transparent;
  background-color:#17171a;
  background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-face.webp');
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
  background-blend-mode:normal;
  border:1px solid rgba(255,255,255,.06);
  border-radius:14px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -2px 0 rgba(0,0,0,.7),
    0 9px 0 #0f1013,
    0 13px 22px rgba(0,0,0,.62),
    0 0 20px 1px rgba(225,180,58,.16)}

.rplf__btn:hover{filter:brightness(1.09) saturate(1.06);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.2),
    inset 0 -2px 0 rgba(0,0,0,.7),
    0 9px 0 #0f1013,
    0 16px 28px rgba(0,0,0,.66),
    0 0 34px 4px rgba(225,180,58,.34)}

/* pressed: the slab drops into its housing and the carved letters flare */
.rplf__btn:active{transform:translateY(9px);filter:brightness(1.16) saturate(1.1);
  box-shadow:
    inset 0 3px 14px rgba(0,0,0,.85),
    inset 0 0 26px rgba(0,0,0,.45),
    0 1px 0 #0f1013,
    0 2px 5px rgba(0,0,0,.5),
    0 0 30px 3px rgba(225,180,58,.4)}

/* Juan, 2026-08-25: "when i clicked it, it went dark. that's not good, it should
   look like its pressed down and the letters get filled with the yellow."

   He was right, and the cause was mine: the pressed state painted heavy black
   inset shadow to fake a recess, and that shadow sat over the whole stone face,
   so the button dimmed instead of depressing.

   Now there are two faces. At rest the letters are lit from within the cut; on
   press the face swaps to one where the channels are FILLED with molten gold. The
   letterforms sit within 5px of each other between the two, measured, so the swap
   reads as the light coming on rather than the type moving.

   Depth now comes from the slab travelling its full 9px and its base collapsing
   to 1px - not from painting shadow over the artwork.

   The lit face doubles as the ambient bloom behind the slab, which also means the
   browser has already fetched it before the first press. */
.rplf__f--submit::before{
  background:url('/wp-content/uploads/geo-vehicles/check-my-case-face-lit.webp') center/cover no-repeat;
  filter:blur(18px);opacity:.20;
  transition:opacity .14s ease, filter .14s ease}
.rplf__f--submit:hover::before{opacity:.34}
.rplf__f--submit:active::before{opacity:.5;filter:blur(22px)}

.rplf__btn:active{
  transform:translateY(9px);
  filter:none;
  background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-face-lit.webp');
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    0 1px 0 #0f1013,
    0 2px 6px rgba(0,0,0,.55),
    0 0 34px 5px rgba(225,180,58,.45)}

/* ── */

/* Juan, 2026-08-25: "these should invert colors when you hover over them. Golden
   background on hover with white text i think."

   The invert is here. The text is DARK rather than white, and that is a deliberate
   departure I have flagged to him: white on our gold measures 2.2:1, which fails
   the 4.5:1 minimum badly and is genuinely hard to read on a card this full of
   body copy. Dark on the same gold measures 8.4:1. It is also what every other
   gold surface on this site already does - the Free Case Review button, the CTA
   bands. If he wants white specifically, the gold has to deepen to a bronze that
   can carry it; that is a one-line change to the two colours below.

   Scoped to the venue section only. .llp-card is shared with the eligibility and
   vehicle rows, which he did not ask to change. */
.llp-dark2 .llp-card{
  transition:background-color .18s ease, border-color .18s ease,
             transform .18s ease, box-shadow .18s ease;
  cursor:default}
.llp-dark2 .llp-card:hover,
.llp-dark2 .llp-card:focus-within{
  background:var(--llp-gold,#cca967);
  border-top-color:#fff;
  transform:translateY(-3px);
  box-shadow:0 14px 32px rgba(0,0,0,.45)}
.llp-dark2 .llp-card:hover h3,
.llp-dark2 .llp-card:focus-within h3{color:#141416}
.llp-dark2 .llp-card:hover p,
.llp-dark2 .llp-card:focus-within p{color:rgba(9,9,11,.82)}
/* links inside the card have to survive the invert too */
.llp-dark2 .llp-card:hover a,
.llp-dark2 .llp-card:focus-within a{color:#141416;text-decoration-color:rgba(9,9,11,.55)}
.llp-dark2 .llp-card:hover .llp-gloss__t,
.llp-dark2 .llp-card:focus-within .llp-gloss__t{color:#141416;border-bottom-color:rgba(9,9,11,.5)}
@media(prefers-reduced-motion:reduce){
  .llp-dark2 .llp-card{transition:background-color .18s ease,border-color .18s ease}
  .llp-dark2 .llp-card:hover,.llp-dark2 .llp-card:focus-within{transform:none}
}

/* Juan, 2026-08-25: "show 4 at a time, in other words" - conventional first, EVs
   last and out of view until the arrows or the rotation bring them in.
   The rail was a fixed four-column grid, so the fifth card did not hide, it
   WRAPPED onto a second row underneath. It is now a clipped four-wide window with
   the row sliding one card at a time. */
.llp-vehstage__cards{display:flex!important;gap:16px;overflow:hidden;
  grid-template-columns:none!important}
.llp-vehstage__cards .llp-vehcard{flex:0 0 calc((100% - 48px) / 4);min-width:0;
  transform:translateX(calc(var(--veh-shift, 0) * (100% + 16px) * -1));
  transition:transform .5s cubic-bezier(.22,.61,.36,1)}
@media(max-width:1100px){
  .llp-vehstage__cards .llp-vehcard{flex:0 0 calc((100% - 16px) / 2)}
}
@media(max-width:620px){
  .llp-vehstage__cards .llp-vehcard{flex:0 0 100%}
}
@media(prefers-reduced-motion:reduce){
  .llp-vehstage__cards .llp-vehcard{transition:none}
}

/* Juan, 2026-08-25: "On mobile we need to be able to thumb slide past these cards,
   and maybe some arrows?"
   Everything here is inside max-width:860 - the 4-up window, the 42px arrows and
   the rotation at >=861px are signed off and untouched. */
@media(max-width:860px){
  /* The arrows go on their OWN ROW under the rail rather than flanking it. Flanking
     a 1-up rail would have cost 2 x (46 + 12) = 116px of a 350px card - the copy is
     the thing being read, so the chrome moves out of its way instead of shrinking it.
     Nothing overlaps the card: they are laid out in flow, not positioned over it. */
  .llp-vehstage__nav{flex-wrap:wrap;justify-content:center;row-gap:14px}
  .llp-vehstage__cards{flex:0 0 100%;order:1;
    /* the detail that decides whether this feels right: pan-y hands the horizontal
       axis to our handler and leaves the vertical to the page, so a thumb drag
       slides the cards and a thumb flick down still scrolls. No preventDefault is
       needed anywhere once the browser knows which axis is ours. */
    touch-action:pan-y}
  .llp-vehstage__arrow{display:flex;align-items:center;justify-content:center;
    width:46px;height:46px;                 /* >=44px tap target */
    -webkit-tap-highlight-color:transparent}
  .llp-vehstage__arrow[data-veh-prev]{order:2}
  .llp-vehstage__arrow[data-veh-next]{order:3}
  .llp-vehstage__arrow:active{background:rgba(204,169,103,.28);
    border-color:var(--llp-gold,#cca967)}
  /* while the finger is down the rail must track it exactly - the .5s settle
     easing is what the RELEASE uses, not the drag. */
  .llp-vehstage__cards.is-dragging .llp-vehcard{transition:none}
}

/* ── */

/* Juan, 2026-08-25: "ticker should disappear after scroll, super gracefully and
   delayed and cool."
   It collapses its own height as well as fading, so the sticky header closes the
   gap behind it rather than leaving a hole. Long easing, and the JS holds off
   before triggering so it never twitches on a small scroll.
   Height is animated via grid-template-rows, which unlike max-height gives an
   honest 0-to-content transition with no guessed magic number. */
.rpl-geo-ticker{
  display:grid;grid-template-rows:1fr;
  opacity:1;transform:translateY(0);
  transition:grid-template-rows .62s cubic-bezier(.22,.61,.36,1) .06s,
             opacity .46s ease,
             transform .62s cubic-bezier(.22,.61,.36,1);
  will-change:grid-template-rows,opacity,transform}
.rpl-geo-ticker > *{min-height:0}
.rpl-geo-ticker.is-tucked{
  grid-template-rows:0fr;opacity:0;transform:translateY(-6px);
  pointer-events:none}
@media(prefers-reduced-motion:reduce){
  .rpl-geo-ticker{transition:opacity .2s ease}
  .rpl-geo-ticker.is-tucked{transform:none}
}

/* ── */

/* Juan, 2026-08-25: "the button on mobile needs to be done differently, to fit the
   text inside... one liner, big text, big button like it is now."

   The desktop face is a SQUARE with the words on two lines. On a phone the button
   is a short wide bar, so background-size:cover was scaling that square to the
   bar's width and cropping straight through the middle of both lines - you saw the
   bottom of CHECK and the top of MY CASE.

   Below 640px it now uses a landscape face with all three words on ONE line, and
   the button takes the same 4:1 ratio as the artwork, so cover is an exact fit and
   nothing crops at any phone width. Same engraving, same gold-filled letters on
   press. */
@media(max-width:640px){
  .rplf__btn{
    aspect-ratio:4 / 1;height:auto;width:100%;min-width:0;
    background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-wide.webp');
    background-size:cover;background-position:center;
    border-radius:12px;
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.14),
      inset 0 -2px 0 rgba(0,0,0,.7),
      0 6px 0 #0f1013,
      0 9px 16px rgba(0,0,0,.55),
      0 0 16px 1px rgba(225,180,58,.16)}
  .rplf__btn:active{
    transform:translateY(6px);
    background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-wide-lit.webp');
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.10),
      0 1px 0 #0f1013,
      0 2px 5px rgba(0,0,0,.5),
      0 0 26px 4px rgba(225,180,58,.45)}
  /* the ambient bloom behind it follows the wide art too, and preloads it */
  .rplf__f--submit::before{
    background:url('/wp-content/uploads/geo-vehicles/check-my-case-wide-lit.webp') center/cover no-repeat;
    filter:blur(14px);opacity:.18}
}


/* The submit is an <input> living inside a .rplf__f cell, so any future field rule
   written as `.rplf__f input` will match the button too and a `background:` shorthand
   there will silently wipe its engraved face. This re-asserts the face for every
   interaction state so that class of bug cannot come back. */
.rplf__btn:focus,.rplf__btn:focus-visible,.rplf__btn:hover{
  background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-face.webp')}
.rplf__btn:active{
  background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-face-lit.webp')}
@media(max-width:640px){
  .rplf__btn:focus,.rplf__btn:focus-visible,.rplf__btn:hover{
    background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-wide.webp')}
  .rplf__btn:active{
    background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-wide-lit.webp')}
}

/* ── */

/* Juan, 2026-08-25, corrected: "I want all attorneys pictures the same size, none
   small. All the same size as Ron is now."
   My first pass read this as "make them consistent" and put everyone in a small
   two-up grid. Wrong way round - he wants them all at the LARGE size, one per row,
   which is what Ron had. So: single column on mobile, every card full width, one
   portrait shape for everyone. No featured tier, no small tier. */
@media(max-width:860px){
  .rpl-home-blocks .team-featured,
  .rpl-home-blocks .team-grid{
    display:grid!important;
    grid-template-columns:minmax(0,1fr)!important;
    gap:18px;align-items:start}
  .rpl-home-blocks .team-card,
  .rpl-home-blocks .team-card-featured{
    width:auto!important;max-width:none!important;flex:none!important;margin:0!important;
    grid-column:1 / -1!important}
  .rpl-home-blocks .team-card img,
  .rpl-home-blocks .team-card-featured img{
    width:100%!important;height:300px!important;max-height:none!important;
    aspect-ratio:auto!important;object-fit:cover;object-position:center 15%;display:block}
}

/* ── */

/* Juan, 2026-08-25: "these are design styles indicative of AI design, let's not use
   those capsule style elements. Redo those in a better way that doesn't scream AI
   did this."

   He is right, and the tell is specific: `border-radius: 100vmax` on a tinted chip
   with a 1px border. Three of them stacked is the default output of every layout
   generator going, and a law firm is the last place it belongs.

   Replaced with a typeset credential line - the way a masthead or a letterhead sets
   this kind of thing. No container, no border, no radius, no fill. A hairline rule
   above, the items separated by thin vertical rules, the key term in gold. On a
   phone they stack with hairlines between rather than wrapping mid-row, because a
   vertical divider at the start of a wrapped line looks like a mistake. */
.llp-hero-badges{
  display:flex;flex-wrap:wrap;align-items:center;gap:0;
  margin-bottom:32px;padding-top:14px;
  border-top:1px solid rgba(204,169,103,.26)}
.llp-hero-badge{
  border:0;background:none;border-radius:0;padding:2px 18px;
  font-size:13px;letter-spacing:.015em;line-height:1.5;
  color:rgba(243,241,236,.76);
  border-left:1px solid rgba(204,169,103,.28)}
.llp-hero-badge:first-child{padding-left:0;border-left:0}
.llp-hero-badge b{color:var(--llp-gold,#cca967);font-weight:700;letter-spacing:.01em}

@media(max-width:640px){
  .llp-hero-badges{display:block;padding-top:12px;margin-bottom:26px}
  .llp-hero-badge{display:block;padding:9px 0;border-left:0;
    border-bottom:1px solid rgba(243,241,236,.09)}
  .llp-hero-badge:last-child{border-bottom:0;padding-bottom:0}
}

/* ── */

/* City coverage as a streaming ticker on a phone (Juan, 2026-08-25).
   Capsules gone: no border, no fill, no pill radius. The towns read as one moving
   line separated by gold points, which is how a coverage strip is set in print.
   Desktop keeps its existing layout - that band is locked. */
@media(max-width:860px){
  .llp-pills__win{overflow:hidden;margin-top:26px;position:relative;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 28px,#000 calc(100% - 28px),transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 28px,#000 calc(100% - 28px),transparent 100%)}
  .llp-pills__win .llp-pills{display:flex;flex-wrap:nowrap;gap:0;margin:0;padding:0;
    width:max-content;
    animation:llpPillsRun var(--pills-dur,28s) linear infinite}
  .llp-pills__win .llp-pills li{
    flex:none;list-style:none;
    border:0!important;background:none!important;border-radius:0!important;
    padding:0 16px;white-space:nowrap;
    font-size:14px;letter-spacing:.015em;color:var(--llp-gold,#cca967)}
  /* a small gold point between towns, never trailing the last one */
  .llp-pills__win .llp-pills li::after{content:"";position:absolute;
    width:3px;height:3px;border-radius:50%;background:rgba(204,169,103,.55);
    margin-left:16px;margin-top:.62em}
  @keyframes llpPillsRun{
    from{transform:translateX(0)}
    to{transform:translateX(-50%)}   /* exactly the original set; the clone lands in its place */
  }
  .llp-pills__win:hover .llp-pills{animation-play-state:paused}
}
@media(max-width:860px) and (prefers-reduced-motion:reduce){
  /* no travel for anyone who asked for none - it becomes a strip they can swipe */
  .llp-pills__win{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .llp-pills__win .llp-pills{animation:none}
}

/* ── */

/* Self-check qualify capture (Speed, 2026-08-25, Juan). Tick every statement in
   a test and the "Have us read your repair record" link is replaced in place by
   a short capture: the message is prefilled with what was just ticked, plus
   make/model/year and name/email/phone. Ticking only some statements leaves the
   panel exactly as it was.

   EVERY rule here is scoped under .llp-testcheck, which lives inside
   .llp-modal[hidden] - a display:none overlay. Nothing in this block can reach
   the page itself at any width, which is what keeps the locked desktop layout
   byte-identical.

   The two overrides at the top are load-bearing: the panel already styles
   ".llp-testcheck label" as a flex row and ".llp-testcheck input" as an 18x18
   checkbox, for the tick list. Without resetting both, the text inputs render as
   18px squares. */
.llp-testcheck .llp-qcap{margin-top:18px;padding-top:18px;
  border-top:1px solid rgba(17,17,17,.12)}
.llp-testcheck .llp-qcap[hidden]{display:none}
.llp-testcheck .llp-qcap__body[hidden]{display:none}
/* The panel's own button rule sets display:inline-block, and ANY display
   declaration outranks the user-agent [hidden] rule - so the link stayed
   painted on screen while marked hidden+inert. Restate it here at higher
   specificity so "hidden" actually hides. (Speed, 2026-08-25) */
.llp-testcheck a.llp-btn[hidden]{display:none}

.llp-testcheck .llp-qcap__f{display:block;margin:0 0 12px;font-size:13px;
  font-weight:700;cursor:default;gap:0;align-items:stretch}
.llp-testcheck .llp-qcap__f>span{display:block;margin:0 0 5px}
.llp-testcheck .llp-qcap input,
.llp-testcheck .llp-qcap textarea{display:block;width:100%;height:auto;margin:0;
  box-sizing:border-box;font:inherit;font-weight:400;
  /* 16px, not smaller: iOS zooms the whole dialog when a sub-16px field is focused */
  font-size:16px;line-height:1.5;padding:11px 13px;border-radius:10px;
  color:#1a1a1a;background:#fff;border:1px solid rgba(17,17,17,.22);
  accent-color:auto;flex-shrink:1}
.llp-testcheck .llp-qcap textarea{resize:vertical;min-height:124px}
.llp-testcheck .llp-qcap input:focus-visible,
.llp-testcheck .llp-qcap textarea:focus-visible{outline:3px solid var(--llp-gold,#cca967);
  outline-offset:1px;border-color:transparent}

.llp-testcheck .llp-qcap__lead{margin:0 0 14px;font-size:14px;line-height:1.55;opacity:.85}
.llp-testcheck .llp-qcap__legend{margin:16px 0 8px;font-size:13px;font-weight:700}
.llp-testcheck .llp-qcap__grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:0 10px}
.llp-testcheck .llp-qcap__grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 10px}
@media (max-width:520px){
  .llp-testcheck .llp-qcap__grid3{grid-template-columns:1fr 1fr}
  .llp-testcheck .llp-qcap__grid2{grid-template-columns:1fr}
}

.llp-testcheck .llp-qcap__send{margin-top:6px;width:100%;text-align:center;
  border:0;cursor:pointer}
.llp-testcheck .llp-qcap__send[disabled]{opacity:.6;cursor:default;transform:none}
.llp-testcheck .llp-qcap__status{margin:12px 0 0;font-size:14px;line-height:1.5;font-weight:700}
.llp-testcheck .llp-qcap__status:empty{margin:0}
.llp-testcheck .llp-qcap__status:focus{outline:none}
.llp-testcheck .llp-qcap__status--err{color:#a3242b}
.llp-testcheck .llp-qcap__status--ok{color:#1a1a1a}

/* Motion is opt-in: nothing animates unless the visitor has expressed no
   preference against it. */
@media (prefers-reduced-motion:no-preference){
  .llp-testcheck .llp-qcap{animation:qcapIn .22s ease}
  @keyframes qcapIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
}

/* ==========================================================================
   CLIENT REVIEW FIXES - geo city pages (RockPoint)
   From the client's recorded review of /dallas-lemon-law-attorney/.
   Speed (Juan) - 2026-08-26 - STAGING

   Three items, all DESKTOP ONLY. Everything lives inside one
   min-width:1200px block so tablet and mobile render identically to before
   this edit (verified at 1194 / 1024 / 768 / 390px: zero computed property
   changes).

   1. "The H1 is just way too big, taking up too much space."
      72px -> 60px. At 1440 the heading drops from 3 lines / 248.4px to
      2 lines / 138px (-110px, -44% vertical). The nowrap on <em> keeps the
      gold italic phrase ("Lemon Law") from splitting across the new
      two-line wrap.

   2. "Too much dead space above and below the Google Map."
      Root cause: .llp-2col centres its grid items, so the short sidebar
      column (360px) floated in the middle of a 992px row, leaving 316px of
      empty space above AND below the map. Top-align it instead - the same
      treatment .llp-2col--ground already uses for this reason. The map goes
      200px -> 300px so the card carries the column instead of looking
      marooned in it.

   3. "Maybe just a little bit more margin on the sides on desktop."
      Content measure 1320px -> 1260px. At 1440 the side gutter goes
      60px -> 90px; at 1920, 300px -> 330px.
   ========================================================================== */
@media (min-width: 1200px) {

  /* (1) Hero heading - trim the desktop size only. */
  .llp-hero h1 { font-size: 60px; }
  .llp-hero h1 em { white-space: nowrap; }

  /* (2) Google Business Profile map - remove the dead space around it.
     :has() scopes this to 2-col blocks that actually carry a sidebar, so the
     other .llp-2col instances on the page are left alone. */
  .llp-2col:has(.llp-2col__side) { align-items: start; }
  .llp-2col__side .llp-gbp iframe { height: 300px; }

  /* (3) Desktop side margins. */
  .llp-wrap .llp-container { max-width: 1260px; }
}


/* SPEED 2026-08-26: map fills sidebar negative space (Juan request).
   The aside is shorter than the text column, leaving a large gap below it.
   Stretch the aside and let the map iframe flex to absorb the remainder,
   so the map grows with the column instead of a hardcoded height. */
@media (min-width: 1200px) {
  .llp-2col:has(.llp-2col__side) .llp-2col__side {
    align-self: stretch;
    display: flex;
    flex-direction: column;
  }
  /* SPEED 2026-09-11: scoped to cards that actually hold a map. Unscoped, this
     rule made a MAPLESS card absorb the whole column -- 1,156px of empty white
     beside the copy on Georgia (no office, --nolisting) and on Long Island (has
     an office but no embed). Dallas and Philadelphia carry an iframe, so they
     match :has(iframe) and render byte-identically to before this change. */
  .llp-2col__side .llp-gbp:has(iframe) {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }
  /* A mapless card keeps its natural height and sits at the top of the column;
     the state artwork then fills the open span, which is the authored intent. */
  .llp-2col__side .llp-gbp:not(:has(iframe)) { flex: 0 0 auto; }
  .llp-2col__side .llp-gbp iframe {
    flex: 1 1 auto;
    height: auto;
    min-height: 320px;
  }
}


/* SPEED 2026-08-26: lifted from page 1931 post_content (hero credential line, bottom trust strip, exit-popup button fix) */
/* hero credential line - Aaron Waldo, Texas bar number, surfaced high on the page */
.llp-wrap .llp-hero-attorney{
  margin:18px 0 0; font-size:14px; line-height:1.6;
  color:rgba(243,241,236,.78);
}
.llp-wrap .llp-hero-attorney a{ color:var(--llp-gold); font-weight:700; }

/* bottom trust strip */
.llp-wrap .llp-trust{ text-align:center; }
.llp-wrap .llp-trust h2{ margin-bottom:44px; }
.llp-wrap .llp-trust__grid{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:32px; text-align:center;
}
.llp-wrap .llp-trust__num{
  font-family:var(--llp-font-heading); font-weight:800;
  font-size:clamp(32px,4vw,52px); line-height:1;
  color:var(--llp-text); margin-bottom:10px;
}
.llp-wrap .llp-trust__num span{ color:var(--llp-gold-hover); }
.llp-wrap .llp-trust__num sup.fn{ font-size:.42em; font-weight:700; top:-.75em; }
.llp-wrap .llp-trust__label{
  font-size:14px; letter-spacing:.06em; text-transform:uppercase;
  font-weight:600; color:rgba(9,9,11,.62); line-height:1.4;
}
.llp-wrap .llp-trust__badges{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:14px 32px; margin-top:44px; padding-top:28px;
  border-top:1px solid rgba(204,169,103,.4);
}
.llp-wrap .llp-trust__badge{
  display:flex; align-items:center; gap:9px;
  font-size:13.5px; font-weight:600; color:rgba(9,9,11,.72); line-height:1.4;
}
.llp-wrap .llp-trust__badge svg{
  width:20px; height:20px; flex:0 0 auto;
  fill:none; stroke:var(--llp-gold-hover); stroke-width:1.5;
}
.llp-wrap .llp-trust__badge sup.fn{ font-size:.72em; }
@media(max-width:900px){
  .llp-wrap .llp-trust__grid{ grid-template-columns:repeat(2,1fr); gap:36px 24px; }
}
@media(max-width:520px){
  .llp-wrap .llp-trust__badges{ gap:12px 20px; }
  .llp-wrap .llp-trust__badge{ font-size:12.5px; }
}

/* Exit-intent popup CTA. This popup renders OUTSIDE .llp-wrap, and every .llp-btn
   rule in geo-city.css is scoped ".llp-wrap .llp-btn", so this button has never
   picked up the gold pill - it rendered as plain #444 text. That went unnoticed
   while the popup also carried the gold .llp-exit__phone link. The client asked for
   the phone CTA to go ("we're not taking any calls"), so this is now the popup's
   only CTA and it has to read as one. Declarations copied verbatim from
   .llp-wrap .llp-btn; the existing .llp-exit__box .llp-btn width/text-align rule in
   geo-city.css still applies on top. No !important, no inline style. */
.llp-exit__box .llp-btn{
  display:inline-block; background:var(--llp-gold); color:var(--llp-text);
  font-family:var(--llp-font-heading); font-weight:700; font-size:16px;
  padding:16px 32px; border-radius:100vmax; text-decoration:none; line-height:1;
  transition:background .2s ease, transform .2s ease;
}
.llp-exit__box .llp-btn:hover{
  background:var(--llp-gold-hover); color:#fff; transform:translateY(-1px);
}


/* ==========================================================================
   SPEED 2026-09-11 — Juan Loom walkthrough fixes (Georgia 1372 / Long Island 1947).
   Nothing here touches the 2026-09-11 `.llp-2col__side .llp-gbp:has(iframe)`
   stretch rule above; these are additive.
   ========================================================================== */

/* (a) STEP IMAGES: no white flash while the picture is on its way.
   Juan: "Image 2, for some reason, doesn't load right away... It's white. I don't
   like the white space." The box was already reserved (width/height are on every
   <img>), so the white was the section ground showing through an empty box. The
   media cell now carries a neutral placeholder in the section's own family, so an
   image that is still decoding reads as a plate, not a hole. Geometry is unchanged:
   background only, plus the radius the picture already has. */
.llp-hstep__media{ background:rgba(17,17,17,.07); border-radius:14px; }
.llp-cream .llp-hstep__media{ background:rgba(17,17,17,.07); }
.llp-dark .llp-hstep__media,
.llp-dark2 .llp-hstep__media,
.llp-dark3 .llp-hstep__media{ background:rgba(243,241,236,.08); }
/* The plate goes on the picture too, so it carries the same 14px radius the loaded
   image has and an empty box is never a hard-edged white rectangle. */
.llp-hstep__pic{ background:rgba(17,17,17,.07); }
.llp-dark .llp-hstep__pic,
.llp-dark2 .llp-hstep__pic,
.llp-dark3 .llp-hstep__pic{ background:rgba(243,241,236,.08); }

/* (b) GBP CARD: the "Open in Google Maps" link on the Long Island card had no rule
   anywhere in this file and rendered as bare blue-grey text under the address.
   Now it reads as the card's own footer action. */
.llp-gbp__cta{
  display:block; padding:11px 15px; border-top:1px solid rgba(17,17,17,.10);
  font-size:12.5px; font-weight:600; letter-spacing:.2px; text-decoration:none;
  color:#6a5a2e; transition:background .2s ease, color .2s ease;
}
.llp-gbp__cta:hover{ background:rgba(17,17,17,.04); color:var(--llp-gold-hover,#8a6f22); }
.llp-gbp--dark .llp-gbp__cta{
  border-top-color:rgba(243,241,236,.14); color:var(--llp-gold,#cca967);
}
.llp-gbp--dark .llp-gbp__cta:hover{ background:rgba(243,241,236,.06); color:#fff; }

/* (c) SERVICE-AREA CARD (`.llp-gbp--area`). A state map is NOT an office map, and the
   card has to say so in the markup AND on screen. This note is the on-screen half.
   Used on Georgia, where RockPoint has no premises and no Business Profile: the card
   carries no address, no phone and no rating, and this line states that plainly. */
.llp-gbp__note{
  display:block; margin-top:7px; padding-top:7px;
  border-top:1px dashed rgba(17,17,17,.14);
  font-size:11.5px; line-height:1.45; color:#7a7a7a; font-style:italic;
}
.llp-gbp--dark .llp-gbp__note{
  border-top-color:rgba(243,241,236,.16); color:rgba(243,241,236,.6);
}
/* A service-area map is read at state scale, so it wants a wider, shorter frame than
   an office map. Only floors the height; the :has(iframe) flex rule still drives it. */
.llp-gbp--area iframe{ min-height:260px; }


/* ==========================================================================
   SPEED 2026-09-15 - Juan Loom on /texas-lemon-law/ (the REFERENCE BUILD).
   Texas is the pattern page: everything below is written against SHARED
   component classes, not against Texas, so the same six fixes roll to the
   other twelve geo pages by adding the two opt-in modifier classes noted
   in (3) and (4). Nothing here disables a CWV/performance optimisation -
   where something had to be excluded it is excluded by selector.
   ========================================================================== */

/* --------------------------------------------------------------------------
   (1) CONTRAST - text whose colour was too close to its background.

   ROOT CAUSE, and it is one bug, not two. .llp-bookaside__list is authored
   for the DARK .llp-bookaside panel, so its items are cream:
     line ~1786  .llp-bookaside__list li{color:rgba(243,241,236,.82)}
   The list is ALSO used on its own, outside that panel, inside .llp-cream
   copy columns. Cream text on the cream ground is a 1.00:1 ratio - the
   bullets render as gold ticks with nothing beside them. Juan, Loom:
   "you can't see absolutely anything" (the six-months list) and "you put
   again white text on white background" (the allowance-for-use list).
   Both are this selector. Scoping the light-ground override by ancestor
   fixes every present and future occurrence on every page, and leaves the
   panel's own dark-context treatment untouched wherever it IS used.
   -------------------------------------------------------------------------- */
.llp-cream .llp-bookaside__list li,
.llp-light .llp-bookaside__list li { color: rgba(9,9,11,.82); }
.llp-cream .llp-bookaside__list li strong,
.llp-light .llp-bookaside__list li strong { color: var(--llp-text); }
.llp-cream .llp-bookaside__lead,
.llp-light .llp-bookaside__lead { color: var(--llp-text); }
.llp-cream .llp-bookaside__note,
.llp-light .llp-bookaside__note { color: rgba(9,9,11,.62); }

/* Gold-on-cream. --llp-gold (#CCA967) on --llp-cream (#f3f1ec) is 1.97:1.
   The stylesheet already treats --llp-gold-hover (#9a6a00) as THE gold for
   light grounds - see ".llp-cream h2 em,.llp-light h2 em" near the top - and
   this page carries inline style="color:var(--llp-gold-hover)" on some of its
   eyebrows but not others. This finishes that job with the existing token
   (no new brand colour): 1.97:1 -> 4.19:1 on cream.
   Buttons keep their own skins; the Google-review / testimonial subtrees are
   owned elsewhere and are deliberately excluded, not restyled. */
.llp-cream .llp-eyebrow,
.llp-light .llp-eyebrow { color: var(--llp-gold-hover); }
.llp-cream a:not(.llp-btn):not(.llp-btn--ghost):not(.rplf__btn),
.llp-light a:not(.llp-btn):not(.llp-btn--ghost):not(.rplf__btn) { color: var(--llp-gold-hover); }
.llp-cream .llp-gbp a, .llp-light .llp-gbp a,
.llp-cream .test-card a, .llp-light .test-card a,
.llp-cream .rpl-rvw a, .llp-light .rpl-rvw a { color: var(--llp-gold); }
.llp-cream .llp-hstep__num,
.llp-light .llp-hstep__num,
.llp-cream .llp-ocard__n,
.llp-light .llp-ocard__n { color: var(--llp-gold-hover); }

/* --------------------------------------------------------------------------
   (2) FOUR COLUMNS WITH DEAD SPACE AT THE BOTTOM.
   Juan: "the columns are uneven and the bottoms are ragged ... close the
   excess space at the bottom."
   .llp-cards is a grid, so every card in a row was stretched to the tallest
   card: on the Filing-From-Texas row that left 337px of EMPTY card under the
   two short ones while their text stopped two-thirds up. Sizing each card to
   its own content removes that space entirely; ordering the cards shortest
   first (done in the markup) turns what is left into a clean descending
   staircase instead of random raggedness. Opt-in, because .llp-cards is also
   used for short equal-length rows that should stay flush.
   -------------------------------------------------------------------------- */
.llp-cards--stagger { align-items: start; }

/* --------------------------------------------------------------------------
   (3) + (4) FOUR COLUMNS CARRYING HEAVY TEXT -> CHUNKY BOXES, TWO UP.
   Juan on the vehicles block: "four columns do not work with that much text
   ... little square boxes, but they're chunky and they're easy to read", and
   "apply this same treatment anywhere else on the page where four columns
   carry heavy text."
   Two blocks qualify on this page: the vehicle types (.llp-vehstage__cards,
   276px columns / 760px tall) and the qualifying tests (.llp-cards--elig,
   297px columns / 863px tall, 620-910 characters per card). Halving the
   column count roughly doubles the measure and halves the height, which is
   what makes them readable.
   .llp-cards--elig is a named component used by every geo page, so it needs
   no markup change to roll out. .llp-cards--chunky is the opt-in hook for any
   other heavy four-up row.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .llp-cards--chunky,
  .llp-cards--elig {
    grid-template-columns: repeat(2, minmax(0,1fr));
    gap: clamp(20px, 2vw, 30px);
  }
  .llp-cards--chunky > .llp-card,
  .llp-cards--elig > .llp-card {
    padding: clamp(28px, 2.6vw, 40px) clamp(26px, 2.4vw, 38px);
    border-radius: 14px;
  }
  .llp-cards--chunky > .llp-card h3,
  .llp-cards--elig > .llp-card h3 { font-size: clamp(20px, 1.7vw, 24px); margin-bottom: 14px; }
  .llp-cards--chunky > .llp-card p,
  .llp-cards--elig > .llp-card p { font-size: clamp(15px, 1.1vw, 16.5px); line-height: 1.68; }
  /* an odd card never sits alone in a half-width hole */
  .llp-cards--chunky > .llp-card:last-child:nth-child(odd),
  .llp-cards--elig > .llp-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* The vehicle stage is the same treatment on its own grid. It keeps its
   background-swap behaviour, its arrows and its .is-active card - only the
   column count and the box weight change. Five categories, so the fifth
   spans the row rather than leaving a hole. */
/* NOTE, and please read before editing: .llp-vehstage__cards is NOT a grid. Line
   ~1933 turns it into a clipped flex RAIL (display:flex!important) with drag,
   arrows and rotation - Juan, 2026-08-25, \"show 4 at a time\". A
   grid-template-columns rule here is inert. So the 2-up that Juan asked for on
   2026-09-15 is done the only way that keeps the rail intact: the card
   FLEX-BASIS goes 4-up -> 2-up. Drag, arrows and the translateX rotation are
   all expressed relative to card width, so they keep working untouched - this
   is the same basis the >=861px rail already uses below 1100px. */
@media (min-width: 861px) {
  .llp-vehstage__cards .llp-vehcard { flex: 0 0 calc((100% - 16px) / 2); }
}
@media (min-width: 721px) {
  .llp-vehstage .llp-vehcard {
    padding: clamp(26px, 2.4vw, 36px) clamp(24px, 2.2vw, 34px);
    border-radius: 16px;
  }
  .llp-vehstage .llp-vehcard h3 { font-size: clamp(19px, 1.6vw, 23px); margin-bottom: 10px; }
  .llp-vehstage .llp-vehcard p { font-size: clamp(14.5px, 1.05vw, 16px); line-height: 1.66; }
}

/* --------------------------------------------------------------------------
   (5) STEPS 1-5 - IMAGE UNDER THE NUMBER.
   Juan: "put the image underneath the numbers so we have more space for the
   text on the right." He likes the content ("they look like a big chunk of
   important information"), it was the measure that was wrong: the desktop
   grid ran [number 222px][image 260px][copy], leaving the copy 523px in a
   pinned viewport and 875px tall. Stacking the number and the image in one
   left column gives the copy ~960px - the same words, roughly half the height.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
  .llp-hstep {
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    align-items: start;
    row-gap: clamp(14px, 1.6vw, 24px);
  }
  .llp-hstep__num  { grid-column: 1; grid-row: 1; justify-self: start; }
  .llp-hstep__media{ grid-column: 1; grid-row: 2; align-self: start; }
  .llp-hstep__copy { grid-column: 2; grid-row: 1 / span 2; }
  .llp-hstep__copy p { max-width: 76ch; }
}

/* --------------------------------------------------------------------------
   (6) 2-COLUMN BLOCKS - EMPTY SPACE ON THE RIGHT.
   Juan on the allowance-for-use block: "far too much empty space on the right
   ... content is good, the layout wastes the width."
   .llp-2col centres its grid items, so a 413px picture sitting beside a
   1,912px copy column floated in the middle of the row with 750px of nothing
   above it and 750px below. Top-aligning and pinning the picture keeps the
   right-hand column occupied for the whole scroll instead of once in the
   middle. Same :has() scoping the sidebar fix above already uses, so 2-col
   blocks without a picture are untouched.
   -------------------------------------------------------------------------- */
@media (min-width: 881px) {
  .llp-2col:has(> .llp-2col__img) { align-items: start; }
  .llp-2col:has(> .llp-2col__img) > .llp-2col__img {
    position: sticky;
    top: clamp(96px, 11vh, 150px);
    aspect-ratio: auto;
    height: clamp(420px, 62vh, 640px);
  }
}

/* --------------------------------------------------------------------------
   (7) THE LONG LEFT-HAND COPY COLUMN - TIGHTER PRESENTATION.
   Juan: "everything has to be sexy and cool", tighten it WITHOUT cutting
   information. Nothing here removes a word: it is rhythm only - a shorter
   paragraph gap, a slightly tighter leading, a real measure cap, and
   sub-heads that are spaced to break the wall into scannable runs. On the
   Texas "in Brief" column that is a ~3,262px column of continuous prose.
   -------------------------------------------------------------------------- */
.llp-longread > p { margin-bottom: .8em; }
@media (min-width: 1100px) {
  /* Type SIZE is unchanged at 16px - tightening by shrinking the body copy of a
     law page is a false economy. The height comes out of the leading and the
     paragraph gap instead (1.7 -> 1.56, 1.1em -> .8em), which measured -6% on
     the Texas column (3,262px -> 3,060px) with no loss of a single word.
     The h3 rhythm is the other half: more space above a sub-head than below it
     breaks a 3,000px wall into scannable runs. */
  .llp-longread > p { font-size: 16px; line-height: 1.56; max-width: 72ch; }
  .llp-longread > .llp-answer p { font-size: 16.5px; line-height: 1.58; }
  .llp-longread > h3 {
    font-size: clamp(19px, 1.5vw, 22px);
    letter-spacing: -.01em;
    margin: 1.75em 0 .45em;
  }
  .llp-longread > ul { margin-bottom: .95em; }
}


/* ==========================================================================
   SPEED 2026-09-15 (b) - Juan Loom on /texas-lemon-law/, the REFERENCE BUILD.
   Component + interaction fixes. Everything here is written against SHARED
   component classes, so the same behaviour rolls to the other twelve geo pages
   with no per-page CSS. Nothing disables a CWV/performance optimisation.

   Appended AFTER the 2026-09-15 (a) block (contrast, stagger, chunky 2-up,
   steps, 2-col, longread) and deliberately touches none of its selectors.
   ========================================================================== */

/* --------------------------------------------------------------------------
   (1) "WHY <CITY> DRIVERS CHOOSE ROCKPOINT LAW" - GIVE THE GLIDE CONTROLS.

   Juan, Loom: "carousel is really nice actually ... Can somebody drag it?
   Can't even drag it. You're like forced to watch it. You're forced to sit
   here and read it."

   He likes the glide, so the glide stays. What was missing was agency: the
   track ran on a CSS keyframe (transform) inside overflow:hidden, which no
   pointer can catch and no arrow can step. geo-city.js block 13 now drives
   scrollLeft on a rAF loop at the same 26px/s, and adds drag + arrows.

   .is-ctl is added by that script. Gating on it matters: if the script never
   runs, none of this applies and the original keyframe marquee above (line
   ~817) plays exactly as it did. The rail degrades to what it was, not to a
   dead row.

   This is the .llp-why rail ONLY. The vehicle rail (.llp-vehstage__cards) is a
   separate component that already has drag and arrows and was re-flexed to
   2-up in block (a) - it is not touched here.
   -------------------------------------------------------------------------- */
.llp-why.is-ctl.is-glide .llp-why__viewport{
  /* the script owns scrollLeft, so no native scroll to fight and no scrollbar.
     touch-action keeps VERTICAL page scrolling native on a phone while this
     takes the horizontal axis - a swipe down the page still scrolls the page. */
  overflow-x:hidden;
  touch-action:pan-y;
  cursor:grab}
.llp-why.is-ctl.is-glide.is-drag .llp-why__viewport{cursor:grabbing}
.llp-why.is-ctl.is-glide .llp-why__track{animation:none;transform:none;will-change:auto}
.llp-why.is-ctl.is-drag .llp-why__track{user-select:none;-webkit-user-select:none}

/* Arrows. Styled on .llp-vehstage__arrow (line ~485) on purpose - this page now
   carries two rails and they should read as the same control. */
.llp-why__nav{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:16px}
.llp-why__arrow{flex:0 0 auto;width:42px;height:42px;border-radius:50%;cursor:pointer;
  display:grid;place-items:center;padding:0;font:inherit;
  background:rgba(255,255,255,.05);border:1px solid rgba(204,169,103,.35);color:#f3f1ec;
  transition:background .2s ease,border-color .2s ease}
.llp-why__arrow:hover{background:rgba(204,169,103,.2);border-color:var(--llp-gold,#cca967)}
.llp-why__arrow:focus-visible{outline:2px solid var(--llp-gold,#cca967);outline-offset:3px}
.llp-why__arrow svg{width:17px;height:17px;display:block;pointer-events:none}
@media(max-width:560px){
  /* thumb-reachable and centred once the rail is full-bleed on a phone */
  .llp-why__nav{justify-content:center}
  .llp-why__arrow{width:46px;height:46px}
}
@media (prefers-reduced-motion:reduce){
  /* The script does not add .is-ctl in this mode, so the rule at line ~836
     (native scroller, clones hidden) stands and the arrows step that scroller.
     This is here only so a forced .is-ctl could never re-hide the overflow and
     strand a reduced-motion reader with no way to move the rail. */
  .llp-why.is-ctl.is-glide .llp-why__viewport{overflow-x:auto;touch-action:auto}
  .llp-why.is-ctl.is-glide .llp-why__track{animation:none}
}

/* --------------------------------------------------------------------------
   (4) CHECK MY CASE - THE LETTERS SHOULD LIGHT ON HOVER, NOT ON CLICK.

   Juan, Loom: "when they hover over here, I'd like to see the letters turn
   white. Just hovering over. You see how they look now when I click? I
   shouldn't have to wait for the click for that."

   The slab has two faces: check-my-case-face.webp (letters carved and dim) and
   check-my-case-face-lit.webp (channels filled and glowing). The lit face was
   bound to :active only - see the 2026-08-25 note at line ~1846 and the
   re-assertion at line ~2045, which explicitly pinned :hover to the DIM face.
   That pairing is what he is describing, so the lit face moves to hover.

   :active is untouched and still reads as a press: it keeps its own 9px travel
   and collapsed base. The difference between hover and press is now the
   TRAVEL, not whether the letters are lit - which is the right distinction.

   :focus-visible gets the identical treatment, so a keyboard reader sees the
   same state a mouse reader does rather than a dimmer one.

   Later in the file than the line ~2045 re-assertion on purpose: same
   specificity, so source order is what decides it, exactly as that block
   intends for anything written after it.
   -------------------------------------------------------------------------- */
.rplf__btn:hover,
.rplf__btn:focus-visible{
  background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-face-lit.webp');
  /* the lit artwork carries its own brightness; the hover filter on top of it
     blew the gold out, so it stands down here. The hover glow (box-shadow at
     line ~1838) is deliberately left in place. */
  filter:none}
/* the ambient bloom behind the slab follows the same state */
.rplf__f--submit:hover::before,
.rplf__f--submit:focus-within::before{opacity:.34}

@media(max-width:640px){
  /* below 640 the slab swaps to the landscape art, so the lit state must too -
     otherwise hover on a small tablet would snap the face back to the square
     crop mid-interaction. */
  .rplf__btn:hover,
  .rplf__btn:focus-visible{
    background-image:url('/wp-content/uploads/geo-vehicles/check-my-case-wide-lit.webp')}
}


/* ── CTA bands centred — Juan 2026-09-15, "this should be centered aligned" ──
   The band is the full content measure, so left-aligned copy left a long empty
   run to the right of both the sentence and the button. Copy is capped to a
   readable measure and centred; the button centres with it. The gold left
   border is untouched. */
body.rpl-geo .llp-cta-band{text-align:center}
body.rpl-geo .llp-cta-band > p{max-width:64ch;margin-left:auto;margin-right:auto}
body.rpl-geo .llp-cta-band > .llp-btn{margin-left:auto;margin-right:auto}
body.rpl-geo .llp-booksplit > .llp-cta-band{align-items:center}


/* ── Steps: text wraps the number, image gone, runner stops tapping ──────────
   Juan 2026-09-15: "the little guy is too demanding with his toe tapping.. and
   the picture under the number is no longer needed now. lets wrap the text
   around the number."
   The runner is NOT frozen: Juan wants him alive but calm, on a timer. That
   lives in mu-plugins/rpl-geo-runner-idle.php, not here. */
/* the step image is off at every width now */
body.rpl-geo .llp-hstep__media{display:none!important}

/* number floats, copy runs around it. display:block on the article is what lets
   the float escape the old grid; the copy must NOT become a block formatting
   context (no overflow/flow-root here) or it would sit beside the float instead
   of wrapping it. */
body.rpl-geo .llp-hstep{display:block!important}
body.rpl-geo .llp-hstep__num{float:left;margin:0 clamp(18px,2vw,32px) 6px 0;shape-margin:12px}
body.rpl-geo .llp-hstep__copy{display:block;min-width:0}
body.rpl-geo .llp-hstep__copy h3{margin-top:0}
body.rpl-geo .llp-hstep::after{content:"";display:block;clear:both}
@media(max-width:700px){
  /* at phone width a big float eats the measure, so the number sits above */
  body.rpl-geo .llp-hstep__num{float:none;display:block;margin:0 0 6px}
}

/* ===== SPEED 2026-09-15 (d) — THE STATE COVERAGE MAP ==========================
   Juan, video on /texas-lemon-law/: "This section is very long. On the ground
   across Texas, this is a map. We should be presenting a map. A map of Texas...
   And if I hover over Houston I get the information regarding Houston... and
   then 'how to reach us' goes right underneath that map."

   Markup comes from rpl-geo-statemap.php ([rpl_geo_statemap]); behaviour from
   block 18 of geo-city.js. Appended at EOF, no existing rule touched.

   GROUND: the component only ever sits inside .llp-dark, so --llp-gold (#CCA967)
   is the correct gold here. Do NOT reuse this block on a cream ground without
   swapping to --llp-gold-hover (#9a6a00); gold on cream is 1.97:1 (see 2449).

   TYPE SIZES ARE IN ARTBOARD UNITS, NOT PIXELS. An SVG label scales with the
   viewBox, so a single font-size renders 15px at 1440 and 7px at 390. That is
   why every label size below is re-declared per breakpoint. If you change the
   grid ratio, re-check the labels at 1440 / 1100 / 390 before you ship.
   ============================================================================ */

/* NOTE: every <p> rule below is scoped .llp-wrap .llp-statemap__x on purpose.
   Line 31 sets .llp-wrap p{margin:0 0 1.1em}, which is (0,1,1) and outranks a
   bare class -- unscoped, every margin-top here is silently dropped to zero.
   Verified live 2026-09-15: the footnote sat flush against the inset caption. */
.llp-statemap { margin: 34px 0 0; }
.llp-wrap .llp-statemap__lead {
  color: rgba(243,241,236,.82); margin: 0 0 18px; max-width: 62ch;
}
.llp-statemap__grid {
  display: grid; grid-template-columns: minmax(0,1.12fr) minmax(0,1fr);
  gap: clamp(20px, 2.6vw, 44px); align-items: start;
}
.llp-statemap__stage { margin: 0; }
.llp-statemap__svg { display: block; width: 100%; height: auto; overflow: visible; }

/* The state itself. A filled silhouette reads as land; the gold edge ties it to
   the page without competing with the pins. */
.llp-statemap__outline {
  fill: rgba(204,169,103,.15);
  stroke: rgba(204,169,103,.72);
  stroke-width: 2.4;
  stroke-linejoin: round;
}

/* ── The cluster frame on the state map ──────────────────────────────────────
   Eleven-plus markets inside 36 miles cannot be plotted legibly at state scale;
   they would be one blob. The frame says where they are and the inset draws the
   same rectangle again at 9.3x. Two scales, one place, nothing invented. */
.llp-statemap__frameBox {
  fill: rgba(204,169,103,.10);
  stroke: var(--llp-gold); stroke-width: 2.4; stroke-dasharray: 9 7;
}
.llp-statemap__frameTag {
  fill: var(--llp-gold); font-family: var(--llp-font-heading);
  font-weight: 700; font-size: 23px; letter-spacing: .01em;
}
/* Which of the two tags shows is purely a width question -- see the note in
   rpl-geo-statemap.php where both are emitted. */
.llp-statemap__frameTag--short { display: none; }
.llp-statemap__frame { cursor: pointer; }
.llp-statemap__frame:hover .llp-statemap__frameBox,
.llp-statemap__frame:focus-visible .llp-statemap__frameBox,
.llp-statemap__frame.is-on .llp-statemap__frameBox { fill: rgba(204,169,103,.22); stroke-dasharray: none; }
.llp-statemap__frame:focus { outline: none; }
.llp-statemap__frame:focus-visible { outline: none; }
.llp-statemap__frame:focus-visible .llp-statemap__frameBox { stroke: #fff; stroke-width: 3.2; }

/* The inset's own frame, drawn to match, so the eye pairs them. */
.llp-statemap__insetBox {
  fill: rgba(204,169,103,.07);
  stroke: var(--llp-gold); stroke-width: 2.4; stroke-dasharray: 9 7;
}

/* ── Markers ─────────────────────────────────────────────────────────────────
   Structure per marker: a transparent hit circle (the target for mouse and
   thumb), an optional office ring, the house pin glyph, and a label. */
.llp-statemap__mk { cursor: pointer; }
/* The site-wide a11y focus style paints outline:auto on anything focusable, which
   on an SVG <g> becomes a rectangle round the pin AND its label. Suppressed here
   for the pointer case only: keyboard focus still gets an indicator, the white
   ring on .llp-statemap__hit below. Nothing global is disabled. */
.llp-statemap__mk:focus { outline: none; }
.llp-statemap__mk:focus-visible { outline: none; }
.llp-statemap__hit { fill: rgba(0,0,0,0); pointer-events: all; stroke: none; }
.llp-statemap__mk:focus-visible .llp-statemap__hit { stroke: #fff; stroke-width: 3; }
.llp-statemap__glyph {
  fill: var(--llp-gold);
  stroke: var(--llp-dark); stroke-width: 1.1;
  transition: fill .18s ease;
}
.llp-statemap__glyph circle { fill: var(--llp-dark); stroke: none; }
.llp-statemap__lbl {
  fill: rgba(243,241,236,.86); font-family: var(--llp-font-body);
  font-weight: 600; font-size: 23px; paint-order: stroke;
  stroke: var(--llp-dark); stroke-width: 4; stroke-linejoin: round;
  transition: fill .18s ease;
}
.llp-statemap__mk:hover .llp-statemap__glyph,
.llp-statemap__mk:focus-visible .llp-statemap__glyph,
.llp-statemap__mk.is-on .llp-statemap__glyph { fill: #fff; }
.llp-statemap__mk:hover .llp-statemap__lbl,
.llp-statemap__mk:focus-visible .llp-statemap__lbl,
.llp-statemap__mk.is-on .llp-statemap__lbl { fill: #fff; }

/* The office. A ring round the pin, because "we are HERE" should not look like
   "we take cases here". geo-city.css:682 notes that only Texas marks an office;
   a state whose registry entry sets no 'office' simply renders no ring. */
.llp-statemap__ring {
  fill: none; stroke: var(--llp-gold); stroke-width: 2.6; opacity: .75;
}
.llp-statemap__mk--office .llp-statemap__lbl { fill: var(--llp-gold); font-weight: 700; }

/* ── The inset ───────────────────────────────────────────────────────────── */
.llp-statemap__stage--inset .llp-statemap__lbl { font-size: 21px; stroke-width: 4; }
.llp-statemap__cap {
  color: rgba(243,241,236,.62); font-size: 13.5px; line-height: 1.55;
  margin: 10px 0 0;
}

/* ── The panel ───────────────────────────────────────────────────────────── */
.llp-statemap__panel {
  margin-top: 18px; padding: 18px 20px;
  background: rgba(255,255,255,.045);
  border: 1px solid rgba(204,169,103,.26); border-radius: 14px;
  min-height: 176px;
}
.llp-wrap .llp-statemap__panelName {
  font-family: var(--llp-font-heading); font-weight: 800;
  font-size: 19px; color: var(--llp-gold); margin: 0 0 8px;
}
.llp-wrap .llp-statemap__panelBody {
  color: rgba(243,241,236,.86); font-size: 15.5px; line-height: 1.68; margin: 0;
}
.llp-wrap .llp-statemap__howto {
  color: rgba(243,241,236,.52); font-size: 13px; margin: 12px 0 0;
}
/* The footnote is page copy; the inset caption above it is a figure caption.
   Stacked, they land adjacent at similar size and read as one paragraph, so the
   gap does the work the column layout used to do. */
.llp-wrap .llp-statemap__foot {
  color: rgba(243,241,236,.72); font-size: 14px; margin: 32px 0 0; max-width: 78ch;
}

/* "How to reach us", directly underneath the map -- the rule is what makes the
   adjacency read as deliberate rather than as two paragraphs that happen to
   follow each other. */
.llp-statemap__reach {
  margin-top: 22px; padding-top: 20px;
  border-top: 1px solid rgba(204,169,103,.26);
}
.llp-wrap .llp-statemap__reach p { margin: 0; }
.llp-wrap .llp-statemap__credit {
  color: rgba(243,241,236,.42); font-size: 12px; margin: 18px 0 0;
}

/* ── Widths ──────────────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  .llp-statemap__grid { gap: 22px; }
  .llp-statemap__lbl { font-size: 25px; }
  .llp-statemap__stage--inset .llp-statemap__lbl { font-size: 28px; }
}
@media (max-width: 860px) {
  /* Stack. Panel between the two artboards so a tap on either is answered
     within a thumb's reach rather than a scroll away. */
  .llp-statemap__grid { grid-template-columns: minmax(0,1fr); gap: 18px; }
  .llp-statemap__side { display: contents; }
  .llp-statemap__stage--state { order: 1; }
  .llp-statemap__panel { order: 2; margin-top: 0; min-height: 0; }
  .llp-wrap .llp-statemap__howto { order: 3; margin: 0; }
  .llp-statemap__stage--inset { order: 4; margin-top: 4px; }
  .llp-statemap__lbl { font-size: 26px; }
  .llp-statemap__stage--inset .llp-statemap__lbl { font-size: 17px; }
  /* Stacked: the map is full-bleed, so the long tag has no grid gap to spill
     into and would be clipped at the artboard edge. Short form, above the box. */
  .llp-statemap__frameTag--full { display: none; }
  .llp-statemap__frameTag--short { display: block; font-size: 30px; }
}
@media (max-width: 640px) {
  .llp-statemap__lbl { font-size: 34px; }
  .llp-statemap__frameTag--short { font-size: 38px; }
  /* Thirteen labels in a 350px-wide inset is a blob. The seven that clear each
     other by 150 artboard units keep their labels; the rest keep their pins and
     are named by the panel when you tap them. Flagged to Juan. */
  .llp-statemap__stage--inset .llp-statemap__mk.is-dense .llp-statemap__lbl { display: none; }
  .llp-statemap__stage--inset .llp-statemap__lbl { font-size: 21px; }
  .llp-statemap__panel { padding: 15px 16px; }
  .llp-wrap .llp-statemap__panelBody { font-size: 15px; }
}
@media (max-width: 520px) {
  .llp-statemap__stage--inset .llp-statemap__lbl { font-size: 34px; }
}

@media (prefers-reduced-motion: reduce) {
  .llp-statemap__glyph, .llp-statemap__lbl { transition: none; }
}

/* Clipped, not display:none: display:none would take the nineteen markets out of
   the accessibility tree and undo the aria-describedby on every pin. */
.llp-statemap__sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}


/* ── Capped copy columns centre instead of hugging the left ──────────────────
   Juan 2026-09-16: "too much space on the right of that wall of text."
   These blocks carry an inline max-width:78ch, which is the right measure to
   read; what was wrong is that every leftover pixel sat on one side. Selecting
   on the inline cap itself keeps this off anything that is meant to be left
   aligned or has a neighbour to its right. */
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > h2,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > h3,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > h4,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > p,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > ul,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > ol,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > details,
body.rpl-geo .llp-dark2 .llp-container:has(> [style*="78ch"]) > blockquote,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > h2,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > h3,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > h4,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > p,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > ul,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > ol,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > details,
body.rpl-geo .llp-cream .llp-container:has(> [style*="78ch"]) > blockquote{
  /* 49.2rem = the 787px the body copy already measures at 78ch. NOT 78ch here:
     ch is relative to each element's own font size, so 78ch on a 32px heading
     computes to 1327px and the heading stays full width. */
  max-width:49.2rem!important;
  /* important on the margins too: these blocks carry an inline margin shorthand
     (style="margin:40px 0 14px") which otherwise wins and pins them left. */
  margin-left:auto!important;margin-right:auto!important}


/* ── SPEED 2026-09-19 ────────────────────────────────────────────────────────
   The track-record figures under "RockPoint Law, by the numbers" now count up
   when they scroll into view (geo-city.js, block 30). Juan, 2026-09-19: "why
   did the numbers not move?" - they never did; there was no count-up code.

   Proportional digits are different widths, so a number ticking from 0 to
   1,500 changes the width of its own column roughly sixty times a second and
   the whole four-up grid shuffles for the second and a half the count runs.
   Tabular figures give every digit the same advance: the numbers move, the
   layout does not.

   Scoped to the figure itself, so the labels and footnote markers under it
   keep the proportional face the rest of the page is set in. */
.llp-wrap .llp-trust__num{
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}


/* ── Juan's San Antonio walkthrough, 2026-09-19 ─────────────────────────────
   "This whole block of text is aligned to the left... it should be center
   aligned" - twice, under the 30-day test block and under the vehicles
   carousel. Two reasons it was missed before: those intros are capped at 76ch
   while the 2026-09-16 rule only matched 78ch, AND the rule was scoped to
   .llp-dark2 / .llp-cream while this section is .llp-dark. Measured at 0px left
   and 493px right before this.
   Scoped now on the thing that actually signals editorial prose: a container
   whose direct child carries an inline ch cap, on any ground. */
body.rpl-geo .llp-container:has(> [style*="76ch"]) > h2,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > h2,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > h3,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > h3,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > h4,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > h4,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > p,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > p,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > ul,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > ul,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > ol,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > ol,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > details,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > details,
body.rpl-geo .llp-container:has(> [style*="76ch"]) > blockquote,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > blockquote{
  max-width:49.2rem!important;
  margin-left:auto!important;margin-right:auto!important}

/* 2. The granite ground on the consultation card: "that's where we had the
   button, the granite button and the granite background, the rock". Same tile
   as the Check My Case band. Border and contents untouched - delete this one
   rule to put the warm gold panel back. */
body.rpl-geo .llp-book{
  background-color:#16161a;
  background-image:linear-gradient(rgba(10,10,13,.55),rgba(10,10,13,.55)),
                   url('/wp-content/uploads/geo-vehicles/geo-granite-tile.webp');
  background-size:auto, 320px 320px;
  background-repeat:repeat, repeat}

/* ── Juan, 2026-09-22: "that headline is not aligned ... happens in other
   sections". The gold eyebrow sat on the container left edge while the H2 and
   the body copy under it had been pulled in to the centred 49.2rem measure.
   The 2026-09-19 centring rule above caused it: it lists h2/h3/h4/p/ul/ol/
   details/blockquote and never included the eyebrow, so the label stayed at the
   container edge (51px) while its own heading moved to 246px - 195px of gap, on
   seven sections of all twelve geo pages.
   Same measure, same auto margins, so the labels left edge lands on the H2s.
   display:block is what makes the auto margins take - as inline-block they do
   nothing. Text stays left inside the block, so this shifts the label without
   centring the label text. Reviewed on staging and approved by Juan 2026-09-22. */
body.rpl-geo .llp-container:has(> [style*="76ch"]) > .llp-eyebrow,
body.rpl-geo .llp-container:has(> [style*="78ch"]) > .llp-eyebrow{
  display:block!important;
  max-width:49.2rem!important;
  margin-left:auto!important;margin-right:auto!important}

/* ── Juan, 2026-09-22: "too much negative space", flagged on Texas.
   .llp-2col--ground is a two-column grid with align-items:start, so the right
   column stops at the bottom of the office card while the prose column keeps
   running. Measured empty column on production at 1280px:
   Florida 2200, Massachusetts 2084, Maryland 1876, Delaware 1770,
   Connecticut 1722, Texas 1521, San Antonio 1357, Virginia 1286,
   Colorado 825, Long Island 706, Dallas 396, Georgia 217.
   The card now rides down beside the copy, so the column is never empty.
   section.llp-dark carried overflow:hidden to clip the .llp-splash disc, and
   overflow:hidden makes the section a scroll container, which silently kills
   sticky. overflow:clip clips identically WITHOUT becoming one. Scoped with
   :has() so only the dark sections holding a ground grid are touched.
   top:138px clears the sticky header once it condenses (142px at rest, 114px
   scrolled). Desktop only - under 900px the grid is already one column.
   Reviewed on staging and approved by Juan 2026-09-22. */
@media (min-width:881px){
  body.rpl-geo section.llp-dark:has(.llp-2col--ground){ overflow:clip }
  body.rpl-geo .llp-2col--ground > .llp-ground-side{
    position:sticky; top:138px; align-self:start }
}
