/*
VowPair "fresh editorial" theme -- layered on top of the vendored Bootswatch
LUX stylesheet (theme_assets/vendor/bootswatch/lux.min.css). Explicit rules
rather than CSS-variable overrides, since Bootswatch bakes several LUX
colors directly into compiled selectors rather than only through
`--bs-*` custom properties.
*/

/*
Palette: a "quiet luxury" bridal mood -- muted dusty-rose/wine in place of the
earlier rustic terracotta, a cooler warm-ivory background, and a soft
champagne gold reserved for small accents (icon circles, dividers). The aim
is calm and unhurried rather than loud/celebratory -- low chroma throughout,
nothing saturated enough to read as an alert.
*/
:root {
    --vp-ink: #2f2b30;
    --vp-ink-soft: #6b6470;
    /* Page backdrop is a visibly deeper "linen" tone and surfaces are pure
       white (was #faf6f1/#fffefc -- only ~2% apart in lightness, so cards
       barely lifted off the page). The ~8% lightness gap here, plus a
       slightly firmer hairline and a touch more shadow below, is what gives
       every card/list real separation from the page -- same warm palette,
       just enough contrast to read as distinct layers (the brief: "more
       contrast and element separation, same look" -- referencing HoneyBook's
       dashboard as an example of the layering, not its cool neutral palette). */
    --vp-cream: #f2ebe1;
    --vp-surface: #ffffff;
    --vp-hairline: #e2d7c7;
    --vp-accent: #8c5a63;
    --vp-accent-dark: #6d434b;
    --vp-accent-soft: #f2e6e4;
    --vp-sage: #7c8a72;
    --vp-gold: #ab8a4a;
    --vp-gold-soft: #f2ead4;
    --vp-font-display: "Playfair Display", Georgia, "Times New Roman", serif;

    /* Soft ambient elevation -- low-opacity ink, never pure black, so
       shadows read as a gentle lift rather than a hard drop shadow. Deepened
       slightly alongside the palette change above so a card's *resting*
       state already has a visible lift, not just on hover. */
    --vp-shadow-sm: 0 1px 3px rgba(47, 43, 48, .08), 0 3px 8px rgba(47, 43, 48, .06);
    --vp-shadow-md: 0 10px 24px rgba(47, 43, 48, .10), 0 3px 8px rgba(47, 43, 48, .07);
    --vp-shadow-lg: 0 16px 40px rgba(47, 43, 48, .14);
}

/* Sticky footer: <nav>, the messages container, <main>, and <footer> are
   all direct children of <body> (see base.html) -- making body a flex
   column and letting <main> alone grow to fill any leftover height keeps
   the footer pinned to the bottom of the viewport on short pages, without
   it floating mid-screen, while a page with enough content to scroll
   behaves exactly as before. */
html, body {
    min-height: 100%;
}
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background-color: var(--vp-cream);
    color: var(--vp-ink);
}
main {
    flex: 1 0 auto;
}

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

/* Override LUX's default uppercase, wide-tracked headings (h1,h2,h3,h4,h5,h6
{text-transform:uppercase;letter-spacing:3px} in lux.min.css) -- that reads
as corporate/luxury, not editorial. A quiet mixed-case serif is the point. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.display-1, .display-2, .display-3, .display-4 {
    font-family: var(--vp-font-display);
    font-weight: 700;
    color: var(--vp-ink);
    text-transform: none;
    letter-spacing: -0.01em;
}

.navbar-brand {
    font-family: var(--vp-font-display);
}

h1 { margin-bottom: 1rem; }
h2 { margin-top: 3rem; margin-bottom: 1rem; }

.lead {
    color: var(--vp-ink-soft);
    font-weight: 400;
}

/* Small uppercase "kicker" label used above page/section headings. */
.eyebrow {
    display: inline-block;
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--vp-accent);
    margin-bottom: .5rem;
}

a {
    color: var(--vp-accent-dark);
}
a:hover {
    color: var(--vp-accent);
}

hr {
    border-top: 1px solid var(--vp-hairline);
    opacity: 1;
}

/* ---- Navbar: light editorial masthead instead of LUX's dark bar ----
   Deliberately var(--vp-surface), not the page's own --vp-cream -- the two
   were identical before, so the masthead only read as separate from the
   page via its 1px hairline. Using the same "surface" tone as cards gives
   it a quiet, deliberate lift off the cream background. */
.navbar-editorial {
    background-color: var(--vp-surface);
    border-bottom: 1px solid var(--vp-hairline);
    padding-top: .9rem;
    padding-bottom: .9rem;
    box-shadow: 0 0 0 rgba(47, 43, 48, 0);
    transition: box-shadow .25s ease;
}
/* Toggled by editorial.js once the page scrolls past the masthead -- a
   quiet depth cue instead of a shadow that's always there. */
.navbar-editorial--scrolled {
    box-shadow: var(--vp-shadow-sm);
}
.navbar-editorial .navbar-brand {
    font-family: var(--vp-font-display);
    font-style: italic;
    font-size: 1.6rem;
    color: var(--vp-ink);
}
.navbar-editorial .nav-link {
    position: relative;
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--vp-ink-soft);
    padding-left: .85rem;
    padding-right: .85rem;
    transition: color .15s ease;
}
.navbar-editorial .nav-link:hover,
.navbar-editorial .nav-link.active {
    color: var(--vp-accent-dark);
}
/* Small underline-grow accent instead of a static one -- only on links that
   go somewhere (not the disabled username / dropdown toggle). */
.navbar-editorial .nav-link:not(.disabled):not(.dropdown-toggle)::after {
    content: "";
    position: absolute;
    left: .85rem;
    right: .85rem;
    bottom: .1rem;
    height: 2px;
    background: var(--vp-accent);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .2s ease;
}
.navbar-editorial .nav-link:not(.disabled):not(.dropdown-toggle):hover::after {
    transform: scaleX(1);
}
.navbar-editorial .btn-nav-cta {
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* ---- Buttons: soft rounded corners, muted dusty-rose accent, a gentle
   press/lift on interaction so clicking feels tactile rather than static ---- */
.btn {
    border-radius: 6px;
    font-weight: 600;
    letter-spacing: .01em;
    transition: transform .12s ease, box-shadow .12s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn-primary {
    background-color: var(--vp-accent);
    border-color: var(--vp-accent);
    color: #fff;
    box-shadow: var(--vp-shadow-sm);
}
.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--vp-accent-dark);
    border-color: var(--vp-accent-dark);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--vp-shadow-md);
}
.btn-primary:active {
    transform: translateY(0);
    box-shadow: var(--vp-shadow-sm);
}
.btn-outline-primary {
    color: var(--vp-accent-dark);
    border-color: var(--vp-accent);
}
.btn-outline-primary:hover {
    background-color: var(--vp-accent);
    border-color: var(--vp-accent);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--vp-shadow-md);
}
.btn-outline-primary:active {
    transform: translateY(0);
    box-shadow: none;
}
.btn-secondary {
    background-color: var(--vp-sage);
    border-color: var(--vp-sage);
}

/* ---- Cards / surfaces: hairline border, soft ambient shadow ---- */
.card {
    background-color: var(--vp-surface);
    border: 1px solid var(--vp-hairline);
    border-radius: 10px;
    box-shadow: var(--vp-shadow-sm);
    transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.card + .card {
    margin-top: 1.25rem;
}
/* Whole-card links (opportunity/selection lists) get a bit more lift on
   hover than static info cards, since the entire card is the click target. */
a.text-decoration-none:hover > .card {
    box-shadow: var(--vp-shadow-md);
    transform: translateY(-2px);
    border-color: var(--vp-accent);
}
a.text-decoration-none:active > .card {
    transform: translateY(0);
    box-shadow: var(--vp-shadow-sm);
}

/* ---- Forms ---- */
.form-control:focus,
.form-select:focus {
    border-color: var(--vp-accent);
    box-shadow: 0 0 0 .2rem rgba(140, 90, 99, .15);
}
label {
    font-weight: 600;
    font-size: .9rem;
}

/* ---- Hero section on the home page ---- */
.vp-hero {
    padding: 5.5rem 0 4rem;
    border-bottom: 1px solid var(--vp-hairline);
}
.vp-hero h1 {
    font-size: clamp(2.25rem, 4vw, 3.4rem);
    max-width: 18ch;
}
.vp-hero .lead {
    max-width: 52ch;
    font-size: 1.15rem;
}

/* ---- Split hero (marketing pages: home, for-vendors) -- headline/CTA
   beside a real photo instead of a text-only banner. The photo gets the
   same soft rounded/shadowed treatment as every other surface (.card,
   .vp-role-card) rather than a full-bleed background image, so it reads as
   one more editorial "framed" element instead of needing a dark gradient
   overlay just to keep text legible on top of it. ---- */
.vp-hero--split {
    padding: 4.5rem 0;
    border-bottom: 1px solid var(--vp-hairline);
}
.vp-hero--split h1 {
    font-size: clamp(2.1rem, 3.6vw, 3.1rem);
    max-width: 16ch;
}
.vp-hero--split .lead {
    max-width: 46ch;
    font-size: 1.1rem;
}
.vp-hero__copy {
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100%;
}
.vp-hero__image-wrap {
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--vp-shadow-lg);
    aspect-ratio: 4 / 3;
}
.vp-hero__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
@media (max-width: 767px) {
    .vp-hero__image-wrap {
        margin-top: 2.5rem;
        aspect-ratio: 16 / 10;
    }
}

/* ---- Numbered "how it works" steps (marketing pages) ---- */
.vp-step {
    text-align: center;
    padding: 0 .5rem;
}
.vp-step__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--vp-accent-soft);
    color: var(--vp-accent-dark);
    font-family: var(--vp-font-display);
    font-weight: 700;
    font-size: 1.3rem;
    margin-bottom: 1rem;
}
.vp-step h4 {
    margin-top: 0;
}

.vp-role-card {
    border: 1px solid var(--vp-hairline);
    background: var(--vp-surface);
    padding: 2rem;
    height: 100%;
    border-radius: 10px;
    box-shadow: var(--vp-shadow-sm);
    transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.vp-role-card:hover {
    border-color: var(--vp-accent);
    box-shadow: var(--vp-shadow-md);
    transform: translateY(-2px);
}
.vp-role-card h3 {
    margin-top: 0;
}

/* ---- Category picker (bride "start a new request" grid) ----
   A justified grid -- auto-fill/minmax stretches the last row's cards to
   fill the full row width instead of a left-aligned cluster of buttons -- one
   icon-topped card per category, sized for a calm scan rather than a wall of
   text links. */
.vp-category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 1rem;
}
.vp-category-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: .65rem;
    padding: 1.75rem 1rem;
    background: var(--vp-surface);
    border: 1px solid var(--vp-hairline);
    border-radius: 10px;
    box-shadow: var(--vp-shadow-sm);
    text-decoration: none;
    color: var(--vp-ink);
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.vp-category-card:hover,
.vp-category-card:focus {
    border-color: var(--vp-accent);
    transform: translateY(-3px);
    box-shadow: var(--vp-shadow-md);
    color: var(--vp-ink);
}
.vp-category-card:hover .vp-category-card__icon {
    transform: scale(1.08);
}
.vp-category-card:active {
    transform: translateY(-1px);
    box-shadow: var(--vp-shadow-sm);
}
/* Checkbox variant (services_select.html) -- a <label> wrapping a visually-
   hidden checkbox, styled identically to the plain <a> category cards
   elsewhere. :has() gives a real "selected" highlight with no JS; on the
   rare browser without :has() support the checkbox still works, it just
   won't visibly highlight. */
.vp-category-card--checkbox {
    cursor: pointer;
    user-select: none;
}
.vp-category-card--checkbox:has(input:checked) {
    border-color: var(--vp-accent);
    background: var(--vp-accent-soft);
}
.vp-category-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--vp-accent-soft);
    color: var(--vp-accent-dark);
    font-size: 1.35rem;
    box-shadow: var(--vp-shadow-sm);
    transition: transform .2s ease;
}
.vp-category-card__name {
    font-weight: 600;
    font-size: .92rem;
}

/* ---- Vendor photo gallery (dashboard editor + public profile) ---- */
.vp-gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: .75rem;
}
.vp-gallery-grid__item {
    position: relative;
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--vp-hairline);
    box-shadow: var(--vp-shadow-sm);
}
.vp-gallery-grid__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.vp-gallery-grid__delete {
    position: absolute;
    top: .4rem;
    right: .4rem;
    width: 28px;
    height: 28px;
    padding: 0;
    line-height: 1;
    border-radius: 50%;
    border: none;
    background: rgba(47, 43, 48, .55);
    color: #fff;
    font-size: .9rem;
}
.vp-gallery-grid__delete:hover {
    background: var(--vp-accent-dark);
}

/* Public-profile gallery thumbnails are real <button>s (keyboard/AT
   accessible) styled to look identical to the plain <div> tiles elsewhere --
   this modifier only resets the button-specific defaults (padding, UA
   background/font), leaving position/aspect-ratio/border/shadow to the
   shared .vp-gallery-grid__item rule above. */
.vp-gallery-grid__item--clickable {
    display: block;
    width: 100%;
    padding: 0;
    background: none;
    font: inherit;
    cursor: pointer;
    text-align: inherit;
    transition: transform .15s ease, box-shadow .15s ease;
}
.vp-gallery-grid__item--clickable:hover,
.vp-gallery-grid__item--clickable:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--vp-shadow-md);
}
.vp-gallery-grid__item--clickable:focus-visible {
    outline: 2px solid var(--vp-accent);
    outline-offset: 2px;
}

/* Same idea for the vendor's own "Photos" editor, where the outer
   .vp-gallery-grid__item stays a plain <div> (it needs to keep being the
   positioning context for the absolutely-positioned delete button) and
   only the image itself is wrapped in a full-fill button -- a sibling of
   the delete form/button, so clicking delete never opens the lightbox. */
.vp-gallery-grid__photo-button {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.vp-gallery-grid__photo-button:focus-visible {
    outline: 2px solid var(--vp-accent);
    outline-offset: -2px;
}

/* ---- Full-screen photo lightbox (editorial.js) ---- */
.vp-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    background: rgba(20, 18, 20, .92);
}
.vp-lightbox[hidden] {
    display: none;
}
.vp-lightbox__figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .75rem;
    max-width: min(90vw, 1100px);
    max-height: 88vh;
    margin: 0;
}
.vp-lightbox__image {
    max-width: 100%;
    max-height: 78vh;
    object-fit: contain;
    border-radius: 6px;
    box-shadow: var(--vp-shadow-lg);
}
.vp-lightbox__caption {
    color: #fff;
    font-size: .95rem;
    opacity: .85;
    text-align: center;
}
.vp-lightbox__caption:empty {
    display: none;
}
.vp-lightbox__control {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12);
    color: #fff;
    font-size: 1.25rem;
    cursor: pointer;
    transition: background-color .15s ease;
}
.vp-lightbox__control:hover,
.vp-lightbox__control:focus-visible {
    background: rgba(255, 255, 255, .26);
}
.vp-lightbox__control:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}
.vp-lightbox__close {
    top: 1.5rem;
    right: 1.5rem;
}
.vp-lightbox__prev {
    left: 1.5rem;
    top: 50%;
    transform: translateY(-50%);
}
.vp-lightbox__next {
    right: 1.5rem;
    top: 50%;
    transform: translateY(-50%);
}
.vp-lightbox__counter {
    position: absolute;
    bottom: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    color: #fff;
    font-size: .85rem;
    letter-spacing: .05em;
    opacity: .8;
}
@media (max-width: 576px) {
    .vp-lightbox__prev { left: .5rem; }
    .vp-lightbox__next { right: .5rem; }
    .vp-lightbox__close { top: .75rem; right: .75rem; }
}

/* ---- Service request card: category icon + selected-vendor chip ---- */
.vp-request-icon {
    color: var(--vp-accent-dark);
    font-size: .95em;
}

.vp-selected-vendor-chip {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    margin-top: .6rem;
    padding: .3rem .7rem .3rem .3rem;
    background: var(--vp-accent-soft);
    border-radius: 999px;
    text-decoration: none;
    color: var(--vp-ink);
    font-size: .85rem;
    font-weight: 600;
    transition: background-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.vp-selected-vendor-chip:hover {
    background: var(--vp-gold-soft);
    color: var(--vp-ink);
    box-shadow: var(--vp-shadow-sm);
    transform: translateY(-1px);
}
.vp-selected-vendor-chip__logo {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}
.vp-selected-vendor-chip__logo--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--vp-surface);
    color: var(--vp-accent-dark);
    font-size: .8rem;
}

/* ---- Vendor directory listing row (logo/fallback icon + name + short
   description) -- a bigger cousin of the selected-vendor chip above, sized
   for a scannable list rather than an inline pill. ---- */
.vp-vendor-row__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--vp-accent-soft);
    color: var(--vp-accent-dark);
    font-size: 1.5rem;
    flex-shrink: 0;
    overflow: hidden;
}
.vp-vendor-row__logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.vp-vendor-row__info {
    /* flex-basis:0 + min-width:0 (not the flex-item default "auto") is what
       lets this column actually shrink instead of forcing the price on its
       own wrapped line -- a long description's intrinsic width would
       otherwise overflow the row before ever wrapping its own text. */
    flex: 1 1 0;
    min-width: 0;
}
.vp-vendor-row__desc {
    color: var(--vp-ink-soft);
    font-size: .9rem;
    margin-top: .2rem;
    margin-bottom: 0;
    overflow-wrap: break-word;
}
@media (max-width: 420px) {
    .vp-vendor-row__info + span.text-muted {
        display: block;
        margin-top: .5rem;
    }
}

footer.vp-footer {
    background-color: var(--vp-surface);
    border-top: 1px solid var(--vp-hairline);
    color: var(--vp-ink-soft);
    font-size: .875rem;
    padding: 2rem 0;
    margin-top: 4rem;
}

.badge-match {
    font-family: var(--vp-font-display);
    font-style: italic;
    font-size: 1.4rem;
    color: var(--vp-accent-dark);
}

/* ---- Match score hero (opportunity detail) -- the number a vendor is
   actually deciding on, so it gets real visual weight instead of a small
   italic kicker. ---- */
.vp-match-score {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .1rem .5rem;
    margin-bottom: .35rem;
}
.vp-match-score__value {
    font-family: var(--vp-font-display);
    font-weight: 700;
    font-size: 4rem;
    line-height: 1;
    color: var(--vp-accent-dark);
}
.vp-match-score__percent {
    font-family: var(--vp-font-display);
    font-weight: 700;
    font-size: 2rem;
    color: var(--vp-accent-dark);
}
.vp-match-score__label {
    font-size: .85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--vp-ink-soft);
    align-self: center;
}
/* Smaller cousin for use inside a card (e.g. one Budget Match option among
   several), where the full 4rem hero treatment would overwhelm the row. */
.vp-match-score--compact .vp-match-score__value {
    font-size: 2.25rem;
}
.vp-match-score--compact .vp-match-score__percent {
    font-size: 1.1rem;
}

/* ---- Detail grid (opportunity detail's wedding-facts panel) -- hairline
   rows with a bold label column and a larger, higher-contrast value column,
   plus subtle zebra striping so a long list of facts stays easy to scan. ---- */
.vp-detail-grid {
    border: 1px solid var(--vp-hairline);
    border-radius: 10px;
    overflow: hidden;
    background: var(--vp-surface);
    box-shadow: var(--vp-shadow-sm);
}
.vp-detail-grid__row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    padding: 1rem 1.35rem;
    border-bottom: 1px solid var(--vp-hairline);
}
.vp-detail-grid__row:last-child {
    border-bottom: none;
}
/* A warm blush tint (the same token used for tag/chip fills elsewhere), not
   --vp-cream -- now that --vp-cream is the page's own backdrop color,
   reusing it here made every other row blend straight into the page behind
   the card instead of reading as a stripe within it. The blush hue (rosier
   than the page's neutral tan) reads as a stripe by color, not just by a
   fractional lightness difference. */
.vp-detail-grid__row:nth-child(even) {
    background: var(--vp-accent-soft);
}
.vp-detail-grid__row--stacked {
    flex-direction: column;
    align-items: stretch;
    gap: .6rem;
}
.vp-detail-grid__label {
    flex: 0 0 42%;
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--vp-ink-soft);
    padding-top: .15rem;
}
.vp-detail-grid__value {
    flex: 1;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--vp-ink);
    text-align: right;
}
.vp-detail-grid__row--stacked .vp-detail-grid__value {
    text-align: left;
}
.vp-detail-grid__value--muted {
    font-weight: 400;
    color: var(--vp-ink-soft);
    font-size: 1rem;
}

.vp-tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
}
.vp-tag {
    display: inline-block;
    padding: .3rem .75rem;
    background: var(--vp-accent-soft);
    color: var(--vp-ink);
    border-radius: 999px;
    font-size: .88rem;
    font-weight: 600;
    white-space: nowrap;
}

/* ---- Vendor analytics dashboard ---- */
.vp-hero-stat {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2rem;
    padding: 2rem 2.25rem;
    background: var(--vp-surface);
    border: 1px solid var(--vp-hairline);
    border-radius: 14px;
    box-shadow: var(--vp-shadow-sm);
}
.vp-hero-stat__figure {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
.vp-hero-stat__divider {
    width: 1px;
    align-self: stretch;
    background: var(--vp-hairline);
}
.vp-hero-stat__secondary {
    font-size: 1rem;
    color: var(--vp-ink-soft);
}
.vp-hero-stat__secondary strong {
    display: block;
    font-family: var(--vp-font-display);
    font-size: 1.9rem;
    font-weight: 700;
    color: var(--vp-ink);
    line-height: 1.15;
}
.vp-hero-stat__secondary a {
    color: var(--vp-accent-dark);
    text-decoration: none;
    font-weight: 600;
    font-size: .85rem;
}
.vp-hero-stat__secondary a:hover {
    text-decoration: underline;
}

.vp-analytics-section-title {
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--vp-accent-dark);
    margin-bottom: .15rem;
}
.vp-analytics-section-desc {
    color: var(--vp-ink-soft);
    font-size: .92rem;
    margin-bottom: 1.1rem;
}

.vp-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 1rem;
}
.vp-stat-card {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    height: 100%;
    padding: 1.35rem;
}
.vp-stat-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--vp-accent-soft);
    color: var(--vp-accent-dark);
    font-size: 1.1rem;
}
.vp-stat-card__value {
    font-family: var(--vp-font-display);
    font-weight: 700;
    font-size: 2.1rem;
    color: var(--vp-ink);
    line-height: 1;
}
.vp-stat-card__label {
    color: var(--vp-ink-soft);
    font-size: .88rem;
    font-weight: 600;
    flex-grow: 1;
}
.vp-stat-card__link {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: .82rem;
    font-weight: 700;
    color: var(--vp-accent-dark);
}
a.vp-stat-card-link {
    text-decoration: none;
    color: inherit;
    display: block;
    height: 100%;
}
a.vp-stat-card-link:hover .vp-stat-card__link,
a.vp-stat-card-link:focus .vp-stat-card__link {
    text-decoration: underline;
}
a.vp-stat-card-link:hover .card,
a.vp-stat-card-link:focus .card {
    box-shadow: var(--vp-shadow-md);
    transform: translateY(-2px);
    border-color: var(--vp-accent);
}
a.vp-stat-card-link:active .card {
    transform: translateY(0);
    box-shadow: var(--vp-shadow-sm);
}

.vp-checklist-progress {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: 1rem;
}
.vp-checklist-progress__bar {
    flex: 1;
    height: 8px;
    border-radius: 999px;
    background: var(--vp-cream);
    overflow: hidden;
}
.vp-checklist-progress__fill {
    height: 100%;
    background: var(--vp-sage);
    border-radius: 999px;
    transition: width .6s cubic-bezier(.22, 1, .36, 1);
}
.vp-checklist-progress__count {
    font-weight: 700;
    color: var(--vp-ink-soft);
    font-size: .9rem;
    white-space: nowrap;
}

.vp-checklist {
    list-style: none;
    padding: 0;
    margin: 0;
}
.vp-checklist li {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .7rem 0;
    border-bottom: 1px solid var(--vp-hairline);
}
.vp-checklist li:last-child {
    border-bottom: none;
}
.vp-checklist__icon {
    font-size: 1.1rem;
    flex-shrink: 0;
}
.vp-checklist__icon--done {
    color: var(--vp-sage);
}
.vp-checklist__icon--todo {
    color: var(--vp-ink-soft);
    opacity: .5;
}
.vp-checklist__label {
    flex-grow: 1;
    color: var(--vp-ink);
}
.vp-checklist__label--done {
    color: var(--vp-ink-soft);
    text-decoration: line-through;
    text-decoration-color: var(--vp-hairline);
}
.vp-checklist a.vp-checklist__cta {
    font-size: .85rem;
    font-weight: 700;
    color: var(--vp-accent-dark);
    text-decoration: none;
    white-space: nowrap;
}
.vp-checklist a.vp-checklist__cta:hover {
    text-decoration: underline;
}

/* ---- Budget breakdown bar (part-to-whole, one segment per category) ----
   Each segment is independently rounded (not just the bar's outer ends) so
   the whole bar reads as a row of soft pills rather than one hard-edged
   strip -- a 3px cream gap between segments keeps each one visually
   distinct at this height. */
.vp-budget-bar {
    display: flex;
    gap: 3px;
    height: 44px;
    background: var(--vp-cream);
    border-radius: 22px;
    box-shadow: var(--vp-shadow-sm);
}
.vp-budget-bar__segment {
    height: 100%;
    border-radius: 10px;
    transition: width 1s cubic-bezier(.22, 1, .36, 1);
}
@media (prefers-reduced-motion: reduce) {
    .vp-budget-bar__segment {
        transition: none;
    }
}

.vp-budget-legend {
    display: flex;
    flex-wrap: wrap;
    column-gap: 1.5rem;
    row-gap: .4rem;
    margin-top: .75rem;
    font-size: .875rem;
    color: var(--vp-ink-soft);
}
.vp-budget-legend__item {
    display: flex;
    align-items: center;
    gap: .4rem;
}
.vp-budget-legend__swatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.vp-budget-legend__amount {
    color: var(--vp-ink);
    font-weight: 600;
}

.vp-notification-badge {
    font-size: .65rem;
    position: relative;
    top: -1px;
    margin-left: .25rem;
}

/* ---- Alerts: rounded to match the theme, soft shadow, dismissible ---- */
.alert {
    border-radius: 8px;
    border: none;
    box-shadow: var(--vp-shadow-sm);
}

/* ---- Vendor opportunity list row -- a scannable row (name/category, a
   location/date/budget meta line, a couple of preference tags) with the
   match score pulled out to its own column, instead of one line of text and
   a small italic badge. ---- */
.vp-opportunity-card__meta {
    display: flex;
    flex-wrap: wrap;
    column-gap: 1.1rem;
    row-gap: .3rem;
    margin-top: .4rem;
    color: var(--vp-ink-soft);
    font-size: .88rem;
}
.vp-opportunity-card__meta span {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}
.vp-opportunity-card__meta i {
    color: var(--vp-accent-dark);
}
.vp-opportunity-card__score {
    text-align: right;
}

/* ---- Generic empty state -- an icon-topped, centered message instead of a
   single muted sentence, for any list page with nothing in it yet. ---- */
.vp-empty-state {
    text-align: center;
    padding: 3.5rem 1.5rem;
}
.vp-empty-state__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--vp-accent-soft);
    color: var(--vp-accent-dark);
    font-size: 1.6rem;
    margin-bottom: 1rem;
}
.vp-empty-state h2 {
    margin-top: 0;
}
.vp-empty-state p {
    max-width: 42ch;
    margin-left: auto;
    margin-right: auto;
}

/* ---- Scroll-reveal (editorial.js) ----
   Progressive enhancement only: `vp-js` is added by JS after it confirms an
   IntersectionObserver is available, so a no-JS/slow-JS visitor always sees
   full content immediately -- nothing is ever hidden by default in CSS
   alone. Motion is skipped entirely under prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
    html.vp-js .vp-reveal {
        opacity: 0;
        transform: translateY(14px);
        transition: opacity .5s ease, transform .5s ease;
    }
    html.vp-js .vp-reveal.vp-revealed {
        opacity: 1;
        transform: none;
    }
}
