/*
    RVLooker site styles.

    Layered deliberately:
      1. Brand tokens      - semantic custom properties, the single source of the palette.
      2. Bootstrap bridge  - map those tokens onto Bootstrap 5's own custom properties.
      3. Shell             - header, footer and page-frame styling for the app shell.
      4-8. Page styling    - icons and ratings, the listing card, the landing page, browse,
                             the listing detail page.

    The tokens were measured from the live site (see context/project-overview.md section 7).
    Light mode is the only theme today; a dark theme lands later by redefining the block in
    step 1 under [data-bs-theme="dark"] - nothing in steps 2 and 3 hard-codes a colour, so
    that is the only place it has to change.
*/

/* ---------------------------------------------------------------- 1. Brand tokens ---- */

:root {
    /* Primary - buttons, price badges, active nav. */
    --rvl-primary: hsl(164 60% 30%);
    --rvl-primary-hover: hsl(164 60% 25%);
    --rvl-primary-active: hsl(164 60% 21%);
    --rvl-primary-rgb: 31, 122, 98;
    --rvl-on-primary: #ffffff;

    /* Neutrals. */
    --rvl-background: hsl(0 0% 100%);
    --rvl-foreground: hsl(0 0% 9%);
    --rvl-foreground-rgb: 23, 23, 23;
    --rvl-card: hsl(0 0% 98%);
    --rvl-border: hsl(0 0% 90%);

    /* Muted and accent tones, lightly tinted toward the primary hue. */
    --rvl-muted: hsl(164 8% 90%);
    --rvl-muted-foreground: hsl(164 6% 40%);
    --rvl-accent: hsl(164 12% 92%);

    --rvl-destructive: hsl(0 84% 38%);

    /* Sold - the one listing status the public ever sees. Blue, per overview section 8. */
    --rvl-sold: hsl(212 72% 42%);

    /* Shape and type. */
    --rvl-radius: 0.5rem;
    --rvl-font-sans: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;

    /* Shell metrics. */
    --rvl-header-height: 56px;
}

/* ------------------------------------------------------------ 2. Bootstrap bridge ---- */

:root,
[data-bs-theme="light"] {
    --bs-primary: var(--rvl-primary);
    --bs-primary-rgb: var(--rvl-primary-rgb);
    --bs-primary-text-emphasis: var(--rvl-primary-active);
    --bs-primary-bg-subtle: var(--rvl-accent);
    --bs-primary-border-subtle: var(--rvl-muted);

    --bs-body-bg: var(--rvl-background);
    --bs-body-color: var(--rvl-foreground);
    --bs-body-color-rgb: var(--rvl-foreground-rgb);
    --bs-emphasis-color: var(--rvl-foreground);
    --bs-secondary-color: var(--rvl-muted-foreground);
    --bs-secondary-bg: var(--rvl-muted);
    --bs-tertiary-bg: var(--rvl-card);

    --bs-border-color: var(--rvl-border);
    --bs-border-radius: var(--rvl-radius);
    --bs-border-radius-sm: calc(var(--rvl-radius) - 0.125rem);
    --bs-border-radius-lg: calc(var(--rvl-radius) + 0.25rem);

    --bs-link-color: var(--rvl-primary);
    --bs-link-color-rgb: var(--rvl-primary-rgb);
    --bs-link-hover-color: var(--rvl-primary-hover);
    --bs-link-hover-color-rgb: var(--rvl-primary-rgb);

    --bs-danger: var(--rvl-destructive);

    --bs-font-sans-serif: var(--rvl-font-sans);
    --bs-body-font-family: var(--rvl-font-sans);
}

/*
    Bootstrap's components carry their own component-scoped custom properties, compiled from
    Sass - overriding --bs-primary alone does not reach them. Redefining those component
    variables is the framework's own extension point; per-element colour rules are not.
*/
.btn-primary {
    --bs-btn-bg: var(--rvl-primary);
    --bs-btn-border-color: var(--rvl-primary);
    --bs-btn-color: var(--rvl-on-primary);
    --bs-btn-hover-bg: var(--rvl-primary-hover);
    --bs-btn-hover-border-color: var(--rvl-primary-hover);
    --bs-btn-hover-color: var(--rvl-on-primary);
    --bs-btn-active-bg: var(--rvl-primary-active);
    --bs-btn-active-border-color: var(--rvl-primary-active);
    --bs-btn-active-color: var(--rvl-on-primary);
    --bs-btn-disabled-bg: var(--rvl-primary);
    --bs-btn-disabled-border-color: var(--rvl-primary);
    --bs-btn-disabled-color: var(--rvl-on-primary);
    --bs-btn-focus-shadow-rgb: var(--rvl-primary-rgb);
}

.btn-outline-primary {
    --bs-btn-color: var(--rvl-primary);
    --bs-btn-border-color: var(--rvl-primary);
    --bs-btn-hover-bg: var(--rvl-primary);
    --bs-btn-hover-border-color: var(--rvl-primary);
    --bs-btn-hover-color: var(--rvl-on-primary);
    --bs-btn-active-bg: var(--rvl-primary-hover);
    --bs-btn-active-border-color: var(--rvl-primary-hover);
    --bs-btn-active-color: var(--rvl-on-primary);
    --bs-btn-focus-shadow-rgb: var(--rvl-primary-rgb);
}

.bg-primary {
    background-color: var(--rvl-primary) !important;
}

.text-primary {
    color: var(--rvl-primary) !important;
}

:focus-visible {
    outline: 2px solid var(--rvl-primary);
    outline-offset: 2px;
}

/* -------------------------------------------------------------------- 3. Shell ------- */

html {
    font-size: 16px;
}

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    font-family: var(--rvl-font-sans);
    background-color: var(--rvl-background);
    color: var(--rvl-foreground);
}

.site-main {
    flex: 1 0 auto;
}

/* Header - sticky, translucent white with a backdrop blur, 56px tall. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    border-bottom: 1px solid var(--rvl-border);
    background-color: rgba(255, 255, 255, 0.95);
}

@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
    .site-header {
        background-color: rgba(255, 255, 255, 0.6);
        -webkit-backdrop-filter: blur(8px);
        backdrop-filter: blur(8px);
    }
}

.site-header__navbar {
    min-height: var(--rvl-header-height);
    padding-top: 0;
    padding-bottom: 0;
}

.site-header__brand {
    display: inline-flex;
    align-items: center;
    padding: 0;
    margin-right: 1rem;
}

.site-header__logo {
    height: 40px;
    width: auto;
}

.site-header .nav-link {
    --bs-nav-link-color: var(--rvl-foreground);
    --bs-nav-link-hover-color: var(--rvl-primary);
    border-radius: var(--rvl-radius);
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 500;
    transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.site-header .nav-link:hover {
    background-color: var(--rvl-accent);
}

.site-header .nav-link.active {
    background-color: var(--rvl-muted);
    color: var(--rvl-foreground);
}

/*
    The auth seam. The account region is always rendered so the header's layout does not
    shift; auth phase 3 filled _AccountMenu.cshtml in, and everything below styles what that
    partial renders - logged out, the two links; logged in, the call to action and the avatar
    dropdown. Nothing outside this block changed for that.
*/
.site-header__account {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 2rem;
}

.site-header__signin {
    --bs-nav-link-color: var(--rvl-foreground);
    --bs-nav-link-hover-color: var(--rvl-primary);
    padding: 0.375rem 0.75rem;
    border-radius: var(--rvl-radius);
    font-size: 0.875rem;
    font-weight: 500;
}

.site-header__signin:hover {
    background-color: var(--rvl-accent);
}

.site-header__signup,
.site-header__sell {
    padding: 0.375rem 0.875rem;
    font-size: 0.875rem;
    font-weight: 600;
}

/* The avatar is the whole trigger, so the button is only a hit area around it. */
.site-header__avatar-button {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    border-radius: 999px;
    line-height: 1;
}

.site-header__avatar-button:focus-visible {
    outline: 2px solid var(--rvl-primary);
    outline-offset: 2px;
}

.site-header__account-name {
    display: flex;
    flex-direction: column;
    padding-bottom: 0.5rem;
}

.site-header__account-display-name {
    color: var(--rvl-foreground);
    font-weight: 600;
}

.site-header__account-handle {
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
}

/* The sign-out control is a form, so its button has to look like the links above it. */
.site-header__signout {
    margin: 0;
}

.site-header__signout .dropdown-item {
    width: 100%;
    border: 0;
    background: none;
    text-align: left;
}

/*
    The avatar. Shared with the profile page (profile-spec.md) - which is why the size is a
    modifier rather than a hard-coded box, and why the initials variant is styled here rather
    than inside the header block above.
*/
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 999px;
    object-fit: cover;
    background-color: var(--rvl-primary);
    color: var(--rvl-on-primary);
    font-weight: 600;
    line-height: 1;
    user-select: none;
}

.avatar--sm {
    width: 2rem;
    height: 2rem;
    font-size: 0.75rem;
}

.avatar--lg {
    width: 5rem;
    height: 5rem;
    font-size: 1.5rem;
}

/* Footer - top border, muted small text. */
.site-footer {
    flex-shrink: 0;
    margin-top: 3rem;
    padding: 2rem 0;
    border-top: 1px solid var(--rvl-border);
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

.site-footer__mark {
    height: 20px;
    width: auto;
    opacity: 0.7;
}

.site-footer a {
    color: inherit;
    text-decoration: none;
    transition: color 0.15s ease-in-out;
}

.site-footer a:hover,
.site-footer a:focus-visible {
    color: var(--rvl-foreground);
}

/* Branded not-found page. */
.not-found {
    max-width: 32rem;
    margin: 5rem auto;
    text-align: center;
}

.not-found__code {
    font-size: 4rem;
    font-weight: 700;
    line-height: 1;
    color: var(--rvl-primary);
}

/* --------------------------------------------------------- 4. Icons and ratings ------ */

/*
    The sprite element itself is never displayed - it only holds <symbol> definitions that
    <use> pulls from. It still has to be in the document, so it is hidden rather than absent.
*/
.rvl-icon-sprite {
    display: none;
}

.rvl-icon {
    width: 1em;
    height: 1em;
    flex: 0 0 auto;
    vertical-align: -0.125em;
    overflow: visible;
}

.rvl-icon--lg {
    width: 1.5rem;
    height: 1.5rem;
}

.rvl-icon--xl {
    width: 3rem;
    height: 3rem;
    stroke-width: 1.5;
}

/*
    Star rating: two identical rows of stars stacked, the coloured one clipped to a percentage
    of the width. Renders any fraction - including a half star - without a half-star glyph, and
    without five per-star decisions in the view.
*/
.rvl-stars {
    position: relative;
    display: inline-block;
    line-height: 1;
    letter-spacing: 0.05em;
    font-size: 0.8125rem;
}

.rvl-stars__base {
    color: var(--rvl-border);
}

.rvl-stars__fill {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--rvl-stars-fill, 0%);
    overflow: hidden;
    white-space: nowrap;
    color: #e8a33d;
}

/* The rating as a whole: the stars, and the review count beside them. */
.rvl-rating {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: 0 0 auto;
}

.rvl-rating__count {
    font-size: 0.6875rem;
}

/* On a card the rating is pushed to the far end of the seller strip. */
.listing-card__seller .rvl-rating {
    margin-left: auto;
}

/* ----------------------------------------------------------------- 5. Listing card --- */

.listing-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    background-color: var(--rvl-background);
    transition: box-shadow 0.15s ease-in-out, transform 0.15s ease-in-out;
}

.listing-card:hover,
.listing-card:focus-within {
    box-shadow: 0 0.75rem 1.5rem rgba(var(--rvl-foreground-rgb), 0.1);
    transform: translateY(-2px);
}

.listing-card__link {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    color: inherit;
    text-decoration: none;
}

.listing-card__media {
    position: relative;
    aspect-ratio: 4 / 3;
    background-color: var(--rvl-muted);
}

.listing-card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The price is the first thing a shopper looks for - a primary pill over the photo. */
.listing-card__price {
    position: absolute;
    left: 0.75rem;
    bottom: 0.75rem;
    padding: 0.25rem 0.625rem;
    border-radius: calc(var(--rvl-radius) - 0.125rem);
    background-color: var(--rvl-primary);
    color: var(--rvl-on-primary);
    font-size: 0.875rem;
    font-weight: 600;
}

.listing-card__body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem;
}

.listing-card__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.3;

    /* One line, clipped - card heights stay uniform however long a title is. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.listing-card__subtitle {
    margin: 0;
    font-size: 0.875rem;
    color: var(--rvl-muted-foreground);
}

.listing-card__specs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.75rem;
    color: var(--rvl-muted-foreground);
}

.listing-card__spec {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.listing-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: auto;
    padding-top: 0.25rem;
}

.listing-card__location {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
    color: var(--rvl-muted-foreground);
}

.listing-card__condition {
    flex: 0 0 auto;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background-color: var(--rvl-muted);
    color: var(--rvl-foreground);
    font-size: 0.6875rem;
    font-weight: 500;
}

.listing-card__seller {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--rvl-border);
    font-size: 0.75rem;
    color: var(--rvl-muted-foreground);
}

.listing-card__seller-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ------------------------------------------------------------------ 6. Landing page -- */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 480px;
    overflow: hidden;
}

@media (min-width: 768px) {
    .hero {
        min-height: 520px;
    }
}

.hero__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Bottom-heavy so the headline and the search box stay readable over any part of the photo. */
.hero__overlay {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.8),
        rgba(0, 0, 0, 0.4) 50%,
        rgba(0, 0, 0, 0.2)
    );
}

.hero__content {
    position: relative;
    max-width: 48rem;
    padding: 2rem 1rem;
    text-align: center;
    color: #ffffff;
}

.hero__headline {
    margin-bottom: 1rem;
    font-size: clamp(2.25rem, 6vw, 3.75rem);
    font-weight: 700;
    letter-spacing: -0.02em;
}

.hero__subline {
    max-width: 36rem;
    margin: 0 auto 2rem;
    font-size: 1.0625rem;
    color: rgba(255, 255, 255, 0.85);
}

.hero__search {
    display: flex;
    gap: 0.5rem;
    max-width: 36rem;
    margin: 0 auto;
}

.hero__search-input {
    height: 3rem;
    background-color: #ffffff;
    color: var(--rvl-foreground);
}

.hero__search-button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
}

.value-props {
    padding: 4rem 0;
}

.value-prop {
    display: block;
    height: 100%;
    padding: 1rem;
    text-align: center;
}

.value-prop__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: 0.75rem;
    border-radius: 999px;
    background-color: var(--rvl-accent);
    color: var(--rvl-primary);
}

.value-prop__heading {
    margin-bottom: 0.5rem;
    font-size: 1.125rem;
    font-weight: 600;
}

.value-prop__body {
    margin: 0;
    font-size: 0.875rem;
    color: var(--rvl-muted-foreground);
}

.value-prop--link {
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    color: inherit;
    text-decoration: none;
    transition: background-color 0.15s ease-in-out;
}

.value-prop--link:hover,
.value-prop--link:focus-visible {
    background-color: var(--rvl-card);
    color: inherit;
}

.listing-band {
    padding: 3rem 0;
}

/* The top band is visually distinguished - it is the placement people paid the most for. */
.listing-band--premium {
    background-color: var(--rvl-accent);
}

.listing-band--recent {
    background-color: var(--rvl-card);
}

.listing-band__header {
    margin-bottom: 1.5rem;
}

.listing-band__header--split {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.listing-band__title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 700;
}

.listing-band__subtitle {
    margin: 0.25rem 0 0;
    font-size: 0.875rem;
    color: var(--rvl-muted-foreground);
}

.listing-empty {
    padding: 4rem 1rem;
    text-align: center;
    color: var(--rvl-muted-foreground);
}

.listing-empty .rvl-icon {
    margin-bottom: 1rem;
    opacity: 0.5;
}

.listing-empty h2,
.listing-empty h3 {
    color: var(--rvl-foreground);
}

.listing-empty p {
    margin-bottom: 1.5rem;
}

.sell-cta {
    padding: 4rem 0;
    text-align: center;
}

.sell-cta__heading {
    margin-bottom: 1rem;
    font-size: 1.875rem;
    font-weight: 700;
}

.sell-cta__body {
    max-width: 34rem;
    margin: 0 auto 2rem;
    color: var(--rvl-muted-foreground);
}

/* -------------------------------------------------------------------- 7. Browse ------ */

/*
    Vertical padding only. The shorthand would zero the .container's own horizontal padding,
    and the listing grid's Bootstrap row has negative side margins that padding is there to
    absorb - so the grid would hang 12px off each edge and give the page a horizontal scrollbar
    on a phone.
*/
.browse {
    padding-top: 2.5rem;
    padding-bottom: 3rem;
}

.browse__header {
    margin-bottom: 1.5rem;
}

.browse__title {
    margin-bottom: 0;
    font-size: 1.875rem;
    font-weight: 700;
}

/*
    The filter bar. A plain GET form, so it lays out as a form and nothing here depends on
    JavaScript: on a phone the fields stack, and from medium up they sit in a row that wraps.

    The form element itself is only a wrapper - it reaches past the panel to take in the chips and
    the sort dropdown beside the result count, so that every control belongs to one form. The card
    is the panel inside it.
*/
.browse-filters__panel {
    padding: 1.25rem;
    margin-bottom: 1.5rem;
    background-color: var(--rvl-card);
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
}

.browse-filters__search {
    display: flex;
    gap: 0.5rem;
    max-width: 36rem;
}

.browse-filters__fields {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    align-items: flex-end;
    margin-top: 1rem;
}

.browse-filters__field {
    flex: 1 1 10rem;
    min-width: 0;
}

.browse-filters__field .form-label {
    margin-bottom: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--rvl-muted-foreground);
}

.browse-filters__actions {
    flex: 0 0 auto;
}

/*
    On a phone the fields are two to a row, so leaving the button in the flow pairs it with
    whichever field lands last and squeezes that field. Its own row instead.
*/
@media (max-width: 575.98px) {
    .browse-filters__actions {
        flex: 1 1 100%;
    }

    .browse-filters__actions .btn {
        width: 100%;
    }
}

/*
    The RV specs group. A <details>, so the disclosure needs no script. Kept visually secondary to
    the basics above - a rule, a quiet heading, and closed until a spec filter is actually set.
*/
.browse-specs {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--rvl-border);
}

.browse-specs__summary {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--rvl-muted-foreground);
    cursor: pointer;
}

.browse-specs__fields {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    align-items: flex-end;
    margin-top: 0.75rem;
}

/*
    The checkbox has no label above it, so it would sit a line higher than the fields it shares a
    row with. The padding drops it onto their baseline.
*/
.browse-specs__check {
    flex: 1 1 12rem;
    padding-bottom: 0.5rem;
}

.browse-specs__note {
    margin: 0.75rem 0 0;
    font-size: 0.8125rem;
}

/*
    The result count and the sort share a row, and the sort wraps below it on a narrow screen
    rather than squeezing the count.
*/
.browse-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 1.25rem;
}

.browse-toolbar .browse__summary {
    margin-bottom: 0;
}

.browse-sort {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.browse-sort .form-label {
    margin-bottom: 0;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--rvl-muted-foreground);
    white-space: nowrap;
}

.browse-sort .form-select {
    width: auto;
    font-size: 0.875rem;
}

/* The active filters, each a link that removes only itself. */
.browse-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.browse-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    font-size: 0.8125rem;
    text-decoration: none;
    color: var(--rvl-foreground);
    background-color: var(--rvl-muted);
    border: 1px solid var(--rvl-border);
    border-radius: 999px;
}

.browse-chip:hover,
.browse-chip:focus-visible {
    background-color: var(--rvl-border);
    color: var(--rvl-foreground);
}

.browse-chip__name {
    font-weight: 600;
    color: var(--rvl-muted-foreground);
}

.browse-chip__remove {
    font-size: 1rem;
    line-height: 1;
    color: var(--rvl-muted-foreground);
}

.browse-chip--clear {
    background-color: transparent;
    border-style: dashed;
    font-weight: 600;
}

.browse__summary {
    margin: 0 0 1.25rem;
    font-size: 0.875rem;
}

.browse-pagination {
    display: flex;
    justify-content: center;
    margin-top: 2rem;
}

.browse-pagination .pagination {
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 0;
}

/* ---------------------------------------------------------- 8. Listing detail -------- */

.listing-detail {
    padding-block: 2rem 3rem;
}

/*
    Status and vocabulary pills. The neutral one matches the card's condition pill; the sold one
    is the only status a public page ever shows, and it is loud on purpose.
*/
.listing-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.625rem;
    border-radius: 999px;
    background-color: var(--rvl-muted);
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.listing-badge--sold {
    background-color: var(--rvl-sold);
    color: #ffffff;
}

/* --- Gallery --- */

.listing-gallery {
    position: relative;
}

/* The 4:3 frame every photo sits in. */
.listing-gallery__frame {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    overflow: hidden;
    background-color: var(--rvl-card);
}

/*
    The loading state - a skeleton, not a spinner (overview section 7) - and the photo simply
    covers it, so nothing has to switch it off. Only on the carousel: the empty-gallery
    placeholder is not waiting for anything, and shimmering at a listing with no photos promises
    one that is never coming. Counted rather than infinite for the same reason - once the photo
    is in, the animation is running forever behind an opaque image.
*/
.carousel-inner.listing-gallery__frame {
    background-image: linear-gradient(100deg, var(--rvl-card) 30%, var(--rvl-muted) 50%, var(--rvl-card) 70%);
    background-size: 300% 100%;
    animation: rvl-skeleton 1.4s ease-in-out 8 both;
}

@keyframes rvl-skeleton {
    from {
        background-position: 150% 0;
    }

    to {
        background-position: -50% 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .carousel-inner.listing-gallery__frame {
        animation: none;
    }
}

/*
    Bootstrap's slide is auto-height, so without this the photo's height: 100% resolves against
    nothing and the frame shows a band of skeleton under a short image.
*/
.listing-gallery__frame .carousel-item {
    height: 100%;
}

.listing-gallery__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Bootstrap's controls are 15%-wide translucent columns; these are buttons over the photo. */
.listing-gallery__control {
    top: 50%;
    width: 2.5rem;
    height: 2.5rem;
    transform: translateY(-50%);
    border: 0;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.45);
    color: #ffffff;
    opacity: 1;
    transition: background-color 0.15s ease-in-out;
}

.listing-gallery__control:hover,
.listing-gallery__control:focus-visible {
    background-color: rgba(0, 0, 0, 0.7);
}

.carousel-control-prev.listing-gallery__control {
    left: 0.75rem;
}

.carousel-control-next.listing-gallery__control {
    right: 0.75rem;
}

.listing-gallery__expand {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 0;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.45);
    color: #ffffff;
    transition: background-color 0.15s ease-in-out;
}

.listing-gallery__expand:hover,
.listing-gallery__expand:focus-visible {
    background-color: rgba(0, 0, 0, 0.7);
}

.listing-gallery__counter {
    position: absolute;
    bottom: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
    padding: 0.125rem 0.625rem;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.5);
    color: #ffffff;
    font-size: 0.75rem;
}

.listing-gallery__sold {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    padding: 0.3125rem 0.875rem;
    font-size: 0.875rem;
}

.listing-gallery__placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    color: var(--rvl-muted-foreground);

    /* Nothing is loading here, so the shimmer would be a lie. */
    background-image: none;
    animation: none;
}

.listing-gallery__placeholder-text {
    margin: 0;
    font-size: 0.875rem;
}

.listing-gallery__thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.listing-gallery__thumb {
    width: 5rem;
    height: 3.75rem;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--rvl-radius);
    background: none;
    overflow: hidden;
    transition: border-color 0.15s ease-in-out;
}

.listing-gallery__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.listing-gallery__thumb:hover {
    border-color: var(--rvl-muted);
}

.listing-gallery__thumb.is-active {
    border-color: var(--rvl-primary);
}

/* --- The detail column --- */

.listing-detail__badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.listing-detail__title {
    margin-bottom: 0.5rem;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.25;
}

.listing-detail__price {
    margin-bottom: 0.75rem;
    color: var(--rvl-primary);
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
}

.listing-detail__subtitle {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

.listing-detail__section {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--rvl-border);
}

.listing-detail__section-heading {
    margin-bottom: 0.75rem;
    font-size: 1rem;
    font-weight: 600;
}

.listing-detail__description {
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;

    /* The seller's own line breaks, kept without ever handing their text to Html.Raw. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.listing-detail__listed-on {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: 1.5rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
}

/* --- Spec sheet --- */

.listing-specs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.875rem 1rem;
    margin-bottom: 0;
}

.listing-specs__row {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    min-width: 0;
    color: var(--rvl-muted-foreground);
}

.listing-specs__label {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--rvl-muted-foreground);
}

.listing-specs__value {
    margin-bottom: 0;
    color: var(--rvl-foreground);
    font-size: 0.875rem;
    font-weight: 500;
    overflow-wrap: anywhere;
}

/* --- Seller card --- */

.seller-card {
    padding: 1rem;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    background-color: var(--rvl-card);
}

.seller-card__identity {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.seller-card__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    flex: 0 0 auto;
    border-radius: 999px;
    background-color: var(--rvl-accent);
    color: var(--rvl-primary);
}

.seller-card__name {
    margin-bottom: 0.125rem;
    font-size: 0.9375rem;
    font-weight: 600;
}

.seller-card__member-since {
    margin-top: 0.125rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
}

.seller-card__bio {
    margin-top: 0.75rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

.seller-card__location {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: 0.5rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
}

/* --- Contact --- */

.listing-contact {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.listing-contact__link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9375rem;
    overflow-wrap: anywhere;
}

/* --- Lightbox --- */

/*
    A lightbox wants a darker ground than a dialog does - the photo should be the only lit thing
    on the screen. Scoped with :has so a future modal keeps Bootstrap's lighter default.
*/
body:has(#listing-lightbox.show) .modal-backdrop {
    --bs-backdrop-opacity: 0.85;
}

.listing-lightbox__content {
    position: relative;
    align-items: center;
    border: 0;
    background-color: transparent;
}

.listing-lightbox__image {
    display: block;
    max-width: 100%;
    max-height: 85vh;
    border-radius: var(--rvl-radius);
    object-fit: contain;
}

.listing-lightbox__close,
.listing-lightbox__control {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 0;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.5);
    color: #ffffff;
    transition: background-color 0.15s ease-in-out;
}

.listing-lightbox__close:hover,
.listing-lightbox__close:focus-visible,
.listing-lightbox__control:hover,
.listing-lightbox__control:focus-visible {
    background-color: rgba(0, 0, 0, 0.8);
}

.listing-lightbox__close {
    top: 0.5rem;
    right: 0.5rem;
    z-index: 2;
}

.listing-lightbox__control {
    top: 50%;
    transform: translateY(-50%);
}

.listing-lightbox__control--prev {
    left: 0.5rem;
}

.listing-lightbox__control--next {
    right: 0.5rem;
}

.listing-lightbox__counter {
    position: absolute;
    bottom: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
    padding: 0.125rem 0.625rem;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.6);
    color: #ffffff;
    font-size: 0.75rem;
}

/* One column of specs is easier to scan than two squeezed ones on a phone. */
@media (max-width: 575.98px) {
    .listing-specs {
        grid-template-columns: minmax(0, 1fr);
    }

    .listing-detail__price {
        font-size: 1.75rem;
    }
}

/* ------------------------------------------------------- 9. Account pages ------------ */

/*
    The account area - sign in, register, forgot and reset password. Auth phase 3.

    One card, centred, on a page with no other furniture. These are the only pages on the
    site whose whole job is a single form, and the shell's header and footer stay so the
    person can tell they have not left RVLooker.
*/
.account-page {
    display: flex;
    justify-content: center;
    padding: 3rem 0;
}

.account-card {
    width: 100%;
    max-width: 27rem;
    padding: 2rem;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    background-color: var(--rvl-background);
}

.account-card__title {
    margin-bottom: 0.25rem;
    font-size: 1.5rem;
    font-weight: 700;
}

.account-card__subtitle {
    margin-bottom: 1.5rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
}

.account-form .form-label {
    margin-bottom: 0.25rem;
    font-size: 0.875rem;
    font-weight: 500;
}

.account-form .form-control {
    padding: 0.625rem 0.75rem;
}

.account-form__field {
    margin-bottom: 1rem;
}

.account-form__submit {
    width: 100%;
    padding: 0.625rem 1rem;
    font-weight: 600;
}

/* The "forgot your password?" link, sitting on the password field's own label row. */
.account-form__label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
}

.account-form__label-row a {
    font-size: 0.8125rem;
}

/* "or" between the password form and the provider buttons. */
.account-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.5rem 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.account-divider::before,
.account-divider::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background-color: var(--rvl-border);
}

.account-provider {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.account-provider__button {
    width: 100%;
    padding: 0.625rem 1rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
    color: var(--rvl-foreground);
    font-weight: 500;
    transition: background-color 0.15s ease-in-out;
}

.account-provider__button:hover {
    background-color: var(--rvl-accent);
}

.account-card__footer {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--rvl-border);
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
    text-align: center;
}

.account-card__footer p:last-child {
    margin-bottom: 0;
}

/* The notices above the form: a refusal, a suspension, a success carried from elsewhere. */
.account-notice {
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    border-radius: var(--rvl-radius);
    font-size: 0.875rem;
}

.account-notice p:last-child {
    margin-bottom: 0;
}

.account-notice--error {
    border: 1px solid var(--rvl-destructive);
    background-color: hsl(0 84% 97%);
    color: var(--rvl-destructive);
}

.account-notice--warning {
    border: 1px solid hsl(38 92% 50%);
    background-color: hsl(38 92% 96%);
    color: hsl(30 80% 28%);
}

.account-notice--success {
    border: 1px solid var(--rvl-primary);
    background-color: var(--rvl-accent);
    color: var(--rvl-primary-active);
}

/* The validation summary reuses the error notice, so a model-level error looks like one. */
.account-form .validation-summary-errors ul {
    margin-bottom: 0;
    padding-left: 1.25rem;
}

.account-form .field-validation-error {
    display: block;
    margin-top: 0.25rem;
    color: var(--rvl-destructive);
    font-size: 0.8125rem;
}

/* -------------------------------------------------------- 10. Create listing --------- */

.listing-form-page {
    max-width: 56rem;
    padding-top: 2.5rem;
    padding-bottom: 4rem;
}

.listing-form-page__header {
    margin-bottom: 2rem;
}

.listing-form-page__title {
    margin-bottom: 0.5rem;
    font-size: clamp(1.75rem, 4vw, 2.25rem);
    font-weight: 700;
}

.listing-form-page__subtitle {
    margin-bottom: 0;
    max-width: 42rem;
    color: var(--rvl-muted-foreground);
}

.listing-form__section {
    margin-bottom: 1.5rem;
    padding: 1.5rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
}

.listing-form__section-title {
    margin-bottom: 1rem;
    font-size: 1.125rem;
    font-weight: 600;
}

.listing-form__section-note {
    margin-top: -0.5rem;
    margin-bottom: 1.25rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
}

.listing-form__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem 1.25rem;
}

.listing-form__field {
    margin-bottom: 1rem;
}

.listing-form__field--narrow {
    max-width: 16rem;
}

.listing-form .form-label {
    margin-bottom: 0.375rem;
    font-weight: 500;
    font-size: 0.9375rem;
}

.listing-form__hint {
    margin-top: 0.375rem;
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
}

.listing-form__check {
    margin-top: 0.5rem;
}

.listing-form__vin {
    text-transform: uppercase;
}

.listing-form .field-validation-error {
    display: block;
    margin-top: 0.25rem;
    color: var(--rvl-destructive);
    font-size: 0.8125rem;
}

.listing-form .validation-summary-errors ul {
    margin-bottom: 0;
    padding-left: 1.25rem;
}

.listing-form__actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.listing-form__submit {
    padding: 0.625rem 1.75rem;
    font-weight: 600;
}

/* --- Photos --- */

.listing-photos {
    padding: 1.25rem;
    border: 2px dashed var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-card);
    transition: border-color 120ms ease, background-color 120ms ease;
}

.listing-photos:focus-visible,
.listing-photos.is-dragging {
    border-color: var(--rvl-primary);
    background-color: var(--rvl-accent);
    outline: none;
}

.listing-photos.is-uploading {
    opacity: 0.65;
}

.listing-photos__prompt {
    text-align: center;
}

.listing-photos__prompt-text {
    margin-bottom: 0.5rem;
    color: var(--rvl-muted-foreground);
}

.listing-photos__pick {
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

.listing-photos__input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.listing-photos__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.75rem;
    margin: 1.25rem 0 0;
    padding: 0;
    list-style: none;
}

.listing-photos__grid:empty {
    margin-top: 0;
}

.listing-photos__item {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
}

.listing-photos__item.is-cover {
    border-color: var(--rvl-primary);
    box-shadow: 0 0 0 2px var(--rvl-accent);
}

.listing-photos__thumb {
    display: block;
    width: 100%;
    height: 7rem;
    object-fit: cover;
}

.listing-photos__badge {
    display: none;
    position: absolute;
    top: 0.375rem;
    left: 0.375rem;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background-color: var(--rvl-primary);
    color: var(--rvl-on-primary);
    font-size: 0.6875rem;
    font-weight: 600;
}

.listing-photos__item.is-cover .listing-photos__badge {
    display: inline-block;
}

.listing-photos__controls {
    display: flex;
    gap: 0.125rem;
    padding: 0.25rem;
    background-color: var(--rvl-card);
}

.listing-photos__button {
    flex: 1 1 auto;
    padding: 0.25rem 0;
    border: 0;
    border-radius: calc(var(--rvl-radius) - 0.25rem);
    background: transparent;
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
    line-height: 1.2;
    cursor: pointer;
}

.listing-photos__button:hover,
.listing-photos__button:focus-visible {
    background-color: var(--rvl-accent);
    color: var(--rvl-primary-active);
}

.listing-photos__button--remove:hover,
.listing-photos__button--remove:focus-visible {
    background-color: hsl(0 84% 96%);
    color: var(--rvl-destructive);
}

.listing-photos__messages {
    margin-top: 0.75rem;
}

.listing-photos__message {
    margin-bottom: 0.25rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

/* --- The plan picker --- */

.tier-picker {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.tier-card {
    position: relative;
    display: flex;
}

.tier-card__radio {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.tier-card__body {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 100%;
    padding: 1rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
    cursor: pointer;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.tier-card__body:hover {
    border-color: var(--rvl-primary);
}

.tier-card__radio:checked + .tier-card__body {
    border-color: var(--rvl-primary);
    box-shadow: 0 0 0 2px var(--rvl-accent);
}

.tier-card__radio:focus-visible + .tier-card__body {
    outline: 2px solid var(--rvl-primary);
    outline-offset: 2px;
}

.tier-card.is-disabled .tier-card__body {
    opacity: 0.55;
    cursor: not-allowed;
}

.tier-card__name {
    font-weight: 700;
    font-size: 1.0625rem;
}

.tier-card__price {
    color: var(--rvl-primary);
    font-weight: 700;
    font-size: 1.5rem;
    line-height: 1.1;
}

.tier-card__duration,
.tier-card__photos {
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
}

.tier-card__summary {
    margin-top: 0.25rem;
    font-size: 0.875rem;
}

.tier-card__includes {
    margin: 0.5rem 0 0;
    padding-left: 1.1rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
}

.tier-card__includes li {
    margin-bottom: 0.125rem;
}

.tier-card__disabled-reason {
    margin-top: 0.5rem;
    color: var(--rvl-destructive);
    font-size: 0.8125rem;
    font-weight: 500;
}

/* --- The confirmation --- */

.listing-submitted {
    max-width: 40rem;
    padding-top: 3.5rem;
    padding-bottom: 5rem;
}

.listing-submitted__card {
    padding: 2.5rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
    text-align: center;
}

.listing-submitted__icon {
    color: var(--rvl-primary);
}

.listing-submitted__title {
    margin: 1rem 0 0.75rem;
    font-size: 1.75rem;
    font-weight: 700;
}

.listing-submitted__lead {
    color: var(--rvl-muted-foreground);
}

.listing-submitted__steps {
    display: inline-block;
    margin: 1.25rem 0;
    padding-left: 1.25rem;
    text-align: left;
}

.listing-submitted__steps li {
    margin-bottom: 0.375rem;
}

.listing-submitted__note {
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
}

.listing-submitted__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* ----------------------------------------------------------- 11. Quick search --------- */

/*
    The global quick-search palette (global-search-spec.md) and the header trigger that opens it.

    Kept out of section 3 even though half of it is header chrome: the trigger and the palette are
    one feature and read as one block, and the shell above stays what it was before the palette
    existed.
*/

/* The header trigger. A real search form with script off, a button-shaped hint with it on. */
.site-header__search {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
    max-width: 22rem;
    flex: 1 1 14rem;
    margin-left: 0.75rem;
}

.site-header__search-icon {
    position: absolute;
    left: 0.625rem;
    width: 1rem;
    height: 1rem;
    color: var(--rvl-muted-foreground);
    pointer-events: none;
}

.site-header__search-input {
    height: 2.25rem;
    padding-left: 2.125rem;
    /* Room at the right for the keyboard hint sitting on top of the box. */
    padding-right: 3.75rem;
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-card);
    font-size: 0.875rem;
}

.site-header__search-input::placeholder {
    color: var(--rvl-muted-foreground);
}

/* The chord, parked against the right edge. Decoration only - the input keeps the click. */
.site-header__search-hint {
    position: absolute;
    right: 0.5rem;
    padding: 0.125rem 0.375rem;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) - 0.25rem);
    background-color: transparent;
    color: var(--rvl-muted-foreground);
    font-family: inherit;
    font-size: 0.6875rem;
    line-height: 1.25;
    white-space: nowrap;
    pointer-events: none;
}

/*
    The pointer that says "this opens something". Keyed on [readonly], which quick-search.js sets
    when it takes the box over - so with script off the box is still an ordinary search field and
    still looks like one.
*/
.site-header__search-input[readonly] {
    cursor: pointer;
}

/* Below Bootstrap's sm breakpoint the header has no room for it; Ctrl+K still opens the palette. */
@media (max-width: 575.98px) {
    .site-header__search {
        display: none;
    }

    /*
        The search box carries the header's auto margin, so hiding it would let the nav drift into
        the middle of the bar. Hand the margin back to the nav for as long as it is gone.
    */
    .site-header .navbar-nav {
        margin-right: auto;
    }
}

/* The palette itself. */
.quick-search__dialog {
    max-width: 40rem;
    /* Palettes sit high on the viewport rather than centred - the eye is already at the header. */
    margin-top: 4.5rem;
}

.quick-search__content {
    overflow: hidden;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    box-shadow: 0 1.5rem 3rem rgba(var(--rvl-foreground-rgb), 0.18);
}

.quick-search__field {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem 1rem;
    border-bottom: 1px solid var(--rvl-border);
}

.quick-search__field-icon {
    flex: 0 0 auto;
    width: 1.125rem;
    height: 1.125rem;
    color: var(--rvl-muted-foreground);
}

/* Borderless on purpose: the field's frame is the palette's own top row. */
.quick-search__input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: none;
    color: var(--rvl-foreground);
    font-size: 1rem;
    line-height: 1.5;
    outline: none;
}

.quick-search__input::placeholder {
    color: var(--rvl-muted-foreground);
}

.quick-search__close {
    --bs-btn-close-focus-shadow: none;
    flex: 0 0 auto;
}

.quick-search__results {
    max-height: min(24rem, 60vh);
    overflow-y: auto;
    padding: 0.5rem;
    transition: opacity 0.15s ease-in-out;
}

/* The in-flight state, when there are already rows worth keeping on screen. */
.quick-search__results[aria-busy="true"] {
    opacity: 0.55;
}

.quick-search__message {
    margin: 0;
    padding: 1.5rem 0.75rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
    text-align: center;
}

.quick-search__group + .quick-search__group,
.quick-search__group + .quick-search__row {
    margin-top: 0.375rem;
}

.quick-search__group-label {
    margin: 0;
    padding: 0.375rem 0.625rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.quick-search__row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.625rem;
    border-radius: var(--rvl-radius);
    color: var(--rvl-foreground);
    text-decoration: none;
}

/*
    One selected style for the pointer and the keyboard alike. The rows never take DOM focus - the
    caret stays in the input - so :hover and .is-active have to be the same thing, or the palette
    would appear to have two selections at once.
*/
.quick-search__row:hover,
.quick-search__row.is-active {
    background-color: var(--rvl-accent);
    color: var(--rvl-foreground);
}

.quick-search__row-icon {
    flex: 0 0 auto;
    width: 1.125rem;
    height: 1.125rem;
    color: var(--rvl-muted-foreground);
}

.quick-search__thumb {
    flex: 0 0 auto;
    width: 3.5rem;
    height: 2.625rem;
    border-radius: calc(var(--rvl-radius) - 0.125rem);
    background-color: var(--rvl-muted);
    object-fit: cover;
}

.quick-search__row-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.quick-search__row-title {
    overflow: hidden;
    font-size: 0.9375rem;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.quick-search__row-subtitle {
    overflow: hidden;
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.quick-search__row-meta {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.25rem;
}

.quick-search__price {
    color: var(--rvl-primary);
    font-size: 0.9375rem;
    font-weight: 700;
}

.quick-search__badge {
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background-color: var(--rvl-muted);
    color: var(--rvl-muted-foreground);
    font-size: 0.6875rem;
    font-weight: 600;
    white-space: nowrap;
}

.quick-search__row--all {
    margin-top: 0.375rem;
    border-top: 1px solid var(--rvl-border);
    border-radius: 0;
    padding-top: 0.625rem;
    color: var(--rvl-primary);
    font-weight: 600;
}

.quick-search__footer {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 0.625rem 1rem;
    border-top: 1px solid var(--rvl-border);
    background-color: var(--rvl-card);
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
}

.quick-search__legend kbd {
    padding: 0.0625rem 0.3125rem;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) - 0.25rem);
    background-color: var(--rvl-background);
    color: var(--rvl-muted-foreground);
    font-family: var(--rvl-font-sans);
    font-size: 0.6875rem;
}

@media (max-width: 575.98px) {
    .quick-search__footer {
        display: none;
    }
}
/* -------------------------------------------------------------- 12. Profile page ----- */

/*
    The member's own profile.

    A stack of bordered sections rather than a two-column layout, because the page is read top to
    bottom once in a while rather than scanned - and because the moderated/immediate distinction
    it has to make is carried by the note under each heading, which a narrow column would squeeze
    out.
*/

.profile-page {
    max-width: 52rem;
    padding-top: 2.5rem;
    padding-bottom: 5rem;
}

.profile-page__header {
    margin-bottom: 1.75rem;
}

.profile-page__title {
    margin-bottom: 0.375rem;
    font-size: 2rem;
    font-weight: 700;
}

.profile-page__subtitle {
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
}

.profile-section {
    margin-bottom: 1.5rem;
    padding: 1.75rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);

    /* The anchors a post redirects back to would land under the sticky header without this. */
    scroll-margin-top: calc(var(--rvl-header-height) + 1rem);
}

.profile-section__title {
    margin-bottom: 0.5rem;
    font-size: 1.25rem;
    font-weight: 600;
}

.profile-section__note {
    margin-bottom: 1rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

.profile-section__note:last-child {
    margin-bottom: 0;
}

/* The delete section is the only destructive thing on the page, and reads like it. */
.profile-section--danger {
    border-color: hsl(0 84% 88%);
    background-color: hsl(0 84% 99%);
}

/* --- Account --- */

.profile-account {
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
    margin-bottom: 1rem;
}

.profile-account__avatar {
    flex: 0 0 auto;
}

.profile-account__details {
    flex: 1 1 auto;
    min-width: 0;
    margin-bottom: 0;
}

.profile-account__row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--rvl-border);
}

.profile-account__row:last-child {
    border-bottom: none;
}

.profile-account__row dt {
    flex: 0 0 9rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
    font-weight: 500;
}

.profile-account__row dd {
    flex: 1 1 12rem;
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

/* --- Seller stats --- */

.profile-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 0.75rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
}

.profile-stat {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    padding: 0.875rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-card);
}

.profile-stat__count {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

.profile-stat__label {
    font-size: 0.875rem;
    font-weight: 600;
}

.profile-stat__description {
    color: var(--rvl-muted-foreground);
    font-size: 0.75rem;
}

.profile-rating {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
}

.profile-rating__summary {
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

.profile-rating__empty {
    margin-bottom: 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.875rem;
}

/* --- Waiting for review --- */

/*
    Tinted the same warm colour as the suspension notice rather than the success green: this is a
    "not yet" state, and it has to be distinguishable at a glance from the confirmation banner
    that appears above it after a save.
*/
.profile-pending {
    margin-bottom: 1.5rem;
    padding: 1.25rem;
    border: 1px solid hsl(38 92% 50%);
    border-radius: var(--rvl-radius);
    background-color: hsl(38 92% 97%);
}

.profile-pending__title {
    margin-bottom: 0.375rem;
    font-size: 1rem;
    font-weight: 600;
}

.profile-pending__lead {
    margin-bottom: 1rem;
    color: hsl(30 80% 28%);
    font-size: 0.875rem;
}

.profile-pending__changes {
    margin-bottom: 1rem;
}

.profile-pending__change {
    padding: 0.625rem 0;
    border-top: 1px solid hsl(38 60% 88%);
}

.profile-pending__field {
    margin-bottom: 0.375rem;
    font-size: 0.8125rem;
    font-weight: 600;
}

.profile-pending__values,
.profile-pending__images {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-bottom: 0;
}

.profile-pending__images {
    padding-top: 0.75rem;
    border-top: 1px solid hsl(38 60% 88%);
}

.profile-pending__value {
    display: flex;
    flex: 1 1 12rem;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
    font-size: 0.875rem;
    overflow-wrap: anywhere;
}

.profile-pending__value-label {
    color: var(--rvl-muted-foreground);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.profile-pending__value--proposed {
    font-weight: 500;
}

.profile-pending__cancel {
    margin-top: 1rem;
}

/* --- The forms --- */

/*
    Deliberately reuses the account pages' field rhythm rather than inventing a second one, and
    reuses .account-notice for the validation summary so a model-level error on this page looks
    like one anywhere else on the site.
*/
.profile-form__field {
    max-width: 32rem;
    margin-bottom: 1.125rem;
}

.profile-form .form-label {
    margin-bottom: 0.375rem;
    font-size: 0.875rem;
    font-weight: 500;
}

.profile-form__hint {
    margin: 0.375rem 0 0;
    color: var(--rvl-muted-foreground);
    font-size: 0.8125rem;
}

.profile-form .field-validation-error {
    display: block;
    margin-top: 0.25rem;
    color: var(--rvl-destructive);
    font-size: 0.8125rem;
}

.profile-form .validation-summary-errors ul {
    margin-bottom: 0;
    padding-left: 1.25rem;
}

.profile-form__submit {
    margin-top: 0.25rem;
}

@media (max-width: 575.98px) {
    .profile-section {
        padding: 1.25rem;
    }

    .profile-account {
        flex-direction: column;
        gap: 1rem;
    }

    .profile-account__row dt {
        flex-basis: 100%;
    }
}

/* --------------------------------------------------------- 13. Saved listings -------- */

/*
    The save heart, and the /saved page it fills.

    Filled and unfilled are ONE svg symbol: `fill` is set here, on .is-saved, rather than by
    swapping the <use> href. That is what lets the optimistic toggle change a class and be done -
    a two-symbol design would put markup surgery in the click handler for a purely visual state.
*/

.save-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 1px solid var(--rvl-border);
    border-radius: 999px;
    background-color: var(--rvl-background);
    color: var(--rvl-muted-foreground);
    text-decoration: none;
    cursor: pointer;
    transition: color 0.15s ease-in-out, border-color 0.15s ease-in-out, transform 0.1s ease-in-out;
}

.save-toggle:hover,
.save-toggle:focus-visible {
    border-color: var(--rvl-destructive);
    color: var(--rvl-destructive);
}

.save-toggle:active {
    transform: scale(0.92);
}

.save-toggle.is-saved {
    border-color: var(--rvl-destructive);
    color: var(--rvl-destructive);
}

.save-toggle.is-saved .rvl-icon {
    fill: currentColor;
}

.save-toggle-form {
    margin: 0;
    line-height: 0;
}

/*
    The heart on a card sits OVER the card's link rather than inside it - a form cannot live in an
    anchor. .listing-card is the positioned ancestor; the z-index is what keeps the button clickable
    above a link that fills the whole card.
*/
.listing-card__save {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    z-index: 2;
}

.listing-card {
    position: relative;
}

/* A listing that left the site while somebody had it saved. Greyed, badged, and not a link. */
.listing-card--unavailable .listing-card__image {
    filter: grayscale(1);
    opacity: 0.55;
}

.listing-card__link--inert {
    cursor: default;
}

.listing-card__status {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    padding: 0.25rem 0.625rem;
    border-radius: calc(var(--rvl-radius) - 0.125rem);
    background-color: var(--rvl-foreground);
    color: var(--rvl-background);
    font-size: 0.8125rem;
    font-weight: 600;
}

/* Sold is the one status with a colour of its own - overview section 8. */
.listing-card--unavailable .listing-card__status {
    background-color: var(--rvl-muted-foreground);
}

.saved {
    padding-top: 2.5rem;
    padding-bottom: 4rem;
}

.saved__header {
    margin-bottom: 1.75rem;
}

.saved__title {
    margin: 0;
    font-size: 2rem;
    font-weight: 700;
}

.saved__count {
    margin: 0.25rem 0 0;
    color: var(--rvl-muted-foreground);
}

.saved__empty {
    max-width: 32rem;
    margin: 0 auto;
    padding: 3.5rem 2rem;
    border: 1px solid var(--rvl-border);
    border-radius: calc(var(--rvl-radius) + 0.25rem);
    background-color: var(--rvl-card);
    text-align: center;
}

.saved__empty-icon {
    color: var(--rvl-muted-foreground);
}

.saved__empty-title {
    margin: 1rem 0 0.5rem;
    font-size: 1.375rem;
    font-weight: 700;
}

.saved__empty-text {
    margin-bottom: 1.5rem;
    color: var(--rvl-muted-foreground);
}

/* The heart on the detail page: beside the title, not over a photo. */
.listing-detail__title-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.listing-detail__save {
    flex: 0 0 auto;
    padding-top: 0.25rem;
}

/* ---------------------------------------------------------- 14. Share listing -------- */

/*
    The share control on the listing detail page, under the price block. Deliberately quiet:
    it is an outline button beside a filled contact block, because a visitor came here to
    reach the seller and sharing is the secondary errand.

    Only the dropdown's own layout is restyled - Bootstrap already draws the menu, and the
    seven items are ordinary dropdown-items.
*/

.listing-share {
    margin-top: 1rem;
}

.listing-share__button {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.875rem;
    font-weight: 600;
}

.listing-share__menu {
    min-width: 11rem;
    border-color: var(--rvl-border);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.12);
}

.listing-share__item {
    font-size: 0.875rem;
}

/* The copied confirmation. A colour change on the item itself - the project has no toasts. */
.listing-share__item.is-copied,
.listing-share__item.is-copied:hover {
    color: var(--rvl-primary);
    font-weight: 600;
}

/* ------------------------------------------------------- 15. Listing checkout -------- */

/*
    The card step on the create-listing form. It appears only on the re-render of a paid
    submission, below the plan picker, so it reads as the last thing before the button rather than
    as a section of the form that happened to be empty until now.

    Stripe's Payment Element renders inside an iframe this stylesheet cannot reach. What is styled
    here is the frame around it: the panel, the status line and the button. Do not try to restyle
    the card field itself from here - Stripe's own appearance API is the only way in, and a
    half-styled iframe looks worse than an unstyled one.
*/

.listing-checkout {
    padding: 1.25rem;
    border: 1px solid var(--rvl-primary);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
}

/*
    The price breakdown above the card field. A definition list because that is what it is - three
    labels and the amounts they name - and because a table would bring row semantics nothing here
    uses. The total is separated by a rule and set heavier: it is the number the button repeats and
    the only one the card is actually held for.
*/
.listing-checkout__summary {
    margin-bottom: 1rem;
}

.listing-checkout__line {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.25rem 0;
}

.listing-checkout__line dt,
.listing-checkout__line dd {
    margin: 0;
}

/* Tabular figures so the amounts line up on their decimal points rather than drifting. */
.listing-checkout__line dd {
    font-variant-numeric: tabular-nums;
}

.listing-checkout__line--total {
    margin-top: 0.25rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--rvl-border);
    font-weight: 600;
}

/* Enough height that the panel does not jump as the element finishes mounting. */
.listing-checkout__element {
    min-height: 5rem;
    margin-bottom: 0.75rem;
}

/*
    The live region the confirm step talks through - a decline, a network failure, the hand-off to
    the second post. Empty until something is said, so it takes no space on arrival.
*/
.listing-checkout__status:empty {
    display: none;
}

.listing-checkout__status {
    margin-bottom: 0.75rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
}

.listing-checkout__submit {
    width: 100%;
}

@media (min-width: 576px) {
    .listing-checkout__submit {
        width: auto;
    }
}

/* --------------------------------------------------------- 16. Saved searches -------- */

/*
    The "Save this search" control on browse, the /saved/searches page, the save confirmation, and
    the unsubscribe landing page.

    Nothing here is a variant of section 13's heart. A saved listing is a state on one card and
    reads as an icon; a saved search is a standing thing with a name, a count and an email setting,
    and it reads as a row - so the two share the heart glyph and nothing else.
*/

/* --- The control on browse --- */

.save-search {
    display: inline-flex;
    align-items: baseline;
}

.save-search__link {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--rvl-muted-foreground);
    font-size: 0.9375rem;
    text-decoration: none;
}

.save-search__link:hover,
.save-search__link:focus-visible {
    color: var(--rvl-primary);
    text-decoration: underline;
}

.save-search__link .rvl-icon {
    width: 1rem;
    height: 1rem;
}

/* Not a button, so it does not look like one that is broken. */
.save-search__hint {
    font-size: 0.9375rem;
}

.save-search__notice {
    margin-bottom: 1.25rem;
    padding: 0.625rem 0.875rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-accent);
    font-size: 0.9375rem;
}

.save-search__notice a {
    margin-left: 0.375rem;
}

/* --- The confirmation page --- */

.save-search-confirm {
    max-width: 34rem;
    padding-top: 1.5rem;
    padding-bottom: 3rem;
}

.save-search-confirm__title {
    margin-bottom: 1rem;
    font-size: 1.625rem;
    font-weight: 700;
}

.save-search-confirm__empty {
    margin-bottom: 1.25rem;
    color: var(--rvl-muted-foreground);
}

.save-search-confirm__filters,
.saved-search__filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
}

.save-search-confirm__filter,
.saved-search__filter {
    padding: 0.1875rem 0.5rem;
    border: 1px solid var(--rvl-border);
    border-radius: 999px;
    background-color: var(--rvl-card);
    font-size: 0.8125rem;
}

.save-search-confirm__filter-name,
.saved-search__filter-name {
    color: var(--rvl-muted-foreground);
}

.save-search-confirm__note {
    margin: 0.75rem 0 1.25rem;
    font-size: 0.875rem;
}

.save-search-confirm__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* --- The saved-searches page --- */

.saved-searches {
    padding-top: 1.5rem;
    padding-bottom: 3rem;
}

.saved-searches__header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 1rem;
    margin-bottom: 1.25rem;
}

.saved-searches__title {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
}

.saved-searches__count {
    margin: 0;
    color: var(--rvl-muted-foreground);
}

/*
    The link across to /saved, and its twin there. The two halves of overview section 9.11 sit one
    click apart because the account menu offers only the listings half - every item there is
    conditional on its route and the whole set is pinned by a test, so adding one is that test's
    business rather than this feature's.
*/
.saved-searches__sibling,
.saved__sibling {
    margin-left: auto;
    font-size: 0.9375rem;
}

.saved-searches__notice,
.saved-searches__limit {
    margin-bottom: 1.25rem;
    padding: 0.625rem 0.875rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-accent);
    font-size: 0.9375rem;
}

.saved-searches__empty {
    padding: 3rem 1rem;
    border: 1px dashed var(--rvl-border);
    border-radius: var(--rvl-radius);
    text-align: center;
}

.saved-searches__empty-icon {
    color: var(--rvl-muted-foreground);
}

.saved-searches__empty-title {
    margin: 1rem 0 0.5rem;
    font-size: 1.375rem;
    font-weight: 700;
}

.saved-searches__empty-text {
    margin-bottom: 1.5rem;
    color: var(--rvl-muted-foreground);
}

.saved-searches__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.saved-search {
    padding: 1rem;
    margin-bottom: 0.75rem;
    border: 1px solid var(--rvl-border);
    border-radius: var(--rvl-radius);
    background-color: var(--rvl-background);
}

.saved-search__top {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.saved-search__name {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 700;
}

.saved-search__count {
    color: var(--rvl-primary);
    font-size: 0.9375rem;
    text-decoration: none;
    white-space: nowrap;
}

.saved-search__count:hover,
.saved-search__count:focus-visible {
    text-decoration: underline;
}

.saved-search__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.saved-search__frequency,
.saved-search__rename {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin: 0;
}

.saved-search__rename .form-control {
    width: 12rem;
}

.saved-search__delete {
    margin: 0 0 0 auto;
}

/* On a phone the row's controls stack rather than squeezing a text field to nothing. */
@media (max-width: 575.98px) {
    .saved-search__controls {
        flex-direction: column;
        align-items: stretch;
    }

    .saved-search__rename .form-control {
        width: 100%;
    }

    .saved-search__delete {
        margin-left: 0;
    }
}

/* --- The unsubscribe landing page --- */

.unsubscribe {
    max-width: 34rem;
    padding-top: 2.5rem;
    padding-bottom: 3rem;
}

.unsubscribe__title {
    margin-bottom: 1rem;
    font-size: 1.625rem;
    font-weight: 700;
}

.unsubscribe__text {
    margin-bottom: 1.25rem;
}

.unsubscribe__undo,
.unsubscribe__all {
    margin-bottom: 1.5rem;
}

.unsubscribe__manage {
    margin-top: 2rem;
    font-size: 0.9375rem;
}
