﻿/* =========================================================================
   LOCAL LOCKER â€” INNER PAGES
   Browse Gear, Category listing, City listing, Lend Gear, Contact.

   Desktop / base styles only. Every media query lives in css/responsive.css,
   the same split style.css uses.

   The design prototype shipped its own token layer and its own container. Both
   are deliberately NOT ported:

     - Container. The prototype's rail is Bootstrap's 1320px; the homepage's is
       --ll-container (1600px). Inner pages use the homepage's, so a section
       edge lines up whether a visitor is on the home page or two clicks in.
       The prototype also names its rail .ll-container, which is the theme's own
       class at a different width â€” nothing here redefines it.

     - Buttons, headings, section rhythm. .ll-btn and .ll-heading already exist
       and are what the homepage uses, so the inner pages use them rather than a
       second set that drifts.

   What IS bridged below is the prototype's semantic vocabulary â€” spacing steps,
   radii, surfaces, text roles â€” resolved to the theme's values. That keeps the
   ported layout readable without inventing a parallel palette.
   ========================================================================= */

:root {
    /* Spacing â€” the prototype's 5-based steps, which the layouts are authored in. */
    --ll-s1: 5px;
    --ll-s2: 6px;
    --ll-s3: 10px;
    --ll-s4: 12px;
    --ll-s5: 16px;
    --ll-s6: 20px;
    --ll-s7: 24px;
    --ll-s8: 28px;
    --ll-s9: 30px;
    --ll-s10: 40px;
    --ll-s12: 50px;
    --ll-s15: 80px;

    /* Radii */
    --ll-r-panel: 8px;
    --ll-r-plate: 12px;
    --ll-r-card: 16px;
    --ll-r-promo: 30px;
    --ll-r-pill: 100px;
    --ll-r-full: 999px;

    /*
     * Surfaces. The design is black-on-black: cards are separated by a hairline
     * and a barely-lifted fill, never by a border colour that reads as grey.
     */
    --ll-surface-raised: #0B0B0B;
    --ll-surface-inset: #111111;
    --ll-border-card: #232323;
    --ll-border-panel: #222222;
    --ll-border-rule: rgba(255, 255, 255, 0.2);

    /* Text roles */
    --ll-text-muted: rgba(255, 255, 255, 0.7);
    --ll-text-secondary: #8E8E93;

    /*
     * Type scale â€” read off the rendered home page, not invented here. Inner
     * pages pick the nearest step for each role rather than introducing sizes
     * of their own, which is what left one page carrying 45px and 70px section
     * headings at the same time.
     *
     *   80/90 w700  .ll-hero__title          page title (home)
     *   70/90 w600  .ll-heading__title       section title (home)
     *   40/52 w600  .ll-feature__title
     *   36/55 w600  .ll-trust-card__title
     *   30/21 w400  .ll-heading__eyebrow
     *   24/36 w400  .ll-hero__subtitle       standfirst
     *   24/30 w700  .ll-category__label      tile label
     *   20/20 w700  .ll-product__amount      price
     *   16/22 w700  .ll-product__title       card title
     *   14/17 w400  .ll-product__place       card meta
     */
    /*
     * The three text steps are a point up on the figures above: the standfirst
     * under a heading and the copy inside a card were the two things reported
     * as hard to read on these pages, and both live here â€” .ll-meta and
     * .ll-page__lead under every section head, .ll-prod__name / .ll-caption /
     * .ll-gcard__name inside the cards. The heading steps are unchanged, so the
     * hierarchy is the same shape, one notch more legible.
     */
    --ll-fs-title: 70px;
    --ll-fs-h2: 40px;
    --ll-fs-h3: 24px;
    --ll-fs-h4: 20px;
    --ll-fs-lead: 24px;
    --ll-fs-body: 19px;
    --ll-fs-meta: 17px;
    --ll-fs-small: 15px;

    /*
     * Spacing. The home page puts padding on the top of a section only and
     * leaves the bottom to the next one, so one number sets the gap between
     * every pair. Mixing top and bottom padding â€” which is what these pages
     * did â€” gives a different gap for every combination: 180px here, 100px
     * there, 140px somewhere else.
     */
    --ll-sec-pad: 100px;
    --ll-sec-pad-tight: 60px;
    --ll-band-pad: 80px;
    --ll-page-tail: 120px;

    /* Card rows are 20px apart on the home page (.ll-products, .ll-trust__grid). */
    --ll-gap-card: 20px;
    /* Two-column content splits, matching the reference's 62-80px. */
    --ll-gap-split: 60px;

    /* Condition / status semantics, used by the listing badges. */
    --ll-star: #FFC700;
    --ll-good: #4ADE80;

    --ll-hairline-card: inset 0 0 0 1px var(--ll-border-card);
    --ll-hairline-accent: inset 0 0 0 1px var(--ll-red);

    /* Ambient red glow behind CTA bands, as on the homepage hero. */
    --ll-glow-red: radial-gradient(ellipse closest-side,
            var(--ll-red) 0%, rgba(237, 28, 36, 0.38) 42%, rgba(237, 28, 36, 0) 100%);
}

/* Border-box for the inner pages, matching what style.css does for the home page. */
.ll-page,
.ll-page *,
.ll-page *::before,
.ll-page *::after {
    box-sizing: border-box;
}

.ll-page {
    background-color: var(--ll-black);
    color: var(--ll-white);
    font-family: var(--ll-font);
}

/*
 * style.css inherits `h1..h6 { font-family: 'Proxima Nova Lt' }` from the
 * parent theme, which is a serif stand-in that never loads. The home page's
 * sections each set --ll-font on their own headings, so they escape it; these
 * pages set it once for every heading and control inside them instead.
 */
.ll-page h1,
.ll-page h2,
.ll-page h3,
.ll-page h4,
.ll-page h5,
.ll-page h6,
.ll-page input,
.ll-page select,
.ll-page textarea,
.ll-page button {
    font-family: var(--ll-font);
}

/*
 * Section rhythm. The prototype spaced page-level blocks 50px apart; the
 * homepage's sections are considerably more generous, so inner sections take
 * the homepage's padding and the 50px becomes the gap inside a section.
 */
.ll-section {
    position: relative;
    padding: var(--ll-sec-pad) 0 0;
}

/*
 * Same rhythm as .ll-section. The modifier is kept because it still means
 * "this block belongs with the one above it" at narrow widths, where the
 * responsive sheet does pull it in.
 */
.ll-section--tight {
    padding-top: var(--ll-sec-pad);
}

/* Continues the hero rather than starting a new block. */
.ll-section--flush {
    padding-top: var(--ll-sec-pad-tight);
}

/*
 * The tail before the footer, matching the home page's last section
 * (.ll-download, 120px). Sections carry no bottom padding of their own, so
 * without this the last one would run straight into the footer.
 */
.ll-page {
    padding-bottom: var(--ll-page-tail);
}

/* Type roles ------------------------------------------------------------- */

/*
 * The homepage's heading scale is 70px/600 for a section title and 80px for the
 * hero. Inner pages carry more content per screen, so headings clamp down from
 * those figures rather than being a different scale.
 */
.ll-page__title {
    margin: 0;
    font-family: var(--ll-font);
    font-weight: 700;
    font-size: clamp(38px, 4.4vw, var(--ll-fs-title));
    line-height: 1.16;
    letter-spacing: -0.2px;
    color: var(--ll-white);
    /*
     * The last resort for a heading whose longest word is wider than the phone.
     * The category names are the API's, so one of them can be anything; the
     * template offers a break after a slash first, and this only ever fires when
     * even that leaves a word that will not fit.
     */
    overflow-wrap: break-word;
}

.ll-page__h2 {
    margin: 0;
    font-family: var(--ll-font);
    font-weight: 600;
    font-size: clamp(28px, 2.5vw, var(--ll-fs-h2));
    line-height: 1.3;
    letter-spacing: -0.2px;
    color: var(--ll-white);
}

.ll-page__h3 {
    margin: 0;
    font-weight: 600;
    font-size: var(--ll-fs-h3);
    line-height: 1.25;
    color: var(--ll-white);
}

.ll-page__h4 {
    margin: 0;
    font-weight: 600;
    font-size: var(--ll-fs-h4);
    line-height: 1.35;
    color: var(--ll-white);
}

.ll-page__lead {
    margin: 0;
    /*
     * 24px is the home page's standfirst. The measure is in ch so the line
     * length stays readable as the size clamps down, the way the hero subtitle
     * wraps on the home page.
     */
    max-width: 54ch;
    font-size: clamp(17px, 1.5vw, var(--ll-fs-lead));
    line-height: 1.5;
    color: var(--ll-text-muted);
}

.ll-page__accent {
    color: var(--ll-red);
}

.ll-meta {
    margin-bottom: 0;
    font-size: var(--ll-fs-meta);
    line-height: 1.5;
    color: var(--ll-text-secondary);
}

.ll-caption {
    margin: 0;
    font-size: var(--ll-fs-small);
    line-height: 1.5;
    color: var(--ll-text-secondary);
}

.ll-kicker {
    display: block;
    margin: 0;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--ll-red);
}

/* Section heading blocks ------------------------------------------------- */

.ll-sechead {
    display: flex;
    flex-direction: column;
    /*
     * One line-break's worth of air between a section title and its meta line,
     * as the reference's .shead-c (gap: 5px) draws it â€” the 30px the home
     * page's eyebrow uses read as a hole between the two on every section.
     */
    gap: var(--ll-s1);
    /* The reference's .shead sits 40px above its grid. */
    margin-bottom: var(--ll-s10);
}

.ll-sechead--split {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--ll-s10);
}

.ll-sechead--center {
    align-items: center;
    text-align: center;
}

/* Page hero -------------------------------------------------------------- */

.ll-phero {
    position: relative;
    /*
     * Above the sections that follow. The search bar's backdrop-filter makes
     * .ll-search a stacking context of its own, so the Location list and the
     * Dates calendar â€” z-index 20 *inside* it â€” could never rise above the next
     * section, which is position:relative and painted later. The calendar's
     * days and the location options were being covered by an invisible slab of
     * the "Where Do You Need Gear?" section: clicks landed on the section, the
     * wheel scrolled the page, and the panels read as colliding with it.
     * Lifting the hero itself puts its dropdowns over everything below.
     */
    z-index: 5;
    padding: var(--ll-sec-pad-tight) 0 0;
}

.ll-phero__inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s5);
}

/*
 * A hero with a second column: the title on the left and one field on the
 * right, as the city page's reference draws it (.headrow in city-houston.html,
 * 1.4fr / 0.8fr). Only a hero given an `aside` gets the row, so every other
 * inner page keeps the plain column above, unchanged.
 */
.ll-phero__row {
    /* The flex column centres nothing and stretches nothing, so claim the rail. */
    width: 100%;
    display: grid;
    grid-template-columns: minmax(240px, 1.4fr) minmax(200px, 0.8fr);
    align-items: start;
    gap: var(--ll-s8);
}

.ll-phero__lede {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s5);
    /*
     * A grid item's automatic minimum is its content's, and a long city name
     * would push the field past the rail rather than wrap. Let the column
     * shrink to whatever the track gives it.
     */
    min-width: 0;
}

.ll-phero__aside {
    min-width: 0;
    /* The reference's own 3px nudge, so the label sits level with the title. */
    padding-top: 3px;
}

/* Select category, the city page's one control --------------------------- */

/* The reference's .label, to the token: 14px medium, uppercase, 0.28em. */
.ll-cityfield__label {
    display: block;
    margin-bottom: var(--ll-s2);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--ll-text-secondary);
}

.ll-cityfield__ctl {
    position: relative;
    display: block;
}

.ll-cityfield__ctl select {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    /* A select's content-based minimum is wider than a 300px rail. */
    min-width: 0;
    height: 52px;
    /* Room on the right for the chevron the appearance reset removed. */
    padding: 0 var(--ll-s9) 0 var(--ll-s5);
    border: 0;
    border-radius: var(--ll-r-panel);
    box-shadow: var(--ll-hairline-card);
    background-color: var(--ll-surface-inset);
    font-family: inherit;
    /* --size-meta in the reference, not the 14px the filter pills use. */
    font-size: 16px;
    font-weight: 500;
    color: var(--ll-white);
    cursor: pointer;
    transition: box-shadow 0.25s ease;
}

.ll-cityfield__ctl select:hover,
.ll-cityfield__ctl select:focus-visible {
    box-shadow: var(--ll-hairline-accent);
}

/*
 * Native option lists inherit the page's dark ground on some platforms and the
 * system's white on others, which leaves white-on-white text. Set both.
 */
.ll-cityfield__ctl select option {
    background-color: #111111;
    color: #ffffff;
}

.ll-cityfield__chev {
    position: absolute;
    top: 50%;
    right: var(--ll-s5);
    display: flex;
    transform: translateY(-50%);
    /* Decoration: the click belongs to the select underneath. */
    pointer-events: none;
    color: var(--ll-text-secondary);
}

/* Breadcrumb ------------------------------------------------------------- */

.ll-crumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ll-s3);
    margin: 0 0 var(--ll-s5);
    font-size: 14px;
    color: var(--ll-text-secondary);
}

.ll-crumb a {
    color: var(--ll-text-secondary);
}

.ll-crumb a:hover {
    color: var(--ll-white);
}

.ll-crumb__sep {
    opacity: 0.6;
}

.ll-crumb__current {
    color: var(--ll-white);
    font-weight: 600;
}

/*
 * In the lend hero the crumb is one item in a flex column, so the column's own
 * gap sets the space under it â€” the margin above would double it.
 */

/* Pills and chips -------------------------------------------------------- */

/*
 * The reference's own pill (.pill in lend.css), to the letter: red type on a
 * red veil inside a red hairline, uppercase and widely tracked.
 *
 * It used to be a grey chip with muted grey type — the same shape, none of the
 * colour — which is why the hero and the closing call to action did not look
 * like the design even though their content matched.
 */
.ll-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--ll-s2);
    padding: var(--ll-s2) var(--ll-s5);
    border-radius: var(--ll-r-full);
    box-shadow: var(--ll-hairline-accent);
    background-color: rgba(237, 28, 36, 0.1);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--ll-red);
}

/*
 * The step card's eyebrow is the design system's EyebrowPill rather than the
 * pill above — red type and a red outline, but no veil behind it, no tracking
 * and no capitals, at the size the lend page overrides it to.
 */
.ll-pill--accent {
    padding: var(--ll-s3) var(--ll-s6);
    background-color: transparent;
    box-shadow: var(--ll-hairline-accent);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: normal;
    text-transform: none;
    color: var(--ll-red);
}

/* The live dot: a green bead in a soft green halo, as the reference draws it. */
.ll-livedot {
    position: relative;
    width: 6px;
    height: 6px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--ll-good);
    box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.22);
}

.ll-livedot::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 1px solid var(--ll-red);
    opacity: 0.55;
    animation: ll-live 2.4s ease-out infinite;
}

@keyframes ll-live {
    0% {
        transform: scale(0.6);
        opacity: 0.7;
    }

    100% {
        transform: scale(1.5);
        opacity: 0;
    }
}

.ll-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: var(--ll-r-pill);
    background-color: rgba(255, 255, 255, 0.06);
    font-size: 13px;
    color: var(--ll-text-muted);
}

/* Cards ----------------------------------------------------------------- */

.ll-card {
    position: relative;
    padding: var(--ll-s9);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

/*
 * Photography on black needs a scrim, not just a dark image: several of the
 * supplied photographs are light enough that white text on them is unreadable
 * without one.
 */
.ll-shot {
    position: relative;
    overflow: hidden;
    border-radius: var(--ll-r-plate);
    background-color: var(--ll-surface-inset);
}

.ll-shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-shot--scrim::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.85) 100%);
}

/* Product card ---------------------------------------------------------- */

.ll-prod {
    position: relative;
    display: flex;
    flex-direction: column;
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    overflow: hidden;
    color: inherit;
    /* The card is an <a> when it has been given a link, an <article> when not. */
    text-decoration: none;
    transition: transform 0.3s ease;
    /*
     * Hints the browser to give the card its own compositing layer ahead of
     * time, rather than building one the moment a hover starts the transform
     * transition — that on-demand layer creation is what read as lag on a
     * grid with a full page of these cards in the document at once.
     */
    will-change: transform;
}

/*
 * The hover ring, painted once and only ever faded — see .ll-prod:hover
 * below for why. Inset so it sits exactly where the box-shadow it replaces
 * used to draw. Only the lower half is meant to show — clipped there rather
 * than left unclipped, because an inset box-shadow's corners follow the box
 * it is drawn on, not the ancestor that happens to clip it: with no clip at
 * all, the ring's own bottom-left/bottom-right corners lost the card's
 * rounding and squared off past the curve.
 *
 * border-radius: inherit keeps that curve correct on the corners the clip
 * leaves visible.
 */
.ll-prod::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    clip-path: inset(50% 0 0 0);
    box-shadow: var(--ll-hairline-accent);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    will-change: opacity;
}

/*
 * The optional per-card description. The design carries none, so this only
 * exists for a card somebody chooses to write one on, and it takes the same
 * secondary treatment as the line above it.
 */
.ll-prod__text {
    margin: 0;
    font-size: var(--ll-fs-small);
    line-height: 1.45;
    color: var(--ll-text-secondary);
}

.ll-prod:hover {
    transform: translateY(-3px);
    color: inherit;
}

/*
 * Cross-fading the accent ring in over the card's own resting box-shadow,
 * rather than transitioning the box-shadow property directly: box-shadow is
 * not a property a browser can composite, so animating it — even a plain
 * 1px inset one with no blur — repaints the card's full box on the main
 * thread every frame. transform and opacity are the two properties a
 * compositor can animate on their own thread, so with both hover effects now
 * expressed that way, the card's whole hover interaction runs off it.
 */
.ll-prod:hover::after {
    opacity: 1;
}

.ll-prod__shot {
    position: relative;
    /* 312x150 in the reference. */
    aspect-ratio: 25 / 12;
    background-color: var(--ll-surface-inset);
    overflow: hidden;
}

.ll-prod__shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-prod__badge {
    position: absolute;
    top: var(--ll-s4);
    left: var(--ll-s4);
    padding: 6px 12px;
    border-radius: var(--ll-r-pill);
    background-color: var(--ll-red);
    font-size: 12px;
    font-weight: 600;
    color: var(--ll-white);
}

/*
 * The words under the photograph.
 *
 * flex: 1 1 auto so the body takes whatever height the card has spare. The
 * cards in a row are already the same height — grid items stretch — but
 * without this the body stopped at its natural height and the slack piled up
 * underneath it, so a card with a one-line title sat its whole lower half,
 * "View product" included, higher than the card beside it with a two-line one.
 *
 * The same thing .ll-product__body does on the home page, which is why the
 * cards under the hero never had this.
 */
.ll-prod__body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 5px;
    padding: var(--ll-s6);
}

/*
 * .ll-product__title on the home page: 16px/22 at weight 700.
 *
 * Two lines, always: clamped so a long title cannot run to three, and held at
 * two so a short one does not sit on one. That is what makes every card's words
 * the same height, and it is the whole reason the rest of the card lines up
 * without anything being pushed anywhere.
 *
 * It is the home card's own rule (.ll-product__title, "Two lines, then it
 * clips"), which is why the cards under the hero never needed pushing either.
 *
 * 2.75em is two lines of the 1.375 leading below, so it follows the type rather
 * than being a pixel figure that stops being two lines when the type changes.
 */
.ll-prod__name {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    margin: 0;
    min-height: 50px;
    font-size: var(--ll-fs-meta);
    font-weight: 700;
    line-height: 1.375;
    color: var(--ll-white);
}

.ll-prod__where {
    margin: 0;
    font-size: 15px;
    color: var(--ll-text-secondary);
}

.ll-prod__attrs {
    margin: 0;
    font-size: 13px;
    color: var(--ll-text-secondary);
}

/* Price against the verification mark, as the reference pairs them. */
.ll-prod__price-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ll-s4);
    margin-top: var(--ll-s2);
}

/*
 * The deposit line and its rule follow the price, at the normal 5px the body
 * spaces everything by.
 *
 * This used to carry margin-top:auto, to push itself and the button to the
 * bottom of the card and so line them up across a row. That worked, but it paid
 * for the alignment with a hole: a card with a short title showed a band of
 * empty black between "$10 / day" and this rule, which is a worse thing to look
 * at than a button a few pixels off.
 *
 * Nothing is pushed now. The title above reserves two lines whatever it says,
 * so the cards in a row reach this point at the same height on their own.
 */
.ll-prod__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ll-s5);
    padding-top: var(--ll-s3);
    box-shadow: inset 0 1px 0 0 var(--ll-border-card);
    font-size: var(--ll-fs-small);
    color: var(--ll-text-secondary);
}

/*
 * "$10 / day" is one thing to read, so it is kept on one line.
 *
 * The row it sits in never wraps — flex does not — but the price is the only
 * item in it that can shrink, because the verification mark beside it is
 * flex-shrink: 0. So a long enough price, or a longer word than "day" in
 * another language, would break between the figure and the period and leave
 * "/ day" sitting under "$10" with the mark still up on the first line.
 *
 * There is room to spare today: 169px of content in a 315px card at the widest
 * grid. This is the guarantee, not a repair.
 */
.ll-prod__price {
    font-size: 20px;
    font-weight: 700;
    white-space: nowrap;
    color: var(--ll-white);
}

.ll-prod__price small {
    font-size: var(--ll-fs-small);
    font-weight: 400;
    color: var(--ll-text-secondary);
}

.ll-prod__trust {
    color: var(--ll-text-secondary);
}

/* Grids ----------------------------------------------------------------- */

/*
 * One gap for every card row, so a four-up and a three-up on the same page
 * line up. 20px is the home page's (.ll-products, .ll-trust__grid); these
 * grids were a mix of 20px and 30px.
 */
.ll-grid {
    display: grid;
    gap: var(--ll-gap-card);
}

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

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

.ll-grid--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

/*
 * A short row, at the row's own card width.
 *
 * Feeds decide how many cards a section has â€” Recently Rented shows only the
 * products that have actually been rented â€” and two cards stretched across a
 * four-up rail read as a broken grid. This keeps the card the width it would
 * have had with four of them and centres what there is. The track figure is
 * the four-up column: a quarter of the rail, less its three gaps.
 */
.ll-grid--fill {
    grid-template-columns: repeat(auto-fit, minmax(0, calc((100% - 3 * var(--ll-gap-card)) / 4)));
    justify-content: center;
}

/* Forms ----------------------------------------------------------------- */

.ll-form {
    position: relative;
    padding: var(--ll-s9);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    border: 1.5px solid var(--ll-red);
}

.ll-form__head {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
    margin-bottom: var(--ll-s7);
}

.ll-form__rows {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--ll-s7) var(--ll-s6);
}

.ll-field {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
    min-width: 0;
}

.ll-field--full {
    grid-column: 1 / -1;
}

.ll-field > label {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ll-white);
}

.ll-field__req {
    font-style: normal;
    color: var(--ll-red);
}

.ll-field__opt {
    margin-left: 6px;
    font-style: normal;
    font-weight: 400;
    font-size: 13px;
    color: var(--ll-text-secondary);
}

.ll-field__control {
    position: relative;
}

.ll-input {
    width: 100%;
    height: 48px;
    padding: 0 var(--ll-s5);
    border: 1px solid var(--ll-border-rule);
    border-radius: var(--ll-r-full);
    background-color: transparent;
    font-family: var(--ll-font);
    font-size: 15px;
    color: var(--ll-white);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.ll-input::placeholder {
    color: var(--ll-text-secondary);
    opacity: 1;
}

.ll-input:hover {
    border-color: var(--ll-text-secondary);
}

.ll-input:focus {
    border-color: var(--ll-red);
    box-shadow: 0 0 0 3px rgba(237, 28, 36, 0.1);
}

.ll-field.is-invalid .ll-input {
    border-color: var(--ll-red);
}

textarea.ll-input {
    height: auto;
    min-height: 132px;
    padding: 14px var(--ll-s5);
    border-radius: var(--ll-r-promo);
    line-height: 1.55;
    resize: vertical;
}

/* An icon inside a field: the input's padding grows to clear it. */
.ll-field__control--icon .ll-input {
    padding-left: calc(var(--ll-s5) + 24px);
}

.ll-field__icon {
    position: absolute;
    left: var(--ll-s5);
    top: 24px;
    display: flex;
    transform: translateY(-50%);
    color: var(--ll-red);
    pointer-events: none;
}

.ll-field__error {
    margin: 0;
    font-size: 13px;
    line-height: 1.35;
    color: var(--ll-red);
}

.ll-field__count {
    margin: 0;
    text-align: right;
    font-size: 13px;
    color: var(--ll-text-secondary);
}

.ll-form__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ll-s6);
    margin-top: var(--ll-s7);
}

.ll-form__note {
    margin: 0;
    max-width: 44ch;
    font-size: 13px;
    line-height: 1.35;
    color: var(--ll-text-secondary);
}

.ll-form__message {
    margin: var(--ll-s5) 0 0;
    font-size: 15px;
    line-height: 1.4;
}

.ll-form__message:empty {
    display: none;
}

.ll-form__message.is-error {
    color: var(--ll-red);
}

.ll-form__message.is-success {
    color: var(--ll-good);
}

/* The sent state replaces the form body. */
.ll-form__sent {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s5);
}

.ll-form__tick {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background-color: var(--ll-red);
    color: var(--ll-white);
    box-shadow: var(--ll-shadow-red);
}

/* Contact page ---------------------------------------------------------- */

.ll-contact__body {
    display: grid;
    /* 400px rail, as the reference has it. */
    grid-template-columns: 400px minmax(0, 1fr);
    gap: var(--ll-s15);
    align-items: start;
}

.ll-contact__rail {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s9);
    padding-top: var(--ll-s9);
}

.ll-ways {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s6);
    margin-top: var(--ll-s6);
}

.ll-way {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: var(--ll-s5);
    align-items: start;
}

.ll-way__icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

.ll-way__body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.ll-way__body a {
    font-size: var(--ll-fs-body);
    font-weight: 600;
    color: var(--ll-white);
    word-break: break-word;
}

.ll-way__body a:hover {
    color: var(--ll-red);
}

.ll-hours {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s4);
    margin-top: var(--ll-s6);
}

.ll-hour {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ll-s5);
    font-size: 15px;
}

.ll-hour + .ll-hour {
    padding-top: var(--ll-s4);
    box-shadow: inset 0 1px 0 0 var(--ll-border-card);
}

.ll-hour__day {
    color: var(--ll-text-secondary);
}

.ll-hour__time {
    color: var(--ll-white);
    font-weight: 600;
}

.ll-contact__rail > * + * {
    padding-top: var(--ll-s9);
    box-shadow: inset 0 1px 0 0 var(--ll-border-rule);
}

/* =========================================================================
   LEND GEAR
   ========================================================================= */

.ll-grid--5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

/* Hero ------------------------------------------------------------------- */

.ll-lhero {
    position: relative;
    /* The reference's own opening measure (.hero in lend.css: --space-15). */
    padding: var(--ll-s15) 0 0;
}

.ll-lhero__grid {
    display: grid;
    /* 1.12 / 0.88, as the reference splits it â€” the headline needs the room. */
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    gap: var(--ll-gap-split);
    align-items: center;
}

.ll-lhero__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s6);
}

.ll-lhero__actions,
.ll-strip__actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s3);
    margin-top: var(--ll-s3);
}

/*
 * The three listing cards, fanned. A grid rather than absolute positioning, so
 * the stack still lays out sensibly when it wraps to one column on a phone --
 * the offsets below are what fan it, and they are dropped at that width.
 */
/*
 * The card stack.
 *
 * Capped and pushed to the right edge of its column. The reference lays this
 * out in a 543px rail, which is what puts the cards at 261px and makes a 118px
 * photo read as a letterbox rather than a band. This page's container is the
 * home page's wider one, so without the cap the same grid stretched the cards
 * to 363px and the whole stack grew half as tall again as the design.
 */
.ll-gstack {
    position: relative;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto auto;
    gap: var(--ll-s6);
    align-items: start;
    width: 100%;
    max-width: 543px;
    margin-left: auto;
    padding-bottom: var(--ll-s6);
}

.ll-gcard {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--ll-s5);
    border-radius: var(--ll-r-card);
    /* Pure black, as the reference's --surface-card is. */
    background-color: var(--ll-black);
    box-shadow: var(--ll-hairline-card);
    transition: box-shadow 0.3s ease;
}

.ll-gcard:hover {
    box-shadow: var(--ll-hairline-accent);
}

/*
 * Explicit grid areas, not offsets.
 *
 * The featured card sits in the left column across both rows and centres
 * itself against them; the other two stack down the right. This was three
 * auto-placed cards nudged with translateY, which put the featured one on the
 * wrong side and left the stack's real height out of step with what was drawn.
 */
.ll-gcard--1 {
    grid-area: 1 / 2 / 2 / 3;
}

.ll-gcard--2 {
    grid-area: 1 / 1 / 3 / 2;
    align-self: center;
}

.ll-gcard--3 {
    grid-area: 2 / 2 / 3 / 3;
}

/*
 * A fixed 118px band, not a 4/3 plate. The aspect ratio made the photo 248px
 * tall here, which is what pushed the price row past the bottom of the card.
 * The ground is the dark inset, not white: these are photographs bled to the
 * edge, not product cut-outs.
 */
.ll-gcard__shot {
    position: relative;
    height: 118px;
    flex-shrink: 0;
    margin-bottom: var(--ll-s4);
    border-radius: var(--ll-r-plate);
    background-color: var(--ll-surface-inset);
    overflow: hidden;
}

/* Keeps the lighter photographs from washing out the card's top corners. */
.ll-gcard__shot::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgb(0, 0, 0) 100%);
    opacity: 0.5;
}

.ll-gcard__shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-gcard__name {
    margin: 0;
    font-size: var(--ll-fs-meta);
    font-weight: 600;
    line-height: 1.3;
    color: var(--ll-white);
}

.ll-gcard__by {
    margin: 2px 0 0;
    font-size: var(--ll-fs-small);
    color: var(--ll-text-secondary);
}

/*
 * The owner line is one quiet grey run in the reference, star included â€” the
 * gold star belongs to the product cards, where it is the rating that matters.
 */
.ll-gcard__by .ll-rating,
.ll-gcard__by .ll-rating .ll-icon {
    color: inherit;
}

/* Price against availability, divided off from the copy above. */
.ll-gcard__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ll-s3);
    margin-top: var(--ll-s4);
    padding-top: var(--ll-s4);
    box-shadow: inset 0 1px 0 0 var(--ll-border-card);
}

.ll-gcard__price {
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--ll-white);
}

.ll-gcard__price small {
    font-size: var(--ll-fs-small);
    font-weight: 400;
    /* The de-emphasised suffix, as the design has it. */
    color: #3A3A3A;
}

/*
 * The availability pill is a green outline on the card's own ground, not the
 * grey filled pill the rest of the page uses.
 */
.ll-pill--live {
    padding: 5px 10px;
    background-color: transparent;
    box-shadow: inset 0 0 0 1px rgba(74, 222, 128, 0.32);
    font-size: var(--ll-fs-small);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ll-good);
    white-space: nowrap;
}

.ll-pill--live .ll-livedot {
    background-color: var(--ll-good);
}

.ll-pill--live .ll-livedot::after {
    border-color: var(--ll-good);
}

/*
 * The earnings chip hangs off the bottom-left corner of the featured card,
 * overlapping the gap between the two columns. It was sitting inside the card
 * as another row, which is what pushed that card taller than its neighbours.
 */
.ll-gcard__chip {
    position: absolute;
    left: -30px;
    bottom: -50px;
    z-index: 6;
    display: block;
    /*
     * Capped: the label is live data now, and a long category name once made
     * the chip wide enough to blanket the whole card behind it. The design's
     * own chip ("Priya's camera") fits well inside this; anything longer
     * ellipsises rather than spreading.
     */
    max-width: 240px;
    padding: var(--ll-s4) var(--ll-s5);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-red);
    box-shadow: var(--ll-shadow-red);
    white-space: nowrap;
}

.ll-gcard__chip span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--ll-fs-small);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ll-white);
    opacity: 0.92;
}

.ll-gcard__chip b {
    overflow: hidden;
    text-overflow: ellipsis;
}

.ll-gcard__chip b {
    display: block;
    margin-top: 2px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.2px;
    color: var(--ll-white);
}

/* Rating pairs a filled star with its number. */
.ll-rating {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--ll-star);
}

.ll-rating .ll-icon {
    display: block;
}

/* Ticker ---------------------------------------------------------------- */

.ll-ticker {
    margin-top: 60px;
    padding: var(--ll-s5) 0;
    overflow: hidden;
    box-shadow: inset 0 1px 0 0 var(--ll-border-card), inset 0 -1px 0 0 var(--ll-border-card);
    /* Fade the marquee at both ends rather than cutting it off mid-word. */
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.ll-ticker__track {
    display: flex;
    align-items: center;
    width: max-content;
    /*
     * The row is printed twice and translated by half the track's width, so
     * the loop lands exactly on the duplicate.
     *
     * The spacing between items is each item's own margin, NOT a flex gap:
     * with `gap`, two passes of N items share 2N-1 gaps â€” an odd number â€” so
     * -50% lands half a gap short of the seam and the marquee visibly jumped
     * sideways on every loop. With the margin carried inside each item, half
     * the track is exactly one pass and the loop is seamless.
     */
    /*
     * The duration comes from the template, which sets it from how many items
     * a half holds — that count varies with the number of lenders in the feed,
     * and a fixed duration would make the marquee slow with few and fast with
     * many. 46s is the fallback, the figure this was written at.
     */
    animation: ll-ticker var(--ll-ticker-dur, 46s) linear infinite;
    will-change: transform;
}

.ll-ticker:hover .ll-ticker__track {
    animation-play-state: paused;
}

@keyframes ll-ticker {
    from {
        transform: translateX(0);
    }

    to {
        transform: translateX(-50%);
    }
}

.ll-ticker__item {
    display: inline-flex;
    align-items: center;
    gap: var(--ll-s3);
    flex-shrink: 0;
    /* The inter-item spacing â€” see the seam note on .ll-ticker__track. */
    margin-right: var(--ll-s10);
    font-size: 14px;
    color: var(--ll-text-secondary);
}

.ll-ticker__item b {
    color: var(--ll-white);
    font-weight: 600;
}

.ll-avatar {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--ll-red);
    font-size: 12px;
    font-weight: 700;
    color: var(--ll-white);
}

.ll-avatar--lg {
    width: 44px;
    height: 44px;
    font-size: 16px;
}

/* Lender cards ---------------------------------------------------------- */

.ll-lender {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s5);
    padding: var(--ll-s6);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

.ll-lender__rank {
    position: absolute;
    top: var(--ll-s6);
    right: var(--ll-s6);
    font-size: 13px;
    font-weight: 700;
    color: var(--ll-red);
}

.ll-lender__top {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: var(--ll-s4);
    align-items: start;
}

.ll-lender__name {
    margin: 0 0 2px;
    font-size: var(--ll-fs-h4);
    font-weight: 600;
    color: var(--ll-white);
}

.ll-lender__rate {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--ll-text-secondary);
}

.ll-lender__meta {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ll-s3);
    margin: 0;
    padding: var(--ll-s4) 0;
    box-shadow: inset 0 1px 0 0 var(--ll-border-card), inset 0 -1px 0 0 var(--ll-border-card);
    text-align: center;
}

.ll-lender__meta dd {
    margin: 0;
    font-size: 18px;
    font-weight: 700;
    color: var(--ll-white);
}

.ll-lender__meta dt {
    font-size: 11px;
    color: var(--ll-text-secondary);
}

.ll-lender__thumbs {
    display: flex;
    align-items: center;
    gap: var(--ll-s2);
}

.ll-lender__thumb {
    width: 46px;
    height: 46px;
    flex-shrink: 0;
    border-radius: var(--ll-r-panel);
    background-color: var(--ll-white);
    overflow: hidden;
}

.ll-lender__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-lender__more {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    flex-shrink: 0;
    border-radius: var(--ll-r-panel);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-size: 12px;
    color: var(--ll-text-secondary);
}

.ll-lender__shop {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /*
     * Reset, because this is a <button> on the category pages: listing happens
     * in the app, so "Be the first to list" opens the app dialog rather than
     * navigating. Without these it arrived with the browser's own button chrome
     * — a white box around a red link.
     */
    align-self: flex-start;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    margin-top: auto;
    font-family: var(--ll-font);
    font-size: 14px;
    font-weight: 600;
    color: var(--ll-red);
    transition: color 0.25s ease;
}

.ll-lender__shop:hover {
    color: var(--ll-white);
}

/* Reasons --------------------------------------------------------------- */

/*
 * Why Lenders Stay.
 *
 * A step up on every axis from the reference's own figures — a roomier card, a
 * larger plate and both type roles one step higher — because four short cards
 * in a row read as captions at the reference's size and this section is the
 * page's argument for lending.
 */
.ll-reason {
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr);
    gap: var(--ll-s5);
    align-items: start;
    padding: var(--ll-s7);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

.ll-reason__icon {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: var(--ll-r-panel);
    background-color: rgba(237, 28, 36, 0.12);
    color: var(--ll-red);
}

/* Title and its line of copy share the second column. */
.ll-reason__body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.ll-reason .ll-page__h4 {
    font-size: var(--ll-fs-h4);
    font-weight: 700;
    line-height: 1.25;
}

.ll-reason .ll-meta {
    font-size: var(--ll-fs-meta);
    line-height: 1.5;
}

/* Steps ----------------------------------------------------------------- */

.ll-steps__tabs {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--ll-s3);
    margin-bottom: var(--ll-s9);
}

.ll-steps__tab {
    padding: 11px 24px;
    border: 0;
    border-radius: var(--ll-r-pill);
    background-color: var(--ll-surface-inset);
    font-size: 15px;
    font-weight: 500;
    color: var(--ll-text-secondary);
    cursor: pointer;
    transition: background-color 0.3s ease, color 0.3s ease;
}

.ll-steps__tab:hover {
    color: var(--ll-white);
}

.ll-steps__tab.is-active {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

/*
 * A scroll-snapped row. It is the same element on every screen: tabs scroll it
 * on desktop, a thumb swipes it on a phone, and the active card is whichever one
 * is snapped -- which is why the script listens to scroll as well as to clicks.
 */
.ll-steps__track {
    display: flex;
    /* The reference's own gap; the card width below subtracts half of it. */
    gap: 44px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding-bottom: var(--ll-s3);
}

.ll-steps__track::-webkit-scrollbar {
    display: none;
}

/*
 * The reference's step card (.fcard in lend.css): a 800x425 frame at 70.5% of
 * the track, so the next card shows at the edge and the row reads as a deck.
 * The shot and the copy are placed inside it rather than laid out in a grid —
 * left 4.5% / top 7% / width 40% for the phone, left 50% to right 4.5% for the
 * words — which is what gives the card its overlap and its air.
 *
 * These are the reference's *second* set of figures. lend.css states the step
 * card twice: an early 800/425 frame with a 31.5% phone, and then, further
 * down and unconditionally, "step cards: shorter frame, larger phone, tighter
 * type rhythm" — 960/400 with a 40% phone. The later block wins in the
 * reference and is what its screenshots show, so it is what is written here.
 *
 * The width is also what makes the slide smooth: one step is ~70% of the track
 * instead of all of it. See travel() in js/local-locker-inner.js.
 */
.ll-steps__card {
    position: relative;
    flex: 0 0 calc(70.5% - 22px);
    aspect-ratio: 960 / 400;
    overflow: hidden;
    scroll-snap-align: center;
    border-radius: var(--ll-r-promo);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    opacity: 0.6;
    cursor: pointer;
    transition: opacity 0.4s ease, box-shadow 0.4s ease;
}

.ll-steps__card.is-active {
    opacity: 1;
    box-shadow: var(--ll-hairline-accent), 0 26px 70px rgba(237, 28, 36, 0.28);
}

.ll-steps__shot {
    position: absolute;
    left: 4.5%;
    top: 7%;
    /*
     * Narrow enough that the portrait snapshot (813/942) never outgrows the
     * card's height at this aspect-ratio and top offset — a wider figure
     * pushes the image past the card's bottom edge, painting over the
     * inset-shadow "border" there.
     */
    width: 33%;
    pointer-events: none;
}

.ll-steps__shot img {
    display: block;
    width: 100%;
    height: auto;
    /* Paired with the width/height attributes, so the box is the right shape
       before the file arrives rather than collapsing and never loading. */
    aspect-ratio: 813 / 942;
    border-radius: var(--ll-r-card);
}

/*
 * The words: pill, heading, copy. Spaced by their own margins rather than one
 * gap, because the reference's rhythm is not even — 16px above the heading,
 * 12px below it.
 */
.ll-steps__body {
    position: absolute;
    left: 50%;
    right: 4.5%;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
}

/*
 * The reference's own step heading: capped at 30px rather than the full
 * section size, because the shorter frame has less room above and below it.
 */
.ll-steps__h {
    margin: var(--ll-s5) 0 var(--ll-s4);
    font-size: clamp(21px, 1.75vw, 30px);
}

/* And its copy: the meta size, 1.55 leading, with the bold clause in white. */
.ll-steps__body p {
    margin: 0;
    max-width: 40ch;
    line-height: 1.55;
}

.ll-steps__body p strong {
    color: var(--ll-white);
    font-weight: 500;
}

/*
 * "Listings are created in the app" — the reference's .note (lend.css): a
 * red-veiled panel inside a red hairline, not the grey inset one this was. Its
 * own figures throughout: 20px above it, 16px between icon and copy, a 16px
 * card radius, 20/24 of padding, and the copy at the meta step rather than a
 * caption, because the note is the section's last word and not a footnote.
 */
.ll-note {
    display: flex;
    align-items: flex-start;
    gap: var(--ll-s5);
    margin-top: var(--ll-s6);
    padding: var(--ll-s6) var(--ll-s7);
    border-radius: var(--ll-r-card);
    background-color: rgba(237, 28, 36, 0.1);
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

.ll-note svg {
    flex: 0 0 auto;
    /* Optically on the first line of copy beside it. */
    margin-top: 2px;
}

.ll-note p {
    margin: 0;
    font-size: 16px;
    line-height: 1.55;
    color: var(--ll-text-muted);
}

.ll-note strong {
    font-weight: 500;
    color: var(--ll-white);
}

/* CTA strip ------------------------------------------------------------- */

.ll-strip {
    position: relative;
    padding: var(--ll-band-pad) 0;
    overflow: hidden;
    box-shadow: inset 0 1px 0 0 var(--ll-border-card), inset 0 -1px 0 0 var(--ll-border-card);
}

.ll-strip__glow,
.ll-final__glow {
    position: absolute;
    left: 20%;
    top: 50%;
    width: 70%;
    height: 260%;
    transform: translate(-50%, -50%);
    background: var(--ll-glow-red);
    opacity: 0.28;
    pointer-events: none;
}

.ll-strip__inner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ll-s10);
}

/* Worries --------------------------------------------------------------- */

/*
 * The reference's worry card (.tobc in lend.css): the number is a small plate
 * beside the question rather than a big numeral above it, and each answer is
 * marked with a glowing red dot rather than a tick. Card padding is the
 * reference's space-6, and the question sits on the meta step.
 */
.ll-worry {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s5);
    padding: var(--ll-s6);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    transition: box-shadow 0.3s ease;
}

/*
 * The card's hairline goes red on hover â€” the same feedback every other card
 * on this page gives (.ll-gcard, .ll-prod, .ll-lender), through the same
 * --ll-hairline-accent token, so it reads as one system rather than a
 * treatment invented for this section. :focus-within covers keyboard arrival.
 */
.ll-worry:hover,
.ll-worry:focus-within {
    box-shadow: var(--ll-hairline-accent);
}

.ll-worry__q {
    display: flex;
    align-items: center;
    gap: var(--ll-s3);
    margin: 0;
    font-size: var(--ll-fs-meta);
    font-weight: 600;
    line-height: 1.3;
    color: var(--ll-white);
}

/* The number, on the reference's 24px accent plate. */
.ll-worry__q i {
    display: grid;
    place-items: center;
    flex: none;
    width: 24px;
    height: 24px;
    border-radius: var(--ll-r-panel);
    background-color: rgba(237, 28, 36, 0.12);
    box-shadow: var(--ll-hairline-accent);
    font-style: normal;
    font-size: var(--ll-fs-small);
    font-weight: 600;
    line-height: 1;
    color: var(--ll-red);
}

.ll-worry__list {
    display: grid;
    gap: var(--ll-s3);
    margin: 0;
    padding: 0;
}

.ll-worry__list li {
    position: relative;
    padding-left: var(--ll-s5);
    font-size: var(--ll-fs-small);
    line-height: 1.5;
    color: var(--ll-text-muted);
}

.ll-worry__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    width: 6px;
    height: 6px;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-red);
    box-shadow: 0 0 8px rgba(237, 28, 36, 0.45);
}

/* Final CTA ------------------------------------------------------------- */

/*
 * Questions Lenders Ask.
 *
 * The rows are the home page's .ll-faq__item — the same component the
 * reference uses — but the reference sits them in a 820px column
 * (.faqwrap in lend.css) rather than across the whole rail, which is what made
 * the boxes read as too wide next to the design.
 */
.ll-page--lend .ll-faq__list {
    /*
     * The measure only — the base rule's own `max-width: 100%` and auto margins
     * do the rest. Setting max-width here instead left the element's declared
     * `width: 1320px` in play, so it resolved to a flat 820px and pushed a
     * 390px screen 540px sideways.
     */
    width: 820px;
}

/*
 * The hairline the reference draws between its lower sections: at the top of
 * the FAQ block, and again at the top of the closing CTA (.final in lend.css
 * carries inset 0 1px 0 0 var(--border-card)). Sections here carry top padding
 * only, so the line lands in the gap between two sections rather than tight
 * against a heading.
 */
.ll-page--lend .ll-faq,
/*
 * No rule above the closing CTA. It used to carry a hairline across the top,
 * which drew a line between the lender questions and this block — the section
 * already reads as its own on the strength of its glow and its artwork, and the
 * line was the only thing between them that the design does not have.
 *
 * The hairline the lend page does keep is the one above the questions
 * themselves, further up.
 */
.ll-final {
    position: relative;
    padding: var(--ll-sec-pad) 0 0;
    overflow: hidden;
}

.ll-final__inner {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--ll-gap-split);
    align-items: center;
}

.ll-final__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s6);
}

.ll-final__art {
    position: relative;
}

.ll-final__glow {
    left: 58%;
    width: 92%;
    height: 58%;
}

.ll-final__art {
    display: flex;
    align-items: center;
    justify-content: center;
    /* The reference's slot: the artwork is fitted into this, never stretched. */
    height: clamp(360px, 36vw, 520px);
    min-height: 0;
    overflow: visible;
}

.ll-final__art img {
    position: relative;
    display: block;
    /*
     * scale-down inside the fixed slot, exactly as the reference presents it
     * (.final-art img.final-ph in lend.css). The artwork keeps its intrinsic
     * proportions and is only ever shrunk â€” stretching it to the column width
     * is what made the phones read as blurred.
     */
    width: auto;
    max-width: 100%;
    height: 100%;
    object-fit: scale-down;
    object-position: center;
    margin: 0 auto;
    filter: drop-shadow(0 24px 50px rgba(0, 0, 0, 0.5));
}

.ll-store {
    display: flex;
    align-items: center;
    gap: var(--ll-s4);
    flex-wrap: wrap;
}

.ll-store__btn img {
    display: block;
    height: 46px;
    width: auto;
}

/* App dialog ------------------------------------------------------------ */

.ll-modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: grid;
    place-items: center;
    padding: var(--ll-s6);
    background-color: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(6px);
}

.ll-modal[hidden] {
    display: none;
}

.ll-modal__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    /* Centred, as the reference's app modal is (.modal in lend.css). */
    align-items: center;
    text-align: center;
    gap: var(--ll-s5);
    width: 100%;
    max-width: 500px;
    padding: var(--ll-s10);
    border-radius: var(--ll-r-promo);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

.ll-modal__panel .ll-store {
    justify-content: center;
}

/*
 * The dialog is printed by footer.php, outside .ll-page and outside any home
 * section, so nothing overrides the parent theme's `h1..h6 { font-family:
 * 'Proxima Nova Lt' }` for its heading — a font that never loads, which left
 * "Get the app to start lending" in the browser's serif. Set it here instead.
 */
.ll-modal__panel,
.ll-modal__panel h2,
.ll-modal__panel button {
    font-family: var(--ll-font);
}

.ll-modal__panel .ll-modal__qr {
    margin-top: var(--ll-s2);
    margin-bottom: 0;
}

.ll-modal__close {
    position: absolute;
    top: var(--ll-s5);
    right: var(--ll-s5);
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 50%;
    background-color: var(--ll-surface-inset);
    color: var(--ll-white);
    cursor: pointer;
}

.ll-modal__close:hover {
    background-color: var(--ll-red);
}

/* A dialog's own sentence — the panel's gap spaces it, not .ll-meta's margin. */
.ll-modal__text {
    margin: 0 0 var(--ll-s2);
    max-width: 380px;
}

/*
 * A dialog locks the page's scroll (body overflow: hidden), which used to take
 * the scrollbar away and slide the whole page sideways by its width — twice,
 * when one dialog replaced another. Reserving the scrollbar's gutter keeps the
 * page exactly where it is.
 */
html {
    scrollbar-gutter: stable;
}

/* Anything a dialog switches off stays off, whatever its own display is. */
.ll-modal [hidden] {
    display: none;
}

/*
 * One dialog, changing its content in place (the location pop-up): the panel
 * eases from its old height to its new one while the new content fades in,
 * instead of snapping between sizes.
 */
.ll-modal__panel.is-resizing {
    overflow: hidden;
    transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.ll-modal__panel.is-swapped > :not(.ll-modal__close) {
    animation: ll-modal-swap 0.22s ease both;
}

@keyframes ll-modal-swap {
    from {
        opacity: 0;
        transform: translateY(4px);
    }

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

@media (prefers-reduced-motion: reduce) {
    .ll-modal__panel.is-resizing {
        transition: none;
    }

    .ll-modal__panel.is-swapped > * {
        animation: none;
    }
}

/* =========================================================================
   LISTING PAGES (category + city) and the map
   ========================================================================= */

/* Stats and switcher ---------------------------------------------------- */

.ll-cityhead {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ll-s10);
    padding-top: var(--ll-s9);
}

.ll-stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ll-s10);
    margin: 0;
}

.ll-stats dd {
    margin: 0;
    font-size: var(--ll-fs-h2);
    font-weight: 700;
    line-height: 1.1;
    color: var(--ll-white);
}

.ll-stats dt {
    margin-top: 4px;
    font-size: 13px;
    color: var(--ll-text-secondary);
}

.ll-cityswitch {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s3);
}

.ll-cityswitch__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ll-s2);
}

.ll-chip.is-active {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

.ll-chip:hover {
    color: var(--ll-white);
}

.ll-catpick {
    display: flex;
    align-items: center;
    gap: var(--ll-s3);
}

.ll-catpick select {
    height: 44px;
    min-width: 220px;
    padding: 0 var(--ll-s5);
    border: 1px solid var(--ll-border-rule);
    border-radius: var(--ll-r-full);
    background-color: transparent;
    font-size: 15px;
    color: var(--ll-white);
}

/* Results head and filters ---------------------------------------------- */

/*
 * The results block carries no section padding of its own: the rule at the top
 * of its head is the divider between the page head and the grid, which is where
 * the reference puts it (.results{padding-top:0} and .rhead{padding-top:28px;
 * box-shadow:inset 0 1px 0 0 …} in listing.css). It used to sit under the count
 * row instead, which read as an underline on the count rather than a break
 * between the two halves of the page.
 */
.ll-section--tight.ll-results {
    padding-top: 0;
    /*
     * The reference's own gap between the page head and this block: its
     * .results computes to margin-top 80px with no padding, which is the air
     * under the heading that was missing here — the divider sat straight
     * against the h1.
     */
    margin-top: var(--ll-s15);
}

.ll-results__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ll-s6);
    margin-bottom: var(--ll-s10);
    padding-top: var(--ll-s8);
    box-shadow: inset 0 1px 0 0 var(--ll-border-card);
    /*
     * A stacking context above the map. .leaflet-container is positioned but
     * carries no z-index, so its panes — markers at 600, popups at 700 — sit in
     * this same context and a pin was painting over the filter panel below the
     * toolbar: with the Map pane open, the price chips could be seen but not
     * clicked, because the "$40" pin label was taking the pointer.
     */
    position: relative;
    z-index: 800;
}

.ll-results__count strong {
    font-size: 20px;
    color: var(--ll-white);
}

/* The reference's .fright: the controls sit together at the end of the row. */
.ll-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ll-s3);
    margin-left: auto;
}

/*
 * Native option lists inherit the page's dark ground on some platforms and the
 * system's white on others, which left white-on-white text. Set both.
 */
.ll-catpick select option {
    background-color: #111111;
    color: #ffffff;
}

/* Filter pills and the filter panel ------------------------------------- */

/*
 * One pill opens one panel holding every filter, which is how the reference's
 * toolbar works (LLFiltersPill in ui_kits/shared/FilterBar.jsx, .fdw/.fdpanel
 * in city-houston/listing.css). Both pills below — Filters and the sort — are
 * the same component, so they read as one pair of controls.
 */
.ll-fpill {
    display: inline-flex;
    align-items: center;
    gap: var(--ll-s2);
    padding: var(--ll-s3) var(--ll-s5);
    border: 0;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--ll-text-muted);
    white-space: nowrap;
    cursor: pointer;
    transition: box-shadow 0.25s ease, color 0.25s ease;
}

.ll-fpill:hover,
.ll-fpill[aria-expanded="true"] {
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

/* Filters set: the reference turns the pill itself accent. */
.ll-fpill.is-on {
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

.ll-fpill__chev {
    display: flex;
    /* Optically centred against the cap height of the label beside it. */
    margin-top: 1px;
}

.ll-fdcount {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-red);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    color: var(--ll-white);
}

.ll-fdw {
    position: relative;
}

.ll-fdpanel {
    position: absolute;
    right: 0;
    top: calc(100% + var(--ll-s3));
    z-index: 40;
    width: 340px;
    max-width: calc(100vw - 2 * var(--ll-container-pad, 20px));
    /* A tall panel scrolls inside itself rather than off the viewport. */
    max-height: 80vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s6);
    padding: var(--ll-s6);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card), 0 18px 44px rgba(0, 0, 0, 0.55);
}

.ll-fdpanel--sort {
    width: 240px;
}

.ll-fdgroup {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s3);
    padding-bottom: var(--ll-s5);
    box-shadow: inset 0 -1px 0 0 var(--ll-border-rule);
}

.ll-fdgroup:last-of-type {
    padding-bottom: 0;
    box-shadow: none;
}

.ll-ffh {
    font-size: 14px;
    font-weight: 600;
    color: var(--ll-white);
}

/* Distance ------------------------------------------------------------- */

.ll-ffmi {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s3);
}

.ll-ffmi input[type="range"] {
    width: 100%;
    min-width: 0;
    accent-color: var(--ll-red);
}

.ll-ffmi b {
    font-size: 16px;
    font-weight: 500;
    color: var(--ll-red);
}

/* Chip rows ------------------------------------------------------------ */

.ll-ffchips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ll-s2);
}

/* The sort options are one per line, so the current choice is scannable. */
.ll-ffchips--stack {
    flex-direction: column;
    align-items: stretch;
}

.ll-ffchips button {
    height: 30px;
    padding: 0 var(--ll-s4);
    border: 0;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--ll-text-secondary);
    white-space: nowrap;
    cursor: pointer;
    transition: box-shadow 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}

.ll-ffchips button:hover {
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-white);
}

.ll-ffchips button.is-on {
    background-color: var(--ll-red);
    box-shadow: none;
    color: var(--ll-white);
}

/* Min / max pairs ------------------------------------------------------ */

.ll-ffmm {
    display: flex;
    align-items: flex-end;
    gap: var(--ll-s3);
}

.ll-ffmm label {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
    /* Or a date input's intrinsic width pushes the pair past the panel. */
    min-width: 0;
}

.ll-ffmm em {
    padding-bottom: var(--ll-s4);
    font-style: normal;
    color: var(--ll-text-muted);
}

.ll-ffin {
    display: flex;
    align-items: center;
    gap: var(--ll-s2);
    height: 42px;
    padding: 0 var(--ll-s4);
    border-radius: var(--ll-r-panel);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
}

.ll-ffin i {
    font-style: normal;
    font-size: 16px;
    color: var(--ll-text-muted);
}

.ll-ffmm input {
    width: 100%;
    min-width: 0;
    height: 42px;
    padding: 0 var(--ll-s4);
    border: 0;
    border-radius: var(--ll-r-panel);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-family: inherit;
    font-size: 16px;
    color: var(--ll-white);
}

/* Inside the $ wrapper the field is bare — the wrapper is the box. */
.ll-ffin input {
    height: auto;
    padding: 0;
    background-color: transparent;
    box-shadow: none;
}

.ll-ffmm input:focus {
    outline: none;
    box-shadow: var(--ll-hairline-accent);
}

/* Or the platform paints a white calendar picker on a black field. */
.ll-ffmm input[type="date"] {
    color-scheme: dark;
}

.ll-ffnote {
    color: var(--ll-text-muted);
}

/* Rating --------------------------------------------------------------- */

.ll-ffstars {
    display: flex;
    align-items: center;
    gap: var(--ll-s2);
    flex-wrap: wrap;
}

.ll-ffstars button {
    padding: 0;
    border: 0;
    background-color: transparent;
    font-size: 22px;
    line-height: 1;
    color: var(--ll-border-rule);
    cursor: pointer;
    transition: color 0.25s ease;
}

.ll-ffstars button:hover,
.ll-ffstars button.is-on {
    color: var(--ll-red);
}

.ll-ffstars .ll-caption {
    margin-left: var(--ll-s2);
}

/* Panel footer --------------------------------------------------------- */

.ll-fdfoot {
    display: flex;
    align-items: center;
    /* Clear sits left, Show results right — and right alone when it is gone. */
    justify-content: space-between;
    gap: var(--ll-s3);
}

.ll-fdfoot .ll-ffclear[hidden] + .ll-fdapply {
    margin-left: auto;
}

.ll-ffclear {
    padding: 0 var(--ll-s2);
    border: 0;
    background-color: transparent;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--ll-red);
    cursor: pointer;
}

.ll-ffclear:hover {
    color: var(--ll-white);
}

.ll-fdapply {
    height: 42px;
    padding: 0 var(--ll-s5);
    border: 0;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-red);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--ll-white);
    cursor: pointer;
    transition: box-shadow 0.25s ease;
}

/*
 * No glow on hover. Every pill button on the site dropped its red shadow; a
 * filter's Apply is one of them.
 */

/* Sits in the toolbar beside the filters. */
/*
 * Grid/Map segmented control. Lives in the results toolbar and in the browse
 * page's section heading; both put it at the end of their row.
 */
.ll-seg {
    display: inline-flex;
    gap: var(--ll-s1);
    flex-shrink: 0;
    margin-left: auto;
    padding: 4px;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
}

.ll-seg__btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: var(--ll-s1) var(--ll-s6);
    border: 0;
    border-radius: var(--ll-r-full);
    background: none;
    font-family: var(--ll-font);
    font-size: var(--ll-fs-meta);
    font-weight: 500;
    color: var(--ll-text-secondary);
    cursor: pointer;
    transition: background-color 0.25s ease, color 0.25s ease;
}

.ll-seg__btn:hover {
    color: var(--ll-white);
}

.ll-seg__btn.is-on {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

/*
 * "Use my current location" — the reference's .geo pill, opposite the cities
 * heading. Same inset surface and hairline as the Grid/Map switch beside the
 * next heading down, reddening on hover the way the reference draws it.
 */
/*
 * The pill and the status line under it. The wrapper holds the pill's place in
 * the heading row, so a message can appear without moving the heading.
 */
.ll-geo-wrap {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--ll-s2);
    flex-shrink: 0;
    align-self: center;
    max-width: 380px;
    margin-left: auto;
}

.ll-geo__status {
    margin: 0;
    font-size: var(--ll-fs-small);
    line-height: 1.45;
    text-align: right;
    color: var(--ll-text-muted);
}

.ll-geo__status[hidden] {
    display: none;
}

.ll-geo {
    display: inline-flex;
    align-items: center;
    gap: var(--ll-s3);
    min-height: 40px;
    padding: var(--ll-s4) var(--ll-s6);
    border: 0;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-family: var(--ll-font);
    font-size: var(--ll-fs-meta);
    font-weight: 500;
    color: var(--ll-white);
    cursor: pointer;
    transition: box-shadow 0.25s ease, color 0.25s ease;
}

.ll-geo[hidden] {
    display: none;
}

.ll-geo:hover,
.ll-geo:focus-visible {
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

.ll-geo.is-busy {
    cursor: progress;
    opacity: 0.7;
}

.ll-geo.is-error {
    box-shadow: var(--ll-hairline-accent);
    color: var(--ll-red);
}

/*
 * In the results toolbar the switch is the third item in a row that is already
 * pushed right (.ll-filters), so it takes its place from the row's gap. Its own
 * auto margin belongs to the browse page's section heading, where it is alone
 * on the right of a title.
 */
.ll-filters .ll-seg {
    margin-left: 0;
}

/* Grid, empty state ---------------------------------------------------- */

.ll-results__grid {
    gap: var(--ll-s6);
}

.ll-prod__city {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: var(--ll-r-pill);
    background-color: rgba(255, 255, 255, 0.07);
    font-size: 12px;
    color: var(--ll-text-muted);
}

.ll-prod__trust {
    flex-shrink: 0;
}

.ll-results__empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s4);
    padding: var(--ll-s12) var(--ll-s9);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

.ll-results__empty[hidden] {
    display: none;
}

.ll-results__empty-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ll-s4);
    margin-top: var(--ll-s3);
}

.ll-waiting {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s3);
}

/* Owner band ----------------------------------------------------------- */

.ll-owner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--ll-gap-split);
    align-items: center;
}

.ll-owner__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s6);
}

.ll-owner__art {
    aspect-ratio: 3 / 2;
}



/* =========================================================================
   BROWSE GEAR
   ========================================================================= */

/* Trust marks under the search bar. */
.ll-trustrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ll-s6);
    margin-top: var(--ll-s10);
    padding: var(--ll-s6) 0;
    box-shadow: inset 0 1px 0 0 var(--ll-border-card), inset 0 -1px 0 0 var(--ll-border-card);
}

.ll-trustrow__item {
    display: flex;
    align-items: center;
    gap: var(--ll-s4);
}

.ll-trustrow__icon img {
    display: block;
    width: 34px;
    height: 34px;
    object-fit: contain;
}

.ll-trustrow__label {
    font-size: var(--ll-fs-body);
    font-weight: 600;
    color: var(--ll-text-secondary);
}

/* Photo tiles (cities and categories) ----------------------------------- */

/*
 * One tile pattern for both grids: a photograph, a scrim strong enough to carry
 * white type over any of the supplied images, and the label sitting on it.
 */
.ll-tile {
    position: relative;
    display: block;
    /*
     * The reference's city tiles are 421x200 and its category tiles 419x210 â€”
     * wide letterbox plates, not the 4/3 portraits these were, which made the
     * grids roughly twice as tall as the design and pushed everything below
     * them off the screen.
     */
    aspect-ratio: 21 / 10;
    border-radius: var(--ll-r-card);
    overflow: hidden;
    color: inherit;
    box-shadow: var(--ll-hairline-card);
}

.ll-tile__shot {
    position: absolute;
    inset: 0;
    display: block;
    background-color: var(--ll-surface-inset);
}

.ll-tile__shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s ease;
}

.ll-tile:hover .ll-tile__shot img {
    transform: scale(1.06);
}

/* The scrim is a pseudo-element so it sits over the photo but under the text. */
.ll-tile::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 35%, rgba(0, 0, 0, 0.88) 100%);
    transition: background 0.4s ease;
}

.ll-tile:hover::after {
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 25%, rgba(237, 28, 36, 0.75) 100%);
}

.ll-tile__body {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: var(--ll-s6);
}

/* .ll-category__label on the home page: 24px/30 at weight 700. */
.ll-tile__name {
    font-size: var(--ll-fs-h3);
    font-weight: 700;
    line-height: 1.25;
    color: var(--ll-white);
}

.ll-tile__meta {
    font-size: 15px;
    color: rgba(255, 255, 255, 0.8);
}

.ll-tile__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: var(--ll-s3);
}

.ll-tile__chips .ll-chip {
    background-color: rgba(0, 0, 0, 0.45);
    font-size: 12px;
}

.ll-tile__chips .ll-chip b {
    color: var(--ll-white);
}

.ll-tile--cat {
    aspect-ratio: 2 / 1;
}

/*
 * Cities section only — the reference's later pass on this same card
 * (browse.css: "city cards: taller card, caption below the image")
 * replaces the photo-with-scrim-overlay pattern above with a photograph on
 * top and the caption in a solid card body below it, the same shape as a
 * product card. Scoped to #cities so category tiles (.ll-tile--cat), which
 * the reference does not touch here, keep the overlay treatment.
 */
#cities .ll-tile {
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    background-color: var(--ll-surface-raised);
}

#cities .ll-tile:hover {
    box-shadow: var(--ll-hairline-accent);
}

#cities .ll-tile__shot {
    position: relative;
    inset: auto;
    height: 200px;
    flex: none;
    overflow: hidden;
}

/* The scrim belonged to the overlaid caption — no longer needed. */
#cities .ll-tile::after,
#cities .ll-tile:hover::after {
    display: none;
}

#cities .ll-tile__body {
    position: static;
    inset: auto;
    padding: var(--ll-s6) var(--ll-s7) var(--ll-s7);
    gap: var(--ll-s2);
}

@media (max-width: 760px) {
    #cities .ll-tile__shot {
        height: 180px;
    }
}

.ll-cats__more {
    display: flex;
    justify-content: center;
    margin-top: var(--ll-s9);
}

/* Its own half of the same line: the shield and "ID verified" never split. */
.ll-prod__verified {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    flex-shrink: 0;
    white-space: nowrap;
    font-size: var(--ll-fs-small);
    font-weight: 500;
    color: var(--ll-good);
}

/* Unmet demand ---------------------------------------------------------- */

/*
 * The demand board, as the reference draws it (.dcard / .dcard-th / .dcard-bx
 * / .dcard-gap / .dcard-ac in browse.css): a square thumbnail beside a column
 * carrying the name, the count, the gap mark and the action.
 */
.ll-demand {
    display: flex;
    align-items: flex-start;
    gap: var(--ll-s5);
    padding: var(--ll-s6);
}

/*
 * No thumbnail: the reference's markup renders the card as a name, a caption,
 * the gap mark and the pill, and nothing else. Its stylesheet still carries a
 * .dcard-th rule from an earlier draft, which is what led me to paint one here
 * — and with no photograph to put in it the box showed the grey placeholder.
 */

.ll-demand__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
}

.ll-demand__gap {
    /* The reference's gap mark is a plain accent line, not a pill. */
    font-size: var(--ll-fs-small);
    font-weight: 500;
    color: var(--ll-red);
}

.ll-demand__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ll-s2);
    margin-top: var(--ll-s4);
}

/* Request block --------------------------------------------------------- */

.ll-request {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--ll-gap-split);
    align-items: start;
}

.ll-request__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s6);
}

.ll-request__marks {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s4);
    margin: 0;
    padding: 0;
}

.ll-request__marks li {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr);
    gap: var(--ll-s3);
    font-size: 15px;
    line-height: 1.45;
    color: var(--ll-text-muted);
}

.ll-request__marks .ll-icon {
    margin-top: 3px;
    color: var(--ll-red);
}

/*
 * The browse page's search bar sits on the page rather than over the hero
 * artwork it does on the home page, so it needs its own top margin. Everything
 * else about it â€” fields, heights, the picker â€” is the home page's.
 */
.ll-page--browse .ll-search {
    margin-top: var(--ll-s10);
}

/* =========================================================================
   INNER PAGES â€” alignment corrections
   Everything below closes a gap found by measuring the reference UI kit and
   the home page side by side against the implementation.
   ========================================================================= */

/*
 * The search bar spans the content rail on the browse page. On the home page it
 * is centred under the hero and carries its own narrower measure, which left it
 * visibly narrower than every grid beneath it here â€” the section edges did not
 * line up down the page.
 */
.ll-browse__search .ll-search {
    max-width: none;
    width: 100%;
}

/* "View product", as the reference's recent-rental cards carry. */
.ll-prod__view {
    align-self: stretch;
    justify-content: center;
    height: 40px;
    margin-top: var(--ll-s3);
    box-shadow: none;
    font-size: var(--ll-fs-small);
}

/*
 * The card is a link in all but name, so the action inside it must not look
 * independently clickable â€” it lights with the card. Brand red on hover, as
 * the reference's .pc-view:hover paints it, not white.
 */
.ll-prod:hover .ll-prod__view,
.ll-prod__view:hover {
    background-color: var(--ll-red);
    box-shadow: none;
    color: var(--ll-white);
}

/*
 * Compact "tell us what you need" band, between recent rentals and demand.
 *
 * Geometry straight off the reference (.rstrip / .rstrip-row / .rstrip-f in
 * browse-categories/browse.css): 28/30/24 of padding, a 5fr–7fr split 16px
 * apart, and the form capped at 520px and centred in its column.
 *
 * That cap is not cosmetic. The strip's red glow is an ellipse whose hot core
 * sits 180px in from the right edge, and in the reference the Request button
 * covers it — the button is opaque, so only the soft falloff is ever seen. Our
 * form used to stretch the whole column and pushed the button 105px further
 * right, off the core, which let the brightest part of the glow spill out
 * beside the button: measured 67/255 red 30px to its left against the
 * reference's 17. Hence "bohat ziada glow". The glow itself is untouched.
 */
.ll-askstrip {
    position: relative;
    display: grid;
    grid-template-columns: 5fr 7fr;
    gap: var(--ll-s5);
    align-items: center;
    padding: var(--ll-s8) var(--ll-s9) var(--ll-s7);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    overflow: hidden;
}

.ll-askstrip__glow {
    position: absolute;
    right: -80px;
    top: -90px;
    width: 520px;
    height: 340px;
    background: var(--ll-glow-red);
    opacity: 0.3;
    pointer-events: none;
}

.ll-askstrip__copy {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
}

.ll-askstrip__title {
    margin: 0;
    font-size: var(--ll-fs-h3);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.2px;
    color: var(--ll-white);
}

.ll-askstrip__form {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ll-s3);
    /* The reference's cap, centred in its column — see the note on .ll-askstrip. */
    width: 100%;
    max-width: 520px;
    margin-inline: auto;
}

/*
 * The field matches the button rather than the button matching the field.
 * Both were 46px here, which made this the only 46px button on the site; the
 * pair is now the standard 50px, so the row still lines up and the button is
 * the same button it is everywhere else.
 */
.ll-askstrip__form .ll-input {
    flex: 1 1 auto;
    min-width: 0;
    height: 50px;
}

.ll-askstrip__form .ll-btn {
    flex-shrink: 0;
}

/*
 * Demand cards carry the same button as everywhere else. They used to shrink
 * it to 40px and drop it a type size, which is how the site ended up with four
 * button heights on three pages.
 */

/* Load More, centred under the grid with its count beneath. */
.ll-results__more {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ll-s4);
    margin-top: var(--ll-s10);
}

.ll-results__more[hidden] {
    display: none;
}

/*
 * The "ask for it" band.
 *
 * The reference draws this as a bordered card inside the content rail, not as a
 * full-bleed tinted strip: it sits between the results and the page's own
 * closing block, and a band running to the viewport edge there read as a
 * section break rather than as one more card in the column. Same for the owner
 * band below.
 */
/*
 * The band is a card inside a normal section now, so it keeps the section's own
 * top padding. `padding: 0` here was left from when it was a full-bleed strip
 * and it cancelled the rhythm â€” the card ended up flush against the grid above.
 */
.ll-band {
    position: relative;
    box-shadow: none;
}

.ll-band .ll-container {
    position: relative;
}

/*
 * The reference's own card (.band in city-houston/listing.css): two equal-ish
 * columns 30px apart inside 30px of padding, the pitch on the left and the
 * one-field form on the right. It was 40px of padding with an `auto` second
 * track sized to a caption, which left the form column too narrow for a field.
 */
.ll-band__card {
    position: relative;
    display: grid;
    grid-template-columns: minmax(240px, 1.1fr) minmax(240px, 1fr);
    gap: var(--ll-s9);
    align-items: center;
    padding: var(--ll-s9);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-accent);
    overflow: hidden;
}

.ll-band__copy {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
    min-width: 0;
}

.ll-band__title {
    margin: 0;
    font-size: var(--ll-fs-h3);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.2px;
    color: var(--ll-white);
}

/* The reference caps this line at 52ch so it breaks with the heading, not past it. */
.ll-band__copy .ll-caption {
    max-width: 52ch;
}

.ll-band__actions {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--ll-s3);
    min-width: 0;
}

/* Field and button on one line, wrapping to two when the column is narrow. */
.ll-band__form {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ll-s4);
}

.ll-band__input {
    /*
     * Basis 0, so the field takes whatever the button leaves and the two stay
     * on one line. On `auto` the field's own intrinsic width claimed the row
     * and pushed the button under it.
     */
    flex: 1 1 0;
    /* Under this the placeholder is unreadable, so it wraps to its own line. */
    min-width: 190px;
    height: 52px;
    padding: 0 var(--ll-s5);
    border: 0;
    border-radius: var(--ll-r-panel);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-family: inherit;
    font-size: 16px;
    color: var(--ll-white);
    /*
     * The reference's placeholder is longer than the field at every width
     * ("Name the item you need — e.g. pressure washer, flexible next weekend"),
     * so it is always cut off. Left to itself the cut lands wherever the width
     * happens to fall and reads as a typo — at 1440 it ended on a bare "n" of
     * "next". An ellipsis instead, so a cut always looks like a cut.
     */
    text-overflow: ellipsis;
}

.ll-band__input::placeholder {
    color: var(--ll-text-secondary);
    text-overflow: ellipsis;
}

.ll-band__input:focus {
    outline: none;
    box-shadow: var(--ll-hairline-accent);
}

.ll-band__go {
    flex: 0 0 auto;
    height: 52px;
}

.ll-band__sla {
    margin: 0;
}

/*
 * No glow behind the Request button. The reference's card is a flat surface
 * inside a red hairline and nothing more (.band in listing.css) — the red
 * bloom in the corner was mine, and it sat right behind the button.
 */

/*
 * The owner band, to the reference's own figures (.hob in city-houston's
 * listing.css): one card, copy and three numbers on the left, the photograph
 * filling the right 44% of it edge to edge.
 *
 * It used to be a 40px-padded card with the photo inset inside it at 16/10 —
 * so the picture floated in the middle of the card instead of being one half
 * of it. The padding belongs to the copy column, not to the card.
 */
.ll-owner {
    /* 1fr 44%, and both columns run the full height of the card. */
    grid-template-columns: 1fr 44%;
    gap: 0;
    align-items: stretch;
    padding: 0;
    /* --radius-promo, not the 16px card radius. */
    border-radius: var(--ll-r-promo);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    overflow: hidden;
}

.ll-owner__copy {
    gap: var(--ll-s7);
    padding: var(--ll-s10);
    justify-content: center;
}

/*
 * A card heading, not a section heading: the reference sets this one at its
 * category-label step (24px/30), which is our --ll-fs-h3 exactly. At the 40px
 * section size it was the largest thing on the page below the h1.
 */
.ll-owner .ll-page__h2 {
    max-width: 24ch;
    font-size: var(--ll-fs-h3);
    line-height: 1.25;
    text-wrap: pretty;
}

.ll-owner__copy > .ll-caption {
    max-width: 48ch;
    line-height: 1.5;
}

.ll-owner__art {
    position: relative;
    /* The photograph is the card's full height, not a fixed ratio inside it. */
    aspect-ratio: auto;
    min-height: 100%;
    border-radius: 0;
    overflow: hidden;
}

.ll-owner__art img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /*
     * Centred, not the reference's shade-below-centre crop. That figure suited
     * the city photograph this frame used to carry — a landscape shot with its
     * horizon high. It now carries the most-rented item's own photograph from
     * the feed, which is whatever a lender shot on their phone: often portrait,
     * with the item in the middle of the frame. Any offset crops the item
     * itself, so the item stays centred whatever shape arrives.
     */
    object-fit: cover;
    object-position: 50% 50%;
}

.ll-owner__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ll-s6);
    width: 100%;
    margin: 0;
    padding-top: var(--ll-s7);
    box-shadow: inset 0 1px 0 0 var(--ll-border-card);
}

/* A hairline between the figures, as the reference rules them. */
.ll-owner__stats > div {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s2);
    min-width: 0;
}

.ll-owner__stats > div + div {
    padding-left: var(--ll-s6);
    box-shadow: inset 1px 0 0 0 var(--ll-border-card);
}

/* The reference's price step for a figure — 20px bold, which is --ll-fs-h4. */
.ll-owner__stats dd {
    margin: 0;
    font-size: var(--ll-fs-h4);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.2px;
    /* A rate range is one figure: the en dash must not become a line break. */
    white-space: nowrap;
    color: var(--ll-white);
}

.ll-owner__stats dt {
    margin: 0;
    font-size: 14px;
    line-height: 1.35;
    color: var(--ll-text-secondary);
}

/* =========================================================================
   LEGAL PAGES (Terms & Conditions, Privacy Policy)

   Styled on element selectors inside .ll-legal__body, not on classes: the copy
   comes out of the editor as plain h2/h3/p/ul, so an author adding a section
   gets the same treatment without knowing any class names.

   Sizes are the same ramp as every other inner page â€” see the token block at
   the top of this file.
   ========================================================================= */

.ll-legal {
    display: grid;
    grid-template-columns: 280px minmax(0, 1fr);
    gap: var(--ll-gap-split);
    align-items: start;
}

/* Contents rail ---------------------------------------------------------- */

.ll-legal__toc {
    position: sticky;
    /* Clears the header, which is in the flow on inner pages. */
    top: var(--ll-s9);
    padding: var(--ll-s6);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
}

.ll-legal__toc-title {
    margin: 0 0 var(--ll-s4);
    font-size: var(--ll-fs-small);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ll-text-secondary);
}

/*
 * No counter here: the headings carry their own numbering ("1. Information We
 * Collect"), and adding one produced "1. 1. Information We Collect".
 */
.ll-legal__toc-list {
    display: flex;
    flex-direction: column;
    gap: var(--ll-s3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ll-legal__toc-list li {
    font-size: var(--ll-fs-small);
    line-height: 1.45;
}

.ll-legal__toc-list a {
    color: var(--ll-text-muted);
}

.ll-legal__toc-list a:hover {
    color: var(--ll-white);
}

/* Document body ---------------------------------------------------------- */

.ll-legal__body {
    /*
     * A measure, not the full column: legal prose is read start to finish and a
     * 1200px line is unreadable. ~78ch is the usual comfortable maximum.
     */
    max-width: 78ch;
    color: var(--ll-text-muted);
    font-size: var(--ll-fs-body);
    line-height: 1.7;
}

.ll-legal__body > *:first-child {
    margin-top: 0;
}

.ll-legal__body h2 {
    margin: var(--ll-s12) 0 var(--ll-s5);
    font-size: var(--ll-fs-h3);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.2px;
    color: var(--ll-white);
    /*
     * Anchored from the contents rail, so a jump has to clear the header rather
     * than tucking the heading under it.
     */
    scroll-margin-top: var(--ll-s10);
}

.ll-legal__body h3 {
    margin: var(--ll-s9) 0 var(--ll-s4);
    font-size: var(--ll-fs-h4);
    font-weight: 600;
    line-height: 1.35;
    color: var(--ll-white);
    scroll-margin-top: var(--ll-s10);
}

.ll-legal__body p {
    margin: 0 0 var(--ll-s6);
    color: inherit;
}

.ll-legal__body strong {
    color: var(--ll-white);
    font-weight: 600;
}

.ll-legal__body a {
    color: var(--ll-red);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.ll-legal__body a:hover {
    color: var(--ll-white);
}

.ll-legal__body ul,
.ll-legal__body ol {
    margin: 0 0 var(--ll-s6);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s3);
}

/*
 * The source marks bullets with a "â—" glyph in the text; those are stripped on
 * import and the marker is drawn here instead, so the list is a real list and
 * the glyph carries the brand colour.
 */
.ll-legal__body li {
    position: relative;
    padding-left: var(--ll-s7);
    list-style: none;
}

.ll-legal__body li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 0.62em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: var(--ll-red);
}

.ll-legal__body ol {
    counter-reset: ll-legal-ol;
}

.ll-legal__body ol > li {
    counter-increment: ll-legal-ol;
}

.ll-legal__body ol > li::before {
    content: counter(ll-legal-ol) ".";
    top: 0;
    left: 0;
    width: auto;
    height: auto;
    border-radius: 0;
    background: none;
    color: var(--ll-red);
    font-weight: 600;
}

/* The effective-date line, set apart from the prose that follows it. */
.ll-legal__body .ll-legal__effective {
    display: inline-flex;
    margin-bottom: var(--ll-s9);
    padding: 8px 18px;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-size: var(--ll-fs-small);
    color: var(--ll-text-muted);
}

/* A table, should a document ever carry one. */
.ll-legal__body table {
    width: 100%;
    margin: 0 0 var(--ll-s6);
    border-collapse: collapse;
    font-size: var(--ll-fs-meta);
}

.ll-legal__body th,
.ll-legal__body td {
    padding: var(--ll-s4);
    text-align: left;
    box-shadow: inset 0 -1px 0 0 var(--ll-border-card);
}

.ll-legal__body th {
    color: var(--ll-white);
    font-weight: 600;
}
/* =========================================================================
   MAP VIEW
   Two panes in one card: a listings rail and the map. Ported from the design's
   .mv* rules onto this theme's tokens.

   The map is Leaflet with no tile layer â€” a bundled vector outline of the
   contiguous United States drawn flat, which is what the design shows. A raster
   basemap cannot be made to look like this, however it is filtered.
   ========================================================================= */

/* The chip row and the card hide together when the grid is showing. */
[data-ll-map][data-pane="list"] .ll-mv,
[data-ll-map][data-pane="list"] .ll-mv__cats {
    display: none;
}

/* ...and the grid hides when the map is. */
[data-ll-map][data-pane="map"] ~ .ll-results__grid,
[data-ll-map][data-pane="map"] ~ .ll-results__empty,
[data-ll-map][data-pane="map"] ~ .ll-results__more,
[data-ll-map][data-pane="map"] ~ .ll-cats,
[data-ll-map][data-pane="map"] ~ .ll-cats__more {
    display: none;
}

/*
 * Browse Gear's Categories section is the case the sibling rules above cannot
 * reach: the map and the tiles arrive as two separate AJAX sections, each in
 * its own .ll-async wrapper, so the tiles are never the map's siblings. The
 * toggle marks the <section> itself (data-ll-pane, set in bootListingMap) and
 * the whole tiles section — count line, grid and "show more" — goes with it.
 */
[data-ll-pane="map"] [data-ll-section="browse-categories"] {
    display: none;
}

/* Category chips ---------------------------------------------------------- */

.ll-mv__cats {
    display: flex;
    align-items: center;
    gap: var(--ll-s2);
    flex-wrap: nowrap;
    margin-bottom: var(--ll-s5);
    padding-bottom: var(--ll-s2);
    overflow-x: auto;
    /*
     * A visible (thin) scroller. The row holds 35 chips and always overflows;
     * with the scrollbar hidden a mouse user had no way to reach the chips past
     * the right edge â€” the last tabs simply read as cut off.
     */
    scrollbar-width: thin;
    scrollbar-color: var(--ll-border-card) transparent;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}

.ll-mv__cats::-webkit-scrollbar {
    height: 6px;
}

.ll-mv__cats::-webkit-scrollbar-track {
    background: transparent;
}

.ll-mv__cats::-webkit-scrollbar-thumb {
    border-radius: var(--ll-r-full);
    background-color: var(--ll-border-card);
}

.ll-mv__cats > * {
    flex: none;
}

.ll-mv__cats-label {
    margin-right: var(--ll-s1);
    font-size: var(--ll-fs-small);
    font-weight: 600;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--ll-text-secondary);
}

.ll-mv__cats-row {
    display: flex;
    gap: var(--ll-s2);
}

.ll-mv__cat {
    flex: none;
    min-height: 38px;
    padding: var(--ll-s2) var(--ll-s5);
    border: 0;
    border-radius: var(--ll-r-full);
    background-color: var(--ll-surface-inset);
    box-shadow: var(--ll-hairline-card);
    font-family: var(--ll-font);
    font-size: var(--ll-fs-small);
    font-weight: 500;
    color: var(--ll-text-muted);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.25s ease, color 0.25s ease;
}

.ll-mv__cat:hover {
    color: var(--ll-white);
}

.ll-mv__cat.is-on {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

/* The card ---------------------------------------------------------------- */

.ll-mv {
    position: relative;
    display: grid;
    grid-template-columns: 372px minmax(0, 1fr);
    min-height: 600px;
    border-radius: var(--ll-r-card);
    background-color: var(--ll-black);
    box-shadow: var(--ll-hairline-card);
    overflow: hidden;
}

/* Pane tabs are a narrow-screen affordance only. */
.ll-mv__tabs {
    display: none;
}

/* Listings rail ----------------------------------------------------------- */

.ll-mv__side {
    display: flex;
    flex-direction: column;
    min-height: 0;
    box-shadow: inset -1px 0 0 0 var(--ll-border-card);
}

.ll-mv__side-head {
    display: flex;
    align-items: flex-start;
    gap: var(--ll-s4);
    padding: var(--ll-s6);
    box-shadow: inset 0 -1px 0 0 var(--ll-border-card);
}

.ll-mv__title {
    display: block;
    font-size: var(--ll-fs-h4);
    font-weight: 600;
    line-height: 1.3;
    color: var(--ll-white);
}

.ll-mv__side-head .ll-caption {
    margin-top: 3px;
}

.ll-mv__back {
    margin-left: auto;
    flex: none;
    padding: 0;
    border: 0;
    background: none;
    font-family: var(--ll-font);
    font-size: var(--ll-fs-small);
    font-weight: 500;
    color: var(--ll-red);
    cursor: pointer;
}

.ll-mv__back:hover {
    color: var(--ll-white);
}

.ll-mv__back[hidden] {
    display: none;
}

.ll-mv__list {
    flex: 1;
    min-height: 0;
    max-height: 520px;
    display: flex;
    flex-direction: column;
    gap: var(--ll-s1);
    padding: var(--ll-s3);
    overflow-y: auto;
    /* A thin rail, so the scrollbar does not sit on the design like a slab. */
    scrollbar-width: thin;
    scrollbar-color: var(--ll-border-card) transparent;
}

.ll-mv__list::-webkit-scrollbar {
    width: 6px;
}

.ll-mv__list::-webkit-scrollbar-thumb {
    border-radius: var(--ll-r-full);
    background-color: var(--ll-border-card);
}

.ll-mv__row {
    display: flex;
    align-items: center;
    gap: var(--ll-s4);
    width: 100%;
    padding: var(--ll-s3);
    border: 0;
    border-radius: var(--ll-r-plate);
    background: none;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.25s ease, box-shadow 0.25s ease;
}

.ll-mv__row:hover,
.ll-mv__row.is-hi {
    background-color: var(--ll-surface-inset);
    box-shadow: inset 0 0 0 1px var(--ll-red);
}

.ll-mv__row-th {
    width: 64px;
    height: 64px;
    flex: none;
    border-radius: var(--ll-r-plate);
    background-color: var(--ll-surface-inset);
    overflow: hidden;
}

.ll-mv__row-th img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-mv__row-bd {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ll-mv__row-t {
    font-size: var(--ll-fs-body);
    font-weight: 600;
    color: var(--ll-white);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ll-mv__row-m {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ll-s2);
    margin-top: 2px;
    font-size: var(--ll-fs-small);
    color: var(--ll-text-secondary);
}

/* The category's colour, so a row and its pin read as the same thing. */
.ll-mv__row-m i {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    display: block;
}

.ll-mv__row-m b {
    color: var(--ll-white);
    font-weight: 700;
}

.ll-mv__row-m em {
    font-style: normal;
    color: var(--ll-good);
}

.ll-mv__empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ll-s4);
    padding: var(--ll-s7) var(--ll-s6);
}

.ll-mv__empty span {
    display: block;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background-color: rgba(237, 28, 36, 0.1);
    box-shadow: var(--ll-hairline-accent);
}

.ll-mv__empty p {
    max-width: 38ch;
}

/* Canvas ------------------------------------------------------------------ */

.ll-mv__canvas {
    position: relative;
    min-height: 600px;
    overflow: hidden;
    /* A soft lift behind the landmass, as the design has it. */
    background: radial-gradient(120% 90% at 50% 30%, #0B0B0B 0%, var(--ll-black) 70%);
}

.ll-mv__map {
    position: absolute;
    inset: 0;
}

/*
 * Leaflet's own ground has to be transparent: the gradient above is the map's
 * background, and the landmass is the only thing drawn on it.
 *
 * No descendant combinator: L.map() puts .leaflet-container on .ll-mv__map
 * itself. Written as a descendant, this rule matched nothing and Leaflet's
 * default #ddd ground won â€” which is why the whole map rendered as a white
 * slab instead of the design's dark canvas.
 */
.ll-mv__map.leaflet-container,
.ll-mv__map .leaflet-container {
    background: transparent;
    font-family: var(--ll-font);
    outline: none;
}

/*
 * The tiles, made to match the site.
 *
 * OpenStreetMap draws on paper white, and this page is black. Inverting and
 * turning the hues back through 180deg is the standard way to read those same
 * tiles as a night map — land goes dark, water stays blue — and the rest takes
 * the colour out of it until what is left sits under our own red pins without
 * competing with them.
 *
 * On the pane rather than the container, so it darkens the map and not the
 * pins, the captions or the preview card, which are drawn in panes above it.
 */
.ll-mv__map .leaflet-tile-pane {
    filter: invert(1) hue-rotate(180deg) brightness(0.72) contrast(1.08) saturate(0.32);
}

/*
 * Leaflet's own controls are the card's job — the zoom stack, "Full screen" and
 * the two captions are all ours — so the only control left on the map is the
 * credit OpenStreetMap's licence asks for, shrunk to a footnote in the corner.
 */
.ll-mv__map .leaflet-control-attribution {
    margin: 0;
    padding: 3px var(--ll-s3);
    border-radius: var(--ll-r-panel) 0 0 0;
    background-color: rgba(0, 0, 0, 0.72);
    font-family: var(--ll-font);
    font-size: 10px;
    line-height: 1.5;
    color: var(--ll-text-muted);
}

.ll-mv__map .leaflet-control-attribution a {
    color: var(--ll-text-muted);
    text-decoration: underline;
}

/* City bubble ------------------------------------------------------------- */

.ll-mvcity {
    background: none;
    border: 0;
}

/*
 * Centred on the city, not hung off it.
 *
 * Leaflet is given no icon size (the bubble is sized by its own text), so it
 * can only anchor the icon by its top-left corner — which put every bubble
 * down and to the right of the city it names, far enough at country zoom that
 * the Gulf cities' labels sat off the coast in the sea. The offset belongs on
 * the label rather than on the marker root, which Leaflet positions with a
 * transform of its own.
 *
 * declutter() overwrites this transform when it nudges a collision apart, so it
 * restates the centring — keep the two in step.
 */
.ll-mvcity__btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: var(--ll-s3) var(--ll-s5);
    border: 0;
    transform: translate(-50%, -50%);
    border-radius: var(--ll-r-full);
    background-color: var(--ll-white);
    color: var(--ll-black);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.25s ease, color 0.25s ease, box-shadow 0.25s ease;
}

.ll-mvcity__btn b {
    font-size: var(--ll-fs-meta);
    font-weight: 700;
    line-height: 1;
}

.ll-mvcity__btn span {
    font-size: 9px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    opacity: 0.62;
}

.ll-mvcity__btn:hover {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

/* Listing pin ------------------------------------------------------------- */

.ll-mvpin {
    background: none;
    border: 0;
}

/*
 * The dot is what marks the spot, so the dot is what sits on the coordinate —
 * label above it, the way a pin reads. Same reason as the city bubble above:
 * Leaflet anchors a text-sized icon by its corner, which left the dot below and
 * right of the listing it points at.
 *
 * 4px is half the dot; the rest of the pin stands above the point.
 */
.ll-mvpin__btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ll-s1);
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    transform: translate(-50%, calc(-100% + 4px));
}

.ll-mvpin__label {
    padding: 7px var(--ll-s4);
    border-radius: var(--ll-r-full);
    background-color: rgba(0, 0, 0, 0.78);
    font-family: var(--ll-font);
    font-size: var(--ll-fs-small);
    font-weight: 600;
    line-height: 1;
    color: var(--ll-white);
    white-space: nowrap;
    /* The ring is the category's colour â€” set per pin by the script. */
    box-shadow: inset 0 0 0 1.5px var(--ll-pin, var(--ll-white)), 0 8px 22px rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(42px);
    transition: background-color 0.25s ease, color 0.25s ease;
}

.ll-mvpin__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--ll-pin, var(--ll-white));
    box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.18);
}

.ll-mvpin:hover .ll-mvpin__label,
.ll-mvpin.is-hi .ll-mvpin__label {
    background-color: var(--ll-pin, var(--ll-white));
    color: var(--ll-black);
}

.ll-mvpin.is-on .ll-mvpin__label {
    background-color: var(--ll-red);
    color: var(--ll-white);
    box-shadow: var(--ll-shadow-red);
}

/* An opened cluster keeps its label lit, so the way back out is obvious. */
.ll-mvpin--many.is-open .ll-mvpin__label {
    background-color: var(--ll-white);
    color: var(--ll-black);
}

/* One listing of an opened cluster ------------------------------------------ */

.ll-mvdot {
    background: none;
    border: 0;
}

.ll-mvdot__btn {
    display: block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background-color: var(--ll-pin, var(--ll-white));
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.55), 0 0 0 4px rgba(255, 255, 255, 0.22);
    cursor: pointer;
    /* Centred on its coordinate, as .ll-mvpin__btn is — Leaflet anchors an
       icon it was given no size for by the corner. */
    transform: translate(-50%, -50%);
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.ll-mvdot:hover .ll-mvdot__btn,
.ll-mvdot.is-hi .ll-mvdot__btn {
    transform: translate(-50%, -50%) scale(1.45);
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.55), 0 0 0 5px rgba(255, 255, 255, 0.55);
}

.ll-mvdot.is-on .ll-mvdot__btn {
    transform: translate(-50%, -50%) scale(1.6);
    background-color: var(--ll-red);
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.55), var(--ll-shadow-red);
}

/* The thread from a dot back to the cluster it came out of. */
.ll-mvleg {
    pointer-events: none;
}

/* Map chrome -------------------------------------------------------------- */

.ll-mv__ctl,
.ll-mv__legend,
.ll-mv__hint,
.ll-mv__fs {
    position: absolute;
    z-index: 500;
    border-radius: var(--ll-r-panel);
    background-color: rgba(0, 0, 0, 0.72);
    box-shadow: var(--ll-hairline-card);
    backdrop-filter: blur(42px);
}

.ll-mv__ctl {
    right: var(--ll-s6);
    top: var(--ll-s6);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.ll-mv__ctl button {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border: 0;
    background: none;
    font-family: var(--ll-font);
    font-size: var(--ll-fs-meta);
    color: var(--ll-text-muted);
    cursor: pointer;
    transition: background-color 0.25s ease, color 0.25s ease;
}

.ll-mv__ctl button:hover {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

.ll-mv__ctl button + button {
    box-shadow: inset 0 1px 0 0 var(--ll-border-panel);
}

.ll-mv__fs {
    left: var(--ll-s6);
    top: var(--ll-s6);
    padding: var(--ll-s3) var(--ll-s5);
    border: 0;
    font-family: var(--ll-font);
    font-size: var(--ll-fs-small);
    font-weight: 500;
    color: var(--ll-white);
    cursor: pointer;
    transition: background-color 0.25s ease;
}

.ll-mv__fs:hover {
    background-color: var(--ll-red);
}

.ll-mv__legend {
    left: var(--ll-s6);
    bottom: var(--ll-s6);
    display: flex;
    align-items: center;
    gap: var(--ll-s4);
    max-width: calc(100% - 2 * var(--ll-s6));
    padding: var(--ll-s3) var(--ll-s5);
    font-size: var(--ll-fs-small);
    color: var(--ll-text-muted);
    white-space: nowrap;
    overflow: hidden;
}

.ll-mv__legend span {
    display: flex;
    align-items: center;
    gap: var(--ll-s2);
}

.ll-mv__legend i {
    width: 9px;
    height: 9px;
    flex: none;
    display: block;
    border-radius: 50%;
    background-color: var(--ll-white);
}

.ll-mv__hint {
    right: var(--ll-s6);
    /* Clear of the OpenStreetMap credit, which sits flush in this corner. */
    bottom: calc(var(--ll-s6) + 18px);
    max-width: 290px;
    margin: 0;
    padding: var(--ll-s3) var(--ll-s5);
    font-size: var(--ll-fs-small);
    color: var(--ll-text-muted);
}

/* Both step aside while a listing preview is open. */
.ll-mv__canvas.has-prev .ll-mv__legend,
.ll-mv__canvas.has-prev .ll-mv__hint {
    opacity: 0;
    pointer-events: none;
}

/* Full screen ------------------------------------------------------------- */

.ll-mv.is-full {
    position: fixed;
    inset: 0;
    z-index: 180;
    min-height: 0;
    grid-template-columns: 1fr;
    border-radius: 0;
}

.ll-mv.is-full .ll-mv__side,
.ll-mv.is-full .ll-mv__tabs {
    display: none;
}

.ll-mv.is-full .ll-mv__canvas {
    min-height: 0;
    height: 100%;
}

/* Listing preview --------------------------------------------------------- */

.ll-mvprev {
    position: absolute;
    z-index: 600;
    width: 360px;
    max-width: calc(100% - var(--ll-s10));
    display: flex;
    gap: var(--ll-s4);
    padding: var(--ll-s4);
    border-radius: var(--ll-r-card);
    background-color: rgba(0, 0, 0, 0.86);
    box-shadow: var(--ll-hairline-card), 0 26px 64px rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(42px);
}

.ll-mvprev__ph {
    width: 92px;
    height: 92px;
    flex: none;
    border-radius: var(--ll-r-plate);
    background-color: var(--ll-surface-inset);
    overflow: hidden;
}

.ll-mvprev__ph img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ll-mvprev__bd {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding-right: var(--ll-s6);
}

.ll-mvprev__cat {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.28em;
    text-transform: uppercase;
}

.ll-mvprev__t {
    font-size: var(--ll-fs-h4);
    font-weight: 600;
    color: var(--ll-white);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ll-mvprev__where {
    font-size: var(--ll-fs-small);
    color: var(--ll-text-secondary);
}

.ll-mvprev__r {
    display: flex;
    align-items: baseline;
    gap: var(--ll-s1);
    margin-top: var(--ll-s1);
    font-size: var(--ll-fs-small);
    color: var(--ll-text-secondary);
}

.ll-mvprev__price {
    font-size: 20px;
    font-weight: 700;
    line-height: 1;
    color: var(--ll-white);
}

.ll-mvprev__trust {
    margin-left: auto;
    color: var(--ll-good);
}

.ll-mvprev__x {
    position: absolute;
    top: var(--ll-s3);
    right: var(--ll-s3);
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border: 0;
    border-radius: 50%;
    background-color: var(--ll-surface-inset);
    color: var(--ll-text-muted);
    font-size: 10px;
    line-height: 1;
    cursor: pointer;
}

.ll-mvprev__x:hover {
    background-color: var(--ll-red);
    color: var(--ll-white);
}

/* =========================================================================
   INNER PAGES â€” content rail
   The reference's stepped (Bootstrap-style) container: 1320px inside 12px
   gutters at full width, stepping down with the viewport. The homepage keeps
   its own 1600px rail; on the designed inner pages that rail rendered with no
   side padding at all below 1600px, so on a 1440 desktop or an iPad the page
   started at the extreme left edge. Scoped by the template body class so the
   header and footer on these pages follow the same rail. Breakpoint steps
   live in css/inner-responsive.css.
   ========================================================================= */

.page-template-page_templates {
    --ll-container: 1344px; /* 1320px content + the two 12px gutters */
    --ll-container-pad: 12px;
}

/* =========================================================================
   Native form controls on the dark theme
   The select's options open in a browser-drawn popup: without a colour scheme
   the popup is white while the control's text is white, so every option read
   as blank. color-scheme lets the browser draw the popup dark; the option
   rule covers engines that ignore it.
   ========================================================================= */

.ll-page select.ll-input {
    color-scheme: dark;
}

.ll-page select.ll-input option {
    background-color: var(--ll-surface-inset);
    color: var(--ll-white);
}

/* =========================================================================
   BROWSE â€” hero search results
   Shown when the hero search is submitted; every other section hides so the
   page reads as a result set. Driven by initBrowseSearch().
   ========================================================================= */

.ll-results-sec[hidden] {
    display: none;
}

/*
 * The result set replaces the page's sections until the search is cleared.
 * Scoped to a category, template-parts/inner/listing-results.php (.ll-results)
 * is that result set instead of .ll-results-sec, so it is exempted the same
 * way — is-searching is also set then, "category" being one of the scopes
 * ll_search_args() treats as a search.
 */
.ll-page--browse.is-searching > .ll-section:not(.ll-results-sec):not(.ll-results) {
    display: none;
}

[data-ll-search-grid][hidden] {
    display: none;
}

.ll-results-empty {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ll-s4);
    padding: var(--ll-s15) var(--ll-s6);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-surface-raised);
    box-shadow: var(--ll-hairline-card);
    text-align: center;
    overflow: hidden;
}

.ll-results-empty[hidden] {
    display: none;
}

.ll-results-empty__glow {
    position: absolute;
    top: -120px;
    right: -100px;
    width: 460px;
    height: 300px;
    background: var(--ll-glow-red);
    opacity: 0.22;
    pointer-events: none;
}

.ll-results-empty .ll-meta {
    max-width: 52ch;
}

.ll-results-empty .ll-btn {
    margin-top: var(--ll-s3);
}


/* =========================================================================
   Broken photograph fallback
   The API feed can reference images a browser cannot render (HEIC uploads)
   or blobs that no longer exist. initImageFallbacks() hides the failed <img>
   and marks its frame, which paints this quiet placeholder instead of the
   browser broken-image glyph.
   ========================================================================= */

.ll-img-missing {
    position: relative;
    background-color: var(--ll-surface-inset);
}

.ll-img-missing::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 28px;
    height: 28px;
    opacity: 0.45;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238E8E93' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='3'/%3E%3Ccircle cx='9' cy='9' r='2'/%3E%3Cpath d='m21 15-3.5-3.5L11 18'/%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}


/* =========================================================================
   LEND â€” app dialog QR and lender avatars
   ========================================================================= */

/* The scannable QR, on the reference's white plate (.qr in lend.css). */
.ll-modal__qr {
    display: grid;
    place-items: center;
    width: 140px;
    height: 140px;
    margin: var(--ll-s7) auto var(--ll-s2);
    padding: var(--ll-s3);
    border-radius: var(--ll-r-card);
    background-color: var(--ll-white);
}

.ll-modal__qr img {
    display: block;
    width: 100%;
    height: 100%;
    /* Hard edges: a QR must never be smoothed into un-scannability. */
    image-rendering: pixelated;
}

.ll-modal__scanline {
    margin-bottom: var(--ll-s5);
    text-align: center;
}

/* A lender who has a real profile photo shows it instead of the initial. */
.ll-avatar--photo {
    overflow: hidden;
    padding: 0;
}

.ll-avatar--photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}


/* =========================================================================
   LEND â€” the step card arriving after a tab click
   A card is as wide as the content rail, so sliding the track sideways is a
   full-screen photograph whipping past: measured at 155px per frame for one
   step and 218px for two, whether the travel was hand-rolled or handed to the
   browser's own smooth scroll. The track is placed instantly instead and the
   arriving card fades in from the direction of travel â€” one composited
   animation, nothing left to stutter. Declared on the card's CONTENTS, never
   the card: a transform on the card would move its scroll-snap area and invite
   a re-snap. Swiping still uses the native scroll, untouched.
   ========================================================================= */

@keyframes ll-step-arrive {
    from {
        opacity: 0;
        transform: translateX(calc(var(--ll-step-dir, 1) * 26px));
    }

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

.ll-steps__card.is-arriving .ll-steps__shot,
.ll-steps__card.is-arriving .ll-steps__body {
    animation: ll-step-arrive 340ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
    will-change: transform, opacity;
}

/* The copy follows the artwork by a frame or two, so the pair reads as one move. */
.ll-steps__card.is-arriving .ll-steps__body {
    animation-delay: 45ms;
}

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

    .ll-steps__card.is-arriving .ll-steps__shot,
    .ll-steps__card.is-arriving .ll-steps__body {
        animation: none;
    }
}
