/*
 * LDP Associates — design system
 *
 * Hand-built replacement for the Avada/Fusion Builder theme. Every value here
 * traces back to docs/content/design-tokens.md, which is Avada's 541-property
 * theme-options :root block decoded. Do not open the minified Fusion CSS.
 *
 * The signature of this design is a colour inversion: green (--ldp-green) is the
 * RESTING state for headings, links, and the top bar; blue (--ldp-blue) is the
 * ACTIVE state for hover, buttons, and focus. Hovering a green link turns it
 * blue. Preserve that.
 */

/* ==========================================================================
   1. Fonts — self-hosted (SPEC D-009)
   ==========================================================================
   Google serves both families as variable fonts, so one file covers the whole
   weight range rather than one file per weight. Latin subset only.
   Source Sans 3 carries body copy, headings, and nav; Open Sans is used only
   for buttons and footer headings, which is the only place it earns its load.
*/

@font-face {
    font-family: 'Source Sans 3';
    src: url('/fonts/source-sans-3-roman.woff2') format('woff2');
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Source Sans 3';
    src: url('/fonts/source-sans-3-italic.woff2') format('woff2');
    font-weight: 200 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Open Sans';
    src: url('/fonts/open-sans-roman.woff2') format('woff2');
    font-weight: 300 800;
    font-stretch: 100%;
    font-style: normal;
    font-display: swap;
}

/* ==========================================================================
   2. Tokens
   ========================================================================== */

:root {
    /* --- Brand palette ---------------------------------------------------
       The whole design is three colours on white with black body copy. */
    --ldp-green: #81bd06; /* resting: headings, links, top bar */
    --ldp-green-light: #a0ce4e; /* nav highlight bar, logo background */
    --ldp-blue: #42b4e6; /* active: hover, buttons, focus */
    --ldp-navy: #2c2f3e; /* nav link text, button hover */
    --ldp-footer: #1c2727; /* footer + copyright background */

    /* --- Neutrals --- */
    --ldp-white: #ffffff;
    --ldp-black: #000000;
    --ldp-grey-50: #f8f8f8; /* submenu hover background */
    --ldp-grey-100: #f6f6f6;
    --ldp-grey-200: #f1f0ec; /* form border */
    --ldp-grey-300: #e0dede; /* borders, grid separators */
    --ldp-grey-500: #aaa9a9; /* form input text */
    --ldp-grey-700: #333333; /* submenu link text */
    --ldp-rule: #f7f7f7; /* submenu + mobile menu separators */

    /* --- Band fills -------------------------------------------------------
       Avada writes a --awb-background-color per Fusion container. Across the
       18 pages in scope there are only ever four values, so they are tokens
       here rather than per-page literals:

           rgba(113,186,5,0.2)  pale green   -> .ldp-cta--light, .ldp-section--tint, .ldp-panel
           #f9f9f9              off-white    -> .ldp-section--alt
           #efefef              light grey   -> .ldp-section--muted
           rgba(62,70,70,0.39)  over a photo -> .ldp-cta (§13 models this as an overlay) */
    --ldp-tint-green: rgb(113 186 5 / 20%);
    --ldp-band-alt: #f9f9f9;
    --ldp-band-muted: #efefef;

    /* --- Semantic --- */
    --ldp-text: var(--ldp-black);
    --ldp-bg: var(--ldp-white);
    --ldp-heading: var(--ldp-green);
    --ldp-link: var(--ldp-green);
    --ldp-link-hover: var(--ldp-blue);
    --ldp-focus: var(--ldp-blue);

    /* --- Type ------------------------------------------------------------
       Q-10 resolved 2026-08-10: headings use Source Sans 3, the designer's
       intent. The live site declares "Source Sans Pro" — a name Adobe retired
       — so headings there fall back to Arial unintentionally. Switching
       --ldp-font-heading to the Arial stack reverts to the live rendering. */
    --ldp-font-body:
        'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --ldp-font-heading: 'Source Sans 3', Arial, Helvetica, sans-serif;
    --ldp-font-ui: 'Open Sans', Arial, Helvetica, sans-serif;

    --ldp-text-base: 1.0625rem; /* 17px */
    --ldp-leading-base: 1.8;
    --ldp-weight-heading: 300; /* the design leans on size and colour, not weight */

    /* Headings interpolate between the phone floor (640px) and the container
       width (1300px). Avada generates the same curve with calc() from
       --typography_sensitivity 0.54 / --typography_factor 1.50; there is no
       static table of mobile sizes in the theme to copy. */
    --ldp-h1: clamp(2.25rem, 1.099rem + 2.879vw, 3.4375rem); /* 36 -> 55px */
    --ldp-h2: clamp(1.875rem, 0.966rem + 2.273vw, 2.8125rem); /* 30 -> 45px */
    --ldp-h3: clamp(1.5rem, 0.833rem + 1.667vw, 2.1875rem); /*  24 -> 35px */
    --ldp-h4: clamp(1.125rem, 0.64rem + 1.212vw, 1.625rem); /*   18 -> 26px */
    --ldp-h5: clamp(1.0625rem, 0.881rem + 0.455vw, 1.25rem); /*  17 -> 20px */
    --ldp-h6: 1rem; /* 16px, no scaling */

    /* --- Spacing ---------------------------------------------------------
       Avada exposes per-component padding with no underlying rhythm (17, 30,
       31, 40, 50, 80). We impose a 8px-step scale and map onto it. The two
       structural values, 30 and 80, are preserved exactly. */
    --ldp-space-1: 0.5rem; /*  8px */
    --ldp-space-2: 1rem; /*   16px */
    --ldp-space-3: 1.5rem; /* 24px */
    --ldp-space-4: 2rem; /*   32px */
    --ldp-space-5: 3rem; /*   48px */
    --ldp-gutter: 30px; /*    structural: section + header padding */
    --ldp-space-xl: 80px; /*  structural: sidebar gutter, footer rhythm */

    /* The fa-map-marker stand-in for /contact/'s locations list, as a mask so it
       takes its colour from the rule that uses it rather than baking one in. */
    --ldp-pin-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E");

    /* --- Layout --- */
    --ldp-container: 1300px;
    /* Avada centres the body of six pages in a 2/3 column flanked by two empty
       1/6 spacers. 2/3 of 1300px is the measure that produces. */
    --ldp-container-narrow: 866px;
    --ldp-nav-height: 126px;
    --ldp-nav-height-stuck: 76px;
    --ldp-logo-height: 64px;

    /* --- Components --- */
    --ldp-btn-padding: 17px 40px;
    --ldp-radius: 0;
    --ldp-transition: 0.2s ease;
}

/* ==========================================================================
   3. Reset and base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

body {
    margin: 0;
    background: var(--ldp-bg);
    color: var(--ldp-text);
    font-family: var(--ldp-font-body);
    font-size: var(--ldp-text-base);
    line-height: var(--ldp-leading-base);
    -webkit-font-smoothing: antialiased;
}

img,
picture,
svg,
iframe {
    max-width: 100%;
}

img,
svg {
    height: auto;
    vertical-align: middle;
}

/* ==========================================================================
   4. Typography
   ========================================================================== */

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0;
    font-family: var(--ldp-font-heading);
    font-weight: var(--ldp-weight-heading);
    color: var(--ldp-heading);
}

/* Live theme sets h1 line-height to 0.83 — tighter than the glyph box. It only
   survives because no h1 on the site currently wraps; any wrapping h1 would
   overlap itself. Corrected to 1.05. */
h1 {
    font-size: var(--ldp-h1);
    line-height: 1.05;
}

h2 {
    font-size: var(--ldp-h2);
    line-height: 1.21;
    margin-bottom: 0.35em;
}

h3 {
    font-size: var(--ldp-h3);
    line-height: 1.36;
    margin: 0.75em 0 0.7em;
}

h4 {
    font-size: var(--ldp-h4);
    line-height: 1.63;
    margin-bottom: 0.5em;
}

h5 {
    font-size: var(--ldp-h5);
    line-height: 1.83;
}

h6 {
    font-size: var(--ldp-h6);
    line-height: 2;
}

p {
    margin: 0 0 1.5em;
}

a {
    color: var(--ldp-link);
    text-decoration: none;
    transition: color var(--ldp-transition);
}

a:hover,
a:focus-visible {
    color: var(--ldp-link-hover);
}

:focus-visible {
    outline: 2px solid var(--ldp-focus);
    outline-offset: 2px;
}

hr {
    border: 0;
    border-top: 1px solid var(--ldp-grey-300);
    margin: var(--ldp-space-4) 0;
}

/* ==========================================================================
   5. Layout primitives
   ========================================================================== */

.ldp-container {
    width: 100%;
    max-width: var(--ldp-container);
    margin: 0 auto;
    padding: 0 var(--ldp-gutter);
}

/* Replaces Avada's bundled Bootstrap columns (col-lg-4 etc.), which leak into
   the footer and Fusion Builder content. We drop Bootstrap entirely. */
.ldp-cols {
    display: grid;
    gap: var(--ldp-space-5) var(--ldp-space-4);
}

.ldp-cols--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ldp-cols--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Only the homepage industry row is four across (Avada: four 1_4 columns). It
   needs its own middle step — dropping four photo cards straight to one column
   at 800px leaves a very long page on a tablet. */
.ldp-cols--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1024px) {
    .ldp-cols--4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 800px) {
    .ldp-cols--3,
    .ldp-cols--2 {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 600px) {
    .ldp-cols--4 {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The narrow measure: Avada's 1/6 + 2/3 + 1/6 row, which six pages use for
   their body copy. Reproduced by capping the container rather than by
   rendering two empty spacer columns. */
.ldp-container--narrow {
    max-width: var(--ldp-container-narrow);
}

/* The one alignment utility. Avada writes text-align inline on individual
   elements; this exists because five bands are centred as a whole and
   repeating an inline style in five views is worse than one class. */
.ldp-center {
    text-align: center;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: var(--ldp-space-1) var(--ldp-space-2);
    background: var(--ldp-blue);
    color: var(--ldp-white);
}

.skip-link:focus {
    left: 0;
    color: var(--ldp-white);
}

/* ==========================================================================
   6. Buttons
   ========================================================================== */

.ldp-btn {
    display: inline-block;
    font-family: var(--ldp-font-ui);
    font-size: 1.125rem; /* 18px */
    font-weight: 700;
    line-height: 21px;
    text-transform: uppercase;
    text-align: center;
    padding: var(--ldp-btn-padding);
    border: 0;
    border-radius: var(--ldp-radius);
    background: var(--ldp-blue);
    color: var(--ldp-white);
    cursor: pointer;
    transition:
        background-color var(--ldp-transition),
        color var(--ldp-transition);
}

.ldp-btn:hover,
.ldp-btn:focus-visible {
    background: var(--ldp-navy);
    color: var(--ldp-white);
}

/* ==========================================================================
   7. Header — Avada "Header v3": utility bar over a logo-left / menu-right bar
   ========================================================================== */

.ldp-header-wrapper {
    position: relative;
    z-index: 100;
    background: var(--ldp-white);
}

/* Sticky is desktop-only on the live site: the body carries
   no-tablet-sticky-header and no-mobile-sticky-header. */
@media (min-width: 801px) {
    .ldp-header-wrapper {
        position: sticky;
        top: 0;
    }

    .ldp-header-wrapper.is-stuck {
        box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
    }

    .ldp-header-wrapper.is-stuck .ldp-topbar {
        display: none;
    }

    .ldp-header-wrapper.is-stuck .ldp-header {
        min-height: var(--ldp-nav-height-stuck);
    }

    .ldp-header-wrapper.is-stuck .ldp-logo img {
        max-height: 44px;
    }
}

/* --- 7.1 Top utility bar --- */

.ldp-topbar {
    background: var(--ldp-green);
    border-top: 3px solid var(--ldp-blue);
    color: var(--ldp-white);
    font-size: 0.9375rem; /* 15px */
    line-height: 1.6;
}

.ldp-topbar .ldp-container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ldp-space-1) var(--ldp-space-3);
    padding-top: var(--ldp-space-1);
    padding-bottom: var(--ldp-space-1);
}

/* The live site abuses Avada's "email address" contact field to hold a list of
   city names, rendering it as a mailto: link to a non-address. Reproduced here
   as plain text — see docs/content/chrome.md §1.2. */
.ldp-topbar__locations {
    margin: 0;
}

.ldp-topbar__menu {
    display: flex;
    align-items: center;
    gap: var(--ldp-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ldp-topbar__menu a {
    display: inline-flex;
    align-items: center;
    color: var(--ldp-white);
}

.ldp-topbar__menu a:hover,
.ldp-topbar__menu a:focus-visible {
    color: var(--ldp-navy);
}

.ldp-topbar__menu svg {
    width: 18px;
    height: 18px;
    fill: currentColor;
}

/* --- 7.2 Main bar --- */

.ldp-header .ldp-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ldp-space-3);
    min-height: var(--ldp-nav-height);
    transition: min-height var(--ldp-transition);
}

.ldp-header {
    background: var(--ldp-white);
}

.ldp-logo {
    display: inline-flex;
    flex: 0 0 auto;
}

.ldp-logo img {
    max-height: var(--ldp-logo-height);
    width: auto;
    transition: max-height var(--ldp-transition);
}

/* --- 7.3 Primary navigation --- */

.ldp-nav ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ldp-nav > ul {
    display: flex;
    align-items: center;
    gap: var(--ldp-space-3);
}

.ldp-nav > ul > li {
    position: relative;
}

.ldp-nav > ul > li > a {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: var(--ldp-space-1) 0;
    font-family: var(--ldp-font-heading);
    font-size: var(--ldp-text-base);
    font-weight: 400;
    color: var(--ldp-navy);
}

.ldp-nav > ul > li > a:hover,
.ldp-nav > ul > li > a:focus-visible {
    color: var(--ldp-blue);
}

/* Avada's avada-menu-highlight-style-bar: a --menu_highlight_background rule
   that grows under the active/hovered item. */
.ldp-nav > ul > li > a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -2px;
    height: 3px;
    background: var(--ldp-green-light);
    transform: scaleX(0);
    transition: transform var(--ldp-transition);
}

.ldp-nav > ul > li > a:hover::after,
.ldp-nav > ul > li > a:focus-visible::after,
.ldp-nav > ul > li.is-current > a::after {
    transform: scaleX(1);
}

.ldp-nav__caret {
    width: 10px;
    height: 10px;
    fill: currentColor;
    flex: 0 0 auto;
    transition: transform var(--ldp-transition);
}

/* "Get Started" renders as a button rather than a link (li.fusion-menu-item-button). */
.ldp-nav > ul > li.ldp-nav__cta > a {
    padding: 10px 24px;
    font-family: var(--ldp-font-ui);
    font-size: 1rem;
    font-weight: 700;
    text-transform: uppercase;
    background: var(--ldp-blue);
    color: var(--ldp-white);
}

.ldp-nav > ul > li.ldp-nav__cta > a:hover,
.ldp-nav > ul > li.ldp-nav__cta > a:focus-visible {
    background: var(--ldp-navy);
    color: var(--ldp-white);
}

.ldp-nav > ul > li.ldp-nav__cta > a::after {
    display: none;
}

/* --- 7.4 Dropdowns ---
   Opened by hover, by :focus-within for keyboard users, and by the JS toggle
   on touch devices (which sets aria-expanded and .is-open). */

.ldp-nav__sub {
    position: absolute;
    top: 100%;
    left: 0;
    width: max-content;
    min-width: 240px;
    max-width: 340px;
    background: var(--ldp-white);
    border: 1px solid var(--ldp-rule);
    box-shadow: 0 4px 12px rgb(0 0 0 / 8%);
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition:
        opacity var(--ldp-transition),
        transform var(--ldp-transition),
        visibility var(--ldp-transition);
}

.ldp-nav > ul > li:hover > .ldp-nav__sub,
.ldp-nav > ul > li:focus-within > .ldp-nav__sub,
.ldp-nav > ul > li.is-open > .ldp-nav__sub {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.ldp-nav > ul > li:hover > a .ldp-nav__caret,
.ldp-nav > ul > li.is-open > a .ldp-nav__caret {
    transform: rotate(180deg);
}

.ldp-nav__sub a {
    display: block;
    padding: 10px var(--ldp-space-2);
    font-size: 1rem;
    color: var(--ldp-grey-700);
    border-bottom: 1px solid var(--ldp-rule);
}

.ldp-nav__sub li:last-child a {
    border-bottom: 0;
}

.ldp-nav__sub a:hover,
.ldp-nav__sub a:focus-visible {
    background: var(--ldp-grey-50);
    color: var(--ldp-blue);
}

/* --- 7.5 Mobile menu ---
   Avada emits nav.fusion-mobile-nav-holder EMPTY and clones the desktop <ul>
   into it with JS at runtime, so there was no server-rendered markup to port.
   This is written from scratch. Breakpoint must stay at 800px to match
   Avada's --content_break_point. */

.ldp-menu-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ldp-green);
    cursor: pointer;
}

.ldp-menu-toggle svg {
    width: 24px;
    height: 24px;
    fill: currentColor;
}

.ldp-menu-toggle__close {
    display: none;
}

.ldp-menu-toggle[aria-expanded='true'] .ldp-menu-toggle__open {
    display: none;
}

.ldp-menu-toggle[aria-expanded='true'] .ldp-menu-toggle__close {
    display: block;
}

.ldp-mobile-nav {
    display: none;
    background: var(--ldp-white);
    border-top: 1px solid var(--ldp-rule);
}

.ldp-mobile-nav[hidden] {
    display: none;
}

.ldp-mobile-nav ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ldp-mobile-nav a {
    display: block;
    padding: 0 var(--ldp-gutter);
    font-family: var(--ldp-font-heading);
    font-size: 0.75rem; /* 12px, per --mobile_menu_font */
    line-height: 45px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ldp-navy);
    border-bottom: 1px solid var(--ldp-rule);
}

.ldp-mobile-nav a:hover,
.ldp-mobile-nav a:focus-visible {
    color: var(--ldp-green);
}

.ldp-mobile-nav__sub a {
    padding-left: calc(var(--ldp-gutter) + var(--ldp-space-2));
    color: var(--ldp-grey-700);
}

@media (max-width: 800px) {
    .ldp-nav {
        display: none;
    }

    .ldp-menu-toggle {
        display: inline-flex;
    }

    .ldp-mobile-nav:not([hidden]) {
        display: block;
    }

    .ldp-header .ldp-container {
        min-height: 90px;
    }

    .ldp-topbar .ldp-container {
        justify-content: center;
        text-align: center;
    }
}

/* ==========================================================================
   8. Footer
   ========================================================================== */

.ldp-footer {
    background: var(--ldp-footer);
    color: var(--ldp-white);
    text-align: center;
    padding: var(--ldp-space-xl) 0 var(--ldp-space-5);
}

.ldp-footer a {
    color: var(--ldp-white);
}

.ldp-footer a:hover,
.ldp-footer a:focus-visible {
    color: var(--ldp-blue);
}

.ldp-footer__heading {
    font-family: var(--ldp-font-ui);
    font-size: 0.9375rem; /* 15px */
    font-weight: 400;
    line-height: 1.5;
    color: rgb(255 255 255 / 80%);
    margin-bottom: var(--ldp-space-3);
}

.ldp-footer__copyright {
    margin: 0;
    line-height: 1.8;
}

/* ==========================================================================
   9. Main content
   ========================================================================== */

.ldp-main {
    min-height: 40vh;
}

/* ==========================================================================
   10. Page content — sections, prose, rules
   ==========================================================================
   Everything from here down is the Phase 4 page vocabulary: the small set of
   classes the 18 page views are built from. It replaces Fusion Builder's
   container / row / column / element markup, mapped as:

       fusion-fullwidth (container)  -> .ldp-section  (or .ldp-cta)
       fusion-builder-row            -> .ldp-container (already, §5)
       fusion_builder_column_X_Y     -> .ldp-cols modifiers (§5 + below)
       fusion-text                   -> .ldp-prose
       fusion-title                  -> a bare h2/h3 inside .ldp-prose
       fusion-separator              -> .ldp-rule
       fusion-imageframe             -> .ldp-figure / .ldp-logos
       fusion-checklist              -> .ldp-checklist
       fusion-content-boxes          -> .ldp-card

   Page views compose these and add no CSS of their own — see
   docs/page-authoring.md. */

/* A full-bleed band of page content. Always wraps a .ldp-container. Avada gave
   every container 30px of horizontal padding and let row margins supply the
   vertical rhythm, which drifts per page; we impose one rhythm here instead. */
.ldp-section {
    padding: var(--ldp-space-5) 0;
}

.ldp-section--tight {
    padding: var(--ldp-space-3) 0;
}

/* Band fills. Without these every page renders as one undifferentiated white
   column; the live site alternates white / #f9f9f9 / #efefef to separate its
   containers, and the partner-logo strip is on #efefef on all nine pages that
   carry it. Verified per container against docs/harvest/raw/*.html. */
.ldp-section--alt {
    background: var(--ldp-band-alt);
}

.ldp-section--muted {
    background: var(--ldp-band-muted);
}

.ldp-section--tint {
    background: var(--ldp-tint-green);
}

/* Asymmetric column pairs, extending .ldp-cols in §5. Two are enough: the
   legacy Avada grid only ever uses 2/3 + 1/3 (product pages: copy beside the
   contact form) and 1/3 + 2/3 (location pages: address panel beside copy).
   The 3/4 + 1/4 shape is only ever a CTA band, which .ldp-cta handles. */
.ldp-cols--2-1 {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

.ldp-cols--1-2 {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

/* Size the asymmetric pair's children to their own content instead of letting
   the grid's default `stretch` give both the height of the taller one. The
   product pages' tinted .ldp-panel was inheriting the copy column's height and
   trailing up to 560px of empty green below the submit button.

   Faithful as well as tidier: the asymmetric rows in docs/harvest/raw carry no
   fusion-equal-height-columns class, so the legacy float columns end at their
   content — unlike the equal-height rows on /about/, /services/ and the location
   pages, which do carry it and are .ldp-cols--2 / --3 here.

   Scoped to these two modifiers deliberately. Bare .ldp-cols must keep
   stretching: .ldp-card relies on `height: 100%` for its equal-height rows. */
.ldp-cols--2-1 > *,
.ldp-cols--1-2 > * {
    align-self: start;
}

@media (max-width: 800px) {
    .ldp-cols--2-1,
    .ldp-cols--1-2 {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The page title bar. Avada renders this outside #content, but it carries the
   page h1 — and on the four location pages plus /contact/ an h3 subhead — so
   it is page content, not chrome, and each view renders its own.

   Built as a plain bordered band until Phase 7, because the Phase 2 harvest read
   markup and the title bar takes its photo from the Fusion dynamic stylesheet —
   so media-manifest.tsv had none of the eight images and design-tokens.md
   recorded only the overlay colour, with nothing to say an image sat under it.
   The live bar is 400px of page-specific photograph under rgba(0,0,0,.4) with a
   centred white h1. Each view supplies its own photo inline, as .ldp-hero does. */
.ldp-page-title {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 400px;
    background-position: center center;
    background-size: cover;
    background-color: var(--ldp-footer); /* fallback if the photo 404s */
    text-align: center;
}

.ldp-page-title::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / 40%);
}

/* Lifts the copy out of the ::before overlay's stacking context. Without it the
   overlay paints over the h1 and the bar reads as an empty photograph. */
.ldp-page-title > .ldp-container {
    position: relative;
    width: 100%;
    padding-top: var(--ldp-space-5);
    padding-bottom: var(--ldp-space-5);
}

/* 72px, not the 55px of --ldp-h1: the title bar overrides the theme's h1 size,
   and at 55px the bar reads as a caption on a photo rather than a page title. */
.ldp-page-title h1 {
    color: var(--ldp-white);
    /* Both ends measured off the live site rather than borrowed from --ldp-h1:
       48.6px at 390 and 72px from 1200 up. Fitting the slope to 1440 instead of
       1200 topped the bar out near 62px on a 1440 laptop, and taking the 36px
       floor from --ldp-h1 left the mobile bar a third short of the live one. */
    font-size: clamp(3.0375rem, 2.333rem + 2.889vw, 4.5rem); /* 48.6 -> 72px */
    margin-bottom: 0;
}

/* 200px, measured: every live title bar carrying only an h1 is exactly that at
   390px. The four location pages and /contact/ run 330-650px there, but that is
   their subhead wrapping, not a taller bar — so this is a floor, not a height. */
@media (max-width: 800px) {
    .ldp-page-title {
        min-height: 200px;
    }
}

/* The title-bar subhead is a marketing sentence, not a section heading, so it is
   a <p>. It was an <h3> until Phase 6: sitting directly under the <h1> that made
   every location page and /contact/ jump h1 -> h3 -> h2, which is a WCAG 1.3.1
   heading-order failure and tells a screen reader the tagline opens a section.
   These declarations carry the h3's appearance onto the paragraph so the change
   is semantic only — nothing moves on screen. */
.ldp-page-title__subhead {
    max-width: 60ch;
    margin: var(--ldp-space-2) auto 0; /* centred in the bar, like the h1 */
    font-family: var(--ldp-font-heading);
    font-size: var(--ldp-h3);
    font-weight: var(--ldp-weight-heading);
    line-height: 1.36;
    color: var(--ldp-white);
}

/* Rich text — the workhorse. 87 fusion-text instances across 16 pages, all of
   them headings, paragraphs, lists and inline links. Collapsing the first and
   last margins lets a .ldp-prose block sit flush inside any column. */
.ldp-prose > :first-child {
    margin-top: 0;
}

.ldp-prose > :last-child {
    margin-bottom: 0;
}

.ldp-prose ul,
.ldp-prose ol {
    margin: 0 0 1.5em;
    padding-left: 1.25em;
}

.ldp-prose li {
    margin-bottom: 0.35em;
}

/* Inline links stay underline-free, as on the live site. Green on black clears
   the 3:1 contrast WCAG 1.4.1 asks of colour-only link cues, and hover/focus
   changes colour as well, so this is faithful *and* accessible — do not "fix"
   it by adding an underline. */
.ldp-prose a {
    font-weight: 600;
}

/* Intro copy. Avada marks these sentences up as <h4> purely for their size —
   the views correctly demote them to <p>, which would otherwise drop them from
   ~20px to 17px body copy. Sized rather than levelled, which is what the live
   site meant. Works on a single <p> or on the .ldp-prose block around one,
   because a <p> has no font-size of its own to override. */
.ldp-lead {
    font-size: var(--ldp-h5); /* 17 -> 20px, the h4 size these carried */
    line-height: 1.6;
}

/* The homepage kicker above the h1. An inline <span> on the live site
   (14px, uppercase, 1px letter-spacing); it is the only one on the site. */
.ldp-eyebrow {
    font-size: 0.875rem; /* 14px */
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* fusion-separator. Short, centred, and used as a section divider rather than
   a thematic break — the wider `hr` default in §4 stays for prose. */
.ldp-rule {
    width: 100%;
    max-width: 220px;
    margin: var(--ldp-space-4) auto;
    border: 0;
    border-top: 1px solid var(--ldp-grey-300);
    /* The separator is what ends a section, so it is also what ends a float:
       without this the rule after a .ldp-figure--right can ride up beside the
       logo when the paragraph it wraps is shorter than the image. */
    clear: both;
}

/* ==========================================================================
   11. Page content — images and embeds
   ========================================================================== */

.ldp-figure {
    margin: 0 0 var(--ldp-space-3);
}

/* No `width: auto` here, deliberately. Every page view writes the size the live
   site laid the image out at (docs/page-authoring.md, "Images"), and `auto`
   threw those attributes away and rendered the harvested original instead —
   ups2 at 448px against a live 200px, the mid-page APC wordmark at 600px
   against a live 200px. Honouring the attribute is what makes those numbers
   mean something; max-width keeps a wide one inside its column. */
.ldp-figure img {
    display: block;
    max-width: 100%;
}

.ldp-figure--center {
    text-align: center;
}

.ldp-figure--center img {
    margin-inline: auto;
}

/* WordPress's `alignright`: on five product child pages a partner logo floats
   right inside the running paragraph, which is why those paragraphs are
   written to wrap it. Kept as a <figure> before the paragraph — the float
   pulls it alongside — rather than nesting an <img> inside a <strong> as the
   live markup does. Floats have no effect once the column is a phone's width,
   so it drops back to a block image below the collapse breakpoint. */
@media (min-width: 801px) {
    .ldp-figure--right {
        float: right;
        margin: 0 0 var(--ldp-space-2) var(--ldp-space-3);
    }
}

/* Icon-scale image. Named for what it is rather than as .ldp-card__icon,
   because /solutions/ uses two of these as direct children of .ldp-container
   with no card around them — a BEM sub-element outside its block. The clamp is
   the point: the files on disk are 700x700 originals of a 200x200 crop. */
.ldp-icon {
    display: block;
    width: 96px;
    height: auto;
    margin-bottom: var(--ldp-space-2);
}

.ldp-figure__caption {
    margin: var(--ldp-space-1) 0 0;
    font-size: 0.9375rem; /* 15px */
    color: var(--ldp-grey-700);
}

/* The APC / PDI partner-logo pair that closes nine pages. Avada built it as two
   half-width columns holding one imageframe each; a centred wrap is the same
   result with a quarter of the markup and no empty column on mobile. */
.ldp-logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--ldp-space-4);
}

.ldp-logos img {
    max-height: 96px;
    width: auto;
}

/* Google Maps iframe on the four location pages — the only genuine third-party
   embed in any page body. Avada emitted a fixed-height iframe that overflows on
   a phone; the ratio box makes it responsive. */
.ldp-map {
    position: relative;
    aspect-ratio: 4 / 3;
    /* Matches .ldp-figure's bottom margin above, so the map and the Experience
       Center photo that follows it on three of the four location pages get one
       rhythm. Without it the two images butt together and read as a single
       broken one; on /salt-lake-city-ut/, which has no photo, the 35px h2 sat
       with its glyph tops on the iframe's bottom edge. Belongs here rather than
       in the views: page-authoring.md documents a bare .ldp-map, no wrapper. */
    margin-bottom: var(--ldp-space-3);
    background: var(--ldp-grey-100);
}

.ldp-map iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

@media (min-width: 801px) {
    .ldp-map {
        aspect-ratio: 16 / 9;
    }
}

/* ==========================================================================
   12. Page content — checklists and cards
   ========================================================================== */

/* fusion-checklist: a green tick per item. The tick is drawn from borders
   rather than set as U+2713 because the self-hosted fonts are latin-subset
   only (D-009) and would fall back to a system font for that one glyph. */
.ldp-checklist {
    margin: 0 0 1.5em;
    padding: 0;
    list-style: none;
}

.ldp-checklist li {
    position: relative;
    margin-bottom: 0.35em;
    padding-left: 1.75em;
}

.ldp-checklist li::before {
    content: '';
    position: absolute;
    left: 0.35em;
    top: 0.55em;
    width: 0.4em;
    height: 0.8em;
    border: solid var(--ldp-green);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* /contact/'s locations list. Avada lets a fusion-checklist override the tick
   per item, and this is the only list on the site that does — its four entries
   carry fa-map-marker, which is the point of them: they are places, not a list
   of things that are done. Phase 2 recorded the class but not the icon, so the
   list shipped with ticks until Phase 7.

   The pin is an inline SVG rather than a glyph for the same reason the tick is
   drawn from borders — the self-hosted fonts are latin-subset only (D-009). */
.ldp-checklist--pins li::before {
    left: 0.15em;
    top: 0.4em;
    width: 1em;
    height: 1em;
    border: 0;
    transform: none;
    background: var(--ldp-green);
    -webkit-mask: var(--ldp-pin-mask) center / contain no-repeat;
    mask: var(--ldp-pin-mask) center / contain no-repeat;
}

/* fusion-content-boxes and the industry cards: an optional icon or image, a
   heading, a line of copy, and usually a link. The 1px border stands in for
   Avada's column box-shadow, which is flagged in layouts.md as hard to
   reproduce and reads as noise at this scale. */
.ldp-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--ldp-space-3);
    background: var(--ldp-white);
    border: 1px solid var(--ldp-grey-300);
}

.ldp-card--center {
    text-align: center;
    align-items: center;
}

/* Every card heading on /products/ and the homepage is a link to the page the
   card describes. The live content box renders the heading in the title colour
   and turns it green on hover; the global `a` rule in §4 would paint it the
   resting link green instead and lose that distinction. */
.ldp-card :is(h2, h3, h4) a {
    color: var(--ldp-text);
}

.ldp-card :is(h2, h3, h4) a:hover,
.ldp-card :is(h2, h3, h4) a:focus-visible {
    color: var(--ldp-link);
}

/* The card is a flex column at `height: 100%`, so a row of them is already
   equal height — but the content is top-packed, which left each card's trailing
   "Read More" wherever its copy happened to end. `margin-top: auto` eats the
   slack above the last child instead, giving every card in a row one baseline
   for its link. Cooling's three-line summary on /products/ was pushing its link
   28px below Power's. */
.ldp-card > :last-child {
    margin-top: auto;
    margin-bottom: 0;
}

/* A tinted padded box inside a column, as opposed to .ldp-section--tint, which
   is a full-bleed band. The five product child pages put the contact form in
   one (Avada: a 1/3 column with 50px padding and the same pale green fill);
   50px maps onto the 8px scale as space-5. */
.ldp-panel {
    padding: var(--ldp-space-5);
    background: var(--ldp-tint-green);
}

.ldp-panel > :last-child {
    margin-bottom: 0;
}

/* The live column pins this heading to 32px with an inline style. The h2 step
   of the scale is 45px, which is sized for a full-width band and wraps to five
   lines inside a third of one. */
.ldp-panel :is(h2, h3) {
    font-size: 2rem;
    line-height: 1.25;
}

/* The same tinted box in a two-thirds column rather than a third — /contact/'s
   form. There the live heading is the scale's own 45px, not the 32px the narrow
   product sidebars pin it to, and at that width it does not wrap badly. */
.ldp-panel--wide :is(h2, h3) {
    font-size: var(--ldp-h2);
    line-height: 1.21;
}

@media (max-width: 800px) {
    .ldp-panel {
        padding: var(--ldp-space-3);
    }
}

/* ==========================================================================
   13. CTA band
   ==========================================================================
   The "How is Your Data Center Performing?" band that opens and closes almost
   every page: copy on the left, one button on the right, over a dark photo.
   The page supplies the photo inline (style="background-image: url(...)"),
   because which photo it is is content, not styling — that is the only inline
   style a page view may write. Without one it falls back to the footer colour. */

.ldp-cta {
    position: relative;
    background-color: var(--ldp-footer);
    background-position: center;
    background-size: cover;
    color: var(--ldp-white);
}

.ldp-cta::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / 40%); /* Avada's --page_title_bar_overlay */
}

.ldp-cta > .ldp-container {
    position: relative; /* lift the content above the overlay */
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--ldp-space-3) var(--ldp-space-4);
    padding-top: var(--ldp-space-xl);
    padding-bottom: var(--ldp-space-xl);
}

.ldp-cta :is(h1, h2, h3, h4, h5, h6),
.ldp-cta a {
    color: var(--ldp-white);
}

/* Green, not the blue every other button uses. design-tokens.md records #81BD06
   as "Button bevel" and #42B4E6 as the button background — that is the theme
   option, and it is right for the header CTA, "Review Us", and every form
   submit, all of which do paint blue. The CTA band's button is the one place
   Avada overrides it per element (--button_gradient_top_color:#81bd06). Read off
   the live site's computed styles in Phase 7, not off the theme options. */
.ldp-cta .ldp-btn {
    background: var(--ldp-green);
    color: var(--ldp-white);
}

.ldp-cta .ldp-btn:hover,
.ldp-cta .ldp-btn:focus-visible {
    background: var(--ldp-navy); /* same hover as every other button */
}

.ldp-cta__actions {
    justify-self: end;
}

/* The light variant. Six pages OPEN with this band and close with the dark one:
   the opening container is a flat rgba(113,186,5,0.2) tint with no photo and no
   overlay, and only the closing container is dark over bg-normal.jpg. Verified
   container by container in docs/harvest/raw/*.html. Modelling .ldp-cta as
   always dark made every one of those pages open with the wrong band. */
.ldp-cta--light {
    background-color: var(--ldp-tint-green);
    color: var(--ldp-text);
}

.ldp-cta--light::before {
    display: none; /* no photo underneath, so nothing to darken */
}

/* Back to document colours: green headings, black copy, green links. */
.ldp-cta--light :is(h1, h2, h3, h4, h5, h6) {
    color: var(--ldp-heading);
}

.ldp-cta--light a:not(.ldp-btn) {
    color: var(--ldp-link);
}

@media (max-width: 800px) {
    /* A legibility deviation, not a transcription. 40% is the faithful value —
       the live overlay is rgba(62,70,70,0.39) — and it works at desktop widths,
       where bg-normal.jpg's bright corridor falls behind the empty right-hand
       third of the band. `background-size: cover` at 390px crops to the centre
       of the photo and puts that same bright region directly behind the white
       body copy, which then reads as grey-on-grey. Phone widths only. */
    .ldp-cta::before {
        background: rgb(0 0 0 / 60%);
    }

    .ldp-cta > .ldp-container {
        grid-template-columns: minmax(0, 1fr);
        padding-top: var(--ldp-space-5);
        padding-bottom: var(--ldp-space-5);
    }

    .ldp-cta__actions {
        justify-self: start;
    }
}

/* --- 15.1 Homepage hero ---
   Not a CTA band, though it was built as one until this pass. The live hero is
   slide1.jpg anchored right-top under a half-width black panel holding the
   eyebrow, the h1, one sentence, and a button stacked beneath them. .ldp-cta's
   3fr/1fr grid pushed that button into the right quarter, over the photo. The
   panel — not the band — carries the darkening, which is why there is no
   ::before overlay here. */

.ldp-hero {
    background-position: right top;
    background-size: cover;
    background-color: var(--ldp-footer); /* fallback if the photo 404s */
}

.ldp-hero > .ldp-container {
    padding-top: 100px;
    padding-bottom: 100px;
}

.ldp-hero__panel {
    max-width: 50%;
    padding: var(--ldp-gutter);
    background: rgb(0 0 0 / 60%);
    color: var(--ldp-white);
}

.ldp-hero__panel :is(h1, h2, h3) {
    color: var(--ldp-white);
}

/* h1 and h2 both have zero margin on the edge that faces the other, so the h1's
   last line and the subtitle touched — and collided outright at 390px, where the
   h1 wraps to four lines. Fixed with a margin rather than by loosening the h1's
   line-height: 1.05 is already the deliberate correction of the theme's 0.83. */
.ldp-hero__panel h1 {
    margin-bottom: var(--ldp-space-2);
}

/* The live h2 is pinned to 24px rather than the 45px the scale would give it —
   it is a subtitle sentence, not a section heading. */
.ldp-hero__panel h2 {
    font-size: 1.5rem;
    line-height: 1.4;
}

.ldp-hero__panel > :last-child {
    margin-bottom: 0;
}

@media (max-width: 800px) {
    .ldp-hero > .ldp-container {
        padding-top: var(--ldp-space-5);
        padding-bottom: var(--ldp-space-5);
    }

    .ldp-hero__panel {
        max-width: none;
    }
}

/* ==========================================================================
   14. Visibility utility
   ==========================================================================
   Six pages carry a duplicate CTA container marked
   fusion-no-medium-visibility fusion-no-large-visibility — a phone-only repeat
   of the CTA that also sits at the foot of the page. The copy appearing twice
   in the harvested markdown is deliberate, not a transcription error. */

.ldp-only-mobile {
    display: none;
}

@media (max-width: 800px) {
    .ldp-only-mobile {
        display: block;
    }
}

/* ==========================================================================
   15. EcoStruxure popup
   ==========================================================================
   Popup Maker's one popup (#pum-20159), hand-written — SPEC D-008. The plugin
   shipped ~70 KB of JS and 11 KB of CSS to deliver a timed div; this and the
   matching block in site.js are the whole replacement.

   Sizing and colour come from Popup Maker theme 1454 in
   docs/harvest/assets/pum-site-styles.css: 640px wide, 25px padding, 2px
   radius, that box-shadow, and a container fill of rgba(66,180,230,1) — which
   is exactly --ldp-blue, so the token stands in for it. The popup's own
   inline styles supply the white text and the 40px title.

   Two deliberate divergences from the live behaviour, both flagged in
   docs/content/integrations.md §2.3 as worth fixing while rebuilding:

     - Responsive width. The live panel is a hard 640px, which overflows a
       390px phone it is not disabled on.
     - z-index 90, not 1999999999. The live value covers the mobile menu; ours
       stays under the header wrapper (§7, z-index 100) so an open menu wins,
       and under the newsletter <dialog>, which showModal() puts in the top
       layer regardless. The popup is non-modal — no overlay, no focus trap —
       so it must never be what the visitor has to deal with first. */

.ldp-popup {
    position: fixed;
    left: var(--ldp-space-2);
    bottom: var(--ldp-space-2);
    z-index: 90;
    width: min(640px, calc(100vw - 2rem));
    padding: 25px; /* theme 1454's container padding */
    background: var(--ldp-blue);
    color: var(--ldp-white);
    border-radius: 2px;
    box-shadow: 1px 1px 3px rgb(2 2 2 / 23%);
    /* Popup Maker's "slide from left bottom", 350ms. The reduced-motion block
       in §3 already clamps this to nothing. */
    animation: ldp-popup-in 350ms ease-out;
}

@keyframes ldp-popup-in {
    from {
        opacity: 0;
        transform: translate(-1.5rem, 1.5rem);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* The copy is long enough to exceed a phone's viewport once it wraps into a
   358px column, so it scrolls inside the panel instead of running off the top
   of the screen. The close button sits outside this box and stays reachable. */
.ldp-popup__body {
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
}

.ldp-popup__body > :last-child {
    margin-bottom: 0;
}

/* Headings default to green (§4) and links to green (§4); everything in here
   is white on blue. */
.ldp-popup :is(h1, h2, h3) {
    color: var(--ldp-white);
}

/* Theme 1454 sets 38px; the popup's own inline style overrides it to 40px with
   line-height 1.3. Floored at 28px so it does not eat a phone screen. */
.ldp-popup__title {
    font-size: clamp(1.75rem, 0.5rem + 5vw, 2.5rem);
    line-height: 1.3;
    margin-bottom: var(--ldp-space-2);
    /* Only the title runs alongside the close button, so the clearance goes
       here rather than on the panel — padding the whole panel would pull the
       body copy and the button in from the right edge for no reason. */
    padding-right: 2.5rem;
}

.ldp-popup__lead {
    font-size: 1.25rem; /* 20px, per the live inline style */
    margin-bottom: var(--ldp-space-1);
}

/* Live button colours: #1C2727 resting, #2C2F3E on hover — the footer and nav
   tokens. The default .ldp-btn blue would vanish into the panel. */
.ldp-popup .ldp-btn {
    background: var(--ldp-footer);
}

.ldp-popup .ldp-btn:hover,
.ldp-popup .ldp-btn:focus-visible {
    background: var(--ldp-navy);
}

.ldp-popup__close {
    position: absolute;
    top: 0;
    right: 5px;
    padding: 8px;
    border: 0;
    background: none;
    color: var(--ldp-white);
    line-height: 0;
    cursor: pointer;
}

.ldp-popup__close svg {
    width: 26px;
    height: 26px;
    fill: currentColor;
}

@media (max-width: 800px) {
    .ldp-popup {
        left: var(--ldp-space-2);
        right: var(--ldp-space-2);
        width: auto;
        padding: var(--ldp-space-3);
        /* 17px/1.8 body copy wraps this paragraph to twelve lines in a 342px
           column, and the panel then eats two thirds of a phone screen. One
           step down is still comfortably readable and gives back ~100px.
           A concession to the copy being long, not a design change. */
        font-size: 1rem;
        line-height: 1.6;
    }

    /* The button is the copy's natural next line at this width, not an inline
       afterthought at the end of it. */
    .ldp-popup .ldp-btn {
        display: block;
        width: 100%;
    }
}

/* ==========================================================================
   16. Blog — the /blog/ listing and the post pages

   Every number in this section was read off www.ldpassociates.com with
   getComputedStyle at 1440px and 390px. None of it is in the harvest: Avada
   serves the blog element's layout from its dynamic stylesheet, which is the
   same gap that cost Phase 3 the page title bar (D-023).
   ========================================================================== */

/* One row of the listing — Avada's "medium" blog layout. Thumbnail left, title
   and excerpt right, the meta rule spanning both. Wrapping is load-bearing
   rather than defensive: it is what puts .ldp-post-meta on its own line at any
   width, and what stacks the whole row once the thumbnail goes full width. */
.ldp-post-summary {
    display: flex;
    flex-wrap: wrap;
    /* Not the default `stretch`. A stretched thumbnail takes the flex line's
       height instead of its own, which overrides the aspect-ratio below and
       made the mobile thumbnail as tall as the excerpt beside it. */
    align-items: flex-start;
    margin-bottom: 65px;
}

.ldp-post-summary__thumb {
    flex: 0 0 320px;
    width: 320px;
    height: 202px;
    margin-right: 25px;
    overflow: hidden;
    /* Behind a photo that has not decoded yet. Without it the row flashes the
       page background at full size, which reads as a broken image. */
    background: var(--ldp-grey-100);
}

/* The live site serves a generated 320x202 crop of each featured image; we
   kept the originals (D-007), which are 1920x1280, 2560x1707, 700x394 and
   everything between. So the crop happens here. This is also why the <img>
   carries the file's intrinsic size rather than a displayed one — the box is
   fixed above, so the attributes only hold the ratio while the file loads. */
.ldp-post-summary__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ldp-post-summary__body {
    flex: 1 1 0;
    /* Without it a long unbroken word in a title stretches the flex item past
       its share and pushes the thumbnail off the row. */
    min-width: 0;
}

/* 32px with a 0.88 leading, both measured — not the 45px --ldp-h2 the rest of
   the site uses. Six post titles in a list are not six section headings, and
   at the section scale the listing reads as six pages rather than one. */
.ldp-post-summary__body h2 {
    font-size: 2rem; /* 32px */
    line-height: 0.88;
    margin-bottom: 25px;
}

@media (max-width: 800px) {
    .ldp-post-summary__thumb {
        flex-basis: 100%;
        width: 100%;
        height: auto;
        /* The same crop, sized by the column instead of by a fixed width.
           Measured: 330x208.31 at 390px, which is 320/202 to two decimals. */
        aspect-ratio: 320 / 202;
        margin: 0 0 20px;
    }

    /* Both at 100%, or nothing wraps: a `flex: 1 1 0` item's hypothetical size
       is zero, so it "fits" beside a full-width thumbnail and is then handed a
       zero-width column with the whole excerpt in it. */
    .ldp-post-summary__body {
        flex-basis: 100%;
    }
}

/* The date-and-category rule: on a listing row, and on a post page where it is
   the only thing between the body and the CTA band. 16px between two 1px
   #e0dede rules with 5px of padding — all measured, and #e0dede is already
   --ldp-grey-300.

   width:100% is what wraps it onto its own line inside .ldp-post-summary's
   flex row; on a post page it is simply a block. clear:both ends
   .ldp-post-featured's float, which is why a post page needs no separator. */
.ldp-post-meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--ldp-space-1);
    clear: both;
    width: 100%;
    margin-top: 20px;
    padding: 5px 0;
    /* The base `p` rule's bottom margin would sit between this rule and the
       next row's 65px gap, which is not what the live listing does. */
    margin-bottom: 0;
    border-top: 1px solid var(--ldp-grey-300);
    border-bottom: 1px solid var(--ldp-grey-300);
    font-size: 1rem; /* 16px */
    line-height: 1.8;
}

/* The pager. 12px, right-aligned, 40px clear of the last row; each number a
   1px #e0dede box, green, and the current page filled with the button blue and
   reversed out. Previous and Next are text with no box. */
.ldp-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--ldp-space-1);
    margin-top: 40px;
    font-size: 0.75rem; /* 12px */
}

.ldp-pagination a,
.ldp-pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    min-height: 23px;
    padding: 2px 6px;
    border: 1px solid var(--ldp-grey-300);
    /* The 1.8 body leading makes a 12px box 28px tall; live is 23px. */
    line-height: 1.4;
}

/* Both selectors carry the parent class, or they lose to the element-qualified
   rule above and Previous/Next keeps its box while the current page keeps a
   grey border instead of a blue one. */
.ldp-pagination .ldp-pagination__step {
    padding-inline: 0;
    border-color: transparent;
}

.ldp-pagination .ldp-pagination__current {
    background: var(--ldp-blue);
    border-color: var(--ldp-blue);
    color: var(--ldp-white);
}

/* A post's featured photograph. The live post floats it right at 45% of the
   content width with the body running beside it, and drops it to a full-width
   block above the text on a phone — so this is the live behaviour, not a
   simplification of it. .ldp-figure--right cannot do the job: it has no width,
   so a floated 2560px original shrink-to-fits to 2560px and overflows. */
.ldp-post-featured {
    margin: 0 0 var(--ldp-space-3);
}

.ldp-post-featured img {
    display: block;
    width: 100%;
    height: auto;
}

@media (min-width: 801px) {
    .ldp-post-featured {
        float: right;
        width: 45%;
        margin: 0 0 var(--ldp-space-3) var(--ldp-space-4);
    }
}
