/* ============================================================
   Launch Lex — Site Overrides + Token Layer
   ------------------------------------------------------------
   This file is the canonical token + override layer. It loads
   AFTER the Webflow stylesheets (normalize.css, webflow.css,
   halden-miller.webflow.css) on every page, so anything declared
   here wins over the original Webflow defaults.

   Two responsibilities:

   1. Friendly-named tokens. The Webflow CSS uses obscure tokens
      like `--_🎨-color--base---neutral--dark-100`. We re-expose
      them with readable names (`--ll-bg-base`, `--ll-text-strong`,
      etc.) so case-studies.css and any future custom CSS can read
      from a single, documented vocabulary.

   2. Site-wide bug fixes and homepage Part 2 polish. Anything
      that would otherwise require editing halden-miller.webflow.css
      lives here instead, scoped tightly enough not to disturb
      unrelated parts of the design.

   Decoupling note: the project no longer syncs from Webflow, so
   editing halden-miller.webflow.css directly is technically safe
   (see /README.md). We still prefer this overrides file for any
   non-trivial change because it keeps the original export readable
   and the overrides reviewable in one place.
   ============================================================ */

/* ============================================================
   1. FONT FIX — IBM Plex Sans Variable
   ------------------------------------------------------------
   The Webflow export points the IBM Plex Sans Variable @font-face
   rules at `../images/` instead of `../fonts/`, so the body font
   silently falls back to Arial. We re-declare the @font-face here
   pointing at the correct local files (which DO exist in /fonts/).
   ============================================================ */
@font-face {
  font-family: 'IBM Plex Sans Variable';
  src: url('../fonts/IBMPlexSans-Italic-VariableFont_wdthwght.ttf') format('truetype-variations');
  font-weight: 100 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Variable';
  src: url('../fonts/IBMPlexSans-VariableFont_wdthwght.ttf') format('truetype-variations');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

/* JetBrains Mono — used only by the /process.html page for blueprint
   annotations (durations, tools labels, sprint tags, T-24H markers,
   gauge percentage). Self-hosted via the variable wght axis so a single
   file covers 100..800. Falls back to IBM Plex Mono everywhere else
   via --ll-font-mono-blueprint below. */
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/JetBrainsMono-VariableFont_wght.ttf') format('truetype-variations');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/JetBrainsMono-Italic-VariableFont_wght.ttf') format('truetype-variations');
  font-weight: 100 800;
  font-style: italic;
  font-display: swap;
}

/* ============================================================
   2. FRIENDLY TOKEN LAYER
   ------------------------------------------------------------
   These re-expose the Webflow base palette + scale under sane
   names. Custom CSS (case-studies, etc.) should read from these
   instead of touching the emoji tokens directly.
   ============================================================ */
:root {
  /* ----- Color: surfaces ------------------------------------ */
  --ll-bg-base:        #f7f7f2;  /* paper white — body, default sections */
  --ll-bg-lift:        #efede7;  /* warm beige — cards, raised surfaces */
  --ll-bg-depth:       #e1dcd5;  /* deeper beige — sunken, FAQ rows */

  --ll-bg-dark-base:   #191818;  /* warm dark — footer, dark callouts */
  --ll-bg-dark-lift:   #1e1c1b;  /* warm dark elevated */
  --ll-bg-dark-depth:  #22201f;  /* warm dark sunken */

  /* ----- Color: text on light surfaces --------------------- */
  --ll-text-strong:    #191818;                        /* headings */
  --ll-text-body:      rgba(25, 24, 24, 0.88);         /* body */
  --ll-text-medium:    rgba(25, 24, 24, 0.64);         /* subdued */
  --ll-text-subtle:    rgba(25, 24, 24, 0.48);         /* captions */
  --ll-text-faint:     rgba(25, 24, 24, 0.32);         /* watermark-faint */

  /* ----- Color: text on dark surfaces ---------------------- */
  --ll-text-on-dark-strong: #f7f7f2;
  --ll-text-on-dark-body:   rgba(247, 247, 242, 0.88);
  --ll-text-on-dark-medium: rgba(247, 247, 242, 0.64);
  --ll-text-on-dark-subtle: rgba(247, 247, 242, 0.48);

  /* ----- Color: borders + accents -------------------------- */
  --ll-border-subtle:  rgba(25, 24, 24, 0.08);
  --ll-border-medium:  rgba(25, 24, 24, 0.16);
  --ll-border-strong:  rgba(25, 24, 24, 0.32);

  --ll-border-dark-subtle: rgba(247, 247, 242, 0.08);
  --ll-border-dark-medium: rgba(247, 247, 242, 0.16);
  --ll-border-dark-strong: rgba(247, 247, 242, 0.32);

  --ll-accent-cta:     linear-gradient(135deg, #1a3a6e 0%, #2563eb 50%, #1a3a6e 100%);
  --ll-accent-solid:   #2563eb;
  --ll-accent-deep:    #1a3a6e;

  --ll-ui-error:       #c94040;
  --ll-ui-success:     #2ad87f;
  --ll-ui-warning:     #c56a21;

  /* ----- Typography: family stacks ------------------------- */
  --ll-font-display: 'IBM Plex Serif', 'Times New Roman', Georgia, serif;
  --ll-font-heading: 'IBM Plex Serif', 'Times New Roman', Georgia, serif;
  --ll-font-body:    'IBM Plex Sans Variable', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --ll-font-mono:    'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Blueprint-flavoured mono — used on /process.html only. */
  --ll-font-mono-blueprint: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ----- Typography: size scale ---------------------------- */
  --ll-size-display: 96px;  /* h0 */
  --ll-size-h1:      64px;
  --ll-size-h2:      48px;
  --ll-size-h3:      40px;
  --ll-size-h4:      32px;
  --ll-size-h5:      28px;
  --ll-size-h6:      24px;
  --ll-size-body-1:  20px;
  --ll-size-body-2:  16px;
  --ll-size-body-3:  14px;
  --ll-size-label-1: 12px;
  --ll-size-label-2: 10px;
  --ll-size-button:  16px;

  /* ----- Typography: line-heights -------------------------- */
  --ll-lh-display: 88px;
  --ll-lh-h1:      72px;
  --ll-lh-h2:      52px;
  --ll-lh-h3:      44px;
  --ll-lh-h4:      36px;
  --ll-lh-h5:      32px;
  --ll-lh-h6:      28px;
  --ll-lh-body-1:  28px;
  --ll-lh-body-2:  24px;
  --ll-lh-body-3:  20px;
  --ll-lh-label:   16px;

  /* ----- Typography: letter-spacing ------------------------ */
  --ll-ls-display:  -2.5px;
  --ll-ls-h1:       -2.5px;
  --ll-ls-h2:       -2px;
  --ll-ls-h3:       -1px;
  --ll-ls-h4:       -1px;
  --ll-ls-h5:       -0.5px;
  --ll-ls-h6:       -0.5px;
  --ll-ls-body:     0;
  --ll-ls-label:    0.75px;

  /* ----- Typography: weights ------------------------------- */
  --ll-weight-regular: 400;
  --ll-weight-medium:  500;
  --ll-weight-semi:    600;
  --ll-weight-bold:    700;

  /* ----- Spacing scale ------------------------------------- */
  --ll-space-0:   0px;
  --ll-space-4:   4px;
  --ll-space-8:   8px;
  --ll-space-12: 12px;
  --ll-space-16: 16px;
  --ll-space-20: 20px;
  --ll-space-24: 24px;
  --ll-space-32: 32px;
  --ll-space-48: 48px;
  --ll-space-64: 64px;
  --ll-space-80: 80px;
  --ll-space-120: 120px;

  /* ----- Section padding (vertical rhythm) ----------------- */
  --ll-section-sm:   80px;
  --ll-section-md:  120px;
  --ll-section-lg:  160px;
  --ll-section-xl:  200px;

  /* ----- Containers ---------------------------------------- */
  --ll-container:        1200px;  /* preferred read width — narrower than Webflow's 1800 default for editorial content */
  --ll-container-narrow:  912px;
  --ll-container-wide:   1800px;
  --ll-page-padding:       32px;

  /* ----- Border radius ------------------------------------- */
  --ll-radius-sm:    8px;   /* inputs */
  --ll-radius-md:   12px;   /* default cards */
  --ll-radius-lg:   16px;   /* buttons, large cards, tags */
  --ll-radius-pill: 24px;
  --ll-radius-full: 100vw;

  /* ----- Shadows (subtle paper-edge, not drop shadows) ----- */
  --ll-shadow-card:
    0 -1px 0 0 rgba(247, 247, 242, 0.16),
    0  1px 0 0 rgba(247, 247, 242, 0.08);

  --ll-shadow-card-elevated:
    0 -1px 0 0 rgba(247, 247, 242, 0.20),
    0  1px 0 0 rgba(247, 247, 242, 0.12),
    0 12px 32px -16px rgba(25, 24, 24, 0.18);

  /* ----- Motion -------------------------------------------- */
  --ll-ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ll-ease-soft:   cubic-bezier(0.22, 1, 0.36, 1);
  --ll-dur-fast:   150ms;
  --ll-dur-base:   250ms;
  --ll-dur-slow:   500ms;
}

/* ── Global typography smoothing ── */
* {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ── Loader initial state ── */
.loader { display: flex !important; }

/* ============================================================
   3. HOMEPAGE OVERRIDES
   ------------------------------------------------------------
   Each block is a targeted Part 2 polish fix. Scoped tightly so
   they don't bleed into other pages. Every rule here is a
   deliberate deviation from the Webflow export — keep comments
   explaining WHY each fix exists.
   ============================================================ */

/* ---------- Accent color tokenization -------------------
   The site's accent is solid blue #2563eb — already used on the
   CTA gradient mid-stop and on `.promo-section-headline em`
   ("free of charge"). The homepage also had a blue→purple→magenta
   gradient on `.headline-foundations h2 em` ("Choose LaunchLex")
   that introduced a 4th color nowhere else. We flatten that to
   the same solid blue so the accent reads as a single system
   element across the page. */
.headline-foundations h2 em {
  background: none !important;
  -webkit-text-fill-color: var(--ll-accent-solid) !important;
  color: var(--ll-accent-solid) !important;
  font-style: italic !important;
}

/* "free of charge" is already #2563eb via the promo-section
   inline styles. Re-pin it to the token so the accent system has
   a single source of truth — zero visual change. */
.promo-section-headline em {
  color: var(--ll-accent-solid) !important;
}

/* ---------- Reviews marquee styling ---------------------
   The reviews section ported from services.html uses Webflow's
   existing .marquee-testimonials / .card-testimonial-marquee /
   .testimonial-rating / .icon-star pattern. Two things to fix:
     1. Stars inherit currentColor from body text, which reads as
        a muted gray. Color them in the accent for the brand's
        third deliberate use of blue.
     2. Fade-edge mask so cards scroll in/out of transparency at
        the section edges, not hard-cut. */
.testimonial-rating .icon-star {
  color: var(--ll-accent-solid);
}

/* Reviews marquee motion — CSS fallback for non-services pages
   ------------------------------------------------------------
   The `.marquee-testimonials` markup ships inline Webflow transforms
   + `data-w-id` hooks that point at interactions registered per
   page in Webflow's compiled runtime. Those interactions only exist
   for the services page ID, so on homepage + about the tracks sit
   static. We drive them here with a pure CSS vertical scroll that
   matches the services visual behaviour: ~40s loop, linear, infinite.

   Each column has 4 duplicated `.single-marquee-testimonials` groups,
   so translating 0 → -50% shows 2 groups' worth and lands on a
   visually identical position (seamless loop). Column 2 uses a
   half-offset starting delay to match the services page where its
   initial transform was already translated -50%.

   `!important` on the transform/animation ensures we override the
   inline Webflow transforms that ship in the markup. */

/* GAP / LOOP-MATH FIX -----------------------------------------
   `.marquee-testimonials` is a flex column with `gap: 16px` between
   its `.single-marquee-testimonials` children. With N duplicated
   groups, a seamless scroll loop requires the distance moved per
   iteration to equal "one-group-plus-one-gap" exactly. The flex
   gap pattern is:
     G  gap  G  gap  G  gap  G        (4 groups, 3 gaps = no trailing gap)
   One-group shift = G + gap, but totalHeight = 4G + 3·gap, so
   (G+gap)/(4G+3gap) is not exactly 1/4. Translating to -50% lands a
   few pixels off and the loop reset shows a visible skip.

   Fix: move the inter-group spacing from `gap` to `padding-bottom`
   on every group (including the last). Now totalHeight = 4·(G+gap),
   and one-group shift = G+gap = 25% exactly. Two-group shift = 50%
   exactly. Both are seamless. */
html .rating-section .marquee-testimonials {
  gap: 0;
  grid-column-gap: 0;
  grid-row-gap: 0;
}
.rating-section .single-marquee-testimonials {
  padding-bottom: var(--grid--column-gap, 16px);
}

/* SCROLL ANIMATION --------------------------------------------
   Columns 1 + 3 scroll UP (translate 0 → -50%).
   Column 2 scrolls DOWN (we reuse the same keyframe with
   `animation-direction: reverse` so there's only one set of
   keyframes to maintain). */
@keyframes llReviewsScroll {
  0%   { transform: translate3d(0, 0%, 0); }
  100% { transform: translate3d(0, -50%, 0); }
}

/* Duration tuned per user feedback — noticeably faster than the
   original 40s. Linear easing so speed reads as constant. */
.rating-section .marquee-testimonials {
  animation: llReviewsScroll 18s linear infinite !important;
  will-change: transform;
  /* Force GPU layer + avoid subpixel rounding on reset. */
  backface-visibility: hidden;
  transform-style: preserve-3d;
}

/* Column 2 — opposite direction (DOWN). Negative delay so it
   doesn't hard-reset when the page loads. */
.rating-section .marquee.testimonials._2nd .marquee-testimonials {
  animation-direction: reverse !important;
  animation-delay: -9s !important;
}

/* Column 3 — same direction as col 1 but offset one-third of the
   duration so it doesn't mirror col 1 exactly. */
.rating-section .marquee.testimonials._3rd .marquee-testimonials {
  animation-delay: -6s !important;
}

/* Pause on hover so a curious visitor can read items. */
.rating-section .marquee-thirds:hover .marquee-testimonials {
  animation-play-state: paused !important;
}

/* Respect reduced-motion — freeze at starting positions. */
@media (prefers-reduced-motion: reduce) {
  .rating-section .marquee-testimonials {
    animation: none !important;
  }
}

/* Section header rating tile: the "4.9/5" score is bold and the
   "from 50+ Kentucky businesses" count is smaller + subtle. */
.rating-tile .rating-score {
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-bold);
  font-size: 24px;
  color: var(--ll-text-strong);
  line-height: 1;
}
.rating-tile .rating-count {
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-regular);
  font-size: 14px;
  color: var(--ll-text-medium);
  margin-top: 4px;
}
.rating-tile .rating-stars {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
}
.rating-tile .rating-stars .icon-star {
  width: 18px;
  height: 18px;
  color: var(--ll-accent-solid);
}

/* ---------- CTA hierarchy — homepage --------------------
   The guiding principle: BASE STATE must do the selling. Hover
   animations already work well and are intentionally untouched.
   Each section's primary button gets confident padding + weight;
   secondary converts to a text link with an arrow. */

/* Hero primary — "Start a Project". More presence: generous
   padding so the label has breathing room, Inter 700 for weight.
   Fill stays the Webflow dark-token default (already high
   contrast against the warm paper hero bg). */
.hero-home-a-section .cta-main[data-wf--cta-main--variant="primary"] {
  padding: var(--ll-space-16) var(--ll-space-24);
}
.hero-home-a-section .cta-main[data-wf--cta-main--variant="primary"] .button-text {
  font-weight: var(--ll-weight-bold);
  font-size: 15px;
}

/* Hero secondary — "View Our Work". Strip button shape
   entirely: transparent bg, zero border. Becomes a plain text
   link clearly subordinate to the primary. Arrow glyph appended
   via CSS so it's part of the styling, not copy. */
.hero-home-a-section .cta-main[data-wf--cta-main--variant="secondary"] .button-bg {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
.hero-home-a-section .cta-main[data-wf--cta-main--variant="secondary"] {
  padding: var(--ll-space-12) var(--ll-space-12);
}
.hero-home-a-section .cta-main[data-wf--cta-main--variant="secondary"] .button-text {
  font-weight: var(--ll-weight-medium);
  font-size: 14px;
  color: var(--ll-text-medium);
}
.hero-home-a-section .cta-main[data-wf--cta-main--variant="secondary"] .button-text::after {
  content: " \2192";
  margin-left: 2px;
  display: inline-block;
  transition: transform 200ms var(--ll-ease-out);
}
.hero-home-a-section .cta-main[data-wf--cta-main--variant="secondary"]:hover .button-text::after {
  transform: translateX(3px);
}

/* Foundation section — "Your website is only as strong..." The
   CTA here was "Let's Talk" rendered as secondary (low weight).
   Promote its visual to primary so the reader has a confident
   action on this scroll stop. Copy change ("See How We Build")
   happens in index.html. */
.home-a-column-a-section .cta-main[data-wf--cta-main--variant="secondary"] .button-bg {
  background: var(--ll-text-strong) !important;
  border-color: var(--ll-text-strong) !important;
}
.home-a-column-a-section .cta-main[data-wf--cta-main--variant="secondary"] .button-text {
  color: var(--ll-bg-base) !important;
  font-weight: var(--ll-weight-bold);
  font-size: 15px;
}
.home-a-column-a-section .cta-main[data-wf--cta-main--variant="secondary"] {
  padding: var(--ll-space-16) var(--ll-space-24);
}

/* Dark banner CTA — on photography + dark overlay. Invert to
   white-fill + dark-text so the button reads against the bg. */
.callout-section .cta-main .button-bg {
  background: var(--ll-bg-base) !important;
  border-color: var(--ll-bg-base) !important;
}
.callout-section .cta-main .button-text {
  color: var(--ll-text-strong) !important;
  font-weight: var(--ll-weight-bold);
  font-size: 15px;
}
.callout-section .cta-main {
  padding: var(--ll-space-16) var(--ll-space-24);
}

/* "Here's how we begin" — both cards sit on dark surfaces.
   Invert CTAs to white-fill / dark-text so they pop. */
.cta-a-section .card-cta-a .cta-main .button-bg {
  background: var(--ll-bg-base) !important;
  border-color: var(--ll-bg-base) !important;
}
.cta-a-section .card-cta-a .cta-main .button-text {
  color: var(--ll-text-strong) !important;
  font-weight: var(--ll-weight-bold);
  font-size: 15px;
}
.cta-a-section .card-cta-a .cta-main {
  padding: var(--ll-space-16) var(--ll-space-24);
}

/* Promo "free of charge" CTA — this is the biggest-offer moment
   on the page. Make it the biggest button. Large padding, Inter
   700, dark fill / paper text. Copy change in index.html. */
html .promo-section-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 18px 32px;
  background: var(--ll-text-strong);
  color: var(--ll-bg-base);
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-bold);
  font-size: 16px;
  border-radius: var(--ll-radius-lg);
  border: 0;
  text-decoration: none;
  letter-spacing: 0;
  transition: background 200ms var(--ll-ease-out);
}
html .promo-section-btn:hover {
  background: #0f0e0e;
}

/* ---------- Dark banner — overlay + stats ---------------
   The Callout.webp photography has a warm amber cast when viewed
   through Webflow's default .overlay-callout (neutral-dark-4 +
   30px blur). Replace with a neutral linear-gradient left-to-
   right: darkest on the text side, thin on the photography side,
   so the image bleeds through without recoloring. Drop backdrop
   blur to 8px so the photo stays recognizable. */
.overlay-callout {
  background: linear-gradient(
    90deg,
    rgba(25, 24, 24, 0.72) 0%,
    rgba(25, 24, 24, 0.45) 50%,
    rgba(25, 24, 24, 0.12) 100%
  ) !important;
  -webkit-backdrop-filter: blur(8px) !important;
  backdrop-filter: blur(8px) !important;
}

/* Callout stat cells — force equal widths and give each label a
   max character width so all three wrap at the same point. */
.callout-stats-strip .callout-stat {
  flex: 1;
  min-width: 0;
}
.callout-stats-strip .callout-stat-label {
  max-width: 18ch;
  margin-left: 0;
  margin-right: auto;
}

/* ---------- FAQ accordion -------------------------------
   The Webflow .expandable-single rows sit on .bg-depth with
   12px radius and use a plus/vertical-bar indicator (webflow.js
   handles the toggle). Adding a subtle border-bottom on the row
   containers creates clear section-like separation so the FAQ
   reads as a styled component rather than unstyled HTML. */
.expandable-single {
  border-bottom: 1px solid var(--ll-border-subtle);
  transition: background-color 250ms var(--ll-ease-out);
}
.expandable-single:last-of-type {
  border-bottom: 0;
}
.expandable-single:hover {
  background: var(--ll-bg-lift);
}

/* The question line is already .text-body-bold on the Webflow
   side; we bump the font-size slightly so it reads as a proper
   FAQ question rather than body text. */
.expandable-single .expandable-top .text-body-bold {
  font-size: 17px;
  line-height: 1.5;
}

/* ============================================================
   4. CASE STUDIES — PART 2 POLISH
   ------------------------------------------------------------
   Scoped overrides that tune case-studies.css elements without
   touching the base file's tokens. Adds some CTA emphasis and
   consistent thumbnail treatment. See /LaunchLexV2Source/css/
   case-studies.css for the underlying component styles.
   ============================================================ */

/* "Read the full case study →" — previously rendered at body
   weight. These are the most important conversion links on the
   page, so add weight, size, underline, and breathing room. */
html .cs-chapter-cta {
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-semi);
  font-size: 15px;
  color: var(--ll-text-strong);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(25, 24, 24, 0.3);
  margin-top: 40px;
  border-bottom: 0;
  padding-bottom: 0;
  min-height: auto;
  gap: 8px;
}

/* More Work rail — the existing .cs-more-arrow span pairs a
   short label ("View Project") with an arrow glyph. The base
   state was visually light compared to its importance, so we
   promote it: text link style, explicit weight + size, arrow
   slides on hover (same micro-pattern as the rest of the site). */
.cs-more-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  font-family: var(--ll-font-body);
  font-size: 13px;
  font-weight: var(--ll-weight-semi);
  color: var(--ll-text-strong);
  transition: color 200ms var(--ll-ease-out);
}
.cs-more-arrow > span[aria-hidden="true"] {
  display: inline-block;
  transition: transform 200ms var(--ll-ease-out);
}
.cs-more-card:hover .cs-more-arrow {
  color: var(--ll-accent-solid);
}
.cs-more-card:hover .cs-more-arrow > span[aria-hidden="true"] {
  transform: translate(3px, -3px);
}

/* Thumbnail overlay — identical gradient on every More Work
   card regardless of the underlying image content, for visual
   consistency across UI screenshots + editorial photography. */
.cs-more-thumb {
  position: relative;
}
.cs-more-thumb::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 55%,
    rgba(25, 24, 24, 0.22) 100%
  );
  pointer-events: none;
}

/* Final CTA section — the last conversion opportunity after
   three full case studies. Primary becomes the biggest button on
   the page; secondary collapses to a plain text link. */
html .cs-cta-buttons .cs-btn.is-primary {
  padding: 18px 36px;
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-bold);
  font-size: 16px;
  border-radius: var(--ll-radius-lg);
}

html .cs-cta-buttons .cs-btn.is-secondary {
  padding: 18px 12px;
  background: transparent;
  border: 0;
  color: var(--ll-text-medium);
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-medium);
  font-size: 15px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.cs-cta-buttons .cs-btn.is-secondary::after {
  content: " \2192";
  display: inline-block;
  transition: transform 200ms var(--ll-ease-out);
}
.cs-cta-buttons .cs-btn.is-secondary:hover::after {
  transform: translateX(4px);
}
html .cs-cta-buttons .cs-btn.is-secondary:hover {
  color: var(--ll-text-strong);
}

/* Annashree placeholder — the device frame renders a dark-lift
   surface with centered url text until a real screenshot is
   provided. Keeps the frame shape readable in placeholder state. */
.cs-device-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ll-bg-dark-lift);
  color: var(--ll-text-on-dark-subtle);
  font-family: var(--ll-font-body);
  font-size: 12px;
  letter-spacing: 0.02em;
  text-align: center;
  padding: 0 12px;
  pointer-events: none;
}

/* ============================================================
   NAVIGATION — header component styles
   ============================================================ */

/* ── Header: logo sizing ── */
.logo-nav .logo-desktop { height: 52px; width: auto; }
.logo-nav .logo-mobile  { height: 40px; width: auto; display: none; }

/* ── Header: responsive logo toggle ── */
@media (max-width: 767px) {
  .logo-nav .logo-desktop { display: none; }
  .logo-nav .logo-mobile  { display: inline-block; }
  html .brand-navbar { width: auto; }
}

/* ── Header: right-side CTA group ── */
.nav-cta-group { display: flex; align-items: center; gap: 8px; }

/* ── Header: mobile button stack ── */
.button-wrap-nav { display: flex; flex-direction: column; gap: 8px; }

/* ── Nav layout fixes ── */
html .nav-container { align-items: center; }
html .left-nav { align-items: center; }
html .brand-navbar {
  width: 200px;
  display: flex;
  align-items: center;
}

/* ── Nav CTA (small) — shimmer animation on primary variant ── */
.cta-small[data-wf--cta-small--variant="primary"] {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, #1a3a6e 0%, #2563eb 50%, #1a3a6e 100%) !important;
  background-size: 200% 200% !important;
  animation: shimmer 3s ease infinite !important;
  border: 1px solid rgba(255,255,255,0.15) !important;
  box-shadow:
    0 0 12px rgba(37,99,235,0.4),
    0 0 30px rgba(37,99,235,0.15),
    inset 0 1px 0 rgba(255,255,255,0.1) !important;
  transition: box-shadow 0.3s ease, transform 0.2s ease !important;
}
.cta-small[data-wf--cta-small--variant="primary"]:hover {
  box-shadow:
    0 0 20px rgba(37,99,235,0.6),
    0 0 50px rgba(37,99,235,0.25),
    inset 0 1px 0 rgba(255,255,255,0.15) !important;
  transform: translateY(-1px) !important;
}
.cta-small[data-wf--cta-small--variant="primary"] .button-bg {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
@keyframes shimmer {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ============================================================
   FOOTER — .ll-footer component styles
   ------------------------------------------------------------
   These were previously embedded as a <style> block inside
   components/footer.html and injected via innerHTML. They belong
   here in the normal CSS cascade, loaded by every page via the
   site-overrides.css <link> tag.
   ============================================================ */
.ll-footer {
  font-family: 'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  color: #fff;
  position: relative;
  overflow: hidden;
  background: hsl(240 15% 5%);
}

/* ── Top accent line ── */
.ll-footer-accent {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(37,99,235,0.45), transparent);
}

/* ── Background court-line decoration ── */
.ll-footer-bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.ll-footer-arc {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(37,99,235,0.10);
}
.ll-footer-arc-1 { right: -128px; top: 50%; transform: translateY(-50%); width: 500px; height: 500px; }
.ll-footer-arc-2 { right: -192px; top: 50%; transform: translateY(-50%); width: 600px; height: 600px; border-color: rgba(37,99,235,0.06); }
.ll-footer-diag {
  position: absolute;
  height: 1px;
}
.ll-footer-diag-1 { right: 80px; top: 40px; width: 300px; transform: rotate(45deg); background: linear-gradient(90deg, transparent, rgba(37,99,235,0.12), transparent); }
.ll-footer-diag-2 { right: 160px; top: 80px; width: 250px; transform: rotate(45deg); background: linear-gradient(90deg, transparent, rgba(37,99,235,0.08), transparent); }
.ll-footer-diag-3 { right: 40px; bottom: 80px; width: 200px; transform: rotate(-12deg); background: linear-gradient(90deg, transparent, rgba(37,99,235,0.09), transparent); }
.ll-footer-corner {
  position: absolute;
  right: 0; bottom: 0;
  width: 128px; height: 128px;
  background: radial-gradient(circle at 100% 100%, rgba(37,99,235,0.07) 0%, transparent 70%);
}

/* ── Content wrapper ── */
.ll-footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 48px 24px 40px;
  position: relative;
}

/* ── Main grid ── */
.ll-footer-grid {
  display: grid;
  grid-template-columns: 5fr 3fr 3fr;
  gap: 48px;
  margin-bottom: 40px;
}

/* ── Brand column ── */
.ll-footer-brand a { display: inline-block; margin-bottom: 20px; transition: transform 0.2s; }
.ll-footer-brand a:hover { transform: scale(1.02); }
.ll-footer-brand img { height: 48px; width: auto; display: block; }
.ll-footer-brand p {
  font-size: 0.875rem;
  line-height: 1.7;
  color: hsl(240 8% 55%);
  margin: 0 0 24px;
  max-width: 360px;
  font-weight: 400;
}
.ll-footer-socials { display: flex; gap: 16px; margin-bottom: 24px; }
.ll-footer-socials a {
  color: hsl(240 8% 55%);
  transition: color 0.2s, opacity 0.2s;
  display: flex;
}
.ll-footer-socials a:hover { color: #fff; opacity: 0.9; }
.ll-footer-socials svg { width: 20px; height: 20px; }

/* ── Back-to-top button ── */
.ll-footer-top-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  border-radius: 8px;
  border: 1px solid hsla(240, 8%, 35%, 0.5);
  background: transparent;
  color: hsl(240 8% 65%);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
  font-family: inherit;
}
.ll-footer-top-btn:hover {
  border-color: hsla(240, 8%, 50%, 0.6);
  color: hsl(240 8% 80%);
  background: rgba(255,255,255,0.03);
}
.ll-footer-top-btn svg { width: 16px; height: 16px; }

/* ── Link columns ── */
.ll-footer-col-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: #fff;
  margin-bottom: 20px;
}
.ll-footer-links {
  display: flex;
  flex-direction: column;
  gap: 12px;
  list-style: none;
  margin: 0; padding: 0;
}
.ll-footer-links a {
  font-size: 0.875rem;
  color: hsl(240 8% 55%);
  text-decoration: none;
  transition: color 0.2s;
  font-weight: 400;
}
.ll-footer-links a:hover { color: #fff; }

/* ── Bottom bar ── */
.ll-footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 24px;
  border-top: 1px solid hsla(240, 8%, 18%, 0.5);
}
.ll-footer-copy {
  font-size: 0.75rem;
  color: hsl(240 8% 40%);
}
.ll-footer-credit {
  font-size: 0.75rem;
  color: hsl(240 8% 40%);
}
.ll-footer-credit a {
  font-weight: 500;
  background: linear-gradient(135deg, hsl(260 70% 70%), hsl(220 85% 72%), hsl(270 65% 75%), hsl(230 80% 70%));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  text-decoration: none;
  transition: filter 0.2s;
}
.ll-footer-credit a:hover { filter: brightness(1.25); }

/* ── Responsive ── */
@media (max-width: 900px) {
  .ll-footer-grid { grid-template-columns: 1fr 1fr; gap: 40px; }
  .ll-footer-brand { grid-column: 1 / -1; }
  .ll-footer-diag { display: none; }
}
@media (max-width: 600px) {
  .ll-footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
  .ll-footer-bottom { flex-direction: column; align-items: flex-start; gap: 8px; }
}

/* ============================================================
   SERVICES PAGE — refresh layer
   ------------------------------------------------------------
   Scoped polish for /services.html. Adds the B3 hero scanline
   texture, replaces the stock master-marquee with a single
   editorial photograph, swaps the fake brand logos for a tech
   stack marquee, and aligns the contact form + approach grid
   with the rest of the design system.
   ============================================================ */

/* B3 hero scanlines — same fixed-overlay treatment used on case
   studies, scoped here to the hero section so it doesn't bleed
   into the rest of the page. */
.ll-hero-scanlines { position: relative; }
.ll-hero-scanlines::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 87px,
    rgba(25, 24, 24, 0.025) 87px,
    rgba(25, 24, 24, 0.025) 88px
  );
  pointer-events: none;
  z-index: 0;
}
.ll-hero-scanlines > * { position: relative; z-index: 1; }
@media (max-width: 767px) {
  .ll-hero-scanlines::before {
    background-image: repeating-linear-gradient(
      to bottom,
      transparent 0px,
      transparent 63px,
      rgba(25, 24, 24, 0.025) 63px,
      rgba(25, 24, 24, 0.025) 64px
    );
  }
}

/* Hero subheadline — sits between the H1 and the primary CTA.
   Uses the body-1 type via .text-large but tightens the colour
   to the medium body token so it reads as supporting copy. */
.ll-hero-services-sub {
  max-width: 640px;
  margin: 0;
  color: var(--ll-text-medium);
}

/* Replace the legacy Webflow image-collage marquee with a single
   editorial photo. The figure is full-width like the original
   collage but renders one curated image at a controlled max
   height so it remains hero-scaled, not banner-scaled. */
.ll-hero-services-figure {
  margin: 0 auto;
  padding: 0 var(--ll-space-32, 32px);
  max-width: var(--ll-container-wide, 1800px);
}
.ll-hero-services-figure img {
  display: block;
  width: 100%;
  height: clamp(360px, 52vw, 640px);
  object-fit: cover;
  border-radius: var(--ll-radius-lg, 24px);
  box-shadow: var(--ll-shadow-lift, 0 40px 80px -32px rgba(25, 24, 24, 0.25));
}
@media (max-width: 767px) {
  .ll-hero-services-figure { padding: 0 16px; }
  .ll-hero-services-figure img {
    height: clamp(260px, 70vw, 420px);
    border-radius: 16px;
  }
}

/* Hide the original Webflow master-marquee (stock images +
   videos + duplicated phase widgets) without removing its
   markup — the Webflow JS still attaches to it on page load. */
.ll-hidden-marquee { display: none !important; }

/* ------------------------------------------------------------
   TECH STACK MARQUEE
   ------------------------------------------------------------
   Continuous-scroll rail of the tools we actually build with.
   Uses Simple Icons CDN (https://cdn.simpleicons.org/[slug])
   for crisp SVG logos, all rendered in the same muted gray
   so the rail reads as one cohesive band instead of a circus
   of brand colours.
   ------------------------------------------------------------ */
.ll-tech-marquee-section {
  padding: 56px 0 80px;
  background: var(--ll-bg-base);
}
.ll-tech-marquee-wrap {
  max-width: var(--ll-container-wide, 1800px);
  margin: 0 auto;
  padding: 0 var(--ll-space-32, 32px);
}
.ll-tech-marquee-label {
  display: block;
  text-align: center;
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-medium);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ll-text-subtle);
  margin: 0 0 32px;
}
.ll-tech-marquee {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 80px,
    #000 calc(100% - 80px),
    transparent 100%
  );
          mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 80px,
    #000 calc(100% - 80px),
    transparent 100%
  );
}
.ll-tech-marquee-track {
  display: flex;
  width: max-content;
  gap: 64px;
  align-items: center;
  animation: llTechMarqueeScroll 38s linear infinite;
}
.ll-tech-marquee:hover .ll-tech-marquee-track { animation-play-state: paused; }
.ll-tech-marquee-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  flex-shrink: 0;
}
.ll-tech-marquee-item img {
  height: 36px;
  width: auto;
  display: block;
  opacity: 0.78;
  transition: opacity var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease);
}
.ll-tech-marquee-item:hover img { opacity: 1; }

@keyframes llTechMarqueeScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .ll-tech-marquee-track { animation: none; }
}

@media (max-width: 767px) {
  .ll-tech-marquee-section { padding: 40px 0 56px; }
  .ll-tech-marquee-track { gap: 44px; }
  .ll-tech-marquee-item, .ll-tech-marquee-item img { height: 28px; }
  .ll-tech-marquee {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
  }
}

/* ------------------------------------------------------------
   APPROACH SECTION (REPLACES "You don't need more copy")
   ------------------------------------------------------------
   Stand-alone four-up grid of authentic-voice principles.
   No photo — the section is stronger as pure typography. */
.ll-approach-section {
  padding: 96px 0 112px;
  background: var(--ll-bg-base);
}
.ll-approach-wrap {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 var(--ll-space-32, 32px);
}
.ll-approach-head {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
  margin-bottom: 64px;
  max-width: 820px;
}
.ll-approach-head h2 {
  margin: 0;
  font-family: var(--ll-font-heading);
  color: var(--ll-text-strong);
}
.ll-approach-head .ll-approach-sub {
  margin: 0;
  color: var(--ll-text-medium);
  font-size: var(--ll-size-body-1);
  line-height: var(--ll-lh-body-1);
  max-width: 660px;
}
.ll-approach-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 56px 48px;
}
.ll-approach-tile {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ll-approach-num {
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-bold);
  font-size: 14px;
  letter-spacing: 0.12em;
  color: var(--ll-text-subtle);
  margin: 0 0 8px;
}
.ll-approach-tile h3 {
  margin: 0;
  font-family: var(--ll-font-heading);
  font-size: 24px;
  line-height: 1.25;
  color: var(--ll-text-strong);
  letter-spacing: -0.01em;
}
.ll-approach-tile p {
  margin: 0;
  color: var(--ll-text-body);
  font-size: 16px;
  line-height: 1.6;
}
@media (max-width: 767px) {
  .ll-approach-section { padding: 64px 0 72px; }
  .ll-approach-grid { grid-template-columns: 1fr; gap: 40px; }
  .ll-approach-head { margin-bottom: 40px; }
}

/* ------------------------------------------------------------
   SERVICES CONTACT FORM
   ------------------------------------------------------------
   The contact section sits on a dark surface (set by the
   Webflow tokens in halden-miller.webflow.css), so every label
   / input / checkbox state needs to read as light-on-dark while
   still feeling like the rest of the design system. */
.ll-services-contact-sub {
  margin: 16px 0 0;
  max-width: 640px;
  color: var(--ll-text-on-dark-medium);
  font-size: var(--ll-size-body-1);
  line-height: var(--ll-lh-body-1);
}
.services-contact-section .text-input-label {
  font-family: var(--ll-font-body);
  font-size: 11px;
  font-weight: var(--ll-weight-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ll-text-on-dark-subtle);
  margin-bottom: 8px;
}
.services-contact-section .text-field {
  border: 1px solid var(--ll-border-dark-medium);
  border-radius: 4px;
  padding: 14px 16px;
  font-family: var(--ll-font-body);
  font-weight: var(--ll-weight-regular);
  font-size: 15px;
  line-height: 1.4;
  background: rgba(247, 247, 242, 0.04);
  color: var(--ll-text-on-dark-strong);
  transition: border-color var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease),
              box-shadow var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease),
              background-color var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease);
}
.services-contact-section .text-field::placeholder {
  color: var(--ll-text-on-dark-subtle);
}
.services-contact-section .text-field:focus,
.services-contact-section .text-field:focus-visible {
  border-color: var(--ll-text-on-dark-strong);
  outline: none;
  background: rgba(247, 247, 242, 0.06);
  box-shadow: 0 0 0 3px rgba(247, 247, 242, 0.1);
}
.services-contact-section select.text-field {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.services-contact-section .textarea-contact-a { min-height: 140px; resize: vertical; }
.services-contact-section .checkbox-contact {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--ll-border-dark-strong);
  border-radius: 3px;
  background: rgba(247, 247, 242, 0.04);
  margin-right: 10px;
  transition: background var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease),
              border-color var(--ll-dur-fast, 160ms) var(--ll-ease-out, ease);
}
.services-contact-section .checkbox-contact.w--redirected-checked {
  background-color: var(--ll-text-on-dark-strong);
  border-color: var(--ll-text-on-dark-strong);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'><path d='M3.5 8.5l3 3 6-7' stroke='%23191818' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-size: 14px 14px;
  background-position: center;
  background-repeat: no-repeat;
}
.services-contact-section .checkbox-contact.w--redirected-focus {
  box-shadow: 0 0 0 3px rgba(247, 247, 242, 0.15);
}
.services-contact-section .checkbox-text {
  color: var(--ll-text-on-dark-medium);
  font-size: 14px;
}
.services-contact-section .text-underline {
  color: var(--ll-text-on-dark-strong);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================
   SHARED CTA COMPONENT
   ------------------------------------------------------------
   Markup lives in /components/cta.html and is mounted by
   site-chrome.js into <div id="site-cta" data-...>. Selectors
   stay .cs-* to preserve existing case-studies.html visuals;
   variable references swapped from --cs-* to --ll-* so the
   rules work on any page without case-studies.css loaded.
   Originally lived at the bottom of /css/case-studies.css.
   ============================================================ */

/* Minimal .cs-container fallback so the CTA component can mount on
   pages that don't load case-studies.css. case-studies.css declares
   the same rule; identical values mean no specificity conflicts. */
[data-ll-cta] .cs-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  width: 100%;
}

.cs-cta {
  padding: 140px 0;
  text-align: center;
  border-top: 1px solid var(--ll-border-subtle);
}
.cs-cta-avatars {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 40px;
}
.cs-cta-avatars img {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid var(--ll-text-strong);
  object-fit: cover;
  margin-left: -12px;
  background: var(--ll-bg-lift);
}
.cs-cta-avatars img:first-child { margin-left: 0; }
.cs-cta-headline {
  font-family: var(--ll-font-body);
  font-weight: 800;
  font-size: clamp(28px, 4.5vw, 54px);
  line-height: 1.1;
  letter-spacing: -0.04em;
  color: var(--ll-text-strong);
  margin-bottom: 24px;
}
.cs-cta-sub {
  max-width: 560px;
  margin: 0 auto 48px;
  font-family: var(--ll-font-body);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.75;
  color: var(--ll-text-medium);
}
.cs-cta-buttons {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  justify-content: center;
}
.cs-btn {
  display: inline-flex;
  align-items: center;
  padding: 14px 28px;
  font-family: var(--ll-font-body);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  border-radius: 4px;
  border: 1px solid transparent;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.cs-btn.is-primary {
  background: var(--ll-text-strong);
  color: var(--ll-bg-base);
  border-color: var(--ll-text-strong);
}
.cs-btn.is-primary:hover {
  background: transparent;
  color: var(--ll-text-strong);
}
.cs-btn.is-secondary {
  background: transparent;
  color: var(--ll-text-strong);
  border-color: var(--ll-text-strong);
}
.cs-btn.is-secondary:hover {
  background: var(--ll-text-strong);
  color: var(--ll-bg-base);
}
@media (max-width: 900px) {
  .cs-cta { padding: 64px 0; }
  .cs-cta-avatars { margin-bottom: 28px; }
  .cs-cta-avatars img { width: 38px; height: 38px; border-width: 2px; }
  .cs-cta-headline { margin-bottom: 20px; }
  .cs-cta-sub { font-size: 16px; line-height: 1.65; margin-bottom: 32px; }
  .cs-cta-buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 280px;
    margin: 0 auto;
  }
  .cs-btn { justify-content: center; width: 100%; padding: 14px 20px; font-size: 14px; }
}
@media (max-width: 480px) {
  .cs-cta { padding: 56px 0; }
  .cs-cta-headline { font-size: 28px; }
}

/* ============================================================================
   PROMO ANNOUNCEMENT BAR (top of every page)
   ----------------------------------------------------------------------------
   Markup: components/promo-bar.html. Mounted at the top of <body> on every
   page by js/site-chrome.js → loadPromoBar(). Was previously inline in
   index.html only; lifted to a global so every page gets the same banner.
   ============================================================================ */
.promo-bar {
  position: relative;
  height: 36px;
  background: #ffffff;
  color: #0a0f1e;
  text-align: center;
  padding: 0 44px 0 16px;
  font-family: 'Inter', sans-serif;
  border-bottom: 1px solid rgba(37, 99, 235, 0.2);
  box-shadow:
    0 2px 28px rgba(37, 99, 235, 0.18),
    inset 0 0 80px rgba(147, 197, 253, 0.06);
  overflow: hidden;
  display: flex;
  align-items: center;
  z-index: 1100;
}
/* Two soft spotlight ellipses sweeping back-and-forth so the bar
   reads as alive without animating any text. */
.promo-bar::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 380px;
  height: 380px;
  background: radial-gradient(ellipse at center,
    rgba(59, 130, 246, 0.38) 0%,
    rgba(37, 99, 235, 0.18) 30%,
    transparent 68%);
  transform: translateY(-50%);
  animation: promo-sweep-left 7s ease-in-out infinite alternate;
  pointer-events: none;
}
.promo-bar::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 280px;
  height: 280px;
  background: radial-gradient(ellipse at center,
    rgba(99, 179, 255, 0.3) 0%,
    rgba(147, 197, 253, 0.14) 35%,
    transparent 65%);
  transform: translateY(-50%);
  animation: promo-sweep-right 7s ease-in-out infinite alternate;
  pointer-events: none;
}
@keyframes promo-sweep-left {
  0%   { left: 5%;  opacity: 0.6; transform: translateY(-50%) scale(0.85); }
  40%  { opacity: 1; }
  100% { left: 70%; opacity: 0.85; transform: translateY(-50%) scale(1.15); }
}
@keyframes promo-sweep-right {
  0%   { left: 75%; opacity: 0.85; transform: translateY(-50%) scale(1.1); }
  60%  { opacity: 1; }
  100% { left: 10%; opacity: 0.6; transform: translateY(-50%) scale(0.8); }
}
.promo-bar-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: nowrap;
  max-width: 1000px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
}
.promo-tag {
  background: rgba(37, 99, 235, 0.1);
  border: 1px solid rgba(37, 99, 235, 0.25);
  border-radius: 3px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #2563eb;
  padding: 2px 7px;
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1.4;
}
.promo-bar-text {
  font-size: 12px;
  line-height: 1;
  color: #374151;
  white-space: nowrap;
}
/* Mobile-only condensed message — hidden on desktop, replaces the long
   desktop sentence + tag + divider + CTA on screens < 768px so the bar
   stays a clean single line at 36px without clipping. */
.promo-bar-text--mobile {
  display: none;
}
.promo-bar-text strong {
  color: #1e3a8a;
  font-weight: 600;
}
.promo-bar-divider {
  width: 1px;
  height: 14px;
  background: rgba(37, 99, 235, 0.2);
  flex-shrink: 0;
}
.promo-bar-cta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #2563eb;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  letter-spacing: 0.01em;
  border-bottom: 1px solid rgba(37, 99, 235, 0.35);
  padding-bottom: 1px;
  transition: color 0.15s, border-color 0.15s;
  flex-shrink: 0;
}
.promo-bar-cta:hover {
  color: #1d4ed8;
  border-color: #1d4ed8;
}
.promo-bar-dismiss {
  background: none;
  border: none;
  color: #9ca3af;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  transition: color 0.2s;
  z-index: 2;
  padding: 4px;
}
.promo-bar-dismiss:hover { color: #374151; }

/* Push the desktop sticky nav down so the promo bar sits above it.
   Mobile nav handles its own offset via --ll-mnav-promo-h in mobile.css. */
.master-navigation { top: 36px !important; }
.master-navigation.sticky { top: 36px !important; }
/* When promo is dismissed or scrolled past, the desktop sticky nav
   resets to the top edge. */
body.promo-dismissed .master-navigation,
body.promo-dismissed .master-navigation.sticky,
body.promo-hidden    .master-navigation.sticky { top: 0 !important; }

@media (max-width: 767px) {
  /* Tighter padding on mobile — single-line condensed copy fits the
     fixed 36px height without clipping. */
  .promo-bar { padding: 0 40px 0 14px; }
  .promo-bar-inner { gap: 0; justify-content: center; }
  /* Hide the long desktop content; show the condensed mobile line. */
  .promo-bar .promo-tag,
  .promo-bar .promo-bar-text,
  .promo-bar .promo-bar-divider,
  .promo-bar .promo-bar-cta { display: none; }
  .promo-bar-text--mobile {
    display: inline-flex;
    align-items: center;
    font-size: 12px;
    line-height: 1;
    color: #374151;
    white-space: nowrap;
    text-decoration: none;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .promo-bar-text--mobile strong { color: #1e3a8a; font-weight: 600; }
}

/* ============================================================
   Hero trust line — avatars + social proof bar
   ============================================================ */
.ll-trust-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--ll-font-body);
  font-size: 13px;
  font-weight: 400;
  color: var(--ll-text-medium);
  line-height: 1;
}

.ll-trust-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}

.ll-trust-item strong {
  font-weight: 600;
  color: var(--ll-text-strong);
}

.ll-trust-icon {
  display: inline-flex;
  align-items: center;
  color: #d4a017;
  flex-shrink: 0;
}

.ll-trust-sep {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ll-text-subtle);
  flex-shrink: 0;
}
