/**
 * landing.css - Landing page (index.php) UI polish ONLY.
 *
 * Loaded exclusively by index.php (see the cssAsset() link in its <head>).
 * Every rule is scoped to `.landing-page` â€” the class added to
 * <main id="main-content"> on the landing page â€” so this file can never
 * affect the standalone frontend pages, the shared components or the admin
 * panel even if it were linked elsewhere.
 *
 * Design language (kept identical to the navbar + the stats strip):
 *   navy        #06163a   (primary brand blue: navbar rail, dark bands, text accents)
 *   navy deep   #04122e   (drawer + scrolled header)
 *   cyan        #22b8d1   (primary accent, buttons, active states)
 *   brand light #E8ECF4   (chips, active pill backgrounds)
 *   brand cloud #b9c2d6   (muted brand tone)
 * No new colors are introduced â€” the variables below are aliases only.
 * ============================================================ */

/* ============================================================
   1. TOKENS
   ============================================================ */
.landing-page {
    --lp-navy: #06163a;
    --lp-navy-deep: #04122e;
    --lp-cyan: #22b8d1;
    --lp-light: #E8ECF4;
    --lp-cloud: #b9c2d6;
    --lp-ink: #33424d;
    --lp-muted: #64748b;
    --lp-line: #e6ecf2;
    --lp-radius: 1rem;
    --lp-ease: cubic-bezier(0.16, 1, 0.3, 1);
    --lp-sticky-nav-h: 46px;
    overflow-anchor: none;
}

/* Below the desktop breakpoint only the nav rail stays on screen and it is
   62px tall there (home.css @media max-width:1023px), so the section offset
   tracks that instead of the 46px desktop rail. */
@media (max-width: 1023px) {
    .landing-page {
        --lp-sticky-nav-h: 62px;
    }
}

/* ============================================================
   2. SECTION HEADER (one canonical recipe for all sections)
   eyebrow pill -> headline -> subtitle -> accent rule
   ============================================================ */
.landing-page .lp-head {
    text-align: center;
    max-width: 46rem;
    margin: 0 auto clamp(2.5rem, 4vw, 4rem);
}

.landing-page .lp-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 1rem;
    border-radius: 9999px;
    background: rgba(34, 184, 209, 0.10);
    border: 1px solid rgba(34, 184, 209, 0.30);
    color: var(--lp-navy);
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    white-space: nowrap;
}

.landing-page .lp-eyebrow__dot {
    width: 0.375rem;
    height: 0.375rem;
    border-radius: 9999px;
    background: var(--lp-cyan);
    flex-shrink: 0;
}

/* Eyebrow on a navy band: the cyan reads directly on the dark surface. */
.landing-page .lp-eyebrow--invert {
    color: var(--lp-cyan);
    background: rgba(34, 184, 209, 0.12);
    border-color: rgba(34, 184, 209, 0.32);
}

@media (min-width: 640px) {
    .landing-page .lp-eyebrow {
        font-size: 0.8125rem;
        padding: 0.45rem 1.15rem;
    }
}

.landing-page .lp-title {
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.75rem, 1.15rem + 2.4vw, 3rem);
    font-weight: 800;
    line-height: 1.12;
    letter-spacing: -0.02em;
    margin: 1rem 0 0;
}

.landing-page .lp-title--light {
    color: #0f172a;
}

.landing-page .lp-title--dark {
    color: #ffffff;
}

/* One accent word per headline (cyan on every band, as in the navbar). */
.landing-page .lp-accent {
    color: var(--lp-cyan);
}

.landing-page .lp-sub {
    font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.125rem);
    line-height: 1.7;
    color: #475569;
    max-width: 40rem;
    margin: 1rem auto 0;
}

.landing-page .lp-sub--dark {
    color: rgba(226, 232, 240, 0.92);
}

/* Accent rule: 64 x 4px, brand cyan -> brand navy. */
.landing-page .lp-rule {
    display: block;
    width: 4rem;
    height: 0.25rem;
    border-radius: 9999px;
    margin: 1.5rem auto 0;
    background: linear-gradient(90deg, var(--lp-cyan), var(--lp-navy));
}

/* ============================================================
   3. BUTTON SYSTEM
   One primary, one photo/dark ghost, one outline. The primary is
   the flat #22b8d1 fill used by the navbar's "Request A Quote"
   button, so every CTA feels like the same control family.
   ============================================================ */
.landing-page .lp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.625rem;
    min-height: 3rem;
    padding: 0 2rem;
    border: 1px solid transparent;
    border-radius: 0.75rem;
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.01em;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    transition: background-color 0.25s ease, border-color 0.25s ease,
        color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}

.landing-page .lp-btn i,
.landing-page .lp-btn svg {
    transition: transform 0.3s var(--lp-ease);
}

.landing-page .lp-btn:hover i,
.landing-page .lp-btn:hover svg {
    transform: translateX(0.25rem);
}

.landing-page .lp-btn--primary {
    background: var(--lp-cyan);
    color: #ffffff;
    box-shadow: 0 10px 26px -12px rgba(34, 184, 209, 0.85);
}

.landing-page .lp-btn--primary:hover {
    background: var(--lp-navy);
    box-shadow: 0 16px 32px -12px rgba(34, 184, 209, 0.90);
    transform: translateY(-2px);
}

/* Photo / dark band: navy glass so it stays legible over imagery. */
.landing-page .lp-btn--ghost {
    background: rgba(6, 22, 58, 0.72);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.40);
    backdrop-filter: blur(10px);
    box-shadow: 0 10px 26px -14px rgba(3, 12, 30, 0.90);
}

.landing-page .lp-btn--ghost:hover {
    background: rgba(6, 22, 58, 0.90);
    border-color: #ffffff;
    transform: translateY(-2px);
}

/* Dark section: subtle white wash secondary. */
.landing-page .lp-btn--outline {
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.25);
}

.landing-page .lp-btn--outline:hover {
    background: rgba(255, 255, 255, 0.20);
    border-color: rgba(255, 255, 255, 0.45);
    transform: translateY(-2px);
}

/* Light surface (white sections): hairline slate secondary that answers
   with the brand cyan on hover â€” same language as the navbar links. */
.landing-page .lp-btn--light {
    background: #ffffff;
    color: #0f172a;
    border-color: #e2e8f0;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04);
}

.landing-page .lp-btn--light:hover {
    color: var(--lp-navy);
    border-color: rgba(34, 184, 209, 0.55);
    background: #ffffff;
    box-shadow: 0 14px 30px -16px rgba(34, 184, 209, 0.65);
    transform: translateY(-2px);
}

.landing-page .lp-btn:active {
    transform: translateY(0) scale(0.98);
}

.landing-page .lp-btn:focus-visible {
    outline: 2px solid var(--lp-cyan);
    outline-offset: 3px;
}

@media (min-width: 640px) {
    .landing-page .lp-btn {
        font-size: 1rem;
        min-height: 3.25rem;
    }
}

/* ============================================================
   Cards now come from the shared .flip-card component in home.css;
   the old card recipe was removed with the card unification.
   ============================================================ */

/* ============================================================
   6. FEATURE STRIP
   The stats bar and the About strip share one recipe: equal-height
   items, 48px icon tiles, bold title + muted non-clipped subtitle.
   ============================================================ */
.landing-page #stats .feature-item,
.landing-page #about .feature-item {
    height: 100%;
    align-items: center;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.landing-page #stats .feature-item-title,
.landing-page #about .feature-item-title {
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

@media (min-width: 640px) {

    .landing-page #stats .feature-item-title,
    .landing-page #about .feature-item-title {
        font-size: 1rem;
    }
}

/* Subtitle: never truncate (the shared `truncate` utility clipped
   longer copy such as "The price is always reasonable & good"). */
.landing-page #stats .feature-item-subtitle,
.landing-page #about .feature-item-subtitle {
    margin-top: 0.25rem;
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.8125rem;
    line-height: 1.45;
    color: #64748b;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

/* The About strip items lift slightly on hover, like the stats bar. */
.landing-page #about .feature-item {
    transition: background-color 0.25s ease, transform 0.25s ease;
}

.landing-page #about .feature-item:hover {
    transform: translateY(-2px);
}

/* ============================================================
   7. SECTION-SPECIFIC REFINEMENTS
   ============================================================ */

/* --- About: soft slate feature-strip band (sits between the white navbar /
   stats bar above and the white services band below, so the section reads as
   its own gentle step without breaking the page's light rhythm) --- */
.landing-page #about {
    position: relative;
    background: #f8fafc;
}

/* Soft brand glow behind the band: the navbar/stats cyan used as light so
   the tint never reads as flat and the strip pops out of it. */
.landing-page #about::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(60rem 22rem at 90% -8%, rgba(34, 184, 209, 0.12), transparent 68%),
        radial-gradient(48rem 20rem at -8% 112%, rgba(6, 22, 58, 0.055), transparent 68%);
}

/* --- About watermark: a subtle, elegant brand signature behind the content
   (z-index 0 â€” the content shell above it is `relative z-10`). Two composed
   layers: the WebStrive "W" monogram drawn as inline-SVG strokes in brand
   navy at very low alpha (no extra HTTP request â€” the same data-URI technique
   already used in admin.css), plus a fine dot grid that fades out over the
   copy column. Static by design (nothing to disable for reduced motion) and
   purely decorative: `pointer-events: none` + `aria-hidden` on the element. --- */
.landing-page #about .about-watermark {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    background-image:
        url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240' fill='none'%3E%3Cpath d='M40 50L90 190L120 100L150 190L200 50' stroke='%2306163a' stroke-opacity='0.07' stroke-width='7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
        radial-gradient(rgba(6, 22, 58, 0.05) 1px, transparent 1.5px);
    background-repeat: no-repeat, repeat;
    background-position: right 2% bottom 6%, 0 0;
    background-size: clamp(18rem, 32vw, 30rem) auto, 22px 22px;
    -webkit-mask-image: radial-gradient(125% 125% at 16% 52%, transparent 0%, rgba(0, 0, 0, 0.35) 40%, #000 80%);
    mask-image: radial-gradient(125% 125% at 16% 52%, transparent 0%, rgba(0, 0, 0, 0.35) 40%, #000 80%);
}

/* Phones: drop the watermark so the stacked layout stays perfectly clean. */
@media (max-width: 640px) {
    .landing-page #about .about-watermark {
        display: none;
    }
}

/* --- About strip: the same raised surface + hairline language as #stats,
   so the four value items read as the page's second reference bar.
   The wrapper keeps its Tailwind utilities as a no-CSS fallback; the
   higher-specificity rules here own the band. --- */
.landing-page #about .about-strip {
    position: relative;
    z-index: 10;
    margin-top: clamp(2.5rem, 4vw, 3.5rem);
    padding: clamp(0.75rem, 1.6vw, 1.125rem) clamp(0.5rem, 1.4vw, 1rem);
    border: 1px solid var(--lp-line);
    border-radius: var(--lp-radius);
    background: #ffffff;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 22px 48px -34px rgba(6, 22, 58, 0.55);
}

/* Hairline dividers: the band is the raised white surface now (it inverted
   with the section tint), so the dividers keep the same one-step-stronger
   slate tone the stats bar uses on white. */
.landing-page #about .about-strip .feature-item {
    border-color: #e2e8f0;
}

/* Hover: the item settles onto the slate tint â€” the exact mirror of the
   stats bar's lift-onto-white language, tuned for the white band. */
.landing-page #about .about-strip .feature-item:hover {
    background-color: #f8fafc;
    box-shadow: 0 12px 26px -20px rgba(6, 22, 58, 0.55);
}

/* --- About media composition: same radius / hairline language as the
   strip tiles so the photography belongs to the feature-strip system. --- */
.landing-page #about .about-media {
    border-radius: var(--lp-radius);
    box-shadow: 0 30px 60px -36px rgba(6, 22, 58, 0.65);
}

.landing-page #about .about-media-float {
    border-radius: var(--lp-radius);
    border-color: #ffffff;
    box-shadow: 0 26px 50px -26px rgba(6, 22, 58, 0.60);
}

/* --- Video: navy -> cyan brand overlay (no stray teal / sky) --- */
.landing-page #video .lp-btn--play {
    background: var(--lp-cyan);
    border: 3px solid rgba(255, 255, 255, 0.85);
    color: #ffffff;
    box-shadow: 0 18px 40px -14px rgba(6, 22, 58, 0.9);
}

.landing-page #video .lp-btn--play:hover {
    background: var(--lp-navy);
    border-color: #ffffff;
    transform: scale(1.07);
}

/* --- Team: social circles mirror the navbar treatment --- */
.landing-page #team .lp-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 9999px;
    border: 1.5px solid rgba(34, 184, 209, 0.45);
    background: #f8fafc;
    color: var(--lp-navy);
    font-size: 0.75rem;
    line-height: 1;
    text-decoration: none;
    transition: background-color 0.25s ease, border-color 0.25s ease,
        color 0.25s ease, transform 0.25s ease;
}

.landing-page #team .lp-social:hover {
    background: var(--lp-navy);
    border-color: var(--lp-navy);
    color: #ffffff;
    transform: translateY(-2px);
}

/* --- Testimonials: compact Google proof badge (header) ---
   Only rendered when a Google place is connected, so the band never shows an
   empty "0.0" chip. */
.landing-page #testimonials .tst-rating-badge {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.35rem 0.6rem;
    margin-top: 1.5rem;
    padding: 0.5rem 1rem;
    border-radius: 9999px;
    border: 1px solid rgba(34, 184, 209, 0.28);
    background: rgba(255, 255, 255, 0.75);
    box-shadow: 0 12px 28px -20px rgba(6, 22, 58, 0.55);
    font-size: 0.8125rem;
    line-height: 1;
    color: var(--lp-muted);
}

.landing-page #testimonials .tst-rating-badge__stars {
    color: #f59e0b;
    font-size: 0.9rem;
}

.landing-page #testimonials .tst-rating-badge__score {
    font-weight: 800;
    font-size: 0.95rem;
    color: var(--lp-navy);
    font-variant-numeric: tabular-nums;
}

.landing-page #testimonials .tst-rating-badge__link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding-left: 0.6rem;
    border-left: 1px solid rgba(6, 22, 58, 0.12);
    font-weight: 700;
    color: #0e7490;
    text-decoration: none;
    transition: color 0.25s ease;
}

.landing-page #testimonials .tst-rating-badge__link:hover,
.landing-page #testimonials .tst-rating-badge__link:focus-visible {
    color: var(--lp-cyan);
    text-decoration: underline;
}

/* --- Testimonials: the slider itself ---
   Swiper sizes the slides from the element's own border box, so this
   container must stay padding-free (a horizontal padding here is silently
   eaten by the slide width and clips the last card). Vertical breathing
   room for the card hover-shadow comes from the wrapper instead. */
.landing-page #testimonials .testimonials-swiper {
    overflow: hidden;
}

.landing-page #testimonials .testimonials-swiper .swiper-wrapper {
    padding-bottom: 1.25rem;
}

/* Slides are flex columns so every card in a row stretches to the height of
   the tallest one, instead of each card floating at its own natural height. */
.landing-page #testimonials .tst-slide {
    display: flex;
    height: auto;
}

.landing-page #testimonials .tst-slide>.tst-card {
    width: 100%;
}

/* Decorative quote glyph, tucked behind the card content. */
.landing-page #testimonials .tst-card::after {
    content: "\201C";
    position: absolute;
    top: 0.25rem;
    right: 0.9rem;
    font-family: 'Fraunces', Georgia, serif;
    font-size: 5.5rem;
    line-height: 1;
    color: rgba(34, 184, 209, 0.12);
    pointer-events: none;
    z-index: 0;
}

.landing-page #testimonials .tst-card>* {
    position: relative;
    z-index: 1;
}

.landing-page #testimonials .tst-card {
    transition: transform 0.35s var(--lp-ease), box-shadow 0.35s ease,
        border-color 0.35s ease;
}

.landing-page #testimonials .tst-card:hover,
.landing-page #testimonials .tst-card:focus-within {
    transform: translateY(-4px);
}

/* --- Testimonials: dot indicator ---
   The band ships no arrow buttons and no "01 / 06" counter, so this row is
   the slider's whole control surface: clickable bullets that also show which
   card is currently on screen. */
.landing-page #testimonials .testimonial-slider-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.75rem clamp(0.9rem, 2.2vw, 1.5rem);
    margin-top: clamp(1rem, 2vw, 1.5rem);
}

/* The slider hides the whole row when every card already fits. */
.landing-page #testimonials .testimonial-slider-nav[hidden] {
    display: none;
}

.landing-page #testimonials .testimonial-pagination-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
    min-width: 0;
}

.landing-page #testimonials .testimonial-pagination {
    position: static;
    width: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
}

.landing-page #testimonials .swiper-pagination-bullet {
    width: 0.5rem;
    height: 0.5rem;
    margin: 0 !important;
    border-radius: 9999px;
    background: rgba(15, 23, 42, 0.22);
    opacity: 1;
    cursor: pointer;
    transition: width 0.35s var(--lp-ease), background-color 0.3s ease;
}

.landing-page #testimonials .swiper-pagination-bullet:hover {
    background: rgba(34, 184, 209, 0.55);
}

.landing-page #testimonials .swiper-pagination-bullet:focus-visible {
    outline: 2px solid var(--lp-cyan);
    outline-offset: 3px;
}

.landing-page #testimonials .swiper-pagination-bullet-active {
    width: 1.75rem;
    background: var(--lp-cyan);
}

/* --- Testimonials: responsive + motion preferences --- */
@media (max-width: 639px) {
    .landing-page #testimonials .tst-rating-badge {
        gap: 0.3rem 0.5rem;
        padding: 0.45rem 0.85rem;
        font-size: 0.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .landing-page #testimonials .tst-card,
    .landing-page #testimonials .tst-card:hover,
    .landing-page #testimonials .swiper-pagination-bullet {
        transition: none;
    }

    .landing-page #testimonials .tst-card:hover {
        transform: none;
    }
}


/* --- Section scroll offset ---------------------------------------------
   Every menu-mapped section anchors its top edge just below the sticky
   navbar. This is the no-JS / native-anchor counterpart of the offset the
   sectionNav block in component/scripts.php applies at runtime, and it
   deliberately REPLACES the blanket `section[id] { scroll-margin-top: 126px }`
   in home.css: 126px is the FULL header (80px info rail + 46px navbar), and
   the info rail collapses after 80px, so that value parks every section a whole
   rail too low. Scoped to .landing-page so the standalone pages, which keep a
   different header, are untouched. --- */
.landing-page section[id] {
    scroll-margin-top: var(--lp-sticky-nav-h);
}

/* Hero is the first section at the very top of the document: it must never
   inherit the navbar offset above, otherwise a native /#hero anchor (or the
   browser's pre-JS anchor jump) parks it one navbar-height below the top. */
.landing-page #hero {
    scroll-margin-top: 0 !important;
    scroll-padding-top: 0 !important;
}

/* --- Contact: canonical header, applied through the landing scope
       only. component/contact.php markup is shared with the standalone
       /contact page, so it stays byte-identical and is styled here. --- */
.landing-page #contact h2 {
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.75rem, 1.15rem + 2.4vw, 3rem);
    font-weight: 800;
    line-height: 1.12;
    letter-spacing: -0.02em;
    margin-top: 1rem;
}

/* Accent word: flat brand cyan like every other landing headline. */
.landing-page #contact h2>span {
    background-image: none !important;
    color: var(--lp-cyan);
    -webkit-text-fill-color: var(--lp-cyan);
}

/* Accent rule under the header (left aligned on the lg two-column layout). */
.landing-page #contact header::after {
    content: "";
    display: block;
    width: 4rem;
    height: 0.25rem;
    border-radius: 9999px;
    margin: 1.5rem auto 0;
    background: linear-gradient(90deg, var(--lp-cyan), var(--lp-navy));
}

@media (min-width: 1024px) {
    .landing-page #contact header::after {
        margin-left: 0;
        margin-right: auto;
    }
}

/* Form controls + submit: one comfortable size across all three tabs. */
.landing-page #contact input,
.landing-page #contact textarea,
.landing-page #contact select {
    border-radius: 0.75rem;
}

.landing-page #contact form button[type="submit"] {
    min-height: 3.25rem;
    border-radius: 0.75rem;
    font-size: 1rem;
}

/* --- Services Section (Redesigned: clean grid + asia map bg) --- */
/* No background colour â€” the section inherits the page background */
.landing-page #services {
    position: relative;
    background: linear-gradient(to bottom, #fbf4ff 0%, #f9efff 100%);
}

/* Asia map watermark â€” cropped into the upper background band */
.landing-page #services .services-map-bg {
    background-image: url('assets/img/services/world_map_bg.jpg');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
    height: 550px;
    bottom: auto;
    opacity: 0.22;
    mix-blend-mode: multiply;
}

.landing-page #services::before,
.landing-page #services::after {
    content: "";
    position: absolute;
    z-index: 0;
    pointer-events: none;
}

/* Reference watermark: soft dot matrix at the lower left. */
.landing-page #services::before {
    bottom: 28px;
    left: max(8%, calc((100% - 1240px) / 2));
    width: 130px;
    height: 125px;
    background-image: radial-gradient(circle, rgba(185, 194, 214, 0.34) 0 5px, transparent 5.5px);
    background-size: 20px 20px;
}

/* Reference watermark: fine diagonal strokes at the lower right. */
.landing-page #services::after {
    bottom: 22px;
    right: max(8%, calc((100% - 1240px) / 2));
    width: 135px;
    height: 125px;
    background: repeating-linear-gradient(120deg, transparent 0 8px, rgba(185, 194, 214, 0.25) 9px 11px, transparent 12px 18px);
    transform: skewX(-8deg);
}

@media (max-width: 767px) {
    .landing-page #services {
        background: linear-gradient(to bottom, #fbf4ff 0%, #f9efff 100%);
    }

    .landing-page #services .services-map-bg {
        height: 420px;
    }

    .landing-page #services::before {
        left: 8%;
        bottom: 22px;
        transform: scale(0.8);
        transform-origin: left top;
    }

    .landing-page #services::after {
        right: 7%;
        bottom: 18px;
        transform: skewX(-8deg) scale(0.8);
        transform-origin: right top;
    }
}

/* Service cards moved to the shared .flip-card component (home.css). */
/* "View All Services" CTA */
.landing-page .view-all-services-btn {
    transition: transform 0.25s ease, box-shadow 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}

.landing-page .view-all-services-btn:hover {
    background: var(--lp-cyan);
    color: #ffffff;
    transform: translateY(-2px);
    box-shadow: 0 12px 28px -6px rgba(34, 184, 209, 0.5);
}

/* ============================================================
   8. REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {

    .landing-page .lp-btn,
    .landing-page .lp-btn i,
    .landing-page .lp-btn svg,
    .landing-page .view-all-services-btn {
        transition: none !important;
    }

    .landing-page .lp-btn:hover,
    .landing-page #about .feature-item:hover {
        transform: none !important;
    }

    .landing-page #about .feature-item {
        transition: none !important;
    }
}

/* ============================================================
   9. HEADER / EDGE-CASE SAFETY
   ============================================================ */

/* Left-aligned header variant (two-column sections such as About). */
.landing-page .lp-head--start {
    text-align: left;
    max-width: 40rem;
    margin-left: 0;
    margin-right: 0;
    margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}

.landing-page .lp-head--start .lp-sub {
    margin-left: 0;
    margin-right: 0;
}

.landing-page .lp-head--start .lp-rule {
    margin-left: 0;
}

/* Team portraits ride the shared .flip-card media band now. */

/* Very small phones: let section eyebrows wrap instead of overflowing. */
@media (max-width: 400px) {
    .landing-page .lp-eyebrow {
        white-space: normal;
        text-align: center;
        line-height: 1.35;
    }
}

/* --- Portfolio Section (Redesigned: mirrors the Services look + portfolio_bg watermark) --- */
.landing-page #portfolio {
    position: relative;
    background: linear-gradient(to bottom, #eefafd 0%, #e7f7fc 100%);
}

/* Portfolio watermark image - anchored to the BOTTOM of the Portfolio section */
.landing-page #portfolio .portfolio-map-bg {
    background-image: url('assets/img/portfolio/portfolio_bg.jpg');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
    height: 550px;
    bottom: auto;
    opacity: 0.16;
    mix-blend-mode: multiply;
}

.landing-page #portfolio::before,
.landing-page #portfolio::after {
    content: "";
    position: absolute;
    z-index: 0;
    pointer-events: none;
}

/* Watermark: soft dot matrix at the lower left */
.landing-page #portfolio::before {
    bottom: 28px;
    left: max(8%, calc((100% - 1240px) / 2));
    width: 130px;
    height: 125px;
    background-image: radial-gradient(circle, rgba(34, 184, 209, 0.30) 0 5px, transparent 5.5px);
    background-size: 20px 20px;
}

/* Watermark: fine diagonal strokes at the lower right */
.landing-page #portfolio::after {
    bottom: 22px;
    right: max(8%, calc((100% - 1240px) / 2));
    width: 135px;
    height: 125px;
    background: repeating-linear-gradient(120deg, transparent 0 8px, rgba(34, 184, 209, 0.22) 9px 11px, transparent 12px 18px);
    transform: skewX(-8deg);
}

/* Cards on the light band now come from the shared .flip-card component
   (home.css); no page-specific card overrides remain. */

@media (max-width: 767px) {
    .landing-page #portfolio {
        background: linear-gradient(to bottom, #eefafd 0%, #e7f7fc 100%);
    }

    .landing-page #portfolio .portfolio-map-bg {
        height: 420px;
    }

    .landing-page #portfolio::before {
        left: 8%;
        bottom: 22px;
        transform: scale(0.8);
        transform-origin: left top;
    }

    .landing-page #portfolio::after {
        right: 7%;
        bottom: 18px;
        transform: skewX(-8deg) scale(0.8);
        transform-origin: right top;
    }
}

/* ============================================================
   7b. SERVICES SECTION — capability catalogue
   A deliberately NON-card layout: a sticky, left-aligned intro
   column beside a numbered list of wide service rows. The
   Services band must never read like the Portfolio mosaic, so
   numerals, icon plates and row rhythm carry the design here
   instead of photography. Tokens only — no new colours.
   ============================================================ */

/* --- Split shell: intro column + row list ------------------------------ */
.landing-page #services .lp-svc {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 4vw, 3rem);
    align-items: start;
}

@media (min-width: 1024px) {

    .landing-page #services .lp-svc {
        grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.6fr);
        gap: clamp(2.5rem, 4.5vw, 4rem);
    }

    /* The intro parks itself while the rows scroll past it. Its containing
       block is the grid row (as tall as the row list), so there is room. */
    .landing-page #services .lp-svc__intro {
        position: sticky;
        top: 7rem;
    }
}

/* --- Left column: header, promise list, catalogue CTA ------------------ */
.landing-page #services .lp-svc__intro .lp-head {
    margin-bottom: clamp(1.5rem, 2.5vw, 2rem);
}

/* The intro column is narrow, so let the eyebrow wrap instead of overflowing. */
.landing-page #services .lp-svc__intro .lp-eyebrow {
    white-space: normal;
    text-align: left;
    line-height: 1.35;
}

.landing-page #services .lp-svc__promise {
    list-style: none;
    margin: 0 0 clamp(1.75rem, 3vw, 2.25rem);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.landing-page #services .lp-svc__promise li {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    color: var(--lp-ink);
    font-size: 0.9375rem;
    font-weight: 500;
    line-height: 1.5;
}

.landing-page #services .lp-svc__promise li i {
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    background: rgba(34, 184, 209, 0.14);
    color: var(--lp-cyan);
    font-size: 0.625rem;
}

/* --- Right column: the numbered rows ----------------------------------- */
.landing-page #services .lp-svc__list {
    display: flex;
    flex-direction: column;
    gap: clamp(0.9rem, 1.6vw, 1.25rem);
}


/* --- The row: one white surface per service ---------------------------- */
.landing-page #services .lp-svc__row {
    --lp-svc-plate: 3.25rem;
    position: relative;
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr);
    align-items: center;
    gap: clamp(0.9rem, 2vw, 1.5rem);
    padding: clamp(1.15rem, 2.2vw, 1.6rem) clamp(1.15rem, 2.4vw, 1.9rem);
    border: 1px solid var(--lp-line);
    border-radius: 1.25rem;
    background: #ffffff;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 20px 44px -34px rgba(6, 22, 58, 0.55);
    overflow: hidden;
    text-decoration: none;
    transition: transform 0.35s var(--lp-ease), box-shadow 0.35s var(--lp-ease),
        border-color 0.35s var(--lp-ease);
}

/* Accent bar that grows down the leading edge on hover / keyboard focus. */
.landing-page #services .lp-svc__row::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background: linear-gradient(180deg, var(--lp-cyan), var(--lp-navy));
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform 0.45s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover,
.landing-page #services .lp-svc__row:focus-visible {
    transform: translateY(-4px);
    border-color: rgba(34, 184, 209, 0.45);
    box-shadow: 0 28px 56px -30px rgba(6, 22, 58, 0.55),
        0 10px 22px -16px rgba(34, 184, 209, 0.45);
}

.landing-page #services .lp-svc__row:hover::before,
.landing-page #services .lp-svc__row:focus-visible::before {
    transform: scaleY(1);
}

.landing-page #services .lp-svc__row:focus-visible {
    outline: 3px solid rgba(34, 184, 209, 0.55);
    outline-offset: 3px;
}

/* --- Numeral + icon plate ---------------------------------------------- */
.landing-page #services .lp-svc__num {
    font-family: 'Fraunces', Georgia, serif;
    font-style: italic;
    font-size: clamp(1.35rem, 2.4vw, 1.9rem);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.02em;
    color: rgba(6, 22, 58, 0.16);
    transition: color 0.35s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__num,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__num {
    color: var(--lp-cyan);
}

.landing-page #services .lp-svc__plate {
    width: var(--lp-svc-plate);
    height: var(--lp-svc-plate);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 1rem;
    border: 1px solid rgba(6, 22, 58, 0.08);
    background: linear-gradient(135deg, rgba(34, 184, 209, 0.16), rgba(6, 22, 58, 0.05));
    color: var(--lp-navy);
    font-size: 1.15rem;
    transition: background 0.35s var(--lp-ease), color 0.35s var(--lp-ease),
        border-color 0.35s var(--lp-ease), box-shadow 0.35s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__plate,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__plate {
    background: linear-gradient(135deg, var(--lp-navy) 0%, var(--lp-cyan) 135%);
    border-color: transparent;
    color: #ffffff;
    box-shadow: 0 14px 26px -14px rgba(6, 22, 58, 0.60);
}


/* --- Copy block -------------------------------------------------------- */
.landing-page #services .lp-svc__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.landing-page #services .lp-svc__head {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.landing-page #services .lp-svc__title {
    margin: 0;
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.125rem, 1.5vw, 1.4rem);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--lp-navy);
    /* Cyan -> navy underline that draws itself in on hover. */
    background-image: linear-gradient(90deg, var(--lp-cyan), var(--lp-navy));
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% 2px;
    padding-bottom: 2px;
    transition: background-size 0.45s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__title,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__title {
    background-size: 100% 2px;
}

.landing-page #services .lp-svc__arrow {
    margin-left: auto;
    width: 2.5rem;
    height: 2.5rem;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    border: 1px solid rgba(6, 22, 58, 0.10);
    background: var(--lp-light);
    color: var(--lp-navy);
    font-size: 0.75rem;
    transition: transform 0.4s var(--lp-ease), background 0.4s var(--lp-ease),
        color 0.4s var(--lp-ease), border-color 0.4s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__arrow,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__arrow {
    transform: translateX(4px);
    border-color: var(--lp-cyan);
    background: var(--lp-cyan);
    color: #ffffff;
}

.landing-page #services .lp-svc__desc {
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--lp-muted);
    font-size: 0.9375rem;
    line-height: 1.65;
}

/* --- Tag strip + rating / duration meta -------------------------------- */
.landing-page #services .lp-svc__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1rem;
    margin-top: 0.15rem;
}

.landing-page #services .lp-svc__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.landing-page #services .lp-svc__tag {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.7rem;
    border-radius: 9999px;
    background: rgba(34, 184, 209, 0.10);
    border: 1px solid rgba(34, 184, 209, 0.28);
    color: var(--lp-navy);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-page #services .lp-svc__meta {
    display: inline-flex;
    align-items: center;
    gap: 0.9rem;
    margin-left: auto;
    color: var(--lp-muted);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.landing-page #services .lp-svc__stars {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    color: #f59e0b;
    font-size: 0.7rem;
}

.landing-page #services .lp-svc__stars em {
    margin-left: 0.15rem;
    color: var(--lp-muted);
    font-size: 0.7rem;
    font-style: normal;
    font-weight: 600;
}

.landing-page #services .lp-svc__time i {
    color: var(--lp-cyan);
}

/* --- Phones: compact two-column rows (numeral above the icon plate) ----- */
@media (max-width: 639px) {

    .landing-page #services .lp-svc__row {
        --lp-svc-plate: 2.75rem;
        grid-template-columns: auto minmax(0, 1fr);
        gap: 0.5rem 1rem;
        align-items: center;
    }

    .landing-page #services .lp-svc__num {
        grid-column: 1;
        grid-row: 1;
    }

    .landing-page #services .lp-svc__plate {
        grid-column: 1;
        grid-row: 2;
    }

    .landing-page #services .lp-svc__body {
        grid-column: 2;
        grid-row: 1 / span 2;
        gap: 0.4rem;
    }

    .landing-page #services .lp-svc__meta {
        margin-left: 0;
    }
}

/* --- Reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    .landing-page #services .lp-svc__row,
    .landing-page #services .lp-svc__row::before,
    .landing-page #services .lp-svc__num,
    .landing-page #services .lp-svc__plate,
    .landing-page #services .lp-svc__arrow,
    .landing-page #services .lp-svc__title {
        transition: none !important;
    }

    .landing-page #services .lp-svc__row:hover,
    .landing-page #services .lp-svc__row:focus-visible {
        transform: none !important;
    }
}


/* ============================================================
   7c. PORTFOLIO SECTION — bento mosaic
   The image-forward counterpoint to the Services catalogue. The
   four published projects are cut into one asymmetric mosaic
   (large hero tile -> wide strip -> two small tiles) with the
   caption riding on a navy scrim over the media. No flip, no
   uniform grid, and no silhouette shared with the band above.
   ============================================================ */

.landing-page #portfolio .lp-bento {
    --lp-bento-row: clamp(12rem, 15vw, 14rem);
    --lp-bento-gap: clamp(0.9rem, 1.6vw, 1.25rem);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--lp-bento-gap);
}

.landing-page #portfolio .lp-bento__item {
    position: relative;
    min-width: 0;
}

/* --- The tile: full-bleed media + caption overlay ----------------------- */
.landing-page #portfolio .lp-bento__tile {
    position: relative;
    display: block;
    border-radius: 1.25rem;
    overflow: hidden;
    isolation: isolate;
    background: var(--lp-navy);
    text-decoration: none;
    box-shadow: 0 14px 34px -22px rgba(6, 22, 58, 0.50);
    transition: transform 0.4s var(--lp-ease), box-shadow 0.4s var(--lp-ease);
}

.landing-page #portfolio .lp-bento__tile:hover,
.landing-page #portfolio .lp-bento__tile:focus-visible {
    transform: translateY(-5px);
    box-shadow: 0 32px 60px -28px rgba(6, 22, 58, 0.62),
        0 16px 30px -18px rgba(34, 184, 209, 0.40);
}

.landing-page #portfolio .lp-bento__tile:focus-visible {
    outline: 3px solid rgba(34, 184, 209, 0.60);
    outline-offset: 3px;
}

.landing-page #portfolio .lp-bento__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s var(--lp-ease);
}

.landing-page #portfolio .lp-bento__tile:hover .lp-bento__img,
.landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__img {
    transform: scale(1.06);
}

/* No-image fallback: a brand navy plate instead of an empty frame. */
.landing-page #portfolio .lp-bento__placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--lp-navy) 0%, #0b2c66 100%);
    color: rgba(255, 255, 255, 0.30);
    font-size: 2.25rem;
}

/* Navy scrim: keeps every caption legible over any photograph. */
.landing-page #portfolio .lp-bento__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
            rgba(6, 22, 58, 0.55) 0%,
            rgba(6, 22, 58, 0.15) 32%,
            rgba(6, 22, 58, 0.72) 72%,
            rgba(6, 22, 58, 0.95) 100%);
    transition: opacity 0.4s var(--lp-ease);
}

.landing-page #portfolio .lp-bento__tile:hover .lp-bento__scrim,
.landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__scrim {
    opacity: 0.86;
}


/* --- Top-left chips: category + optional featured star ----------------- */
.landing-page #portfolio .lp-bento__top {
    position: absolute;
    top: clamp(0.9rem, 1.6vw, 1.25rem);
    left: clamp(0.9rem, 1.6vw, 1.25rem);
    right: clamp(0.9rem, 1.6vw, 1.25rem);
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.landing-page #portfolio .lp-bento__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.75rem;
    border-radius: 9999px;
    background: rgba(6, 22, 58, 0.62);
    border: 1px solid rgba(255, 255, 255, 0.28);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: #ffffff;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-page #portfolio .lp-bento__chip--featured {
    background: linear-gradient(135deg, var(--lp-cyan) 0%, var(--lp-navy) 145%);
    border-color: rgba(255, 255, 255, 0.45);
}

/* --- Bottom caption ---------------------------------------------------- */
.landing-page #portfolio .lp-bento__bottom {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    padding: clamp(1.1rem, 2.2vw, 1.75rem);
}

.landing-page #portfolio .lp-bento__title-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.landing-page #portfolio .lp-bento__title {
    margin: 0;
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.15rem, 1.5vw, 1.5rem);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: #ffffff;
    /* Cyan underline that draws itself in on hover. */
    background-image: linear-gradient(90deg, var(--lp-cyan), rgba(34, 184, 209, 0));
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% 2px;
    padding-bottom: 4px;
    transition: background-size 0.45s var(--lp-ease);
}

.landing-page #portfolio .lp-bento__tile:hover .lp-bento__title,
.landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__title {
    background-size: 100% 2px;
}

.landing-page #portfolio .lp-bento__go {
    margin-top: 0.2rem;
    width: 2.5rem;
    height: 2.5rem;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    background: rgba(255, 255, 255, 0.12);
    color: #ffffff;
    font-size: 0.75rem;
    transition: transform 0.4s var(--lp-ease), background 0.4s var(--lp-ease),
        border-color 0.4s var(--lp-ease);
}

.landing-page #portfolio .lp-bento__tile:hover .lp-bento__go,
.landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__go {
    transform: translateX(4px);
    background: var(--lp-cyan);
    border-color: var(--lp-cyan);
}

.landing-page #portfolio .lp-bento__desc {
    margin: 0;
    color: rgba(255, 255, 255, 0.82);
    font-size: 0.875rem;
    line-height: 1.6;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.landing-page #portfolio .lp-bento__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.landing-page #portfolio .lp-bento__tag {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.7rem;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.24);
    color: #ffffff;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-page #portfolio .lp-bento__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.75rem;
    font-weight: 600;
}

.landing-page #portfolio .lp-bento__meta i {
    color: var(--lp-cyan);
}


/* --- Mosaic proportions ------------------------------------------------- */

/* Stacked by default (phones + tablets): one column, every tile a comfortable
   band that can only GROW.

   Below 1024px the tile becomes a flex column - chips first (pinned to the top
   by `margin-bottom: auto`), caption last - so both sit in normal flow. That
   matters because the media, the scrim, the chips and the caption are all
   positioned: with a bottom-anchored overlay the tile could never exceed its
   min-height, so a caption long enough (a 36-char project title, a 2-line
   description, 3 tech tags, client + date) would just be clipped away by the
   tile's own `overflow: hidden`. In flow the tile grows to fit instead. The
   media and the scrim keep `inset: 0`, so whenever the caption fits the band
   renders exactly like the desktop overlay: same chips, same bottom caption. */
@media (max-width: 1023px) {

    .landing-page #portfolio .lp-bento__tile {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        min-height: 16rem;
    }

    /* The lead tile carries the hero weight on every small breakpoint. */
    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__tile {
        min-height: 21rem;
    }

    /* Chips: in flow at the top of the tile (the media stays behind them). */
    .landing-page #portfolio .lp-bento__top {
        position: relative;
        inset: auto;
        margin-bottom: auto;
        padding: clamp(0.9rem, 1.6vw, 1.25rem) clamp(0.9rem, 1.6vw, 1.25rem) 0;
    }

    /* Caption: in flow on the tile's bottom edge, so it is never clipped. */
    .landing-page #portfolio .lp-bento__bottom {
        position: relative;
        inset: auto;
    }
}

/* Phones: a compact rhythm so the caption never takes the tile over and the
   photograph stays the subject. Nothing is dropped - chip, title, description,
   tags and client/date all stay; only the scale changes. */
@media (max-width: 639px) {

    .landing-page #portfolio .lp-bento {
        --lp-bento-gap: 0.85rem;
    }

    .landing-page #portfolio .lp-bento__tile {
        border-radius: 1.1rem;
        min-height: 18rem;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__tile {
        min-height: 20.5rem;
    }

    .landing-page #portfolio .lp-bento__top {
        gap: 0.35rem;
        padding: 1rem 1rem 0;
    }

    /* `max-width` + `overflow-wrap` on every field that carries a DB value, so a
       long category / technology name wraps inside the tile instead of escaping
       it (the section masks the overflow, so an escape would read as a crop). */
    .landing-page #portfolio .lp-bento__chip {
        max-width: 100%;
        padding: 0.25rem 0.6rem;
        font-size: 0.6rem;
        letter-spacing: 0.1em;
    }

    .landing-page #portfolio .lp-bento__bottom {
        gap: 0.45rem;
        padding: 1rem;
    }

    .landing-page #portfolio .lp-bento__title-row {
        gap: 0.75rem;
    }

    .landing-page #portfolio .lp-bento__title {
        font-size: 1.15rem;
        overflow-wrap: break-word;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__title {
        font-size: 1.3rem;
    }

    .landing-page #portfolio .lp-bento__go {
        width: 2.25rem;
        height: 2.25rem;
        font-size: 0.7rem;
    }

    .landing-page #portfolio .lp-bento__desc {
        font-size: 0.8125rem;
        line-height: 1.55;
        overflow-wrap: break-word;
    }

    .landing-page #portfolio .lp-bento__tags {
        gap: 0.35rem;
    }

    .landing-page #portfolio .lp-bento__tag {
        max-width: 100%;
        padding: 0.25rem 0.6rem;
        font-size: 0.6rem;
        letter-spacing: 0.04em;
    }

    .landing-page #portfolio .lp-bento__meta {
        gap: 0.3rem 0.85rem;
        font-size: 0.7rem;
        overflow-wrap: break-word;
    }
}

/* Very small phones (320-400px): one more step down. Every field still shows -
   the tiles tighten instead of dropping content. */
@media (max-width: 400px) {

    .landing-page #portfolio .lp-bento__tile {
        min-height: 17rem;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__tile {
        min-height: 19.5rem;
    }

    .landing-page #portfolio .lp-bento__chip,
    .landing-page #portfolio .lp-bento__tag {
        font-size: 0.55rem;
    }

    .landing-page #portfolio .lp-bento__title {
        font-size: 1.05rem;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__title {
        font-size: 1.2rem;
    }

    .landing-page #portfolio .lp-bento__meta {
        font-size: 0.65rem;
    }
}

/* Tablets: hero on top, then a 2-up pair, then a full-width banner. */
@media (min-width: 640px) and (max-width: 1023px) {

    .landing-page #portfolio .lp-bento {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1),
    .landing-page #portfolio .lp-bento__item:nth-child(4) {
        grid-column: 1 / -1;
    }
}

/* Desktops: the bento proper. A 4 x 2 cell grid that the four projects pack
   exactly, so there is no hole and no two tiles the same size:
       [ hero hero | strip strip ]
       [ hero hero | small small ]
   grid-auto-rows (not grid-template-rows) keeps a short result set from
   leaving a whole empty track behind. */
@media (min-width: 1024px) {

    .landing-page #portfolio .lp-bento {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        grid-auto-rows: var(--lp-bento-row);
    }

    /* Every layer inside the tile is absolutely positioned, so the tile itself
       fills its grid area outright and inherits the row track's height. */
    .landing-page #portfolio .lp-bento__tile {
        position: absolute;
        inset: 0;
        min-height: 0;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(1) {
        grid-column: 1 / span 2;
        grid-row: 1 / span 2;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(2) {
        grid-column: 3 / span 2;
        grid-row: 1;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(3) {
        grid-column: 3;
        grid-row: 2;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(4) {
        grid-column: 4;
        grid-row: 2;
    }

    /* The two smallest tiles keep chip + title + arrow only: the full story
       belongs to the hero and the wide strip, which is the hierarchy the old
       uniform card grid could never express. */
    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__desc,
    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__tags,
    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__meta {
        display: none;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__bottom {
        padding: clamp(0.9rem, 1.5vw, 1.15rem);
        gap: 0.4rem;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__title {
        font-size: 1.05rem;
    }

    .landing-page #portfolio .lp-bento__item:nth-child(n + 3) .lp-bento__go {
        width: 2.25rem;
        height: 2.25rem;
        font-size: 0.7rem;
    }

    /* The hero tile gets the display-scale headline. */
    .landing-page #portfolio .lp-bento__item:nth-child(1) .lp-bento__title {
        font-size: clamp(1.35rem, 2vw, 1.9rem);
    }
}

/* --- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    .landing-page #portfolio .lp-bento__tile,
    .landing-page #portfolio .lp-bento__img,
    .landing-page #portfolio .lp-bento__title,
    .landing-page #portfolio .lp-bento__go,
    .landing-page #portfolio .lp-bento__scrim {
        transition: none !important;
    }

    .landing-page #portfolio .lp-bento__tile:hover,
    .landing-page #portfolio .lp-bento__tile:focus-visible,
    .landing-page #portfolio .lp-bento__tile:hover .lp-bento__img,
    .landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__img,
    .landing-page #portfolio .lp-bento__tile:hover .lp-bento__go,
    .landing-page #portfolio .lp-bento__tile:focus-visible .lp-bento__go {
        transform: none !important;
    }
}


/* ============================================================
   10. VIDEO SECTION — layout fixes (sizing / alignment / spacing)
   Scoped to the landing page only.
   ============================================================ */

/* Full-height band: content is vertically centered and the band
   never collapses to an awkwardly short strip. */
.landing-page #video {
    position: relative;
    display: flex;
    align-items: center;
    min-height: clamp(26rem, 62vh, 42rem);
    isolation: isolate;
}

/* Inner column: consistent responsive padding on every side. */
.landing-page #video .video-inner {
    width: 100%;
    padding-block: clamp(3.5rem, 8vw, 6rem);
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Content stack: one centered column with a stable max width. */
.landing-page #video .video-content {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    max-width: 46rem;
    margin-inline: auto;
    text-align: center;
}

/* Play button: always a perfect circle that scales fluidly. */
.landing-page #video .video-play {
    width: clamp(4.75rem, 9vw, 6rem);
    height: clamp(4.75rem, 9vw, 6rem);
    flex-shrink: 0;
}

/* Ping ring: concentric with the button on every breakpoint. */
.landing-page #video .video-ping {
    width: clamp(6.25rem, 12vw, 7.5rem);
    height: clamp(6.25rem, 12vw, 7.5rem);
}

/* Rhythm between the stacked elements. */
.landing-page #video .video-content .lp-rule {
    margin-top: clamp(1.5rem, 2.5vw, 2rem);
}

/* ============================================================
   11. TEAM SECTION — Team_Watermark.jpg as a subtle watermark
   Same watermark recipe as the Services / Portfolio map layers.
   ============================================================ */

/* Tighter vertical height for the band. */
.landing-page #team {
    padding-top: clamp(1.75rem, 3vw, 2.75rem);
    padding-bottom: 0.75rem !important;
}

/* Header + nav/CTA gaps shrink a step to match. */
.landing-page #team .lp-head {
    margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}

.landing-page #team .mt-12 {
    margin-top: clamp(1.5rem, 2.5vw, 2rem);
}

.landing-page #team .team-watermark-bg {
    position: absolute;
    inset: -15% 0;
    z-index: 0;
    pointer-events: none;
    background-image: url('assets/img/team/Team_Watermark.jpg');
    background-repeat: no-repeat;
    background-size: 115% 145%;
    background-position: center center;
    opacity: 0.08;
    mix-blend-mode: multiply;
}

@media (max-width: 767px) {
    .landing-page #team .team-watermark-bg {
        opacity: 0.06;
    }
}

/* ============================================================
   12. BLOG SECTION — light band (like Team) + Blog_Watermark.jpg
   Same treatment as the Team watermark: multiply blend over a
   light tinted background. The band itself is an editorial journal
   (cover story + card stack) - see 12b below.
   ============================================================ */
.landing-page #blog .blog-watermark-bg {
    position: absolute;
    inset: -15% 0;
    z-index: 0;
    pointer-events: none;
    background-image: url('assets/img/blog/Blog_Watermark.jpg');
    background-repeat: no-repeat;
    background-size: 115% 145%;
    background-position: center center;
    opacity: 0.08;
    mix-blend-mode: multiply;
}

/* --- 12b. THE JOURNAL: cover story + card stack ----------------------- */
/* The blog band no longer uses the shared .flip-card component (unlike Team /
   Key-features / Pricing): nothing here flips, rotates or turns on hover, so
   the band shares no silhouette with the card sections above it. The newest
   post becomes one large cover story and the remaining posts sit beside it as
   a stack of subdued white cards (the Services / Portfolio row recipe), so the
   two halves of the spread read as one polished card set. Every article is a
   single link (component/blog.php). Tokens only - no new colours. */

/* Shell: cover story | index list. Stacked until 1024px, then one row.
   `stretch` (not `start`) so the two halves of the spread share one height
   once they sit side by side - see "12c. EQUAL-HEIGHT SPREAD" below. */
.landing-page #blog .lp-jnl {
    --lp-jnl-radius: 1.5rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 4vw, 2.75rem);
    align-items: stretch;
}

@media (min-width: 1024px) {
    .landing-page #blog .lp-jnl {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
        gap: clamp(2.25rem, 3.4vw, 3.25rem);
    }
}

.landing-page #blog .lp-jnl__cover,
.landing-page #blog .lp-jnl__index {
    min-width: 0;
}

/* A single published post: the cover keeps the band's full width, capped so a
   wide monitor cannot stretch it into a billboard. */
.landing-page #blog .lp-jnl--solo .lp-jnl__cover {
    max-width: 58rem;
    margin-inline: auto;
}

/* One link per article: the anchor wraps the whole cover / row. */
.landing-page #blog .lp-jnl__cover-link,
.landing-page #blog .lp-jnl__row {
    display: block;
    color: inherit;
    text-decoration: none;
}

/* The cover is a CARD: the photograph is its top plate and the text block is
   its tinted footer, so the cover shares one surface - and one silhouette -
   with the card stack on the right. All depth lives here, never on the plate. */
.landing-page #blog .lp-jnl__cover-link {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--lp-line);
    border-radius: var(--lp-jnl-radius);
    background: #ffffff;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 24px 54px -38px rgba(6, 22, 58, 0.60);
    transition: transform 0.4s var(--lp-ease), box-shadow 0.4s var(--lp-ease),
        border-color 0.4s var(--lp-ease);
}

.landing-page #blog .lp-jnl__cover-link:focus-visible {
    outline: 3px solid rgba(34, 184, 209, 0.55);
    outline-offset: 6px;
    /* No border-radius override: the card already carries --lp-jnl-radius, and
       re-radius-ing it on focus would make the corners jump while tabbing. */
}

/* Media plate: the photograph carries the cover; the navy scrim keeps the flag
   legible over any image. The plate sits flush against the card's top edge -
   the radius, the hairline and the depth all belong to .lp-jnl__cover-link. */
.landing-page #blog .lp-jnl__cover-media {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    /* Own stacking context: the band's mix-blend-mode watermark must never
       reach into the photograph. */
    isolation: isolate;
    background: var(--lp-navy);
}

.landing-page #blog .lp-jnl__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s var(--lp-ease);
}

.landing-page #blog .lp-jnl__cover-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
            rgba(6, 22, 58, 0.34) 0%,
            rgba(6, 22, 58, 0.06) 34%,
            rgba(6, 22, 58, 0.46) 100%);
    transition: opacity 0.45s var(--lp-ease);
}

/* "Featured / Latest story" chip - navy glass + the cyan brand dot. */
.landing-page #blog .lp-jnl__flag {
    position: absolute;
    top: clamp(0.85rem, 1.6vw, 1.15rem);
    left: clamp(0.85rem, 1.6vw, 1.15rem);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.8rem;
    border-radius: 9999px;
    background: rgba(6, 22, 58, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: #ffffff;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-page #blog .lp-jnl__flag i {
    color: var(--lp-cyan);
    font-size: 0.65rem;
}

/* No featured image on the record: a brand navy plate stands in, so no frame
   in the band is ever left empty. */
.landing-page #blog .lp-jnl__placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--lp-navy) 0%, #0b2c66 60%, rgba(34, 184, 209, 0.85) 150%);
    color: rgba(255, 255, 255, 0.32);
    font-size: 2.25rem;
}

.landing-page #blog .lp-jnl__placeholder--sm {
    font-size: 1.25rem;
}

/* Hover / keyboard focus: the whole card lifts, the photograph breathes and the
   scrim deepens. Nothing rotates or flips - this band carries no flip card. */
.landing-page #blog .lp-jnl__cover-link:hover,
.landing-page #blog .lp-jnl__cover-link:focus-visible {
    transform: translateY(-4px);
    border-color: rgba(34, 184, 209, 0.45);
    box-shadow: 0 32px 66px -34px rgba(6, 22, 58, 0.60),
        0 14px 28px -18px rgba(34, 184, 209, 0.38);
}

.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__img,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__img {
    transform: scale(1.04);
}

.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__cover-scrim,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__cover-scrim {
    opacity: 0.88;
}

/* Card footer: the tinted plate that carries the meta line, the headline, the
   lede and the "read the full story" cue. The hairline separates it from the
   photograph exactly the way the index cards separate themselves from the band. */
.landing-page #blog .lp-jnl__cover-body {
    display: block;
    padding: clamp(1.25rem, 2vw, 1.75rem);
    border-top: 1px solid var(--lp-line);
    background: linear-gradient(180deg, #ffffff 0%, rgba(232, 236, 244, 0.55) 100%);
}

/* Shared meta line (cover + index rows): category chip, date, read time. */
.landing-page #blog .lp-jnl__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    color: var(--lp-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.landing-page #blog .lp-jnl__cat {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.7rem;
    border-radius: 9999px;
    background: rgba(34, 184, 209, 0.10);
    border: 1px solid rgba(34, 184, 209, 0.28);
    color: var(--lp-navy);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-page #blog .lp-jnl__stamp {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

.landing-page #blog .lp-jnl__stamp i {
    color: var(--lp-cyan);
    font-size: 0.8rem;
}

/* The band's display headline, sized to stand on its own under the cover
   photograph. The cyan -> navy rule draws itself in on hover, the same
   language the Services rows speak. */
.landing-page #blog .lp-jnl__cover-title {
    margin: 0.9rem 0 0.6rem;
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.4rem, 1.05rem + 1.5vw, 2.05rem);
    font-weight: 700;
    line-height: 1.18;
    letter-spacing: -0.02em;
    color: var(--lp-navy);
    /* A long unbroken headline from the DB can never push the column wider
       than its grid track. */
    overflow-wrap: anywhere;
    background-image: linear-gradient(90deg, var(--lp-cyan), var(--lp-navy));
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% 2px;
    padding-bottom: 3px;
    transition: background-size 0.5s var(--lp-ease);
}

.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__cover-title,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__cover-title {
    background-size: 100% 2px;
}

.landing-page #blog .lp-jnl__cover-lede {
    margin: 0;
    color: #475569;
    font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.0625rem);
    line-height: 1.7;
    display: -webkit-box;
    -webkit-line-clamp: var(--lp-jnl-lede-lines, 3);
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.landing-page #blog .lp-jnl__more {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1.25rem;
    color: var(--lp-navy);
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    transition: color 0.35s var(--lp-ease);
}

.landing-page #blog .lp-jnl__more-icon {
    width: 2.25rem;
    height: 2.25rem;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    /* Same brand-tinted circle the index cards use, so both halves of the
       spread speak one CTA language. */
    border: 1px solid rgba(34, 184, 209, 0.28);
    background: rgba(34, 184, 209, 0.10);
    color: var(--lp-cyan);
    font-size: 0.75rem;
    transition: transform 0.4s var(--lp-ease), background 0.4s var(--lp-ease),
        color 0.4s var(--lp-ease), border-color 0.4s var(--lp-ease);
}

.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__more,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__more {
    color: var(--lp-cyan);
}

.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__more-icon,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__more-icon {
    transform: translateX(4px);
    background: var(--lp-cyan);
    color: #ffffff;
}

.landing-page #blog .lp-jnl__index-label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding-bottom: 0.95rem;
    color: var(--lp-muted);
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

/* Whisper-thin rule trailing the label. It replaces the old hairline that used
   to double as the top rule of row 01 - the rows are surfaces now, so they
   separate themselves. */
.landing-page #blog .lp-jnl__index-label::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: linear-gradient(90deg, var(--lp-line), rgba(230, 236, 242, 0));
}

/* The index is a STACK OF CARDS now: one surface per article with a gap
   between them. The old between-row hairlines are gone - the border on each
   card does that job, and a gap keeps the stack light rather than boxy. */
.landing-page #blog .lp-jnl__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: clamp(0.7rem, 1.2vw, 0.95rem);
}

/* One subdued white card per article - the Services / Portfolio row recipe
   (1px brand hairline + white surface + soft brand shadow) so the right-hand
   stack speaks the same card language as the rest of the page. */
.landing-page #blog .lp-jnl__row {
    position: relative;
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    align-items: center;
    gap: clamp(0.75rem, 1.5vw, 1.15rem);
    padding: clamp(0.95rem, 1.8vw, 1.3rem) clamp(1rem, 1.8vw, 1.35rem);
    border: 1px solid var(--lp-line);
    border-radius: 1.15rem;
    background: #ffffff;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 18px 40px -32px rgba(6, 22, 58, 0.55);
    overflow: hidden;
    transition: transform 0.35s var(--lp-ease), box-shadow 0.35s var(--lp-ease),
        border-color 0.35s var(--lp-ease);
}

/* Cyan -> navy accent bar that grows down the card's leading edge on hover /
   focus (the Services row recipe, held to 3px so the stack stays calm). */
.landing-page #blog .lp-jnl__row::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: linear-gradient(180deg, var(--lp-cyan), var(--lp-navy));
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform 0.45s var(--lp-ease);
}

/* The card lifts and keeps its white surface: the cyan wash stays at the leading
   edge, so the headline, the thumbnail and the arrow keep full contrast while
   the card is hovered or keyboard-focused. */
.landing-page #blog .lp-jnl__row:hover,
.landing-page #blog .lp-jnl__row:focus-visible {
    transform: translateY(-3px);
    border-color: rgba(34, 184, 209, 0.45);
    background: linear-gradient(90deg,
            rgba(34, 184, 209, 0.08) 0%,
            #ffffff 48%);
    box-shadow: 0 26px 52px -30px rgba(6, 22, 58, 0.55),
        0 10px 22px -18px rgba(34, 184, 209, 0.40);
}

.landing-page #blog .lp-jnl__row:hover::before,
.landing-page #blog .lp-jnl__row:focus-visible::before {
    transform: scaleY(1);
}

.landing-page #blog .lp-jnl__row:focus-visible {
    outline: 3px solid rgba(34, 184, 209, 0.55);
    outline-offset: 2px;
}

/* Fixed-width numeral column: every thumbnail and headline in the list stays on
   one optical axis. */
.landing-page #blog .lp-jnl__num {
    width: 1.9rem;
    font-family: 'Fraunces', Georgia, serif;
    font-style: italic;
    font-size: clamp(1.1rem, 1.1rem + 0.5vw, 1.45rem);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.02em;
    color: rgba(6, 22, 58, 0.16);
    transition: color 0.35s var(--lp-ease);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__num,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__num {
    color: var(--lp-cyan);
}

.landing-page #blog .lp-jnl__thumb {
    position: relative;
    display: block;
    width: clamp(4.25rem, 6vw, 6rem);
    aspect-ratio: 4 / 3;
    border-radius: 0.875rem;
    overflow: hidden;
    background: var(--lp-light);
    /* Hairline + a whisper of shadow so the plate sits IN the card instead of
       floating on top of it. */
    border: 1px solid rgba(6, 22, 58, 0.06);
    box-shadow: 0 6px 16px -12px rgba(6, 22, 58, 0.55);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__thumb .lp-jnl__img,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__thumb .lp-jnl__img {
    transform: scale(1.06);
}

.landing-page #blog .lp-jnl__row-body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.landing-page #blog .lp-jnl__title {
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--lp-navy);
    /* Long unbroken words wrap instead of widening the row. */
    overflow-wrap: anywhere;
    transition: color 0.3s var(--lp-ease);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__title,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__title {
    color: var(--lp-cyan);
}

.landing-page #blog .lp-jnl__excerpt {
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--lp-muted);
    font-size: 0.875rem;
    line-height: 1.6;
}

.landing-page #blog .lp-jnl__go {
    width: 2.5rem;
    height: 2.5rem;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    border: 1px solid rgba(34, 184, 209, 0.28);
    background: rgba(34, 184, 209, 0.10);
    color: var(--lp-cyan);
    font-size: 0.75rem;
    transition: transform 0.4s var(--lp-ease), background 0.4s var(--lp-ease),
        color 0.4s var(--lp-ease), border-color 0.4s var(--lp-ease);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__go,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__go {
    transform: translateX(4px);
    border-color: var(--lp-cyan);
    background: var(--lp-cyan);
    color: #ffffff;
}

/* --- 12c. EQUAL-HEIGHT SPREAD (from 1024px) --------------------------- */
/* The cover story and the index are two halves of ONE spread, so they must
   share a single height: no ragged edge, no half-empty column. The grid
   stretches both items to whichever half is taller, and the columns below
   decide how that shared height gets spent:
     * cover  - the photograph (object-fit:cover) absorbs the surplus, so the
                plate always ends exactly where the paragraphs end and the
                text block keeps its natural rhythm.
     * index  - the cards share the surplus evenly, so every gap sits
                exactly midway between two titles and each card's content stays
                optically centred in its band.
   Below 1024px the halves stack, so none of this applies and the list keeps
   its natural height (see the max-width blocks further down). */
@media (min-width: 1024px) {

    .landing-page #blog .lp-jnl__cover,
    .landing-page #blog .lp-jnl__index {
        display: flex;
        flex-direction: column;
    }

    .landing-page #blog .lp-jnl__cover-link {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
    }

    /* min-height keeps the plate from collapsing in engines that derive an
       aspect-ratio flex-basis from the (absolutely positioned) photo. */
    .landing-page #blog .lp-jnl__cover-media {
        flex: 1 1 auto;
        min-height: clamp(15rem, 21vw, 21rem);
    }

    .landing-page #blog .lp-jnl__cover-body {
        flex: 0 0 auto;
    }

    .landing-page #blog .lp-jnl__list {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

    .landing-page #blog .lp-jnl__item {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
    }

    .landing-page #blog .lp-jnl__row {
        flex: 1 1 auto;
    }
}

/* Below 1024px the cover story leads the band and the card stack follows it.
   Everything that carries the story (image, category, date, headline) survives
   every breakpoint - only the excerpt and the numeral step aside once the card
   gets narrow. */
@media (max-width: 767px) {

    /* The numeral needs a column of its own that a phone cannot spare. */
    .landing-page #blog .lp-jnl__num {
        display: none;
    }

    .landing-page #blog .lp-jnl__row {
        grid-template-columns: auto minmax(0, 1fr) auto;
        gap: 0.85rem;
        /* The row is a card now, so its content keeps the card's inner gutter
           instead of bleeding to the edge. */
        padding-inline: clamp(0.85rem, 3vw, 1.1rem);
    }

    .landing-page #blog .lp-jnl__excerpt {
        -webkit-line-clamp: 1;
    }

    .landing-page #blog .lp-jnl__go {
        width: 2.25rem;
        height: 2.25rem;
    }
}

@media (max-width: 639px) {
    .landing-page #blog .lp-jnl__cover-media {
        aspect-ratio: 4 / 3;
    }

    /* Cover: the lede tightens to two lines. Index: the excerpt goes, so the
       thumbnail, the category, the date and the headline keep the row. */
    .landing-page #blog .lp-jnl__cover-lede {
        --lp-jnl-lede-lines: 2;
    }

    .landing-page #blog .lp-jnl__excerpt {
        display: none;
    }

    /* Small phones: a tighter spread rhythm, a smaller plate radius and a
       smaller thumbnail, so the headline keeps its line instead of being
       squeezed between the thumbnail and the arrow. The meta row (category +
       date + read time) drops a step so it wraps cleanly rather than running
       past the row's width. */
    .landing-page #blog .lp-jnl {
        --lp-jnl-radius: 1.15rem;
        gap: 1.75rem;
    }

    .landing-page #blog .lp-jnl__row {
        gap: 0.7rem;
        padding-block: 0.95rem;
    }

    .landing-page #blog .lp-jnl__thumb {
        width: clamp(3.5rem, 20vw, 4.5rem);
        border-radius: 0.7rem;
    }

    .landing-page #blog .lp-jnl__meta {
        gap: 0.4rem 0.7rem;
        font-size: 0.6875rem;
    }

    .landing-page #blog .lp-jnl__cover-body {
        /* The footer plate keeps its surface, but drops a step so a short card
           never reads as padding around a single headline. */
        padding: 1.15rem 1.15rem 1.35rem;
    }

    .landing-page #blog .lp-jnl__more {
        margin-top: 1rem;
    }

    .landing-page #blog .lp-jnl__index-label {
        padding-bottom: 0.7rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .landing-page #blog .lp-jnl__img,
    .landing-page #blog .lp-jnl__cover-media,
    .landing-page #blog .lp-jnl__cover-scrim,
    .landing-page #blog .lp-jnl__cover-title,
    .landing-page #blog .lp-jnl__more,
    .landing-page #blog .lp-jnl__more-icon,
    .landing-page #blog .lp-jnl__row,
    .landing-page #blog .lp-jnl__row::before,
    .landing-page #blog .lp-jnl__cover-link,
    .landing-page #blog .lp-jnl__num,
    .landing-page #blog .lp-jnl__title,
    .landing-page #blog .lp-jnl__go {
        transition: none !important;
    }

    /* The card lifts are motion too: surfaces, borders and shadows may still
       change, but nothing travels across the layout. */
    .landing-page #blog .lp-jnl__cover-link:hover,
    .landing-page #blog .lp-jnl__cover-link:focus-visible,
    .landing-page #blog .lp-jnl__row:hover,
    .landing-page #blog .lp-jnl__row:focus-visible,
    .landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__img,
    .landing-page #blog .lp-jnl__row:hover .lp-jnl__thumb .lp-jnl__img,
    .landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__more-icon,
    .landing-page #blog .lp-jnl__row:hover .lp-jnl__go {
        transform: none !important;
    }
}

@media (max-width: 767px) {
    .landing-page #blog .blog-watermark-bg {
        opacity: 0.06;
    }
}

/* ============================================================
   13. TESTIMONIALS SECTION — light band (like Team) +
   Team_Watermark.jpg as a subtle watermark. Same multiply
   treatment as the Team / Blog watermarks.
   ============================================================ */

/* Tighter vertical height for the band, with a subtle light divider
   between Team and Testimonials so they read as separate sections. */
.landing-page #testimonials {
    padding-top: 0.75rem !important;
    padding-bottom: clamp(2.25rem, 3.5vw, 3.25rem);
    border-top: 1px solid rgba(6, 22, 58, 0.10);
}

/* Header + nav/CTA gaps shrink a step to match. */
.landing-page #testimonials .lp-head {
    margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}

.landing-page #testimonials .mt-8 {
    margin-top: clamp(1.5rem, 2.5vw, 2rem);
}

.landing-page #testimonials .mt-12 {
    margin-top: clamp(2rem, 3vw, 2.75rem);
}

.landing-page #testimonials .testimonial-watermark-bg {
    position: absolute;
    inset: -15% 0;
    z-index: 0;
    pointer-events: none;
    background-image: url('assets/img/team/Team_Watermark.jpg');
    background-repeat: no-repeat;
    background-size: 115% 145%;
    background-position: center center;
    opacity: 0.08;
    mix-blend-mode: multiply;
}

@media (max-width: 767px) {
    .landing-page #testimonials .testimonial-watermark-bg {
        opacity: 0.06;
    }
}

/* ============================================================
   14. OUR CLIENTS SECTION — the logo ribbon shares the light band
   treatment with Team / Testimonials, so the three read as one
   continuous trust block leading into the quotes.
   ============================================================ */

/* The Tailwind utilities on the section (py-16 md:py-24 lg:py-28) are
   replaced by the tighter band rhythm used by the neighbouring sections.
   The id in the selector outranks the utility classes, so no !important. */
.landing-page #clients {
    padding-top: clamp(2.75rem, 4vw, 4rem);
    padding-bottom: clamp(2.25rem, 3.5vw, 3.25rem);
    border-top: 1px solid rgba(6, 22, 58, 0.10);
}

.landing-page #clients .lp-head {
    margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}

/* Ribbon -> CTA spacing, one step tighter than the utility defaults so the
   section never grows a dead band. The CTA links to the /clients page, so
   there is no inline expanded grid to space out. */
.landing-page #clients .clients-more {
    margin-top: clamp(2rem, 3vw, 2.75rem);
}

@media (max-width: 767px) {

    /* The edge fade wastes precious width on a phone and the ribbon is
       replaced by the flat hairline wall there anyway (responsive.css). */
    .landing-page #clients .clients-marquee {
        -webkit-mask-image: none;
        mask-image: none;
    }
}

/* Small-tablet band only: below 641px the phone rule in responsive.css §16b
   owns the columns (this selector outranks a bare .clients-wall, so it must
   not reach the phone range or it would win there and stretch one cell across
   the whole row). */
@media (min-width: 641px) and (max-width: 767px) {
    .landing-page #clients .clients-wall {
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    }
}

/* ============================================================
   15. CARD POLISH — Services + Blog white surfaces
   ------------------------------------------------------------
   An additive layer. Everything above still owns the layout,
   the breakpoints and the accessibility states; this block only
   deepens the *surface* of the existing white cards so they stop
   reading as flat white rectangles:

     * a cyan ambient "spotlight" that fades in behind the content
     * a diagonal gloss that wipes across the card on hover
     * a lit top edge + a three-layer shadow stack at rest
     * a soft cyan ring instead of a flat border-colour flip
     * refined icon plate, numeral, chips, arrows and thumbnails

   Design rules honoured here:
     * Tokens only. --lp-navy / --lp-cyan / --lp-light / --lp-line
       at low alpha. No new colours are introduced.
     * The accent bar already owns ::before on the two row recipes,
       so the ambient + gloss layer rides on ::after.
     * Everything is scoped to .landing-page, so the standalone
       pages, shared components and the admin panel are unaffected.
   ============================================================ */

/* ------------------------------------------------------------
   15a. SHARED AMBIENT LAYER
   Two backgrounds on one pseudo-element: the sheen is the first
   (topmost) layer, the cyan spotlight the second. The sheen is
   parked off-canvas left and travels right on hover; the
   spotlight simply fades up, so the two never fight for opacity.
   ------------------------------------------------------------ */
.landing-page #services .lp-svc__row::after,
.landing-page #blog .lp-jnl__row::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    background-image:
        linear-gradient(115deg,
            rgba(255, 255, 255, 0) 28%,
            rgba(255, 255, 255, 0.35) 46%,
            rgba(255, 255, 255, 0) 62%),
        radial-gradient(130% 150% at 10% 0%,
            rgba(34, 184, 209, 0.16) 0%,
            rgba(34, 184, 209, 0) 58%);
    background-size: 260% 100%, 100% 100%;
    /* The sheen rests off the left edge and travels right on hover; the
       spotlight simply fades up, so the two never fight for opacity. */
    background-position: -70% 0, 0 0;
    background-repeat: no-repeat;
    opacity: 0;
    transition: opacity 0.45s var(--lp-ease),
        background-position 0.9s var(--lp-ease);
}

/* ------------------------------------------------------------
   15b. SERVICE ROWS — a lit surface, a real ring, a plate glow
   ------------------------------------------------------------ */

/* Three-layer shadow at rest: a tight contact line, a wide
   brand-tinted drop and a soft ambient lift. The lit top edge is
   painted as a background layer on the card itself, so it sits
   under the ambient pseudo-element rather than over it. */
.landing-page #services .lp-svc__row {
    background-image:
        /* Watermark dot grid (section 16) */
        radial-gradient(rgba(6, 22, 58, 0.05) 1px, rgba(6, 22, 58, 0) 1.4px),
        /* Veil: fades the grid out under the text column so the copy
           stays on clean white while the trailing edge shows texture. */
        linear-gradient(100deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0) 58%,
            rgba(255, 255, 255, 0.55) 88%,
            rgba(255, 255, 255, 0.30) 100%),
        linear-gradient(180deg,
            rgba(34, 184, 209, 0.06) 0%,
            rgba(255, 255, 255, 0) 42%);
    /* The opaque base is a `background-color`, NOT a trailing `#ffffff` layer:
       a bare colour is invalid in `background-image`, so appending one makes
       the browser discard the whole declaration - which is how these cards
       ended up rendering as flat, texture-free white. */
    background-color: #ffffff;
    background-size: 15px 15px, 100% 100%, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 0 0;
    box-shadow:
        0 1px 2px rgba(6, 22, 58, 0.05),
        0 10px 24px -20px rgba(6, 22, 58, 0.45),
        0 28px 56px -38px rgba(6, 22, 58, 0.55);
    transition: transform 0.4s var(--lp-ease), box-shadow 0.4s var(--lp-ease),
        border-color 0.4s var(--lp-ease);
}

/* Hover / keyboard focus: a deeper lift plus a cyan ring (an outer
   bloom and an inner hairline) instead of the flat border-colour
   flip the base recipe uses. */
.landing-page #services .lp-svc__row:hover,
.landing-page #services .lp-svc__row:focus-visible {
    border-color: rgba(34, 184, 209, 0.55);
    box-shadow:
        0 0 0 4px rgba(34, 184, 209, 0.10),
        0 2px 4px rgba(6, 22, 58, 0.05),
        0 34px 64px -32px rgba(6, 22, 58, 0.60),
        0 12px 26px -18px rgba(34, 184, 209, 0.50);
}

/* The numeral reads as a printed index rather than flat grey: a
   cyan-tinted gradient that deepens toward the brand navy. The base
   recipe recolours it on hover, which a clipped gradient cannot
   show, so the hover state travels as opacity instead. */
.landing-page #services .lp-svc__num {
    background-image: linear-gradient(150deg,
            rgba(34, 184, 209, 0.55) 0%,
            rgba(6, 22, 58, 0.20) 65%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    transition: opacity 0.35s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__num,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__num {
    opacity: 0.35;
}

/* Icon plate: a richer gradient, an inner top highlight for a
   physical bevel, and a soft tint that lifts off the card. */
.landing-page #services .lp-svc__plate {
    background-image:
        linear-gradient(180deg,
            rgba(255, 255, 255, 0.75) 0%,
            rgba(255, 255, 255, 0) 55%),
        linear-gradient(140deg,
            rgba(34, 184, 209, 0.22) 0%,
            rgba(6, 22, 58, 0.06) 100%);
    box-shadow: 0 6px 16px -12px rgba(6, 22, 58, 0.55);
}

.landing-page #services .lp-svc__row:hover .lp-svc__plate,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__plate {
    box-shadow: 0 16px 30px -14px rgba(6, 22, 58, 0.60),
        0 0 0 4px rgba(34, 184, 209, 0.12);
}

/* The arrow nudges and rotates a touch, so the CTA reads as
   directional rather than merely recoloured. */
.landing-page #services .lp-svc__arrow {
    box-shadow: 0 6px 16px -12px rgba(6, 22, 58, 0.50);
}

.landing-page #services .lp-svc__row:hover .lp-svc__arrow,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__arrow {
    transform: translateX(4px) rotate(-45deg);
}

/* Feature chips: a quiet surface that warms on hover. */
.landing-page #services .lp-svc__tag {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
    transition: background 0.3s var(--lp-ease), border-color 0.3s var(--lp-ease);
}

.landing-page #services .lp-svc__row:hover .lp-svc__tag,
.landing-page #services .lp-svc__row:focus-visible .lp-svc__tag {
    background: rgba(34, 184, 209, 0.18);
    border-color: rgba(34, 184, 209, 0.42);
}

/* The rating stars get a resting glow so the meta line is not the
   flattest part of the card. */
.landing-page #services .lp-svc__stars {
    filter: drop-shadow(0 2px 4px rgba(245, 158, 11, 0.30));
}


/* ------------------------------------------------------------
   15c. BLOG COVER STORY
   The cover already has a photograph for depth, so it takes the
   ring + sheen treatment rather than a second ambient wash. Its
   ::after is free, and it rides on top of the media plate while
   the text block keeps its own stacking position.
   ------------------------------------------------------------ */
.landing-page #blog .lp-jnl__cover-link {
    position: relative;
    box-shadow:
        0 1px 2px rgba(6, 22, 58, 0.05),
        0 12px 28px -22px rgba(6, 22, 58, 0.50),
        0 30px 60px -40px rgba(6, 22, 58, 0.60);
}

/* Gloss sweep: parked off the left edge, travels across on hover.
   Kept low-alpha so it never fights the photograph underneath. */
.landing-page #blog .lp-jnl__cover-link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    border-radius: inherit;
    background-image: linear-gradient(112deg,
            rgba(255, 255, 255, 0) 34%,
            rgba(255, 255, 255, 0.22) 48%,
            rgba(255, 255, 255, 0) 60%);
    background-size: 240% 100%;
    background-position: -80% 0;
    background-repeat: no-repeat;
    opacity: 0;
    transition: opacity 0.45s var(--lp-ease),
        background-position 0.9s var(--lp-ease);
}

.landing-page #blog .lp-jnl__cover-link:hover::after,
.landing-page #blog .lp-jnl__cover-link:focus-visible::after {
    opacity: 1;
    background-position: 180% 0;
}

/* The ring replaces the flat border-colour flip, matching Services. */
.landing-page #blog .lp-jnl__cover-link:hover,
.landing-page #blog .lp-jnl__cover-link:focus-visible {
    border-color: rgba(34, 184, 209, 0.55);
    box-shadow:
        0 0 0 4px rgba(34, 184, 209, 0.10),
        0 2px 4px rgba(6, 22, 58, 0.05),
        0 40px 76px -34px rgba(6, 22, 58, 0.62),
        0 16px 32px -20px rgba(34, 184, 209, 0.50);
}

/* The text plate keeps its tint but gains a lit top edge where it
   meets the photograph. */
.landing-page #blog .lp-jnl__cover-body {
    /* Hatch instead of the dot grid: the photograph above this plate
       already supplies the visual interest, so the texture here stays
       linear and quiet. */
    background-image:
        repeating-linear-gradient(135deg,
            rgba(6, 22, 58, 0.035) 0px,
            rgba(6, 22, 58, 0.035) 1px,
            rgba(6, 22, 58, 0) 1px,
            rgba(6, 22, 58, 0) 7px),
        linear-gradient(180deg,
            rgba(34, 184, 209, 0.07) 0%,
            rgba(255, 255, 255, 0) 38%),
        linear-gradient(180deg, #ffffff 0%, rgba(232, 236, 244, 0.55) 100%);
    background-size: 7px 7px, 100% 100%, 100% 100%;
}

/* "Read the full story": a sliding rule under the label, so the cue
   animates as well as recolours. */
.landing-page #blog .lp-jnl__more {
    position: relative;
    padding-bottom: 3px;
    background-image: linear-gradient(90deg, var(--lp-cyan), var(--lp-navy));
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% 2px;
    transition: color 0.35s var(--lp-ease), background-size 0.5s var(--lp-ease);
}

/* The cue is an inline-flex of [text][2.25rem icon] with a 0.6rem gap, so the
   rule is held to the text width (icon + gap) rather than running under the
   circle. */
.landing-page #blog .lp-jnl__cover-link:hover .lp-jnl__more,
.landing-page #blog .lp-jnl__cover-link:focus-visible .lp-jnl__more {
    background-size: calc(100% - 2.85rem) 2px;
}

/* ------------------------------------------------------------
   15d. BLOG INDEX CARDS
   Same language as the cover and the Service rows: lit top edge,
   three-layer shadow, cyan ring on hover. The cyan wash the base
   recipe paints on hover is kept — the ambient layer sits over it.
   ------------------------------------------------------------ */
.landing-page #blog .lp-jnl__row {
    background-image:
        /* Watermark dot grid (section 16) */
        radial-gradient(rgba(6, 22, 58, 0.05) 1px, rgba(6, 22, 58, 0) 1.4px),
        /* Veil: same idea as the Service rows, so the two card families
           share one texture recipe. */
        linear-gradient(100deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0) 58%,
            rgba(255, 255, 255, 0.55) 88%,
            rgba(255, 255, 255, 0.30) 100%),
        linear-gradient(180deg,
            rgba(34, 184, 209, 0.06) 0%,
            rgba(255, 255, 255, 0) 45%);
    /* See the note in 15b: an opaque `#ffffff` layer is invalid here. */
    background-color: #ffffff;
    background-size: 15px 15px, 100% 100%, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 0 0;
    box-shadow:
        0 1px 2px rgba(6, 22, 58, 0.05),
        0 10px 22px -20px rgba(6, 22, 58, 0.45),
        0 24px 48px -36px rgba(6, 22, 58, 0.55);
    transition: transform 0.4s var(--lp-ease), box-shadow 0.4s var(--lp-ease),
        border-color 0.4s var(--lp-ease);
}

/* The resting gradient is replaced by the base hover wash, so the
   two must be declared together or the wash would paint over the
   lit edge. */
.landing-page #blog .lp-jnl__row:hover,
.landing-page #blog .lp-jnl__row:focus-visible {
    border-color: rgba(34, 184, 209, 0.55);
    background-image:
        radial-gradient(rgba(6, 22, 58, 0.05) 1px, rgba(6, 22, 58, 0) 1.4px),
        linear-gradient(100deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0) 58%,
            rgba(255, 255, 255, 0.55) 88%,
            rgba(255, 255, 255, 0.30) 100%),
        linear-gradient(90deg,
            rgba(34, 184, 209, 0.10) 0%,
            rgba(255, 255, 255, 0) 55%),
        linear-gradient(180deg,
            rgba(34, 184, 209, 0.06) 0%,
            rgba(255, 255, 255, 0) 45%);
    box-shadow:
        0 0 0 4px rgba(34, 184, 209, 0.10),
        0 2px 4px rgba(6, 22, 58, 0.05),
        0 30px 58px -30px rgba(6, 22, 58, 0.58),
        0 12px 24px -18px rgba(34, 184, 209, 0.45);
}

/* Thumbnail: a ring on hover, and a slightly stronger zoom so the
   card's focal point is obvious. */
.landing-page #blog .lp-jnl__thumb {
    transition: box-shadow 0.4s var(--lp-ease), border-color 0.4s var(--lp-ease);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__thumb,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__thumb {
    border-color: rgba(34, 184, 209, 0.40);
    box-shadow: 0 0 0 3px rgba(34, 184, 209, 0.12),
        0 10px 22px -14px rgba(6, 22, 58, 0.55);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__thumb .lp-jnl__img,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__thumb .lp-jnl__img {
    transform: scale(1.10);
}

/* The category chip deepens on hover and the "go" pill gains the
   same resting glow the Services arrow carries. */
.landing-page #blog .lp-jnl__cat {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
    transition: background 0.3s var(--lp-ease), border-color 0.3s var(--lp-ease);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__cat,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__cat {
    background: rgba(34, 184, 209, 0.18);
    border-color: rgba(34, 184, 209, 0.42);
}

.landing-page #blog .lp-jnl__go {
    box-shadow: 0 6px 16px -12px rgba(6, 22, 58, 0.45);
}

.landing-page #blog .lp-jnl__row:hover .lp-jnl__go,
.landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__go {
    box-shadow: 0 14px 26px -14px rgba(34, 184, 209, 0.75);
}

/* ------------------------------------------------------------
   15e. "TECHNOLOGIES WE USED" CHIP WALL
   These are white cards too, but a 24-cell grid of full-bleed
   hover shadows reads busy. They get a quieter treatment: a hairline
   brand rule on the top edge, a deeper radius, and a small lift.
   The grid columns and gaps stay with the Tailwind utilities.
   ------------------------------------------------------------ */
.landing-page #services .lp-tech>div {
    position: relative;
    overflow: hidden;
    border-radius: 0.9rem;
    border-color: var(--lp-line);
    background-image:
        linear-gradient(180deg,
            rgba(34, 184, 209, 0.05) 0%,
            rgba(255, 255, 255, 0) 55%),
        #ffffff;
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 12px 24px -22px rgba(6, 22, 58, 0.50);
    transition: transform 0.35s var(--lp-ease), box-shadow 0.35s var(--lp-ease),
        border-color 0.35s var(--lp-ease);
}

/* The brand rule on the chip's top edge. */
.landing-page #services .lp-tech>div::before {
    content: "";
    position: absolute;
    top: 0;
    left: 22%;
    right: 22%;
    height: 2px;
    border-radius: 0 0 9999px 9999px;
    background: linear-gradient(90deg,
            rgba(34, 184, 209, 0) 0%,
            var(--lp-cyan) 50%,
            rgba(34, 184, 209, 0) 100%);
    opacity: 0.45;
    transition: opacity 0.35s var(--lp-ease);
}

.landing-page #services .lp-tech>div:hover {
    transform: translateY(-3px);
    border-color: rgba(34, 184, 209, 0.38);
    box-shadow: 0 0 0 3px rgba(34, 184, 209, 0.08),
        0 18px 30px -22px rgba(6, 22, 58, 0.55);
}

.landing-page #services .lp-tech>div:hover::before {
    opacity: 1;
}

/* The stack icon scales a touch so the chip has a focal point. */
.landing-page #services .lp-tech>div i {
    transition: transform 0.35s var(--lp-ease);
}

.landing-page #services .lp-tech>div:hover i {
    transform: scale(1.12);
}

/* ------------------------------------------------------------
   15f. EMPTY STATES (no services / no articles)
   The base markup is a Tailwind panel; these rules give both bands
   the same lit surface, a floating icon plate and a cyan wash, so
   a fallback state is not the plainest card on the page.
   ------------------------------------------------------------ */
.landing-page .lp-empty {
    position: relative;
    overflow: hidden;
    border-radius: 1.5rem;
    border-color: var(--lp-line);
    /* The Tailwind bg-white/xx utility only sets background-color, so the
       gradient below layers over it - the colour is pinned opaque here so
       the panel never reads as washed out against the band. */
    background-color: #ffffff;
    background-image:
        radial-gradient(90% 120% at 50% 0%,
            rgba(34, 184, 209, 0.10) 0%,
            rgba(34, 184, 209, 0) 62%);
    box-shadow: 0 1px 2px rgba(6, 22, 58, 0.04),
        0 24px 50px -36px rgba(6, 22, 58, 0.55);
}

/* The pictogram sits in a tinted plate instead of floating loose. */
.landing-page .lp-empty>i {
    display: inline-block;
    border-radius: 1.25rem;
    padding: 0.85rem;
    box-sizing: content-box;
    background: rgba(34, 184, 209, 0.10);
    border: 1px solid rgba(34, 184, 209, 0.24);
    color: var(--lp-cyan);
    box-shadow: 0 14px 30px -20px rgba(34, 184, 209, 0.70);
}

.landing-page .lp-empty>svg {
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    background: none;
    border: none;
    box-shadow: none;
    color: rgba(100, 116, 139, 0.55);
}

.landing-page .lp-empty>h3 {
    color: var(--lp-navy);
}

/* ------------------------------------------------------------
   15g. REDUCED MOTION
   The polish layer adds transforms and background travel, so the
   two existing reduced-motion blocks are extended with it here.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {

    .landing-page #services .lp-svc__row::after,
    .landing-page #blog .lp-jnl__row::after,
    .landing-page #blog .lp-jnl__cover-link::after,
    .landing-page #services .lp-tech>div::before,
    .landing-page #services .lp-svc__num,
    .landing-page #services .lp-svc__tag,
    .landing-page #blog .lp-jnl__cat,
    .landing-page #blog .lp-jnl__more,
    .landing-page #blog .lp-jnl__thumb,
    .landing-page #services .lp-tech>div,
    .landing-page #services .lp-tech>div i {
        transition: none !important;
    }

    /* The surface, border and shadow may still change - only the
       travel across the layout is removed. */
    .landing-page #services .lp-svc__row:hover .lp-svc__arrow,
    .landing-page #services .lp-svc__row:focus-visible .lp-svc__arrow,
    .landing-page #blog .lp-jnl__row:hover .lp-jnl__go,
    .landing-page #blog .lp-jnl__row:focus-visible .lp-jnl__go,
    .landing-page #services .lp-tech>div:hover,
    .landing-page #services .lp-tech>div:hover i {
        transform: none !important;
    }

    /* The gloss sweep is pure motion: hold it at rest. */
    .landing-page #services .lp-svc__row:hover::after,
    .landing-page #services .lp-svc__row:focus-visible::after,
    .landing-page #blog .lp-jnl__row:hover::after,
    .landing-page #blog .lp-jnl__row:focus-visible::after,
    .landing-page #blog .lp-jnl__cover-link:hover::after,
    .landing-page #blog .lp-jnl__cover-link:focus-visible::after {
        opacity: 0 !important;
    }
}

/* The card's own content rides above the ambient layer. */
.landing-page #services .lp-svc__row>*,
.landing-page #blog .lp-jnl__row>* {
    position: relative;
    z-index: 1;
}

.landing-page #services .lp-svc__row:hover::after,
.landing-page #services .lp-svc__row:focus-visible::after,
.landing-page #blog .lp-jnl__row:hover::after,
.landing-page #blog .lp-jnl__row:focus-visible::after {
    opacity: 1;
    background-position: 170% 0, 0 0;
}


/* ============================================================
   16. CARD WATERMARK LAYER — texture without noise
   ------------------------------------------------------------
   The surfaces in 15 are lit but still read as plain white, so
   each card now carries a watermark *under* its content:

     * a faint dot grid (Service rows + Blog index cards) or a
       quiet hatch (the cover story's text plate) - painted as
       extra background layers on the card itself, so no extra
       stacking context is introduced;
     * a white veil over the grid on the copy side, so the text
       column still sits on clean white;
     * a large, near-invisible glyph of the service's own icon
       on the Service rows, which is what gives those cards
       their personality.

   Design rules honoured here:
     * Tokens only, at 3.5-5.5% alpha. No new colours.
     * The watermark is purely decorative (aria-hidden,
       pointer-events: none) and never intercepts a click.
     * Specificity beats the `> * { z-index: 1 }` rule in 15d,
       so the glyph stays pinned beneath the card's own content.
   ============================================================ */

/* ------------------------------------------------------------
   16a. THE GLYPH (Service rows only)
   Bleeds off the trailing edge and is clipped by the card's own
   overflow, so it reads as a printed watermark rather than an
   icon parked in the corner.
   ------------------------------------------------------------ */
.landing-page #services .lp-svc__row .lp-wm {
    position: absolute;
    top: 50%;
    right: clamp(1.5rem, 5vw, 3.25rem);
    z-index: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    font-size: clamp(6rem, 13vw, 9.5rem);
    color: rgba(6, 22, 58, 0.055);
    transform: translateY(-50%) rotate(-9deg);
    pointer-events: none;
    user-select: none;
    transition: transform 0.6s var(--lp-ease), color 0.45s var(--lp-ease);
}

.landing-page #services .lp-svc__row .lp-wm i {
    display: block;
    line-height: 1;
}

/* Hover / keyboard focus: the watermark drifts and deepens a
   touch, answering the card's lift without ever becoming an
   image the visitor is meant to read. */
.landing-page #services .lp-svc__row:hover .lp-wm,
.landing-page #services .lp-svc__row:focus-visible .lp-wm {
    color: rgba(34, 184, 209, 0.10);
    transform: translateY(-50%) rotate(-3deg) scale(1.07);
}

/* Phones: the rows are compact two-column stacks, so the glyph
   drops to a whisper and tucks into the bottom corner. */
@media (max-width: 639px) {
    .landing-page #services .lp-svc__row .lp-wm {
        right: 0.75rem;
        top: auto;
        bottom: -0.5rem;
        font-size: 5rem;
        color: rgba(6, 22, 58, 0.04);
        transform: rotate(-6deg);
    }

    .landing-page #services .lp-svc__row:hover .lp-wm,
    .landing-page #services .lp-svc__row:focus-visible .lp-wm {
        color: rgba(34, 184, 209, 0.08);
        transform: rotate(-6deg) scale(1.05);
    }
}

/* ------------------------------------------------------------
   16b. REDUCED MOTION
   The watermark is pure decoration, so it holds at rest for
   anyone who has asked the OS for less movement.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    .landing-page #services .lp-svc__row .lp-wm {
        transition: none !important;
    }

    .landing-page #services .lp-svc__row:hover .lp-wm,
    .landing-page #services .lp-svc__row:focus-visible .lp-wm {
        transform: translateY(-50%) rotate(-9deg) !important;
    }
}

@media (prefers-reduced-motion: reduce) and (max-width: 639px) {

    .landing-page #services .lp-svc__row:hover .lp-wm,
    .landing-page #services .lp-svc__row:focus-visible .lp-wm {
        transform: rotate(-6deg) !important;
    }
}


/* ============================================================
   17. UI REDESIGN 2024 — SERVICES / PORTFOLIO / BLOG
   ------------------------------------------------------------
   The three bands below were rebuilt to match the approved
   reference designs. Their markup lives in component/services.php,
   component/portfolio.php and component/blog.php and is built from
   the `uix-` class family documented here.

   Everything is scoped to `.landing-page`, so the standalone
   frontend pages and the admin panel can never be affected.

   NOTE ON SUPERSEDED RECIPES (deliberate, not an accident):
     - §7b `.lp-svc__*`     (numbered service rows)
     - §7c `.lp-bento__*`   (portfolio mosaic)
     - §12/12b `.lp-jnl__*` (blog journal)
     - §15e `.lp-tech`      (the "Technologies we used" chip wall)
   are no longer referenced by any component. They are kept because
   deleting a few hundred lines of unrelated CSS is riskier than
   leaving it inert, but no new markup should use them.

   The decorative band backgrounds (Asia map, portfolio_bg,
   Blog_Watermark) were retired with the redesign: these three bands
   are now clean light surfaces.
   ============================================================ */

/* --- 17a. Shared primitives -------------------------------------------- */

/* The `hidden` attribute must win over the display values set below on the
   filterable wrappers, otherwise filtering would not actually hide them. */
.landing-page .uix-head [hidden],
.landing-page .uix-blog [hidden],
.landing-page .uix-pf [hidden],
.landing-page .uix-svc-wrap [hidden] {
    display: none !important;
}

/* Centred section header: eyebrow -> headline -> subtitle -> filter pills */
.landing-page .uix-head {
    text-align: center;
    max-width: 46rem;
    margin: 0 auto clamp(2rem, 3.2vw, 3rem);
}

.landing-page .uix-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #0a192f;
    line-height: 1;
}

.landing-page .uix-eyebrow__line {
    display: inline-block;
    width: 28px;
    height: 3px;
    border-radius: 9999px;
    background: #f97316;
    flex-shrink: 0;
}

@media (min-width: 640px) {
    .landing-page .uix-eyebrow {
        font-size: 0.8125rem;
    }
}

.landing-page .uix-title {
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.75rem, 1.1rem + 2.4vw, 2.875rem);
    font-weight: 700;
    line-height: 1.18;
    letter-spacing: -0.02em;
    color: #0a192f;
    margin: 0.9rem 0 0;
}

.landing-page .uix-title--start {
    margin-top: 1rem;
}

.landing-page .uix-title__accent {
    color: #0284c7;
}

.landing-page .uix-title__accent--orange {
    color: #f97316;
}

.landing-page .uix-amp {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 600;
    display: inline-block;
    padding: 0 0.1em;
}

.landing-page .uix-sub {
    margin: 1rem auto 0;
    max-width: 42rem;
    color: #64748b;
    font-size: 0.9375rem;
    line-height: 1.7;
}

.landing-page .uix-sub--start {
    margin-left: 0;
    margin-right: 0;
}

/* --- 17b. Filter pills -------------------------------------------------- */

.landing-page .uix-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.625rem;
    margin-top: 1.75rem;
    padding: 0.25rem 0.5rem 0.5rem;
}

@media (min-width: 900px) {
    .landing-page .uix-tabs {
        flex-wrap: nowrap;
    }
}

.landing-page .uix-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1.15rem;
    border-radius: 9999px;
    border: 1px solid rgba(2, 132, 199, 0.22);
    background: #f0f7ff;
    color: #0a192f;
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    flex-shrink: 0;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease,
        border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.landing-page .uix-tab i {
    font-size: 0.8125rem;
}

.landing-page .uix-tab:hover,
.landing-page .uix-tab:focus-visible {
    background: #e0f0ff;
    border-color: rgba(2, 132, 199, 0.4);
}

.landing-page .uix-tab:focus-visible {
    outline: 2px solid #0284c7;
    outline-offset: 2px;
}

.landing-page .uix-tab.is-active {
    background: #1053a4;
    border-color: #1053a4;
    color: #ffffff;
    box-shadow: 0 10px 20px -12px rgba(16, 83, 164, 0.75);
}

.landing-page .uix-tab.is-active:hover {
    background: #0d4689;
    border-color: #0d4689;
}


/* --- 17c. Shared CTA + empty state ------------------------------------- */

.landing-page .uix-cta-row {
    text-align: center;
    margin-top: clamp(2rem, 3.5vw, 3.25rem);
}

.landing-page .uix-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem 2rem;
    border-radius: 9999px;
    background: #0f4c81;
    color: #ffffff;
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    box-shadow: 0 12px 24px -14px rgba(15, 76, 129, 0.9);
    transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.landing-page .uix-cta:hover,
.landing-page .uix-cta:focus-visible {
    background: #093256;
    transform: translateY(-1px);
    box-shadow: 0 16px 28px -14px rgba(9, 50, 86, 0.95);
}

.landing-page .uix-cta--navy {
    background: #0a192f;
    box-shadow: 0 12px 24px -14px rgba(10, 25, 47, 0.9);
}

.landing-page .uix-cta--navy:hover,
.landing-page .uix-cta--navy:focus-visible {
    background: #1e293b;
}

.landing-page .uix-empty {
    max-width: 34rem;
    margin: 0 auto;
    padding: 3rem 1.5rem;
    border-radius: 1.25rem;
    border: 1px dashed #cbd5e1;
    background: #ffffff;
    text-align: center;
    color: #64748b;
}

.landing-page .uix-empty--light {
    margin: 0;
}

.landing-page .uix-empty>i {
    font-size: 2.25rem;
    color: #94a3b8;
    margin-bottom: 0.75rem;
}

.landing-page .uix-empty>h3 {
    font-family: 'Fraunces', Georgia, serif;
    font-size: 1.25rem;
    font-weight: 700;
    color: #0a192f;
    margin: 0 0 0.35rem;
}

.landing-page .uix-empty>p {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.6;
}

/* Decorative dot grid (cover story corner) */
.landing-page .uix-dotgrid {
    position: absolute;
    right: 1.25rem;
    bottom: 1.25rem;
    width: 92px;
    height: 62px;
    pointer-events: none;
    z-index: 0;
    background-image: radial-gradient(rgba(15, 23, 42, 0.18) 1.6px, transparent 1.6px);
    background-size: 12px 12px;
    opacity: 0.75;
}


/* --- 17d. OUR BLOG: cover story + index stack --------------------------- */
/*
 * Card colour is Admin Panel driven, exactly like §17b (services). Every
 * accent-driven value below is a `var(--uix-…)` custom property produced by
 * blogCardStyleVars() from the post's own colour fields; this sheet only READS
 * them, so a colour chosen in the admin panel is never overridden by a constant
 * here. The admin panel has no per-post blog colour field today, so the helper
 * emits no inline variables and each `var()` falls back to the page's shared
 * neutral palette — meaning the current design renders unchanged, and the day an
 * admin colour exists the whole band repaints with no change to this file.
 *
 * The var() fallbacks deliberately name NEUTRAL tokens (surfaces, ink, the
 * --lp-* page palette), never a blog-specific brand palette: nothing here
 * hard-codes a colour that could ever override an admin choice.
 */

.landing-page .uix-blog {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    align-items: start;
}

@media (min-width: 1024px) {
    .landing-page .uix-blog {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
        gap: 1.5rem;
        /* Keep the magazine cover and the three-card index ending on the
           same baseline, even when an editorial title or summary is longer.
           The reference layout reads as one balanced two-column unit. */
        align-items: stretch;
    }

    /* Same scoping as the equal-height rows below: the cover story and the index
       stack only stretch to match each other inside the homepage band's
       two-column grid. On the standalone /blog listing there is no grid, so
       height:100% on an auto-height parent collapses the whole stack. */
    .landing-page .uix-blog .uix-blog__feature,
    .landing-page .uix-blog .uix-blog__list {
        min-height: 0;
        height: 100%;
    }

    .landing-page .uix-blog__feature-link {
        display: flex;
        flex-direction: column;
        min-height: 100%;
    }

    .landing-page .uix-blog__foot {
        margin-top: auto;
    }

    /* The index stack sizes each row to its OWN content instead of splitting the
       column's height three ways. `flex: 1 1 0` forced every row to be exactly a
       third of the (much taller) cover story, so a short headline and a 2-line
       excerpt were surrounded by dead space and the three cards read as bloated
       next to the cover. `flex: 0 0 auto` + `align-content: start` keeps each row
       compact, packs them to the top of the column, and leaves the leftover
       height as deliberate breathing room at the foot of the band.

        This ONLY applies inside the homepage band, where the rows are items of the
        .uix-blog two-column grid. The standalone /blog listing renders the same
        .uix-blog__list WITHOUT that grid wrapper (see admin/public/blog.php), and
        there `flex: 1 1 0` + `min-height: 0` collapsed every card to zero height
        (auto height never resolves in an auto-height parent), overlapping the
        text and clipping the image slot. The listing cards must size to their
        content, so this rule is scoped to .uix-blog. */
    .landing-page .uix-blog .uix-blog__list {
        align-content: start;
    }

    .landing-page .uix-blog .uix-blog__row {
        display: flex;
        flex: 0 0 auto;
        min-height: 0;
    }

    /* A compact row no longer needs a 9rem/11rem thumbnail to look proportionate.
       The extra class on the selector (.landing-page .uix-blog .uix-blog__thumb)
       is deliberate: the base and 640px rules for .uix-blog__thumb are written
       WITHOUT the .uix-blog ancestor, so they sit later in the file and would
       otherwise win on source order at equal specificity. */
    .landing-page .uix-blog .uix-blog__thumb {
        width: 7.5rem;
        height: 6.75rem;
    }

    .landing-page .uix-blog .uix-blog__row-link,
    .landing-page .uix-blog .uix-blog__row-body {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* Two lines keeps a long summary from re-inflating a row that is now sized
       to its content. The cover story keeps its own 3-line allowance. */
    .landing-page .uix-blog .uix-blog__excerpt--row {
        -webkit-line-clamp: 2;
    }

    /* When a filter hides the cover story the index stack takes the full row. */
    .landing-page .uix-blog.is-solo .uix-blog__list {
        grid-column: 1 / -1;
    }
}

/* Cover story card */
.landing-page .uix-blog__feature {
    position: relative;
    background: var(--uix-surface, #ffffff);
    border: 1px solid var(--uix-accent-soft, var(--lp-line));
    border-radius: 24px;
    padding: 1.5rem;
    box-shadow: 0 10px 24px -18px rgba(var(--uix-accent-rgb, 6, 22, 58), 0.35);
    transition: box-shadow 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
}

.landing-page .uix-blog__feature:hover {
    box-shadow: 0 24px 44px -22px rgba(var(--uix-accent-rgb, 6, 22, 58), 0.42);
    transform: translateY(-2px);
}

@media (min-width: 640px) {
    .landing-page .uix-blog__feature {
        padding: 1.75rem;
    }
}

.landing-page .uix-blog__feature-link {
    display: block;
    text-decoration: none;
    color: inherit;
    position: relative;
    z-index: 1;
}

.landing-page .uix-blog__media {
    position: relative;
    display: block;
    border-radius: 1rem;
    overflow: hidden;
    /* The empty state paints its own floor; this is the while-loading /
       no-artwork-yet base, derived from the card's own surface tokens. */
    background:
        radial-gradient(125% 130% at 50% -20%, var(--uix-accent-tint, var(--lp-light)) 0%, var(--uix-surface, #ffffff) 70%),
        var(--uix-surface, #ffffff);
}

.landing-page .uix-blog__media-img {
    display: block;
    width: 100%;
    /* !important is mandatory: responsive.css ships a global
       `img { height: auto !important }` guard that would otherwise flatten this
       cover image back to its natural height and break the card. */
    height: 15rem !important;
    object-fit: cover;
    transition: transform 0.5s ease;
}

@media (min-width: 640px) {
    .landing-page .uix-blog__media-img {
        height: 18rem !important;
    }
}

.landing-page .uix-blog__feature-link:hover .uix-blog__media-img {
    transform: scale(1.04);
}

/* "No Image Available" on the cover story.
 *
 * The deliberate empty state, built to the EXACT same box as the image above
 * (15rem / 18rem, matching .uix-blog__media-img) so the card is pixel-for-pixel
 * the same height with or without artwork — the copy below, the footer and the
 * sibling index stack never shift. It is tinted from the card's own accent
 * tokens, carries the same diagonal hatch the service cards use, and names the
 * condition in plain words. No bundled theme graphic and no stock photo is ever
 * used to hide a missing Admin Panel upload. */
.landing-page .uix-blog__media--empty {
    background:
        repeating-linear-gradient(135deg,
            rgba(var(--uix-accent-rgb, 34, 184, 209), 0.07) 0 12px,
            rgba(var(--uix-accent-rgb, 34, 184, 209), 0.015) 12px 24px),
        linear-gradient(135deg, var(--uix-accent-tint, var(--lp-light)) 0%, var(--uix-surface, #ffffff) 78%);
}

.landing-page .uix-blog__media-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    /* Same heights as .uix-blog__media-img — see the note above. */
    height: 15rem;
    padding: 0 2rem;
    color: var(--uix-empty-ink, var(--lp-navy));
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.4;
    text-align: center;
}

.landing-page .uix-blog__media-fallback i {
    font-size: 2.25rem;
    color: var(--uix-accent, var(--lp-cyan));
    opacity: 0.45;
}

@media (min-width: 640px) {
    .landing-page .uix-blog__media-fallback {
        height: 18rem;
    }
}

.landing-page .uix-blog__badge {
    position: absolute;
    top: 1rem;
    left: 1rem;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.75rem;
    border-radius: 9999px;
    background: var(--uix-accent, var(--lp-cyan));
    color: var(--uix-accent-ink, #ffffff);
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    line-height: 1.2;
    box-shadow: 0 8px 16px -10px rgba(var(--uix-accent-rgb, 34, 184, 209), 0.9);
}

.landing-page .uix-blog__date {
    position: absolute;
    bottom: 1rem;
    left: 1rem;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.85);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    color: var(--uix-muted-ink, #334155);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
}

.landing-page .uix-blog__cat {
    display: inline-block;
    margin-top: 1.25rem;
    padding: 0.3rem 0.75rem;
    border-radius: 9999px;
    background: var(--uix-chip-bg, var(--lp-light));
    color: var(--uix-chip-text, var(--lp-navy));
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.3;
}

.landing-page .uix-blog__feature-title {
    margin: 0.75rem 0 0;
    font-family: 'Fraunces', Georgia, serif;
    /* One clamp covers phone -> wide desktop, so no per-breakpoint override is
       needed and the headline never jumps size between the two layouts. */
    font-size: clamp(1.375rem, 1.05rem + 1.4vw, 1.625rem);
    font-weight: 700;
    line-height: 1.25;
    color: var(--uix-ink, #0a192f);
    transition: color 0.2s ease;
}

.landing-page .uix-blog__feature-link:hover .uix-blog__feature-title,
.landing-page .uix-blog__feature-link:focus-visible .uix-blog__feature-title {
    color: var(--uix-accent, var(--lp-cyan));
}


.landing-page .uix-blog__excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0.75rem 0 0;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.9375rem;
    line-height: 1.7;
}

.landing-page .uix-blog__excerpt--row {
    -webkit-line-clamp: 2;
    display: -webkit-box;
    margin-top: 0.4rem;
    font-size: 0.875rem;
    line-height: 1.6;
}

.landing-page .uix-blog__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--uix-accent-soft, var(--lp-line));
}

.landing-page .uix-blog__author {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    /* Long author names must not push the "Read More" CTA off the row. */
    min-width: 0;
}

.landing-page .uix-blog__avatar {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 9999px;
    object-fit: cover;
    flex-shrink: 0;
}

.landing-page .uix-blog__avatar--initials {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--uix-chip-bg, var(--lp-light));
    color: var(--uix-chip-text, var(--lp-navy));
    font-size: 0.8125rem;
    font-weight: 800;
}

.landing-page .uix-blog__author-text {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
    min-width: 0;
}

.landing-page .uix-blog__author-name {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--uix-ink, #0f172a);
    /* A single unbroken author name must not overflow the card. */
    overflow-wrap: anywhere;
}

.landing-page .uix-blog__author-role {
    font-size: 0.75rem;
    color: var(--uix-muted-ink, #94a3b8);
}

.landing-page .uix-blog__more {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--uix-ink, #0f172a);
}

.landing-page .uix-blog__arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Must not be squeezed on narrow screens — it carries the row's only
       affordance. */
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    background: var(--uix-chip-bg, var(--lp-light));
    color: var(--uix-chip-text, var(--lp-navy));
    font-size: 0.75rem;
    transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.landing-page .uix-blog__arrow--sm {
    width: 2rem;
    height: 2rem;
}

.landing-page .uix-blog__feature-link:hover .uix-blog__arrow,
.landing-page .uix-blog__feature-link:focus-visible .uix-blog__arrow {
    background: var(--uix-accent, var(--lp-cyan));
    color: var(--uix-accent-ink, #ffffff);
    transform: translateX(2px);
}

/* Index stack */
.landing-page .uix-blog__list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.landing-page .uix-blog__row {
    background: var(--uix-surface, #ffffff);
    border: 1px solid var(--uix-accent-soft, var(--lp-line));
    border-radius: 1rem;
    padding: 1rem;
    box-shadow: 0 6px 16px -14px rgba(var(--uix-accent-rgb, 6, 22, 58), 0.3);
    transition: box-shadow 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
}

.landing-page .uix-blog__row:hover {
    box-shadow: 0 18px 32px -20px rgba(var(--uix-accent-rgb, 6, 22, 58), 0.4);
    transform: translateY(-2px);
}

@media (min-width: 640px) {
    .landing-page .uix-blog__row {
        padding: 1.25rem;
    }
}

.landing-page .uix-blog__row-link {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    text-decoration: none;
    color: inherit;
}

.landing-page .uix-blog__thumb {
    flex-shrink: 0;
    width: 9rem;
    height: 8rem;
    border-radius: 0.75rem;
    overflow: hidden;
    background:
        radial-gradient(125% 130% at 50% -20%, var(--uix-accent-tint, var(--lp-light)) 0%, var(--uix-surface, #ffffff) 70%),
        var(--uix-surface, #ffffff);
}

@media (min-width: 640px) {
    .landing-page .uix-blog__thumb {
        width: 11rem;
        height: 9rem;
    }
}

.landing-page .uix-blog__thumb-img {
    display: block;
    width: 100%;
    height: 100% !important;
    /* see the note on .uix-blog__media-img */
    object-fit: cover;
    transition: transform 0.5s ease;
}

.landing-page .uix-blog__row-link:hover .uix-blog__thumb-img {
    transform: scale(1.05);
}

/* "No Image Available" in the index-row thumbnail.
 *
 * Fills 100% of .uix-blog__thumb, so the box is the SAME 9rem x 8rem (11rem x
 * 9rem from 640px) it would be with artwork. The row therefore keeps its exact
 * height, the body column keeps its width, and the three index cards stay on one
 * baseline whether or not any post has an image. Same diagonal hatch and accent
 * tint as the cover-story empty state, so the two read as one design system. */
.landing-page .uix-blog__thumb--empty {
    background:
        repeating-linear-gradient(135deg,
            rgba(var(--uix-accent-rgb, 34, 184, 209), 0.07) 0 10px,
            rgba(var(--uix-accent-rgb, 34, 184, 209), 0.015) 10px 20px),
        linear-gradient(135deg, var(--uix-accent-tint, var(--lp-light)) 0%, var(--uix-surface, #ffffff) 78%);
}

.landing-page .uix-blog__thumb-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    width: 100%;
    height: 100%;
    padding: 0 0.5rem;
    color: var(--uix-empty-ink, var(--lp-navy));
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.35;
    text-align: center;
}

.landing-page .uix-blog__thumb-fallback i {
    font-size: 1.25rem;
    color: var(--uix-accent, var(--lp-cyan));
    opacity: 0.45;
}

.landing-page .uix-blog__row-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.landing-page .uix-blog__row-body .uix-blog__cat {
    margin-top: 0;
    align-self: flex-start;
}

.landing-page .uix-blog__row-title {
    margin: 0.5rem 0 0;
    font-family: 'Fraunces', Georgia, serif;
    /* Same clamp approach as the cover headline: one curve from phone to wide
       desktop instead of a step at 640px. */
    font-size: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);
    font-weight: 700;
    line-height: 1.3;
    color: var(--uix-ink, #0a192f);
    transition: color 0.2s ease;
    /* A long unbroken headline must wrap rather than widen the row. */
    overflow-wrap: anywhere;
}

.landing-page .uix-blog__row-link:hover .uix-blog__row-title,
.landing-page .uix-blog__row-link:focus-visible .uix-blog__row-title {
    color: var(--uix-accent, var(--lp-cyan));
}

.landing-page .uix-blog__row-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    margin-top: auto;
    padding-top: 0.75rem;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.75rem;
    font-weight: 600;
}

.landing-page .uix-blog__stamp {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.landing-page .uix-blog__stamp i {
    color: var(--uix-accent, var(--lp-cyan));
}

.landing-page .uix-blog__row .uix-blog__arrow--sm {
    margin-left: auto;
}

.landing-page .uix-blog__row-link:hover .uix-blog__arrow--sm,
.landing-page .uix-blog__row-link:focus-visible .uix-blog__arrow--sm {
    background: var(--uix-accent, var(--lp-cyan));
    color: var(--uix-accent-ink, #ffffff);
    transform: translateX(2px);
}


/* --- 17d-i. OUR BLOG: phone / tablet layout ------------------------------ */
/*
 * Below 640px the index row switches from "thumbnail beside the copy" to
 * "banner above the copy". A fixed 9rem thumbnail with flex-shrink: 0 leaves
 * only ~150px for the body column on a 360px phone, which squeezed long
 * headlines into a one-word-per-line column and left the card looking broken.
 * A full-width 16:9 banner gives the copy the whole card width, and keeps the
 * empty state just as readable because .uix-blog__thumb-fallback fills 100% of
 * whatever box the thumb resolves to. From 640px up the side-by-side layout
 * above takes over unchanged.
 */
@media (max-width: 639.98px) {
    .landing-page .uix-blog__row-link {
        flex-direction: column;
        gap: 0.85rem;
    }

    .landing-page .uix-blog__thumb {
        /* 16:9 across the full card width. `width` is 100% so the banner
           tracks the card; the `height` override is what pairs with the
           !important on .uix-blog__thumb-img (responsive.css forces
           `img { height: auto !important }` globally). */
        width: 100%;
        height: auto;
        aspect-ratio: 16 / 9;
        min-height: 0;
        border-radius: 0.75rem;
    }

    /* Engines without aspect-ratio: fall back to an explicit band. */
    @supports not (aspect-ratio: 16 / 9) {
        .landing-page .uix-blog__thumb {
            height: 11rem;
        }
    }

    .landing-page .uix-blog__thumb-img,
    .landing-page .uix-blog__thumb-fallback {
        height: 100% !important;
    }

    /* The category chip sits at the very top of the stacked body, so it needs
       its breathing room back now that it is no longer beside a thumbnail. */
    .landing-page .uix-blog__row-body .uix-blog__cat {
        margin-top: 0.15rem;
    }

    /* Two lines is the desktop rhythm; on a phone the full width means the
       excerpt can afford the same 3-line allowance the cover story uses. */
    .landing-page .uix-blog__excerpt--row {
        -webkit-line-clamp: 3;
    }

    /* The cover's media box shrinks a little on the narrowest screens so the
       headline and footer stay above the fold. */
    .landing-page .uix-blog__media-img,
    .landing-page .uix-blog__media-fallback {
        height: 12.5rem;
    }
}

@media (min-width: 380px) and (max-width: 639.98px) {

    .landing-page .uix-blog__media-img,
    .landing-page .uix-blog__media-fallback {
        height: 14rem;
    }
}

/* Touch devices get no hover lift, and the "Read More" copy duplicates the
   whole card link — keep the card itself as the only affordance. */
@media (hover: none) {

    .landing-page .uix-blog__feature:hover,
    .landing-page .uix-blog__row:hover {
        transform: none;
        box-shadow: 0 10px 24px -18px rgba(var(--uix-accent-rgb, 6, 22, 58), 0.35);
    }
}


/* --- 17e. OUR PORTFOLIO: showcase + 2x2 grid ---------------------------- */

.landing-page #portfolio::before,
.landing-page #portfolio::after {
    position: absolute;
    z-index: 0;
    width: 19rem;
    height: 19rem;
    border-radius: 9999px;
    background: radial-gradient(circle at 50% 50%, rgba(186, 230, 253, 0.74), rgba(224, 242, 254, 0.35) 68%, transparent 69%);
    content: '';
    pointer-events: none;
}

.landing-page #portfolio::before {
    top: -11rem;
    left: -10rem;
}

.landing-page #portfolio::after {
    top: -13rem;
    right: -7rem;
}

.landing-page .uix-pf__container {
    /* Same measure as the blog band's .max-w-7xl column — see §17h, which
       applies the shared left/right gutters above 1024px. */
    max-width: 84rem;
}

.landing-page #portfolio .uix-head {
    max-width: 66rem;
    margin-bottom: clamp(1.8rem, 2.5vw, 2.5rem);
}

.landing-page #portfolio .uix-title {
    font-size: clamp(2.15rem, 1.15rem + 3vw, 3.6rem);
}

.landing-page #portfolio .uix-sub {
    max-width: 50rem;
    font-size: 1rem;
}

.landing-page .uix-pf {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    align-items: stretch;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf {
        /* The reference keeps both columns on the same baseline.  The fixed
           two-row grid and stretched showcase make that hold for every CMS
           title, excerpt and image combination. */
        grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
        gap: 1.4rem;
    }

    /* When a filter hides the showcase the grid takes the full row. */
    .landing-page .uix-pf.is-solo .uix-pf__grid {
        grid-column: 1 / -1;
    }
}

.landing-page .uix-pf__showcase {
    position: relative;
    background: #ffffff;
    border: 1px solid #cfe8fb;
    border-radius: 1.1rem;
    padding: 1.5rem;
    box-shadow: 0 18px 40px -26px rgba(15, 23, 42, 0.45);
}

@media (min-width: 640px) {
    .landing-page .uix-pf__showcase {
        padding: 2rem;
    }
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__showcase {
        display: flex;
        min-height: 0;
        flex-direction: column;
        padding: 1.5rem;
        overflow: hidden;
        background:
            radial-gradient(65% 80% at 90% 88%, rgba(224, 242, 254, 0.92), transparent 70%),
            #ffffff;
    }

    /* The reference has a pale, layered sky-blue field behind the product
       visual. It belongs to the featured card itself, never the project
       image, so the CMS asset remains completely unmodified. */
    .landing-page .uix-pf__showcase::before {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 62%;
        border-radius: 58% 0 0 42%;
        background:
            radial-gradient(75% 52% at 86% 20%, rgba(219, 239, 255, 0.95) 0 48%, transparent 49%),
            radial-gradient(92% 76% at 56% 77%, rgba(227, 243, 255, 0.9) 0 58%, transparent 59%);
        content: '';
        pointer-events: none;
    }
}

/* --- Portfolio showcase slide ---------------------------------------------
   The slide is the element that receives the Admin Panel colour, so it is
   where the --uix-* custom properties are declared. Every accent-driven colour
   below READS those variables and never hard-codes one, which is what makes a
   colour picked in the admin panel repaint the featured project card.

   The var() fallbacks name the shipping palette's own values, so the card
   renders exactly as before when the admin has chosen no colour. The outer
   .uix-pf__showcase frame stays neutral on purpose: it is shared by every
   slide, so it cannot belong to any single project's colour. */
.landing-page .uix-pf__slide {
    display: block;
    --uix-accent: #0284c7;
    --uix-accent-rgb: 2, 132, 199;
    --uix-accent-ink: #ffffff;
    --uix-accent-soft: #cfe8fb;
    --uix-accent-tint: #e0f2fe;
    --uix-surface: #ffffff;
    --uix-surface-rgb: 255, 255, 255;
    --uix-ink: #0f172a;
    --uix-muted-ink: #64748b;
    --uix-chip-bg: #f0f7ff;
    --uix-chip-text: #1d4ed8;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__slide {
        position: relative;
        z-index: 1;
        flex: 1 1 auto;
        min-height: 0;
    }
}

.landing-page .uix-pf__badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.landing-page .uix-pf__badge-cat {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.8rem;
    border-radius: 9999px;
    /* Category chip: the admin chip tint behind a readable accent. */
    background: var(--uix-accent-tint, #e0f2fe);
    color: var(--uix-chip-text, #0284c7);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.3;
}

.landing-page .uix-pf__badge-featured {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.8rem;
    border-radius: 9999px;
    background: linear-gradient(135deg, #0d9488, #14b8a6);
    color: #ffffff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.3;
    box-shadow: 0 8px 18px -12px rgba(13, 148, 136, 0.95);
}

.landing-page .uix-pf__title {
    margin: 1rem 0 0.5rem;
    font-family: 'Fraunces', Georgia, serif;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.22;
    /* Headline ink: the admin accent mixed towards a dark navy, so it stays
       AA-readable on the card surface for any accent the editor picks. */
    color: var(--uix-ink, #0f172a);
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__title {
        margin-top: 1.8rem;
        font-size: 2rem;
        line-height: 1.23;
    }
}

@media (min-width: 640px) {
    .landing-page .uix-pf__title {
        font-size: 1.875rem;
    }
}

.landing-page .uix-pf__title a {
    color: inherit;
    text-decoration: none;
    transition: color 0.2s ease;
}

.landing-page .uix-pf__title a:hover,
.landing-page .uix-pf__title a:focus-visible {
    color: var(--uix-accent, #0284c7);
}

.landing-page .uix-pf__desc {
    margin: 0;
    /* Body ink: the admin accent mixed towards slate. */
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.9375rem;
    line-height: 1.7;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__desc {
        font-size: 1rem;
        line-height: 1.65;
    }
}

.landing-page .uix-pf__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin: 0.75rem 0 0;
    padding: 0;
    list-style: none;
}

.landing-page .uix-pf__tag {
    padding: 0.3rem 0.85rem;
    border-radius: 9999px;
    /* Technology chips: the admin tag_bg_color, lettered in the contrast-matched ink. */
    background: var(--uix-chip-bg, #f0f7ff);
    color: var(--uix-chip-text, #1d4ed8);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
}

.landing-page .uix-pf__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.25rem;
    margin-top: 0.75rem;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.8125rem;
    font-weight: 600;
}

.landing-page .uix-pf__meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.landing-page .uix-pf__meta-item i {
    color: #f97316;
}

.landing-page .uix-pf__meta-link {
    color: #0284c7;
    text-decoration: none;
    transition: color 0.2s ease;
}

.landing-page .uix-pf__meta-link:hover,
.landing-page .uix-pf__meta-link:focus-visible {
    color: #0c4a6e;
    text-decoration: underline;
}

/* Project facts strip
   ─────────────────────────────────────────────────────────────────────────
   Occupies the space that used to sit empty between the meta line and the
   decorative flourish. Each fact is a small bordered tile, stacked on phones
   and laid out as a row from 640px up.

   All colour comes from the admin-supplied --uix-* palette, so the tiles
   repaint with the project's accent exactly like the chips and badges do. The
   only literal colour is the hairline border fallback, matching the card
   border used elsewhere in this stylesheet. Nothing here is clickable.
   ───────────────────────────────────────────────────────────────────────── */
.landing-page .uix-pf__facts {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 1.25rem 0 0;
    padding: 0;
}

@media (min-width: 640px) {
    .landing-page .uix-pf__facts {
        flex-direction: row;
        flex-wrap: wrap;
    }
}

@media (min-width: 1024px) {

    /* The slide is a BLOCK, so `margin-top: auto` alone would do nothing.
       Making it a flex column (it is a flex ITEM of .uix-pf__showcase, and
       `flex: 1 1 auto` on line above keeps it filling the card) lets the
       auto margin below absorb the slack.

       .uix-pf__stage is absolutely positioned at this width, so it takes up
       no flow height: the free space below the meta line is real, and the
       auto margin parks the tiles against the bottom edge, directly under the
       artwork. Previously they sat right below the meta line and left the
       whole lower half of the card empty. */
    .landing-page .uix-pf__slide {
        display: flex;
        flex-direction: column;
    }

    .landing-page .uix-pf__facts {
        position: relative;
        z-index: 2;
        margin-top: auto;
        padding-top: 0.9rem;
    }
}

.landing-page .uix-pf__fact {
    /* min-width: 0 so a long client name truncates with the ellipsis below
       instead of forcing the tile wider than the column. */
    display: flex;
    flex: 1 1 8rem;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--uix-accent-soft, #cfe8fb);
    border-radius: 0.7rem;
    background: var(--uix-accent-tint, #e0f2fe);
}

.landing-page .uix-pf__fact-label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.landing-page .uix-pf__fact-label i {
    color: var(--uix-accent, #0284c7);
    font-size: 0.625rem;
}

.landing-page .uix-pf__fact-value {
    overflow: hidden;
    margin: 0;
    color: var(--uix-ink, #0f172a);
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.4;
    /* A long client name is clipped to one line rather than wrapping the tile
       to three lines and unbalancing the whole strip. */
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* Dual-device mockup stage: laptop + overlapping phone + succulent accent */
.landing-page .uix-pf__stage {
    position: relative;
    margin-top: 1.5rem;
    border-radius: 1.25rem;
    padding: 1.25rem;
    /* Transparent: like every other frame in this section, the stage must not
       paint a backdrop behind the artwork or a transparent PNG loses its
       alpha. The card surface behind it provides the neutral. */
    background: transparent;
    overflow: hidden;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__mockup-wrap {
        overflow: visible;
        border-radius: 0;
        box-shadow: none;
        background: transparent;
    }

    .landing-page .uix-pf__mockup-img {
        object-fit: contain;
    }
}

.landing-page .uix-pf__mockup-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: 6 / 9;
    border-radius: 1rem;
    overflow: hidden;
    /* box-shadow: 0 18px 38px -20px rgba(15, 23, 42, 0.4); */
    /* See the note above: no painted backdrop, so PNG alpha survives. */
    background: transparent;
}

.landing-page .uix-pf__mockup-img {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 100% !important;
    max-height: 100% !important;
    /* contain, not cover: `cover` scales the picture up until it fills the
       frame and slices off every edge that does not match the frame's ratio,
       which is exactly the "cropped" report. `contain` fits the WHOLE image
       inside the frame and letterboxes the remainder. */
    object-fit: contain;
    transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

/* The hover nudge is kept, but it is now a gentle grow that stays inside the
   frame: at 1.02 a contained image still cannot be cropped by the wrapper. */
.landing-page .uix-pf__showcase:hover .uix-pf__mockup-img {
    transform: scale(1.02);
}

.landing-page .uix-pf__laptop {
    position: relative;
    width: 82%;
    max-width: 420px;
    aspect-ratio: 16 / 10;
    border-radius: 0.75rem 0.75rem 0.35rem 0.35rem;
    border: 6px solid #0f172a;
    /* Transparent screen: the old #0b1f3a fill sat behind the artwork, so a
       transparent PNG rendered against navy instead of the card. */
    background: transparent;
    overflow: hidden;
    box-shadow: 0 22px 40px -26px rgba(15, 23, 42, 0.8);
}

.landing-page .uix-pf__laptop-img {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 100% !important;
    /* see the note on .uix-blog__media-img */
    max-height: 100% !important;
    /* See .uix-pf__mockup-img: contain keeps the whole picture visible. */
    object-fit: contain;
}

.landing-page .uix-pf__screen-art {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: #38bdf8;
    font-size: 2rem;
    background:
        linear-gradient(180deg, rgba(56, 189, 248, 0.14) 0%, transparent 60%),
        repeating-linear-gradient(180deg, rgba(148, 163, 184, 0.22) 0 6px, transparent 6px 14px);
}

.landing-page .uix-pf__phone {
    position: absolute;
    right: 1.25rem;
    bottom: 1.25rem;
    width: 30%;
    max-width: 130px;
    aspect-ratio: 9 / 18;
    border-radius: 1rem;
    border: 5px solid #0f172a;
    /* See .uix-pf__laptop: no painted screen behind the artwork. */
    background: transparent;
    overflow: hidden;
    box-shadow: 0 20px 34px -20px rgba(15, 23, 42, 0.85);
}

.landing-page .uix-pf__phone-img {
    display: block;
    width: 100%;
    height: 100% !important;
    /* see the note on .uix-blog__media-img */
    object-fit: contain;
}

.landing-page .uix-pf__phone-art {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.5rem;
    height: 100%;
    padding: 0.75rem;
}

.landing-page .uix-pf__phone-art>span {
    display: block;
    height: 0.4rem;
    border-radius: 9999px;
    background: rgba(148, 163, 184, 0.55);
}

.landing-page .uix-pf__phone-art>span:first-child {
    width: 60%;
    background: #f97316;
}

.landing-page .uix-pf__phone-art>span:nth-child(2) {
    width: 85%;
}

.landing-page .uix-pf__phone-art>span:last-child {
    width: 45%;
}

.landing-page .uix-pf__plant {
    position: absolute;
    left: 0.75rem;
    bottom: 0.25rem;
    width: 52px;
    opacity: 0.95;
    pointer-events: none;
}

.landing-page .uix-pf__plant svg {
    display: block;
    width: 100%;
    height: auto;
}

/* Showcase flourish (replaces the former carousel navigation bar)
   ─────────────────────────────────────────────────────────────────────────
   This block is intentionally PRESENTATION ONLY: no buttons, no counter, no
   progress bar and no data-uix-* hooks, so it can never be mistaken for a
   control and can never intercept a click.

   It is a centred hairline that fades out toward both edges and passes through
   a small rotated diamond, echoing the card's rounded geometry. Every colour is
   drawn from the admin-supplied --uix-* palette (with the shipping fallbacks),
   so the flourish repaints with the project's accent colour instead of
   hard-coding an orange.
   ───────────────────────────────────────────────────────────────────────── */
.landing-page .uix-pf__flourish {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

@media (min-width: 1024px) {

    /* The flourish now trails the facts strip, which is what carries the
       `margin-top: auto` that pins this pair to the bottom of the showcase
       (it used to live here). Only a fixed gap is needed between them, so the
       diamond sits directly under the tiles instead of the free space being
       split between two auto margins. */
    .landing-page .uix-pf__flourish {
        position: relative;
        z-index: 2;
        margin-top: 0.85rem;
        padding-top: 0;
    }
}

/* The two hairlines mirror each other and fade away from the centre. */
.landing-page .uix-pf__flourish-line {
    display: block;
    width: 4.5rem;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--uix-accent-soft, #cfe8fb));
}

.landing-page .uix-pf__flourish-line:last-child {
    background: linear-gradient(270deg, transparent, var(--uix-accent-soft, #cfe8fb));
}

/* The centre mark: a small rotated square, i.e. a diamond. */
.landing-page .uix-pf__flourish-diamond {
    display: block;
    width: 0.5rem;
    height: 0.5rem;
    flex: 0 0 auto;
    border-radius: 2px;
    background: var(--uix-accent, #0284c7);
    box-shadow: 0 0 0 3px var(--uix-accent-tint, #e0f2fe);
    transform: rotate(45deg);
}

/* 2x2 project grid */
.landing-page .uix-pf__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: repeat(2, minmax(0, 1fr));
        gap: 1rem;
    }
}

@media (min-width: 640px) {
    .landing-page .uix-pf__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.25rem;
    }
}

.landing-page .uix-pf-card {
    background: var(--uix-surface, #ffffff);
    border: 1px solid var(--uix-accent-soft, #d8ebfa);
    border-radius: 1rem;
    box-shadow: 0 8px 20px -16px rgba(var(--uix-accent-rgb, 15, 23, 42), 0.35);
    transition: box-shadow 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
    /* Last line of defence for the thumbnail: even if a future image ever
       renders larger than its box (a huge source file, a stylesheet that loads
       late, or an unknown override), the card clips it here instead of letting
       it overlap the title, excerpt and meta text below. */
    overflow: hidden;
}

.landing-page .uix-pf-card:hover {
    box-shadow: 0 22px 40px -24px rgba(var(--uix-accent-rgb, 15, 23, 42), 0.45);
    transform: translateY(-3px);
    border-color: var(--uix-accent-soft, #e2e8f0);
}

.landing-page .uix-pf-card__link {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0;
    text-decoration: none;
    color: inherit;
    /* Second clipping layer. .uix-pf-card clips at the card edge; this clips at
       the link edge, so an image can never escape the thumbnail strip and ride
       up over the badge or over the card's top border. */
    overflow: hidden;
}

.landing-page .uix-pf-card__badge {
    position: absolute;
    top: 0.6rem;
    left: 0.6rem;
    z-index: 1;
    padding: 0.32rem 0.72rem;
    border-radius: 9999px;
    background: var(--uix-surface, rgba(248, 252, 255, 0.94));
    box-shadow: 0 3px 10px rgba(var(--uix-accent-rgb, 2, 132, 199), 0.08);
    color: var(--uix-accent, #1d4ed8);
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.4;
}

.landing-page .uix-pf-card__title {
    margin: 0;
    font-family: 'Fraunces', Georgia, serif;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--uix-ink, #0a192f);
    transition: color 0.2s ease;
}

.landing-page .uix-pf-card__link:hover .uix-pf-card__title,
.landing-page .uix-pf-card__link:focus-visible .uix-pf-card__title {
    color: var(--uix-accent, #0284c7);
}

.landing-page .uix-pf-card__excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0.35rem 0 0;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.8125rem;
    line-height: 1.6;
}

/* Portfolio card thumbnail strip
   ─────────────────────────────────────────────────────────────────────────
   No background is applied here: the admin panel can supply a solid hex via
   inline `style="background:#rrggbb"`, but when no color is configured the
   thumbnail background is intentionally transparent/neutral so no hard-coded
   color ever leaks through.  The `aspect-ratio` keeps the strip the right
   height regardless of whether an image, a colour, or the placeholder is shown.

   Transparency: the strip's own background is now transparent UNCONDITIONALLY.
   It used to fall back to the card's accent tint, which painted a solid wash
   behind the artwork and made a transparent PNG look like a white-background
   JPG. The admin tint is still applied - but only to the no-image placeholder,
   where there is no photo for it to fight with (see --no-image below).
   ───────────────────────────────────────────────────────────────────────── */
.landing-page .uix-pf-card__thumb {
    display: block;
    position: relative;
    margin-top: 0;
    margin-bottom: 0;
    border-radius: 0.95rem 0.95rem 0 0;
    overflow: hidden;
    /* Never paint a backdrop behind real artwork: PNG alpha must survive. */
    background: transparent;
    /* NO fixed aspect-ratio here any more. A fixed ratio forces the image into
       `object-fit: contain`, which letterboxes a square/portrait photo and
       leaves empty gutters down the left and right of the picture. The image
       is now in normal flow (see the img rule below) and defines the strip's
       height from its own proportions, so it always fills the full card width
       with no side gaps and no cropping at all. */
    aspect-ratio: auto;
    /* Containment: this span is a flex item of the column .uix-pf-card__link, so
       pin it to the card's width and stop it being stretched or shrunk by the
       flex algorithm. The in-flow image below then always yields the height,
       and the media can never spill into .uix-pf-card__body. */
    flex: 0 0 auto;
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

.landing-page .uix-pf-card__thumb img {
    /* In normal flow, NOT absolutely positioned. The image now defines the
       strip's height itself: full card width, natural proportions, nothing
       cropped and no side gutters. It cannot ride up over the card's top
       border either, because it simply starts at the top of the strip. */
    display: block;
    position: static;
    width: 100%;
    /* `height: auto` (not 100%) is what lets the intrinsic ratio drive the box.
       The !important outranks the global `img { height: auto !important }`
       guard in responsive.css with the same value, so load order between the
       two stylesheets can no longer break the sizing. */
    height: auto !important;
    max-width: 100% !important;
    /* No max-height cap: a cap would shrink a tall image and reintroduce side
       gaps, which is precisely what this change removes. */
    max-height: none;
    /* No object-fit: with the intrinsic ratio preserved there is nothing left
       to fit, so `contain` would only add letterboxing. */
    object-fit: initial;
    transition: transform 0.5s ease;
}

/* Hover nudge. Scaled from the centre and clipped by the strip's overflow, so
   it can never crop the artwork the way the old 1.05 did. */
.landing-page .uix-pf-card__link:hover .uix-pf-card__thumb img {
    transform: scale(1.04);
}

/* "No Image Available" placeholder — shown when no CMS image is uploaded */
.landing-page .uix-pf-card__thumb--no-image {
    display: flex;
    align-items: center;
    justify-content: center;
    /* The real-image rule now sets `aspect-ratio: auto` because the in-flow
       photo supplies its own height. With no photo there is nothing to supply
       a height, so the placeholder re-establishes a ratio here - otherwise this
       state would collapse to a 0px strip. */
    aspect-ratio: 2.28 / 1;
    /* Subtle neutral surface — overridden by var(--uix-accent-tint) when admin provides a color */
    background: var(--uix-accent-tint, #f1f5f9);
    border-bottom: 1px solid var(--uix-accent-soft, #e2e8f0);
}

/* When the admin did set a color we use that as the background (via inline
   style variables), so we only want a slightly darker tint for the text, not the flat
   neutral above. */
.landing-page .uix-pf-card__no-img-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    color: var(--uix-muted-ink, #94a3b8);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    pointer-events: none;
    user-select: none;
    padding: 1rem;
    text-align: center;
}

.landing-page .uix-pf-card__no-img-inner i {
    font-size: 1.75rem;
    opacity: 0.45;
    color: inherit;
}

.landing-page .uix-pf-card__thumb--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #93c5fd;
    font-size: 1.5rem;
}

.landing-page .uix-pf-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    /* Tightened from 0.8/1.1/0.95rem. Shorter text block = taller picture above
       it in the same card, which is what "give the image more room" means here. */
    padding: 0.55rem 1rem 0.7rem;
}

.landing-page .uix-pf-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: 0.75rem;
    color: var(--uix-muted-ink, #64748b);
    font-size: 0.75rem;
    font-weight: 600;
}

.landing-page .uix-pf-card__stamp {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.landing-page .uix-pf-card__stamp+.uix-pf-card__stamp {
    padding-left: 0.9rem;
    border-left: 1px solid var(--uix-accent-soft, #cfe8fb);
}

.landing-page .uix-pf-card__stamp i {
    color: var(--uix-accent, #f97316);
}

.landing-page .uix-pf-card__stamp--link {
    color: var(--uix-accent, #0284c7);
}

/* Featured project artwork -------------------------------------------------
   The left-hand feature card mirrors the reference: copy occupies a calm left
   column while the uploaded transparent PNG has a generous, layered stage on
   the right. These are CSS-only surfaces; project imagery is never supplied by
   the theme. */
.landing-page #portfolio::before,
.landing-page #portfolio::after {
    display: none;
}

.landing-page #portfolio .uix-section-dots--portfolio {
    display: none;
}

.landing-page .uix-pf__showcase {
    isolation: isolate;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf {
        grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
        gap: 1.5rem;
        align-items: stretch;
    }

    .landing-page .uix-pf__showcase {
        min-height: 0;
        padding: 1.5rem 1.5rem 1.25rem;
        border-radius: 1.25rem;
        background:
            radial-gradient(75% 85% at 95% 95%, rgba(224, 242, 254, 0.85), transparent 75%),
            #ffffff;
    }

    .landing-page .uix-pf__showcase::before {
        content: '';
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        border-radius: inherit;
        background:
            radial-gradient(ellipse 70% 60% at 95% 15%, rgba(217, 238, 255, 0.75) 0%, transparent 60%),
            radial-gradient(ellipse 65% 55% at 90% 90%, rgba(229, 243, 255, 0.7) 0%, transparent 60%);
        pointer-events: none;
        z-index: 0;
    }

    .landing-page .uix-pf__slide {
        padding-right: 0;
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        width: 100%;
        height: 100%;
        min-height: 0;
    }

    .landing-page .uix-pf__title {
        max-width: 100%;
        margin-top: 0.5rem;
        margin-bottom: 0.5rem;
        font-size: clamp(1.5rem, 1.2rem + 0.7vw, 1.8rem);
        line-height: 1.22;
    }

    .landing-page .uix-pf__desc {
        max-width: 40rem;
        margin-bottom: 0.75rem;
        font-size: 0.9rem;
        line-height: 1.6;
        color: var(--uix-muted-ink, #475569);
    }

    .landing-page .uix-pf__content {
        display: flex;
        flex-direction: column;
        width: 100%;
        position: relative;
        z-index: 1;
    }

    .landing-page .uix-pf__stage {
        position: relative;
        top: auto;
        right: auto;
        bottom: auto;
        left: auto;
        width: 100%;
        flex: 1 1 auto;
        min-height: 11rem;
        max-height: 15rem;
        margin: 0.75rem 0 0.85rem;
        padding: 1rem 1.5rem;
        border-radius: 1.1rem;
    }

    .landing-page .uix-pf__facts {
        width: 100%;
        max-width: 100%;
        margin-top: auto;
        position: relative;
        z-index: 1;
    }
}

/* Base and mobile/tablet stage & artwork rules */
.landing-page .uix-pf__content {
    display: flex;
    flex-direction: column;
    width: 100%;
    position: relative;
    z-index: 1;
}

.landing-page .uix-pf__desc {
    margin: 0 0 1rem;
    color: var(--uix-muted-ink, #475569);
    font-size: 0.9375rem;
    line-height: 1.68;
}

.landing-page .uix-pf__stage {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 14rem;
    margin: 1.25rem 0;
    padding: 1.25rem 1.5rem;
    border-radius: 1rem;
    background: linear-gradient(145deg, rgba(240, 249, 255, 0.65) 0%, rgba(224, 242, 254, 0.45) 100%);
    border: 1px solid rgba(207, 232, 251, 0.75);
    box-shadow: inset 0 2px 6px rgba(2, 132, 199, 0.04), 0 8px 24px -16px rgba(15, 23, 42, 0.08);
    overflow: hidden;
    isolation: isolate;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.landing-page .uix-pf__showcase:hover .uix-pf__stage {
    border-color: rgba(186, 222, 248, 0.95);
    box-shadow: inset 0 2px 6px rgba(2, 132, 199, 0.06), 0 12px 28px -14px rgba(15, 23, 42, 0.12);
}

.landing-page .uix-pf__stage-orb,
.landing-page .uix-pf__stage-dots {
    position: absolute;
    z-index: 0;
    display: block;
    pointer-events: none;
}

.landing-page .uix-pf__stage-orb--one {
    right: -10%;
    bottom: -15%;
    width: 65%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(186, 224, 255, 0.5) 0%, rgba(218, 237, 255, 0.1) 70%, transparent 100%);
}

.landing-page .uix-pf__stage-orb--two {
    left: -8%;
    top: -12%;
    width: 55%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(224, 242, 254, 0.6) 0%, rgba(240, 249, 255, 0.15) 70%, transparent 100%);
}

.landing-page .uix-pf__stage-dots {
    top: 1rem;
    right: 1.5rem;
    width: 4rem;
    height: 4rem;
    opacity: 0.45;
    background-image: radial-gradient(circle, rgba(56, 189, 248, 0.45) 1.5px, transparent 1.8px);
    background-size: 0.9rem 0.9rem;
}

.landing-page .uix-pf__artwork {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    max-height: 100%;
    transform: none;
}

.landing-page .uix-pf__artwork-img {
    display: block;
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: 12rem;
    object-fit: contain;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px -12px rgba(15, 23, 42, 0.22);
    filter: drop-shadow(0 8px 16px rgba(15, 61, 98, 0.08));
    transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__artwork-img {
        max-height: 13rem;
    }
}

.landing-page .uix-pf__showcase:hover .uix-pf__artwork-img {
    transform: translateY(-4px) scale(1.02);
    box-shadow: 0 22px 42px -12px rgba(15, 23, 42, 0.28);
}

.landing-page .uix-pf__artwork-secondary {
    position: absolute;
    z-index: 2;
    right: 1rem;
    bottom: 0.85rem;
    width: 22%;
    max-width: 105px;
    overflow: hidden;
    border: 3px solid rgba(15, 23, 42, 0.9);
    border-radius: 0.75rem;
    box-shadow: 0 16px 28px -12px rgba(15, 23, 42, 0.55);
    background: #0f172a;
    transform: none;
    transition: transform 0.35s ease;
}

.landing-page .uix-pf__showcase:hover .uix-pf__artwork-secondary {
    transform: translateY(-2px) scale(1.03);
}

.landing-page .uix-pf__artwork-secondary img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: cover;
}

/* 2x2 Grid styling on the right — prominent image, compact body.
   Scoped to .uix-pf__grid so the left showcase (.uix-pf__showcase) is untouched. */
.landing-page .uix-pf__grid .uix-pf-card {
    display: flex;
    flex-direction: column;
}

.landing-page .uix-pf__grid .uix-pf-card__link {
    flex: 1 1 auto;
}

.landing-page .uix-pf__grid .uix-pf-card__thumb {
    aspect-ratio: 16 / 10;
    min-height: 9.5rem;
    background: var(--uix-accent-tint, #f1f5f9);
}

.landing-page .uix-pf__grid .uix-pf-card__thumb img {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    max-height: none;
    object-fit: cover;
    object-position: center;
}

.landing-page .uix-pf__grid .uix-pf-card__thumb--no-image {
    aspect-ratio: 16 / 10;
    min-height: 9.5rem;
}

.landing-page .uix-pf__grid .uix-pf-card__body {
    gap: 0.15rem;
    padding: 0.6rem 0.95rem 0.7rem;
}

.landing-page .uix-pf__grid .uix-pf-card__excerpt {
    -webkit-line-clamp: 1;
    margin-top: 0.25rem;
}

.landing-page .uix-pf__grid .uix-pf-card__meta {
    padding-top: 0.55rem;
}

@media (min-width: 1024px) {
    .landing-page .uix-pf__grid {
        grid-template-rows: repeat(2, minmax(0, 1fr));
        align-items: stretch;
    }

    .landing-page .uix-pf__grid .uix-pf-card {
        min-height: 0;
    }

    .landing-page .uix-pf__grid .uix-pf-card__thumb,
    .landing-page .uix-pf__grid .uix-pf-card__thumb--no-image {
        aspect-ratio: 16 / 10;
        min-height: 9.5rem;
    }

    .landing-page .uix-pf__grid .uix-pf-card__thumb img {
        height: 100% !important;
        object-fit: cover;
        object-position: center;
    }
}

@media (min-width: 1024px) and (max-width: 1279.98px) {
    .landing-page .uix-pf {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        gap: 1.1rem;
    }

    .landing-page .uix-pf__showcase {
        padding: 1.25rem 1.25rem 1rem;
    }

    .landing-page .uix-pf__title {
        font-size: clamp(1.4rem, 1.1rem + 0.6vw, 1.6rem);
    }

    .landing-page .uix-pf__stage {
        min-height: 10rem;
        max-height: 13rem;
        padding: 0.85rem 1.1rem;
    }

    .landing-page .uix-pf__artwork-img {
        max-height: 11rem;
    }

    .landing-page .uix-pf__grid .uix-pf-card__thumb,
    .landing-page .uix-pf__grid .uix-pf-card__thumb--no-image {
        aspect-ratio: 16 / 10;
        min-height: 8.5rem;
    }
}

/* Wide desktops: cap the showcase so it never grows tall again while the
   2x2 grid stretches to the same row height for a balanced pair. */
@media (min-width: 1280px) {
    .landing-page .uix-pf {
        align-items: stretch;
    }

    .landing-page .uix-pf__showcase {
        max-height: 44rem;
    }

    .landing-page .uix-pf__grid {
        align-content: stretch;
    }

    .landing-page .uix-pf__grid .uix-pf-card {
        min-height: 0;
    }
}

@media (min-width: 640px) and (max-width: 1023.98px) {
    .landing-page .uix-pf__grid .uix-pf-card__thumb,
    .landing-page .uix-pf__grid .uix-pf-card__thumb--no-image {
        aspect-ratio: 16 / 10;
        min-height: 12rem;
    }
}

@media (max-width: 639.98px) {
    .landing-page .uix-pf__stage {
        min-height: 13rem;
        padding: 1rem;
    }

    .landing-page .uix-pf__stage-dots {
        right: 3%;
        transform: scale(0.78);
        transform-origin: top right;
    }
}

.landing-page .uix-pf__badge-featured {
    padding: 0.38rem 0.85rem;
    background: var(--uix-accent-tint, #e0f2fe);
    color: var(--uix-accent, #0284c7);
    border: 1px solid rgba(2, 132, 199, 0.15);
    box-shadow: none;
}

.landing-page .uix-pf__facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    width: 100%;
    max-width: 100%;
    overflow: hidden;
    border: 1px solid var(--uix-accent-soft, #cfe8fb);
    border-radius: 0.85rem;
    background: var(--uix-accent-tint, #e0f2fe);
}

.landing-page .uix-pf__fact {
    min-width: 0;
    padding: 0.75rem 1rem;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.landing-page .uix-pf__fact+.uix-pf__fact {
    border-left: 1px solid var(--uix-accent-soft, #cfe8fb);
}

.landing-page .uix-pf__fact:only-child {
    grid-column: 1 / -1;
}

.landing-page .uix-pf__flourish {
    display: none;
}


/* --- 17f. OUR SERVICES: intro column + numbered cards ------------------- */

.landing-page .uix-svc-wrap {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    align-items: stretch;
}

.landing-page .uix-svc__container {
    /* Same measure as the blog band's .max-w-7xl column — see §17h, which
       applies the shared left/right gutters above 1024px. */
    max-width: 84rem;
}

@media (min-width: 1024px) {
    .landing-page .uix-svc-wrap {
        /* Match the reference's deliberate 37/63 split.  Stretching the grid
           children makes the introduction and the two-card column finish on
           precisely the same baseline, regardless of the CMS copy length. */
        grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.05fr);
        gap: 1.25rem;
    }
}

.landing-page .uix-svc__intro {
    text-align: left;
    display: flex;
    min-width: 0;
    flex-direction: column;
}

/* Promise list with circular icon badges */
.landing-page .uix-promises {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
}

.landing-page .uix-promise {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    color: #334155;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.5;
}

.landing-page .uix-promise__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 9999px;
    font-size: 0.9375rem;
    flex-shrink: 0;
}

.landing-page .uix-promise__icon--orange {
    background: #ffedd5;
    color: #ea580c;
}

.landing-page .uix-promise__icon--sky {
    background: #e0f2fe;
    color: #0284c7;
}

.landing-page .uix-promise__icon--emerald {
    background: #d1fae5;
    color: #059669;
}

/* The "View All Services" button no longer lives in the intro column: it moved
   into the shared .uix-cta-row under the card grid — the same slot, alignment
   and pill the Portfolio band uses for "View All Projects" (see §17c and
   component/services.php). */

/* Cursive callout + curved arrow pointing at the illustration */
.landing-page .uix-scribble {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.landing-page .uix-scribble__text {
    font-family: 'Caveat', 'Segoe Script', 'Bradley Hand', cursive;
    font-size: 1.85rem;
    font-weight: 700;
    line-height: 1;
    color: #f97316;
    transform: rotate(-3deg);
}

.landing-page .uix-scribble__arrow {
    display: inline-block;
    width: 84px;
    color: #f97316;
    opacity: 0.85;
}

.landing-page .uix-scribble__arrow svg {
    display: block;
    width: 100%;
    height: auto;
}

/* Desk illustration */
.landing-page .uix-desk {
    margin-top: auto;
    padding-top: 1.25rem;
    max-width: 31rem;
    /* border-radius: 1.25rem; */
    overflow: hidden;
}

.landing-page .uix-desk__img {
    display: block;
    width: 100%;
    height: auto;
    border: none !important;
    /* border-radius: 1.25rem;
    box-shadow: 0 20px 42px -20px rgba(15, 23, 42, 0.35);
    border: 1px solid rgba(226, 232, 240, 0.85); */
}

.landing-page .uix-desk__svg {
    display: block;
    width: 100%;
    height: auto;
}


/* Numbered service cards */
.landing-page .uix-svc__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    min-width: 0;
}

/* Two cards per row from 640px (not 768px): a single column between 640 and
   767px stretched one card across the entire measure — a ~700px-wide card with a
   ~350px-tall picture — which is what made the band tower over the page on
   tablets and large phones instead of reading as a card grid. */
@media (min-width: 640px) {
    .landing-page .uix-svc__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .landing-page .uix-svc__grid {
        grid-template-rows: repeat(2, minmax(0, 1fr));
        gap: 1.125rem;
    }
}

/* Category filter + card grid share the right-hand column of .uix-svc-wrap.
   The tabs are the grid's own control, so they sit directly above it. */
.landing-page .uix-svc__panel {
    display: flex;
    flex-direction: column;
    gap: 1.125rem;
    min-width: 0;
}

/* Flush with the cards: left aligned and without the centred band's extra top
   margin (the panel gap already spaces them from the grid). */
.landing-page .uix-svc__panel .uix-tabs {
    justify-content: flex-start;
    margin-top: 0;
    padding-left: 0;
    padding-right: 0;
}

/* The category filter can reveal more than the reference's four-card set, so
   the homepage grid lets the extra rows flow instead of locking to two (the
   same treatment the standalone /services listing already applies). */
.landing-page #services .uix-svc__grid {
    grid-template-rows: none;
}

/* Card shell. Every accent-driven colour arrives as a --uix-* custom property
   built by serviceCardPalette() from the Admin Panel's accent_color and
   tag_bg_color; this sheet only ever READS those variables, so a colour picked
   in the admin panel can never be overridden by a constant here. The var()
   fallbacks repeat the shipping presets, so a card still renders if the inline
   variables are ever missing (e.g. a cached markup fragment). The neutral
   surface/ink colours below are the page's shared palette, not per-card data. */
.landing-page .uix-svc {
    --uix-accent: #0f3b7a;
    --uix-accent-rgb: 15, 59, 122;
    --uix-accent-ink: #ffffff;
    --uix-accent-soft: #d4dce7;
    --uix-accent-tint: #f1f3f7;
    /* Mirror serviceCardPalette(): the surface and the two ink tones are mixed
       from the accent there, so these literals only ever apply if a cached
       fragment arrives without its inline --uix-* block. */
    --uix-surface: #fbfcfd;
    --uix-surface-rgb: 251, 252, 253;
    --uix-ink: #0b1f3d;
    --uix-muted-ink: #3f516b;
    --uix-chip-bg: #f0f7ff;
    --uix-chip-text: #0f3b7a;
    --uix-chip-edge: #ccd9ea;
    --uix-star: #0f3b7a;
    --uix-empty-ink: #0f3b7a;
    position: relative;
    /* Clips the full-bleed media band to the card radius. */
    overflow: hidden;
    background: var(--uix-surface);
    border: 1px solid var(--uix-accent-soft);
    border-radius: 1.25rem;
    box-shadow:
        0 1px 2px rgba(var(--uix-accent-rgb), 0.05),
        0 20px 38px -28px rgba(var(--uix-accent-rgb), 0.38);
    transition: box-shadow 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
}

/* The lift is tinted with the card's own accent, so hovering a navy card and a
   purple card reads differently — powered by the admin colour, not a constant. */
.landing-page .uix-svc:hover {
    transform: translateY(-4px);
    box-shadow:
        0 1px 2px rgba(var(--uix-accent-rgb), 0.06),
        0 30px 54px -26px rgba(var(--uix-accent-rgb), 0.5);
}

.landing-page .uix-svc__link {
    display: flex;
    flex-direction: column;
    height: 100%;
    /* Tighter than the first reference pass: the band, copy, chips and footer
       now share a shorter card, which is what lets the whole band drop in height
       without the copy reading as crowded. The media band's negative margins
       further down must always repeat this exact box. */
    padding: 1.45rem 1.75rem 1.2rem;
    text-decoration: none;
    color: inherit;
}

/* Catalogue number: an overlay ON the artwork, pinned to the image's TOP-RIGHT
   corner. It lives inside .uix-svc__art (position: relative), so it always sits
   on the picture itself rather than floating in the copy column. Filled with the
   admin accent and lettered in the contrast-matched --uix-accent-ink, with a
   halo in the card's own surface colour and a shadow in its accent — both
   derived from the Admin Panel fields, so the badge separates from any
   photograph on any card. */
.landing-page .uix-svc__num {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    padding: 0.32rem 0.6rem;
    border-radius: 9999px;
    background: var(--uix-accent);
    color: var(--uix-accent-ink);
    font-family: 'Fraunces', Georgia, serif;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.06em;
    text-align: center;
    box-shadow:
        0 0 0 3px rgba(var(--uix-surface-rgb), 0.62),
        0 10px 20px -10px rgba(var(--uix-accent-rgb), 0.55);
}

/* Fluid media band (top of the card, full-bleed). The picture is sized by the
   CARD's width, not by a fixed rem height: a fixed height cropped the artwork
   differently at every viewport, and because the band is also a flex item of the
   column-flex .uix-svc__link long copy could compress it further. `flex: 0 0
   auto` makes the band unshrinkable and `aspect-ratio` alone drives its height,
   which is what keeps ONE consistent crop from 320px to 1920px (the technique
   .uix-pf-card__thumb already uses in §17d).

   2:1 rather than 16:9: the band is the largest block on the card, so its ratio
   is the single biggest lever on how tall the whole band of cards gets. 2:1
   keeps a generous, consistent picture while letting the section close up by
   roughly 6% — the copy, chips and footer are what a service card is selling.
   The LISTING page asks for the opposite (see admin/public/service.php, which
   raises its own cards to 3:2).

   NO `max-height` on purpose: a fixed ceiling pinned the band to a constant
   ~200-224px strip while its width kept growing with the card, so the very same
   artwork was cropped anywhere from 1.78:1 (wide desktop) to 3.06:1 (tablet
   portrait) depending on the viewport — measured in Chrome at 505/640/768/1024/
   1280/1440/1920px. `min-height` is only the narrow-card floor; the ratio wins
   everywhere else.

   `width` MUST stay auto: with equal negative side margins that is what spans
   the whole padding box — `width: 100%` over-constrains the box and leaves the
   band short of the card's right edge. The top corners are clipped by the
   shell's `overflow: hidden`. */
.landing-page .uix-svc__art {
    position: relative;
    /* anchors the catalogue-number overlay */
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: auto;
    aspect-ratio: 2 / 1;
    min-height: 8.5rem;
    /* Must repeat .uix-svc__link's padding box exactly (1.45rem top / 1.75rem
       sides / 0.8rem gap below) for a flush, full-bleed band. */
    margin: -1.45rem -1.75rem 0.8rem;
    overflow: hidden;
    background:
        radial-gradient(125% 130% at 50% -20%, var(--uix-accent-tint) 0%, var(--uix-surface) 70%),
        var(--uix-surface);
}

/* Static fallback for engines without aspect-ratio: the band still reserves a
   real box (and the image still covers it) instead of collapsing to the
   min-height above. */
@supports not (aspect-ratio: 1 / 1) {
    .landing-page .uix-svc__art {
        height: 10.5rem;
    }
}

.landing-page .uix-svc__art-svg {
    height: 80%;
    width: auto;
    color: var(--uix-accent);
}

.landing-page .uix-svc__art-img {
    display: block;
    width: 100%;
    height: 100% !important;
    /* see the note on .uix-blog__media-img */
    object-fit: cover;
    object-position: center;
    transition: transform 0.45s ease;
}

.landing-page .uix-svc:hover .uix-svc__art-img {
    transform: scale(1.05);
}

/* "No Image Available" — the deliberate empty state, tinted from the card's own
   accent. The card keeps its media band (so the grid stays on one baseline) and
   names the condition in plain words: no bundled theme graphic and no stock
   photo is ever used to hide a missing Admin Panel upload. */
.landing-page .uix-svc__art--empty {
    background:
        repeating-linear-gradient(135deg,
            rgba(var(--uix-accent-rgb), 0.07) 0 12px,
            rgba(var(--uix-accent-rgb), 0.015) 12px 24px),
        linear-gradient(135deg, var(--uix-accent-tint) 0%, var(--uix-surface) 78%);
}

.landing-page .uix-svc__art-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    height: 100%;
    padding: 0 4.25rem;
    /* keeps the copy clear of the number badge */
    color: var(--uix-empty-ink);
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.4;
    text-align: center;
}

.landing-page .uix-svc__art-fallback i {
    font-size: 1.4rem;
    color: var(--uix-accent);
    opacity: 0.45;
}

/* Responsive type: one clamp per element covers phone -> wide desktop, so no
   per-breakpoint font-size override is needed anywhere. */
.landing-page .uix-svc__title {
    margin: 0.25rem 0 0;
    font-family: 'Fraunces', Georgia, serif;
    font-size: clamp(1.2rem, 1rem + 0.55vw, 1.5rem);
    font-weight: 700;
    line-height: 1.25;
    /* Accent-tinted ink from the Admin Panel (--uix-ink): the headline picks up
       the card's own colour family instead of a fixed navy. */
    color: var(--uix-ink);
    letter-spacing: -0.01em;
    text-wrap: balance;
    /* A long, unbroken service name wraps inside the card instead of widening
       the grid column. */
    overflow-wrap: anywhere;
    transition: color 0.2s ease;
}

.landing-page .uix-svc__link:hover .uix-svc__title,
.landing-page .uix-svc__link:focus-visible .uix-svc__title {
    color: var(--uix-accent);
}

/* Two lines are reserved so the chip rows and footers of all four cards stay on
   one baseline regardless of copy length. */
.landing-page .uix-svc__sub {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.8em;
    margin: 0.35rem 0 0;
    color: var(--uix-muted-ink);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.landing-page .uix-svc__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.8rem 0 0;
    padding: 0;
    list-style: none;
}

/* Chip surface, hairline and label all come from the Admin Panel colours
   (--uix-chip-bg / --uix-chip-edge / --uix-chip-text). Long labels wrap inside
   the pill, so a chip can never overflow the card. */
.landing-page .uix-svc__chip {
    max-width: 100%;
    padding: 0.34rem 0.7rem;
    border: 1px solid var(--uix-chip-edge);
    border-radius: 9999px;
    background: var(--uix-chip-bg);
    color: var(--uix-chip-text);
    font-size: 0.625rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* Footer: a hairline in the card's chip tint groups the metadata, and
   `margin-top: auto` pins it to the bottom so every card in the grid aligns. */
.landing-page .uix-svc__foot {
    display: flex;
    align-items: center;
    gap: 0.65rem 0.9rem;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: 0.8rem;
    border-top: 1px solid var(--uix-chip-bg);
}

.landing-page .uix-svc__rating {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--uix-muted-ink);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Stars follow the card accent (--uix-star), not a fixed amber. */
.landing-page .uix-svc__stars {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    color: var(--uix-star);
    font-size: 0.6875rem;
}

.landing-page .uix-svc__rating em {
    font-style: normal;
}

.landing-page .uix-svc__time {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--uix-muted-ink);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.landing-page .uix-svc__time i {
    color: var(--uix-accent);
}

.landing-page .uix-svc__go {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    margin-left: auto;
    border-radius: 9999px;
    background: var(--uix-accent);
    color: var(--uix-accent-ink);
    font-size: 0.95rem;
    flex-shrink: 0;
    box-shadow: 0 10px 20px -12px rgba(var(--uix-accent-rgb), 0.85);
    transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}

.landing-page .uix-svc__link:hover .uix-svc__go,
.landing-page .uix-svc__link:focus-visible .uix-svc__go {
    transform: translateX(3px) scale(1.04);
    filter: brightness(1.06);
    box-shadow: 0 14px 26px -12px rgba(var(--uix-accent-rgb), 0.95);
}

/* Keyboard focus ring on every redesigned card link */
.landing-page .uix-svc__link:focus-visible,
.landing-page .uix-blog__feature-link:focus-visible,
.landing-page .uix-blog__row-link:focus-visible,
.landing-page .uix-pf-card__link:focus-visible,
.landing-page .uix-cta:focus-visible {
    outline: 2px solid #0284c7;
    outline-offset: 3px;
    border-radius: 1.25rem;
}

.landing-page .uix-cta:focus-visible {
    border-radius: 9999px;
}

/* The service shell clips its contents, so its ring is re-drawn just inside the
   card — in the card's own accent — after the shared group rule above (equal
   specificity, so source order decides). */
.landing-page .uix-svc__link:focus-visible {
    outline: 2px solid var(--uix-accent);
    outline-offset: -3px;
}

/* --- Small phones (320px - 400px) ---------------------------------------
   The card keeps its structure and simply tightens: a smaller gutter, a shorter
   band floor and one notch down on the type, so a 320px screen still shows the
   picture, the title, the chips and the footer inside one card with nothing
   wrapping badly. The band's negative margins always repeat the link padding
   declared here.
   The #services duplicates are required: responsive.css anchors its phone card
   padding to #services and is loaded BEFORE this sheet, so an equally specific
   selector here only wins on source order. */
@media (max-width: 400px) {

    .landing-page .uix-svc__link,
    .landing-page #services .uix-svc__link {
        padding: 1.1rem 1.15rem 1rem;
    }

    .landing-page .uix-svc__art,
    .landing-page #services .uix-svc__art {
        min-height: 7.5rem;
        margin: -1.1rem -1.15rem 0.7rem;
    }

    .landing-page .uix-svc__title,
    .landing-page #services .uix-svc__title {
        font-size: 1.1rem;
    }

    .landing-page .uix-svc__sub {
        min-height: 2.6em;
        font-size: 0.875rem;
    }

    .landing-page .uix-svc__chip {
        padding: 0.28rem 0.58rem;
        font-size: 0.5625rem;
    }

    .landing-page .uix-svc__go,
    .landing-page #services .uix-svc__go {
        width: 2.35rem;
        height: 2.35rem;
    }
}

/* --- 17h. Reference desktop proportions ---------------------------------
   All three redesigned bands share ONE measure so their left/right gutters
   line up exactly: the blog's magazine column (6.25rem each side, 84rem of
   content). The selectors below must name the real container classes —
   #services and #portfolio carry .uix-svc__container / .uix-pf__container,
   NOT Tailwind's .max-w-7xl, so a .max-w-7xl selector here would be dead
   code and those two bands would silently fall back to the narrow
   lg:px-8 padding while the blog kept the wider measure. */
@media (min-width: 1024px) {
    .landing-page #services {
        /* Tighter band: the CTA now sits in its own row under the grid (§17f),
           so the button provides the closing whitespace instead of the section
           padding. */
        padding-top: 1.5rem;
        padding-bottom: 1.5rem;
    }

    .landing-page #portfolio,
    .landing-page #blog {
        padding-top: 3.25rem;
        padding-bottom: 3.25rem;
    }

    .landing-page #services>.uix-svc__container,
    .landing-page #portfolio>.uix-pf__container,
    .landing-page #blog>.max-w-7xl {
        width: calc(100% - 12.5rem);
        max-width: 84rem;
        padding-right: 0;
        padding-left: 0;
    }

    .landing-page .uix-title {
        font-size: clamp(2.75rem, 2rem + 2vw, 3.5rem);
    }

    .landing-page .uix-sub {
        font-size: 1rem;
    }

    .landing-page #services .uix-svc__grid {
        gap: 1rem;
    }

    .landing-page #services .uix-svc {
        /* Only a floor for a card with unusually short copy — the content (band,
           copy, chips, footer) sets the real height, so the grid follows the
           copy instead of padding every card out to a fixed box. */
        min-height: 26rem;
    }

    /* The desktop band. The ratio alone reproduces the reference proportion at
       the reference measure (~370px card => ~185px band) and keeps scaling with
       the card at every other width, so no max-height is declared here either —
       see the note on .uix-svc__art. The floor is deliberately low so the 2:1
       ratio governs on every desktop card. */
    .landing-page #services .uix-svc__art {
        min-height: 8.5rem;
    }

    .landing-page #services .uix-svc__title {
        font-size: 1.45rem;
    }

    .landing-page #services .uix-svc__sub {
        font-size: 0.9375rem;
    }

    /* The shared .uix-cta-row, tuned for this band: the button keeps the
       Portfolio's centred position and pill styling and simply sits closer to
       the cards, so the two sections read as one family without the Services
       band gaining the Portfolio's full closing gap. */
    .landing-page #services .uix-cta-row {
        margin-top: clamp(1rem, 1.8vw, 1.5rem);
    }

    .landing-page #blog .uix-blog__media {
        margin: -1.75rem -1.75rem 0;
        border-radius: 1.35rem 1.35rem 1rem 1rem;
    }

    /* Paired with the image: the "No Image Available" state resolves to the
       same height, so the card is identical with or without artwork. */
    .landing-page #blog .uix-blog__media-img,
    .landing-page #blog .uix-blog__media-fallback {
        height: 18.5rem !important;
    }

    .landing-page #blog .uix-blog__feature-title {
        font-size: 1.8rem;
    }

    .landing-page #portfolio .uix-pf__title {
        font-size: 2.05rem;
    }

    .landing-page #portfolio .uix-pf-card__title {
        font-size: 1.1rem;
    }
}

/* --- 17g. Reduced motion ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {

    .landing-page .uix-blog__feature,
    .landing-page .uix-blog__media-img,
    .landing-page .uix-blog__row,
    .landing-page .uix-blog__thumb-img,
    .landing-page .uix-blog__arrow,
    .landing-page .uix-pf-card,
    .landing-page .uix-pf-card__thumb img,
    .landing-page .uix-svc,
    .landing-page .uix-svc__art-img,
    .landing-page .uix-svc__go,
    .landing-page .uix-cta,
    .landing-page .uix-tab {
        transition: none !important;
    }

    .landing-page .uix-blog__feature:hover,
    .landing-page .uix-blog__row:hover,
    .landing-page .uix-pf-card:hover,
    .landing-page .uix-svc:hover,
    .landing-page .uix-cta:hover,
    .landing-page .uix-blog__feature-link:hover .uix-blog__media-img,
    .landing-page .uix-blog__row-link:hover .uix-blog__thumb-img,
    .landing-page .uix-pf-card__link:hover .uix-pf-card__thumb img,
    .landing-page .uix-svc:hover .uix-svc__art-img,
    .landing-page .uix-svc__link:hover .uix-svc__go {
        transform: none !important;
    }
}

/* --- 17i. Final reference-surface cascade --------------------------------
   Kept at the end of this legacy stylesheet so older section recipes cannot
   reintroduce their lavender/cyan fills after the landing-page redesign. */
.landing-page #services {
    background:
        radial-gradient(circle at -3rem -2rem, rgba(186, 230, 253, 0.76) 0 11rem, transparent 11.1rem),
        radial-gradient(circle at 103% 102%, rgba(186, 230, 253, 0.56) 0 12rem, transparent 12.1rem),
        linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
}

.landing-page #services::before,
.landing-page #services::after {
    position: absolute;
    z-index: 0;
    display: block;
    border-radius: 9999px;
    content: '';
    pointer-events: none;
}

.landing-page #services::before {
    top: -8.5rem;
    left: -8.5rem;
    width: 19rem;
    height: 19rem;
    background: rgba(186, 230, 253, 0.48);
}

.landing-page #services::after {
    right: -12rem;
    bottom: -13rem;
    width: 26rem;
    height: 26rem;
    background: rgba(224, 242, 254, 0.68);
}

.landing-page #portfolio {
    background:
        radial-gradient(circle at 50% 45%, rgba(240, 249, 255, 0.58), transparent 42rem),
        linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
}

.landing-page #portfolio::before,
.landing-page #portfolio::after {
    background: radial-gradient(circle at 50% 50%, rgba(186, 230, 253, 0.66), rgba(224, 242, 254, 0.28) 68%, transparent 69%);
}

.landing-page #blog {
    background:
        radial-gradient(circle at -2rem 0, rgba(186, 230, 253, 0.62) 0 10rem, transparent 10.1rem),
        radial-gradient(circle at 103% 104%, rgba(186, 230, 253, 0.58) 0 14rem, transparent 14.1rem),
        linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
}

.landing-page #blog::before,
.landing-page #blog::after {
    position: absolute;
    z-index: 0;
    display: block;
    border-radius: 9999px;
    content: '';
    pointer-events: none;
}

.landing-page #blog::before {
    top: -10rem;
    right: -9rem;
    width: 21rem;
    height: 21rem;
    background: rgba(186, 230, 253, 0.52);
}

.landing-page #blog::after {
    bottom: -12rem;
    left: -11rem;
    width: 25rem;
    height: 25rem;
    background: rgba(224, 242, 254, 0.66);
}

.landing-page .uix-section-dots {
    position: absolute;
    z-index: 1;
    display: block;
    width: 4rem;
    height: 4rem;
    background-image: radial-gradient(circle, rgba(96, 165, 250, 0.42) 1.8px, transparent 2px);
    background-size: 12px 12px;
    opacity: 0.78;
    pointer-events: none;
}

.landing-page .uix-section-dots--services {
    right: 3rem;
    bottom: 4.25rem;
}

.landing-page .uix-section-dots--portfolio {
    top: 4.5rem;
    right: 3rem;
}

.landing-page .uix-section-dots--blog-top {
    top: 3rem;
    right: 4rem;
}

.landing-page .uix-section-dots--blog-side {
    top: 38%;
    left: 2.75rem;
    width: 3rem;
    height: 3rem;
    opacity: 0.62;
}

@media (max-width: 767px) {

    .landing-page #services::before,
    .landing-page #services::after,
    .landing-page #blog::before,
    .landing-page #blog::after {
        transform: scale(0.72);
    }

    .landing-page .uix-section-dots--services,
    .landing-page .uix-section-dots--portfolio,
    .landing-page .uix-section-dots--blog-top {
        right: 1rem;
    }

    .landing-page .uix-section-dots--blog-side {
        left: 0.75rem;
    }
}

/* ============================================================
   18. SCROLL REVEAL
   ------------------------------------------------------------
   A single, landing-page-only reveal system. NO component markup is
   touched: the engine in component/scripts.php (its last <script>
   block) assigns the .lp-rv / .lp-rv--in classes at runtime.

   Contracts that keep it safe:
     - The DEFAULT state is fully visible. The hidden "armed" state
       (.lp-rv) is added by JS AFTER first paint, and only to elements
       that start FULLY BELOW the viewport, so nothing ever flashes or
       disappears on load / refresh / a restored scroll position.
     - Only `opacity`, `translate` and `scale` animate - the
       INDEPENDENT CSS properties, never `transform`. A finished
       reveal therefore can never own `transform` and cancel the hover
       motion many cards use (services / portfolio / blog / team /
       stats / about strip). Nothing animates width, height, margin,
       top or left, so there is no layout shift (CLS stays 0).
     - The armed state is wrapped in @supports (translate: ...) and
       the engine mirrors that check, so a browser without the feature
       simply keeps every element visible.
     - prefers-reduced-motion: the engine does not run at all, and the
       block at the foot of this section neutralises the classes too.
     - Everything is scoped to `.landing-page` or `footer#footer`, so
       the standalone pages (which reuse the `.landing-page` card
       wrapper and include this stylesheet) are never affected: their
       markup never carries the runtime classes.

   Tokens are overwritten per element by the engine, which picks a
   richer profile for desktop and a lighter one for phones/tablets.
   ============================================================ */

.landing-page .lp-rv,
footer#footer .lp-rv {
    --lp-rv-y: 24px;
    --lp-rv-x: 24px;
    --lp-rv-scale: 1;
    --lp-rv-dur: 680ms;
    --lp-rv-delay: 0ms;
    --lp-rv-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

@supports (translate: 0 1px) {

    /* Armed: held just off its resting position and faded out. */
    .landing-page .lp-rv,
    footer#footer .lp-rv {
        opacity: 0;
        translate: 0 var(--lp-rv-y);
        scale: var(--lp-rv-scale);
        transition:
            opacity var(--lp-rv-dur) var(--lp-rv-ease) var(--lp-rv-delay),
            translate var(--lp-rv-dur) var(--lp-rv-ease) var(--lp-rv-delay),
            scale var(--lp-rv-dur) var(--lp-rv-ease) var(--lp-rv-delay);
    }

    /* Revealed: the resting state. Higher specificity (three classes)
       so it always beats the directional/scale variants below, which
       may still be on the element. */
    .landing-page .lp-rv.lp-rv--in,
    footer#footer .lp-rv.lp-rv--in {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

/* Directional / scale / accent-rule variants are a DESKTOP refinement.
   Phones keep the plain vertical rise (the engine never applies these
   classes there); the media query is defence in depth. */
@media (min-width: 1024px) and (pointer: fine) {

    .landing-page .lp-rv--left,
    footer#footer .lp-rv--left {
        translate: calc(-1 * var(--lp-rv-x)) 0;
    }

    .landing-page .lp-rv--right,
    footer#footer .lp-rv--right {
        translate: var(--lp-rv-x) 0;
    }

    .landing-page .lp-rv--scale,
    footer#footer .lp-rv--scale {
        translate: 0 0;
        scale: 0.955;
    }

    /* The accent rule draws out from its centre instead of rising. */
    .landing-page .lp-rv--rule,
    footer#footer .lp-rv--rule {
        translate: 0 0;
        scale: 0.12 1;
    }
}

/* Reduced motion: the engine never runs, but neutralise defensively. */
@media (prefers-reduced-motion: reduce) {

    .landing-page .lp-rv,
    .landing-page .lp-rv.lp-rv--in,
    footer#footer .lp-rv,
    footer#footer .lp-rv.lp-rv--in {
        opacity: 1 !important;
        translate: none !important;
        scale: none !important;
        transition: none !important;
        will-change: auto !important;
    }
}
