/* Little Favour — pastel/neutral palette for eco-conscious party bags and
   wedding favours. Every foreground/background pair below meets WCAG AA:
   -deep variants are the text-safe versions, the lighter ones are for fills
   and borders only. */
:root {
    /* Badge text tones: darker than the -deep tokens because they sit on a
       tinted fill rather than on cream. */
    --on-blush: #92594D;
    --on-sand: #905839;
    --terracotta-light: #D8976F;
    --sage: #6F8F76;
    --sage-deep: #4F6B57;
    --sage-light: #9FB59F;
    --blush: #E6C9C2;
    --blush-deep: #9E6154;
    --terracotta: #C08663;
    --terracotta-deep: #9C5F3E;
    --sand: #EDE4D8;
    --cream: #FBF8F4;
    --ink: #3D382F;
    --muted: #6E6659;
    --line: #E5DCD0;
}

body {
    font-family: "Nunito Sans", sans-serif;
    color: var(--ink);
    background: var(--cream);
}

h1,
h2,
h3,
h4,
.brand {
    font-family: "Fraunces", Georgia, serif;
    font-optical-sizing: auto;
}

h1,
h2,
h3 {
    font-weight: 600;
    letter-spacing: -0.01em;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    line-height: 1.05;
}

.brand-mark {
    flex: 0 0 auto;
}

.brand-words {
    display: inline-flex;
    flex-direction: column;
}

.brand-name {
    font-family: "Fraunces", Georgia, serif;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.01em;
}

.brand-tagline {
    font-family: "Nunito Sans", sans-serif;
    font-size: .62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .16em;
    color: var(--muted);
}

.nav-link {
    font-weight: 600;
    color: var(--ink);
    margin-left: 1rem;
}

.cart-link {
    background: var(--sage-deep);
    color: white !important;
    border-radius: 999px;
    padding: .5rem 1rem !important;
}

.hero {
    background: linear-gradient(160deg, #F7F2EA 0%, var(--cream) 45%, #EFF3EC 100%);
    border-bottom: 1px solid var(--line);
    padding: 5.5rem 0;
}

.hero h1 {
    font-size: clamp(2.6rem, 5.5vw, 4.4rem);
    line-height: 1.03;
    margin-bottom: 1.25rem;
}

.hero h1 span {
    color: var(--sage-deep);
    font-style: italic;
}

.hero .lead {
    max-width: 33rem;
    font-size: 1.15rem;
    color: var(--muted);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin-top: 1.75rem;
}

.hero-points {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    padding: 0;
    margin: 2rem 0 0;
    font-size: .9rem;
    color: var(--muted);
}

.hero-points li::before {
    content: "✓";
    color: var(--sage-deep);
    font-weight: 700;
    margin-right: .4rem;
}

.hero-card {
    position: relative;
}

.hero-panel {
    display: grid;
    place-items: center;
    min-height: 300px;
    padding: 2.5rem;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 16px;
    box-shadow: 0 18px 45px rgba(61, 56, 47, .07);
}

.hero-panel img {
    width: 100%;
    max-width: 300px;
    height: auto;
}

.eyebrow {
    display: inline-block;
    color: var(--muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .18em;
    font-size: .72rem;
    margin-bottom: .9rem
}

.section-heading h2 {
    font-size: clamp(1.9rem, 3.5vw, 2.5rem)
}

.product-card {
    background: white;
    border: 0;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 12px 35px rgba(61, 56, 47, .08);
    transition: transform .2s ease, box-shadow .2s ease
}

.product-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 18px 45px rgba(61, 56, 47, .14)
}

/* White, to match the photographs rather than frame them. Every product shot
   is on white: a cream panel behind them drew a visible edge round each one,
   and the card it sits in is white anyway, so the panel read as a band across
   the middle of it. Photographs taken at home are flattened to white by
   scripts/whiten_backgrounds.py so they match the supplier ones. */
.product-image,
.product-detail-image {
    position: relative;
    background: #FFFFFF;
    overflow: hidden
}

/* Square, to match the photographs rather than frame them. Every product
   photo is squared by scripts/match_photo_backgrounds.py --square, so it fills
   this exactly and none of the panel behind it is ever seen. A fixed height
   cannot do that: the slot's shape would follow the column width, and no photo
   would match it at every size. */
.product-image {
    aspect-ratio: 1 / 1
}

/* A backstop for the blurb filter: a description with no sentence break in it
   still cannot stretch the row, because a Bootstrap row makes every card as
   tall as its tallest. */
.card-blurb {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden
}

/* A fixed square, not min-height: photos arrive in a mix of portrait and
   landscape, and a content-driven height made the panel jump as you switched
   thumbnails. The slot is fixed; the photo is fitted inside it. */
.product-detail-image {
    aspect-ratio: 1 / 1;
    border-radius: 18px
}

/* contain, not cover: a tall photo — a puzzle book, a soap — lost its top and
   bottom to a landscape card, which is the one thing a product photo may not
   do. The letterbox is the slot's own background, so the grid still lines up. */
.product-image img,
.product-detail-image img,
.cart-thumb img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center
}

/* A multipack is four cards, not one photograph, so the slot holds a grid.
   This has to undo the rule above: a single product photo is positioned
   absolutely and told to fill the slot, which would stack four cards exactly
   on top of each other. */
.pack-thumbs {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: .4rem;
    padding: .4rem;
    margin: 0
}

.pack-thumbs img {
    position: static;
    inset: auto;
    width: 100%;
    height: 100%;
    min-height: 0;
    object-fit: contain
}

/* The lettering colours. A dot of the exact hex the drawing uses, so what is
   on the page is what comes off the printer. */
.card-ink {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

.card-ink-dot {
    width: 1rem;
    height: 1rem;
    border-radius: 999px;
    border: 1px solid rgba(0, 0, 0, .18);
    flex: 0 0 auto;
}

/* ── Keeping the card in view while it is edited ────────────────────────── */

/* The wording boxes are a long way below the picture, so editing a card used
   to mean scrolling it off the screen. The column sticks instead.
   `align-items-start` on the row is what makes this work at all: a stretched
   flex item is already as tall as the row and has nowhere to stick to. */
@media (min-width: 992px) {
    .product-stage {
        position: sticky;
        top: 1.25rem;
    }
}

/* On a phone there is only one column, so the picture sits above the boxes and
   scrolls away entirely. It sticks to the top of the screen instead, at a size
   that leaves room to type underneath: a full-width square pinned to the top
   would be the whole screen. */
@media (max-width: 991.98px) {
    .product-stage.is-designed {
        position: sticky;
        top: 0;
        z-index: 3;
        padding-top: .5rem;
        margin-inline: -.75rem;
        padding-inline: .75rem;
        background: var(--sand);
    }

    .product-stage.is-designed .product-detail-image {
        max-height: 38vh;
        margin-inline: auto;
    }

    /* The hint and the side buttons go with it, so what is pinned is the card
       and the three views of it rather than a floating picture. */
    .product-stage.is-designed .card-edit-hint {
        display: none;
    }
}

.image-placeholder {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: .3rem;
    color: #B8AFA2;
    font-size: 2.5rem
}

.image-placeholder small {
    font-size: .85rem;
    font-weight: 700
}

.product-card h3 {
    font-size: 1.45rem
}

.product-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem
}

/* Pill tints. Colour carries meaning here, so each one is spent once:
   green says eco and nothing else, the flag pill picks up its own red, and
   the plain "what sort of thing is this" tags take the neutral stone so they
   do not compete with the two tags that actually sell the item.
   Every pair below is AA at pill size. */
.badge-sand {
    color: var(--on-sand);
    background: #EDE4D8
}

.badge-eco {
    color: var(--sage-deep);
    background: #E4EBE3
}

.badge-uk {
    color: var(--on-blush);
    background: #F5E6E1
}

.badge-make {
    color: #8E5537;
    background: #F7E7DC
}

.badge-stone {
    color: var(--ink);
    background: #EFE9E1
}

.price {
    color: var(--sage-deep);
    font-size: 1.5rem
}

.detail-price {
    font-size: 2.2rem
}

.btn {
    font-family: "Nunito Sans", sans-serif;
    font-weight: 600;
    letter-spacing: .01em
}

.btn-primary {
    --bs-btn-bg: var(--sage-deep);
    --bs-btn-border-color: var(--sage-deep);
    --bs-btn-hover-bg: #3F5646;
    --bs-btn-hover-border-color: #3F5646;
    --bs-btn-active-bg: #3F5646;
    --bs-btn-active-border-color: #3F5646
}

.btn-outline-primary {
    --bs-btn-color: var(--sage-deep);
    --bs-btn-border-color: #CFD9CB;
    --bs-btn-hover-bg: var(--sage-deep);
    --bs-btn-hover-border-color: var(--sage-deep)
}

.why-section {
    background: #F3EEE6
}

.why-card {
    padding: 1rem
}

/* Deliberately plain and unshouty: a substantiating disclosure, not a badge.
   Green-claims rules require the qualifying detail to be as visible as the
   claim it qualifies, so this must not be hidden away in small print. */
.materials-note {
    background: #fff;
    border: 1px solid var(--line);
    border-left: 3px solid var(--sage);
    border-radius: 12px;
    padding: 1.25rem 1.5rem;
    max-width: 52rem;
    margin-inline: auto;
    text-align: left
}

.materials-note h4 {
    font-size: 1.05rem;
    margin-bottom: .4rem
}

.materials-note p {
    font-size: .92rem;
    color: var(--muted)
}

.why-icon {
    font-size: 3rem;
    margin-bottom: .75rem
}

.review-link-card {
    cursor: pointer;
    border-radius: 14px;
    transition: background .2s ease
}

.review-link-card:hover {
    background: rgba(255, 255, 255, .6)
}

.party-builder,
.customisation-box,
.tier-box {
    background: white;
    border-radius: 16px;
    padding: 1.5rem;
    box-shadow: 0 12px 35px rgba(61, 56, 47, .07)
}

.selection-count {
    background: #E7EDE5;
    color: var(--sage-deep);
    padding: .4rem .8rem;
    border-radius: 999px
}

.option-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem
}

.option-card {
    position: relative;
    cursor: pointer;
    background: #FFFDFA;
    border: 2px solid #E5DCD0;
    border-radius: 12px;
    padding: 1rem;
    min-height: 145px;
    display: flex;
    flex-direction: column;
    gap: .25rem;
    transition: all .15s ease
}

.option-card:hover {
    border-color: #6F8F76;
    transform: translateY(-2px)
}

.option-card input {
    position: absolute;
    opacity: 0
}

.option-card:has(input:checked) {
    border-color: var(--sage-deep);
    background: #EEF3EC;
    box-shadow: 0 6px 15px rgba(79, 107, 87, .12)
}

.option-card:has(input:disabled):not(:has(input:checked)) {
    opacity: .45;
    cursor: not-allowed
}

.option-check {
    position: absolute;
    top: .6rem;
    right: .6rem;
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: #E5DCD0;
    color: transparent;
    display: grid;
    place-items: center;
    font-weight: 800
}

.option-card:has(input:checked) .option-check {
    background: var(--sage-deep);
    color: white
}

.option-emoji {
    font-size: 1.8rem
}

.option-card strong {
    font-size: .95rem
}

.option-card small {
    color: var(--muted);
    font-size: .75rem
}

.option-price {
    display: inline-block;
    margin-top: .4rem;
    font-size: .8rem;
    font-weight: 700;
    color: var(--sage-deep)
}

.option-section {
    border-top: 1px dashed #E5DCD0;
    padding-top: 1rem
}

.option-section:first-of-type {
    border-top: 0;
    padding-top: 0
}

/* The head is the control that folds the picker away, so it has to look like
   one: a pointer, a chevron, and something under the finger on a phone. */
.option-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0;
    padding: .7rem .25rem;
    cursor: pointer;
    list-style: none;
    border-radius: 10px
}

.option-section-head::-webkit-details-marker {
    display: none
}

.option-section-head:hover {
    background: #F6F3EC
}

.option-section-head::after {
    content: "";
    flex-shrink: 0;
    width: .55rem;
    height: .55rem;
    margin-right: .2rem;
    border-right: 2px solid var(--sage-deep);
    border-bottom: 2px solid var(--sage-deep);
    transform: rotate(45deg) translate(-.1rem, -.1rem);
    transition: transform .15s ease
}

/* A closed <details> is hidden by a browser rule, which any author rule beats:
   .option-grid sets display:grid, so the pickers went on showing through their
   own folded summaries. Said here, at author level, it holds. */
.option-section:not([open]) > *:not(summary) {
    display: none
}

/* On a phone there is no room for a title, a description and a bag's full name
   on one line: "Blue recycled kraft paper bag" took the width and left the
   description breaking one word to a line. The name drops to a line of its
   own, and the heading keeps the width. */
@media (max-width: 575.98px) {
    .option-section-head {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto auto;
        grid-template-areas:
            "title state chevron"
            "picked picked picked";
        align-items: center;
        gap: .2rem .6rem
    }

    .option-section-head > div {
        grid-area: title
    }

    .option-section-head > .section-count:not(.section-picked) {
        grid-area: state
    }

    .option-section-head::after {
        grid-area: chevron
    }

    .option-section-head > .section-picked {
        grid-area: picked;
        max-width: 100%;
        text-align: left;
        white-space: normal
    }

    /* Nothing picked yet, so the row would otherwise leave a gap. */
    .option-section-head > .section-picked:empty {
        display: none
    }
}

/* The choice a folded section is holding, said plainly rather than counted. */
.section-picked {
    font-weight: 600;
    font-size: .85rem;
    color: var(--muted);
    text-align: right;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap
}

.option-section[open] > .option-section-head {
    margin-bottom: .75rem
}

.option-section[open] > .option-section-head::after {
    transform: rotate(-135deg) translate(-.1rem, -.1rem)
}

.section-count {
    flex-shrink: 0;
    font-weight: 800;
    font-size: .9rem;
    text-align: right
}

.section-count small {
    display: block;
    font-weight: 500
}

.option-section.section-unmet .option-section-head h3 {
    color: var(--sage-deep)
}

.option-section.section-unmet .section-count {
    color: var(--sage-deep)
}

.selected-summary {
    background: #F1EFE8;
    border-radius: 12px;
    padding: .9rem 1rem;
    font-size: .9rem
}

.quantity-input {
    max-width: 120px
}

.trust-box,
.secure-note {
    background: #F1F5EE;
    border: 1px solid #D8E2D4;
    border-radius: 12px;
    padding: 1rem;
    color: #4F6B57
}

.tier-box {
    background: #F6EFE2
}

.tier-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: .5rem
}

.tier-grid div {
    background: white;
    border-radius: 10px;
    padding: .65rem;
    text-align: center;
    display: flex;
    flex-direction: column
}

.tier-grid span {
    font-size: .8rem;
    color: var(--muted)
}

.cart-item {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    background: white;
    border-radius: 14px;
    padding: 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 8px 25px rgba(61, 56, 47, .06)
}

.cart-thumb {
    width: 100px;
    height: 100px;
    border-radius: 12px;
    overflow: hidden;
    position: relative;
    background: #FFFFFF;
    flex-shrink: 0
}

.cart-thumb .image-placeholder {
    font-size: 1.5rem
}

.cart-actions {
    min-width: 180px
}

.quantity-form {
    display: flex;
    gap: .5rem;
    justify-content: flex-end
}

.quantity-form input {
    width: 70px
}

.checkout-card {
    background: white;
    border-radius: 16px;
    padding: 1.5rem;
    box-shadow: 0 12px 35px rgba(61, 56, 47, .1);
    position: sticky;
    top: 100px
}

.shipping-info {
    background: #F1EFE8;
    border-radius: 12px;
    padding: 1rem;
    color: #3D382F
}

.empty-state,
.success-card {
    background: white;
    border-radius: 18px;
    box-shadow: 0 12px 35px rgba(61, 56, 47, .08)
}

.empty-icon,
.success-icon {
    font-size: 4rem
}

.success-card {
    max-width: 650px;
    padding: 4rem 2rem
}

.success-card h1 {
    font-size: 3.5rem
}

.status-pill {
    display: inline-block;
    background: #E7EFE6;
    color: #4F6B57;
    padding: .6rem 1rem;
    border-radius: 999px
}

.reviews-hero {
    background: linear-gradient(135deg, #F3E9E2, #E9EFE7)
}

.reviews-hero h1 {
    font-size: 4rem
}

.review-card {
    background: white;
    border-radius: 16px;
    padding: 1.75rem;
    box-shadow: 0 12px 35px rgba(61, 56, 47, .08)
}

.stars {
    color: #C08663;
    font-size: 1.4rem;
    letter-spacing: .1em
}

.review-card blockquote {
    font-size: 1.05rem;
    line-height: 1.65;
    margin: 1rem 0 1.5rem
}

.review-meta {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    color: var(--muted);
    font-size: .9rem
}

.review-meta span {
    font-weight: 800;
    color: var(--sage-deep)
}

.review-note {
    background: white;
    border-radius: 16px;
    padding: 1.25rem
}

.footer {
    background: #3D382F;
    color: #EFEAE1
}

.footer .brand-mark {
    filter: brightness(0) invert(1) opacity(.85)
}

.footer .brand-name {
    color: var(--sage-light)
}

.footer a {
    color: var(--sage-light)
}

.footer a:hover,
.footer a:focus {
    color: #C4D3C4
}

.footer .brand-tagline {
    color: var(--terracotta-light)
}

@media(max-width:767px) {
    .hero {
        padding: 4rem 0
    }

    .hero-placeholder {
        min-height: 280px
    }

    .option-grid {
        grid-template-columns: 1fr
    }

    .tier-grid {
        grid-template-columns: repeat(3, 1fr)
    }

    .cart-item {
        align-items: flex-start;
        flex-wrap: wrap
    }

    .cart-thumb {
        width: 75px;
        height: 75px
    }

    .cart-actions {
        width: 100%;
        min-width: 0
    }

    .quantity-form {
        justify-content: flex-start
    }

    .reviews-hero h1 {
        font-size: 3rem
    }
}

.option-image {
    width: 100%;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #FFFFFF;
    border-radius: 8px;
    position: relative;
    margin-bottom: .4rem;
}

.option-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 0.1rem;
    display: block;
}

/* 
.image-placeholder {
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    color: #B8AFA2;
    background: #F2EDE5;
} */
/* ── Themed bag summary + collapsible builder ───────────────────────────────
   A themed bag is usually accepted as-is, so its contents and the Add button
   sit at the top and the full picker is collapsed behind a disclosure. */
.theme-summary {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 1.1rem 1.25rem;
    margin-bottom: 1rem
}

.theme-contents {
    list-style: none;
    margin: 0 0 .9rem;
    padding: 0;
    font-size: .93rem
}

.theme-contents li {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .3rem 0;
    border-bottom: 1px dashed var(--line)
}

.theme-contents li:last-child {
    border-bottom: 0
}

.theme-summary-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap
}

.theme-summary-footer strong {
    font-size: 1.25rem
}

.builder-details {
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 0 1rem;
    background: #fff
}

.builder-details[open] {
    padding-bottom: 1rem
}

.builder-details > summary {
    cursor: pointer;
    padding: .9rem .25rem;
    font-weight: 700;
    color: var(--sage-deep);
    list-style-position: inside
}

.builder-details > summary::marker {
    color: var(--sage)
}

/* The picker sits inside the disclosure, so it must not draw its own box. */
.builder-details .option-section:first-of-type {
    border-top: 0;
    padding-top: 0
}

/* A radio behaves like the checkbox cards, but only one can win. */
.style-card .option-check {
    border-radius: 50%
}

/* Shop-by-occasion grid on the homepage, replacing the old generic Shop link. */
.occasion-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1rem
}

.occasion-card {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 1.1rem 1.25rem
}

.occasion-card ul {
    list-style: none;
    margin: .5rem 0 0;
    padding: 0;
    font-size: .92rem
}

.occasion-card li {
    padding: .2rem 0
}

.occasion-card a {
    color: var(--muted);
    text-decoration: none
}

.occasion-card a:hover {
    color: var(--sage-deep);
    text-decoration: underline
}

/* Keeps the running price and Add button reachable however long the picker is,
   which is the whole scrolling complaint on the party bag pages. */
.sticky-bar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: rgba(255, 255, 255, .97);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 20px rgba(61, 56, 47, .07);
    padding: .7rem 0
}

.sticky-bar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem
}

.sticky-bar-text strong {
    font-size: 1.15rem
}

.sticky-bar-text small {
    display: block;
    line-height: 1.2
}

@media (max-width: 575.98px) {
    .sticky-bar-text strong { font-size: 1rem }
    .sticky-bar .btn { padding-left: 1rem; padding-right: 1rem }
}

/* Table-number range picker. */
.range-row {
    display: flex;
    align-items: flex-end;
    gap: .75rem
}

.range-row > div {
    flex: 1
}

.range-dash {
    padding-bottom: .6rem;
    color: var(--muted);
    font-size: 1.2rem
}

.range-summary {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: .7rem .9rem;
    background: #F1EFE8;
    border-radius: 10px
}

.range-summary span {
    font-weight: 700;
    color: var(--sage-deep);
    font-size: 1.15rem
}

#range-error:not(:empty) {
    color: var(--blush-deep);
    margin-top: .4rem
}

/* Makes clear that a price is per item, not for the whole thing. */
.price-suffix {
    font-family: "Nunito Sans", sans-serif;
    font-size: .7em;
    font-weight: 600;
    color: var(--muted)
}

/* ── Full-width party bag builder ───────────────────────────────────────────
   The picker used to sit in a half-width column, so 50+ options meant a very
   long scroll. It now spans the page and the grid fills the available width. */
.builder-band {
    background: linear-gradient(180deg, #F7F2EA 0%, var(--cream) 100%);
    border-top: 1px solid var(--line);
    padding: 2.5rem 0 3rem
}

.builder-band .party-builder,
.builder-band .tier-box {
    box-shadow: 0 10px 30px rgba(61, 56, 47, .06)
}

/* Auto-fill instead of a fixed two columns: six across on a wide screen,
   two on a phone, without a media query per breakpoint. */
.option-grid {
    grid-template-columns: repeat(auto-fill, minmax(158px, 1fr))
}

.option-card {
    min-height: 0;
    padding: .85rem
}

.option-card strong {
    font-size: .88rem;
    line-height: 1.25
}

.option-card small {
    font-size: .72rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden
}

.option-image .image-placeholder {
    display: flex;
    font-size: 1.5rem
}

/* Section headings stay visible while scrolling a long section. */
.builder-band .option-section-head {
    position: sticky;
    top: 76px;
    z-index: 2;
    background: rgba(251, 248, 244, .96);
    backdrop-filter: blur(4px);
    padding: .6rem 0;
    margin-bottom: .5rem;
    border-bottom: 1px solid var(--line)
}

/* Above the section heads, which are sticky too and carry z-index 2. Without
   this the running summary slid under each folded picker as it passed. Still
   below the bar at the foot, which holds the price and the button. */
.builder-band .selected-summary {
    position: sticky;
    bottom: 4.5rem;
    z-index: 3
}

@media (min-width: 992px) {
    .builder-band .option-grid {
        gap: .9rem
    }
}

/* Sold-out items stay on the page, visibly unavailable rather than missing. */
.stock-note {
    display: inline-block;
    margin-top: .3rem;
    font-size: .68rem;
    font-weight: 700;
    color: var(--on-sand)
}

.stock-note.out {
    color: var(--on-blush)
}

.option-card.sold-out {
    opacity: .5;
    cursor: not-allowed
}

.option-card.sold-out:hover {
    transform: none;
    border-color: var(--line)
}

.stock-line {
    font-weight: 700;
    color: var(--on-sand)
}

.stock-line.out {
    color: var(--on-blush)
}

/* ── Availability traffic light ─────────────────────────────────────────────
   The dot carries no meaning on its own; the text beside it always states the
   status, so it is not colour-only information. */
.availability {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-weight: 700;
    font-size: .95rem;
    margin-bottom: .25rem
}

.availability-dot {
    width: .7rem;
    height: .7rem;
    border-radius: 50%;
    flex: 0 0 auto;
    box-shadow: 0 0 0 3px rgba(0, 0, 0, .04)
}

.availability-in .availability-dot { background: #2E7D4F }
.availability-in .availability-text { color: #2E7D4F }

.availability-low .availability-dot { background: #C98A1E }
.availability-low .availability-text { color: #8A5F12 }

.availability-out .availability-dot { background: #C0392B }
.availability-out .availability-text { color: #A5301F }


.notify-box {
    background: #fff;
    border: 1px solid var(--line);
    border-left: 3px solid #C0392B;
    border-radius: 12px;
    padding: 1rem 1.1rem
}

.notify-form {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap
}

.notify-form input[type="email"] {
    flex: 1 1 14rem
}

/* Basket lines are links back to the item. */
.cart-item-link {
    color: inherit;
    text-decoration: none
}

.cart-item-link:hover {
    color: var(--sage-deep);
    text-decoration: underline
}

a.cart-thumb {
    display: block
}

/* Product gallery thumbnails. Buttons, not divs, so they are keyboard-reachable. */
.gallery-thumbs {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .75rem
}

.gallery-thumb {
    width: 72px;
    height: 72px;
    padding: 0;
    border: 2px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    background: #FFFFFF;
    cursor: pointer;
    transition: border-color .15s ease
}

.gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block
}

.gallery-thumb:hover {
    border-color: var(--sage)
}

.gallery-thumb.is-current {
    border-color: var(--sage-deep)
}

.gallery-thumb:focus-visible {
    outline: 2px solid var(--sage-deep);
    outline-offset: 2px
}

/* Navigation: quieter, and sized for text rather than emoji. */
.navbar-nav .nav-link {
    font-size: .95rem;
    letter-spacing: .01em;
    margin-left: .85rem
}

.navbar-nav .nav-link:hover,
.navbar-nav .nav-link:focus-visible {
    color: var(--sage-deep)
}

.dropdown-menu {
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: .4rem;
    box-shadow: 0 14px 34px rgba(61, 56, 47, .10)
}

.dropdown-item {
    border-radius: 8px;
    padding: .45rem .7rem;
    font-size: .92rem;
    color: var(--ink)
}

.dropdown-item:hover,
.dropdown-item:focus {
    background: #EFF3EC;
    color: var(--sage-deep)
}

.cart-link {
    font-weight: 700;
    font-size: .9rem
}

/* Made to order: available, but not from a shelf — sage rather than green. */
.availability-made-to-order .availability-dot { background: var(--sage) }
.availability-made-to-order .availability-text { color: var(--sage-deep) }

/* Take-back note on printed items. */
.take-back-note {
    font-size: .9rem;
    color: var(--muted);
    margin-top: .5rem
}

.take-back-note a {
    color: var(--sage-deep)
}

/* Single / 6 / 12 on one listing, so the saving is visible before you choose. */
.pack-choice {
    border: 0;
    padding: 0;
    margin: 0
}

.pack-choice legend {
    float: none;
    width: auto;
    font-size: 1rem;
    margin-bottom: .5rem
}

.pack-option {
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: .2rem 1rem;
    cursor: pointer;
    border: 2px solid var(--line);
    border-radius: 12px;
    padding: .7rem .9rem;
    margin-bottom: .5rem;
    background: #FFFDFA;
    transition: border-color .15s ease
}

.pack-option input {
    position: absolute;
    opacity: 0
}

.pack-option:hover {
    border-color: var(--sage)
}

.pack-option:has(input:checked) {
    border-color: var(--sage-deep);
    background: #EEF3EC
}

.pack-option:has(input:focus-visible) {
    outline: 2px solid var(--sage-deep);
    outline-offset: 2px
}

.pack-option.sold-out {
    opacity: .5;
    cursor: not-allowed
}

.pack-size {
    font-weight: 700
}

.pack-total {
    font-weight: 700;
    color: var(--sage-deep);
    text-align: right
}

.pack-unit {
    grid-column: 1 / -1;
    font-size: .82rem;
    color: var(--muted)
}

/* Expand a filler in place. The button sits over the card rather than inside
   its label, so opening the detail never toggles the selection. */
.option-cell {
    position: relative
}

.option-detail {
    position: absolute;
    /* Top left, because the selected tick lives top right and the two were
       sitting on top of each other. */
    top: .5rem;
    left: .5rem;
    width: 28px;
    height: 28px;
    padding: 0;
    line-height: 1;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: rgba(255, 255, 255, .94);
    box-shadow: 0 1px 4px rgba(61, 56, 47, .12);
    color: var(--muted);
    font-size: .85rem;
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s ease, color .15s ease, border-color .15s ease
}

/* Shown on hover on a mouse, and always on touch, where there is no hover. */
.option-cell:hover .option-detail,
.option-detail:focus-visible {
    opacity: 1
}

@media (hover: none) {
    .option-detail {
        opacity: .85
    }
}

.option-detail:hover,
.option-detail:focus-visible {
    opacity: 1;
    color: var(--sage-deep);
    border-color: var(--sage)
}

.option-dialog {
    width: min(680px, 92vw);
    padding: 0;
    border: 0;
    border-radius: 18px;
    background: var(--cream);
    color: var(--ink)
}

.option-dialog::backdrop {
    background: rgba(61, 56, 47, .55)
}

.option-dialog-close {
    display: flex;
    justify-content: flex-end;
    padding: .75rem .75rem 0
}

.option-dialog-body {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 1.5rem;
    padding: 0 1.5rem 1.5rem
}

.option-dialog-image {
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: 12px;
    background: #fff
}

.option-dialog-image img {
    width: 100%;
    height: 100%;
    object-fit: contain
}

@media(max-width:575px) {
    .option-dialog-body {
        grid-template-columns: 1fr
    }
}

/* Live, but not taking orders yet. */
.shop-closed-banner {
    background: var(--sand);
    color: var(--ink);
    border-bottom: 1px solid var(--line)
}

.shop-closed {
    background: var(--sand);
    border-radius: 12px;
    padding: 1rem
}

/* Footer profile links, separated by a middot. */
.footer-social a {
    white-space: nowrap
}

.footer-social span {
    padding: 0 .35rem;
    opacity: .6
}

/* Footer: four columns on desktop, stacking to two then one. */
.footer-heading {
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--sage-light);
    margin-bottom: .75rem
}

.footer-blurb {
    font-size: .9rem;
    line-height: 1.55;
    max-width: 34ch;
    opacity: .85
}

.footer-links {
    list-style: none;
    padding: 0;
    margin: 0;
    font-size: .9rem
}

.footer-links li {
    margin-bottom: .45rem
}

.footer-links a {
    text-decoration: none
}

.footer-links a:hover {
    text-decoration: underline
}

.footer-note {
    font-size: .8rem;
    opacity: .7;
    margin-top: .5rem
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    justify-content: space-between;
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(255, 255, 255, .12);
    font-size: .8rem;
    opacity: .75
}

/* Delivery, packaging and returns on a product page. Collapsed by default so
   the page still leads with the product. */
.product-facts {
    border-top: 1px solid var(--line)
}

.product-fact {
    border-bottom: 1px solid var(--line)
}

.product-fact summary {
    cursor: pointer;
    padding: .85rem 0;
    font-weight: 600;
    list-style: none
}

.product-fact summary::-webkit-details-marker {
    display: none
}

.product-fact summary::after {
    content: "+";
    float: right;
    color: var(--muted);
    font-weight: 400
}

.product-fact[open] summary::after {
    content: "\2212"
}

.product-fact-body {
    padding-bottom: .9rem;
    font-size: .92rem;
    color: var(--muted)
}

.product-fact-body ul {
    padding-left: 1.1rem;
    margin-bottom: 0
}

.product-fact-body li {
    margin-bottom: .35rem
}

/* One row, so every pill sits on the same line whether or not it has an
   icon. They were laid out inline before: an inline-flex pill baselines on
   its icon, an inline-block one on its text, so a pill with a leaf rode
   lower than its neighbours. */
.item-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem
}

.item-badges .badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    line-height: 1.1;
    padding: .4rem .7rem
}

.pill-icon {
    flex: none
}

/* The flag is a rectangle, not a glyph, so it needs its own edge. */
.pill-icon-flag {
    border-radius: 1.5px;
    box-shadow: 0 0 0 .5px rgba(61, 56, 47, .25)
}

/* Choosing a postage service in the basket. */
.shipping-option {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "radio name price" ". when when";
    gap: .1rem .6rem;
    align-items: center;
    padding: .7rem .8rem;
    margin-bottom: .5rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease
}

.shipping-option:hover {
    border-color: var(--sage)
}

.shipping-option.is-chosen {
    border-color: var(--sage-deep);
    background: #F6F8F5
}

.shipping-option input {
    grid-area: radio;
    accent-color: var(--sage-deep)
}

.shipping-option-name {
    grid-area: name;
    font-weight: 600
}

.shipping-option-price {
    grid-area: price;
    font-weight: 700
}

.shipping-option-when {
    grid-area: when;
    font-size: .82rem;
    color: var(--muted)
}

.shipping-nudge {
    margin-top: .4rem;
    font-size: .85rem;
    color: var(--sage-deep);
    font-weight: 600
}

/* Bulk savings, as steps you can tap rather than a table to read. */
.tier-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
    gap: .5rem
}

.tier-step {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    padding: .6rem .5rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: #fff;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, transform .15s ease
}

.tier-step:hover {
    border-color: var(--sage);
    transform: translateY(-1px)
}

.tier-step.is-current {
    background: #F6F8F5;
    border-color: var(--sage-deep);
    box-shadow: 0 0 0 2px rgba(79, 107, 87, .18)
}

.tier-qty {
    font-weight: 700;
    font-size: .95rem
}

.tier-off {
    font-size: .78rem;
    color: var(--muted)
}

.tier-each {
    font-size: .82rem;
    font-weight: 600;
    color: var(--sage-deep);
    min-height: 1.1em
}

.tier-saving {
    margin: .75rem 0 0;
    padding: .6rem .75rem;
    border-radius: 10px;
    background: var(--sand);
    font-size: .88rem;
    font-weight: 600;
    color: var(--ink)
}

/* ── Designing a card ───────────────────────────────────────────────────────
   The drawing is the product page's main image and the choices are the
   ordinary product form beside it, so a card is bought the same way as
   anything else in the shop. */
.card-designer {
    display: grid;
    gap: 0;
    margin-top: 1.5rem;
}

/* The card is shown standing on a surface rather than filling the frame: it is
   105x148, and stretched to a square slot it would stop looking like a card.
   The ground and the shadow are what make it read as a physical thing. */
.product-detail-image.is-card-preview {
    background: var(--sand);
    cursor: zoom-in;
    /* Taller than the square a photograph gets. A card is 105x148 and spends
       most of its time being looked at front-on, and in a square stage it only
       ever reached seven tenths of the width. The inside spread is landscape
       and letterboxes here instead, which is the cheaper of the two. */
    aspect-ratio: 5 / 6;

}

/* Positioned, not padded. A percentage height only resolves against a parent
   whose own height is definite: as a centred grid item this box measured auto,
   the drawing fell back to its intrinsic 148mm, and the foot of the card ran
   out of the bottom of the stage. Insets give it a height to resolve against,
   and double as the margin the card stands in. */
.card-preview {
    position: absolute;
    inset: clamp(1.4rem, 5vw, 2.25rem);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The drawing takes the whole stage and fits itself inside it: every card SVG
   carries a viewBox, so preserveAspectRatio centres and scales the artwork and
   nothing can be cropped. Sizing it by its own intrinsic millimetres instead
   left the foot of a portrait card cut off. The shadow follows the painted
   paper rather than the box, so it still hugs the card. */
/* Direct children only. The back of a folded card is cropped with a nested
   <svg>, and a descendant selector resized that one too — which stretched the
   viewport that was doing the cropping and let the front panel back in. */
.card-preview > svg,
.card-lightbox-canvas > svg {
    width: 100%;
    height: 100%;
    display: block;
    filter: drop-shadow(0 .5rem 1.25rem rgba(37, 48, 40, .22));
}

.card-preview-loading {
    color: var(--muted);
    font-size: .9rem;
    margin: 0;
}

.card-preview-sides {
    display: flex;
    gap: .4rem;
    margin-top: .75rem;
}

.card-side {
    flex: 1;
    border: 1px solid var(--line);
    background: white;
    border-radius: 999px;
    padding: .5rem .8rem;
    font-size: .9rem;
    line-height: 1.2;
    cursor: pointer;
    /* A thumb is a tap target before it is a label. */
    min-height: 2.75rem;
}

.card-side[hidden] { display: none; }

/* ── Editing on the card ────────────────────────────────────────────────── */

/* The same faces the drawing letters the card with, so the caret in the box
   you type into keeps step with the words appearing underneath it. Only
   fetched on a card page, where they are being loaded for the drawing anyway. */
@font-face {
    font-family: "Card Great Vibes";
    src: url("../fonts/card/greatvibes.ttf") format("truetype");
    font-display: swap;
}

@font-face {
    font-family: "Card Parisienne";
    src: url("../fonts/card/parisienne.ttf") format("truetype");
    font-display: swap;
}

@font-face {
    font-family: "Card Pinyon";
    src: url("../fonts/card/pinyon.ttf") format("truetype");
    font-display: swap;
}

@font-face {
    font-family: "Card Serif";
    src: url("../fonts/card/serif.ttf") format("truetype");
    font-display: swap;
}

/* Invisible until pointed at. A card covered in boxes is not a card. */
.card-hit {
    fill: transparent;
    cursor: text;
    transition: fill .12s ease;
}

.card-hit:hover,
.card-hit.is-editing {
    fill: rgba(79, 107, 87, .14);
    stroke: var(--sage-deep);
    stroke-width: .3;
    stroke-dasharray: 1.2 1;
}

.card-inline-editor {
    position: absolute;
    z-index: 3;
    margin: 0;
    padding: 0;
    border: 0;
    resize: none;
    overflow: hidden;
    background: transparent;
    text-align: center;
    line-height: 1;
    /* The text is the card's, drawn underneath. This box is here for the
       caret and for the keyboard, and showing its own copy of the words on
       top would only double them. */
    color: transparent;
    caret-color: var(--ink);
}

.card-inline-editor::selection {
    background: rgba(79, 107, 87, .28);
}

.card-inline-editor:focus {
    outline: none;
}

.card-edit-hint {
    margin: .6rem 0 0;
    font-size: .85rem;
    color: var(--muted);
    text-align: center;
}

/* ── Enlarging it ───────────────────────────────────────────────────────── */
.card-zoom {
    position: absolute;
    top: .75rem;
    right: .75rem;
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    color: var(--ink);
    font-size: 1.1rem;
    line-height: 1;
    cursor: zoom-in;
}

.card-lightbox {
    border: 0;
    border-radius: 18px;
    padding: clamp(1rem, 4vw, 2rem);
    background: var(--sand);
    width: min(94vw, 760px);
    max-width: none;
}

.card-lightbox::backdrop {
    background: rgba(37, 48, 40, .62);
}

/* Bounded by the viewport as well as its own shape, so the card is never
   taller than the screen it is being looked at on. */
.card-lightbox-stage {
    position: relative;
    aspect-ratio: 5 / 6;
    max-height: 68vh;
    margin-inline: auto;
}

/* Same reason as .card-preview: the drawing needs a parent of definite height. */
.card-lightbox-canvas {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Looking through a pack ─────────────────────────────────────────────── */

/* The card showing, named under it. The count is there because four pictures
   that all look like a Christmas card give no sense of where you are in them. */
.pack-caption {
    margin: .6rem 0 0;
    text-align: center;
    line-height: 1.35;
}

.pack-caption-name {
    display: block;
    font-weight: 700;
}

.pack-caption-greeting {
    display: block;
    color: var(--muted);
}

.pack-caption-count {
    display: block;
    margin-top: .15rem;
    font-size: .78rem;
    color: var(--muted);
}

/* Over the picture rather than under it: the thumbnails are the main way
   through, and these are for somebody already looking at one card. */
.pack-step {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    color: var(--ink);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

.pack-prev { left: .75rem }
.pack-next { right: .75rem }

/* Inside the enlarged dialog they sit against its edges instead. */
.card-lightbox .pack-prev { left: .4rem }
.card-lightbox .pack-next { right: .4rem }

.card-lightbox-stage img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.card-lightbox-close {
    position: absolute;
    top: .5rem;
    right: .75rem;
    border: 0;
    background: none;
    color: var(--muted);
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
}

.card-side.is-current {
    background: var(--sage-deep);
    border-color: var(--sage-deep);
    color: white;
}

.card-field {
    border: 0;
    padding: 0;
    margin: 0 0 1.1rem;
}

.card-field legend {
    font-size: 1rem;
}

/* One row per choice, with the price of the choice where it can be compared. */
.card-choice {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "radio name price" ". blurb blurb";
    gap: .15rem .6rem;
    align-items: center;
    padding: .7rem .8rem;
    margin-bottom: .5rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    cursor: pointer;
}

.card-choice input { grid-area: radio; }
.card-choice-name { grid-area: name; font-weight: 600; }
.card-choice-price { grid-area: price; color: var(--sage-deep); }
.card-choice-blurb { grid-area: blurb; color: var(--muted); font-size: .85rem; }

.card-choice.is-chosen {
    border-color: var(--sage-deep);
    background: #F4F7F3;
}

.card-swatches {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}

.card-swatch {
    flex: 1 1 8rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: .6rem;
    text-align: center;
    cursor: pointer;
    font-size: .9rem;
}

.card-swatch input {
    display: block;
    margin: 0 auto .35rem;
}

.card-swatch.is-chosen {
    border-color: var(--sage-deep);
    background: #F4F7F3;
}

/* A hint of what each colour does, before the preview has drawn. */
.card-swatch-pastel { box-shadow: inset 0 -4px 0 #E7A4BD; }
.card-swatch-coastal { box-shadow: inset 0 -4px 0 #8FAED6; }
.card-swatch-autumn { box-shadow: inset 0 -4px 0 #D98760; }


/* A g-5 row sets side margins of -1.5rem, and a container's 12px of padding
   cannot absorb them: 12px of the page hung off each edge and a phone scrolled
   sideways. Above this width the container has margins to hide it in, and
   below it every column is stacked, so a horizontal gutter buys nothing
   anyway. */
@media (max-width: 575.98px) {
    .row.g-5,
    .row.gx-5 {
        --bs-gutter-x: 0
    }
}

/* ── Asking about cookies ───────────────────────────────────────────────────
   A card in the corner rather than a bar across the foot of the page: it reads
   as a notice rather than as a bite out of the layout, and leaves the shop
   underneath it usable while somebody decides. Accept and reject are the same
   size, because offering only an easy yes is the part the regulator is least
   impressed by. */
.cookie-banner {
    position: fixed;
    left: 1.25rem;
    bottom: 1.25rem;
    z-index: 1080;
    width: min(26rem, calc(100vw - 2.5rem));
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 16px;
    box-shadow: 0 18px 45px rgba(61, 56, 47, .22);
    padding: 1.25rem
}

.cookie-banner[hidden] {
    display: none
}

.cookie-banner-title {
    font-family: "Fraunces", Georgia, serif;
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0 0 .4rem
}

.cookie-banner-text {
    font-size: .88rem;
    line-height: 1.5;
    color: var(--muted);
    margin: 0 0 1rem
}

.cookie-banner-buttons {
    display: flex;
    gap: .5rem
}

.cookie-banner-buttons .btn {
    flex: 1;
    min-height: 2.75rem;
    border-radius: 999px;
    font-size: .9rem
}

.cookie-banner-more {
    margin-top: .85rem;
    font-size: .78rem;
    color: var(--muted)
}

.cookie-banner-more a {
    color: var(--muted);
    text-underline-offset: 2px
}

.cookie-banner-more a:hover {
    color: var(--sage-deep)
}

/* On a phone it sits along the bottom edge, where a floating card would only
   waste the margins. */
@media (max-width: 575.98px) {
    .cookie-banner {
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        border-radius: 16px 16px 0 0;
        border-left: 0;
        border-right: 0;
        border-bottom: 0
    }
}

/* The longer copy under a listing's grid, and the links across to the other
   listings in its section. Both were added with Bootstrap's layout classes
   only, which left the cross-links as default blue underlined text — the one
   place on the site that looked like an unstyled document. */
.collection-intro {
    border-top: 1px solid var(--line);
    padding-top: 1.75rem
}

.collection-intro h2 {
    margin-bottom: .9rem
}

.collection-intro p {
    color: var(--muted);
    max-width: 62ch;
    margin-bottom: .9rem
}

.collection-siblings {
    border-top: 1px solid var(--line);
    padding-top: 1.5rem
}

.collection-siblings h2 {
    text-transform: uppercase;
    letter-spacing: .18em;
    font-size: .72rem;
    font-weight: 600;
    color: var(--muted);
    margin-bottom: .85rem
}

.collection-siblings .list-inline-item {
    margin-right: .5rem;
    margin-bottom: .5rem
}

.collection-siblings a {
    display: inline-block;
    padding: .4rem .95rem;
    border-radius: 999px;
    background: var(--sand);
    color: var(--ink);
    font-size: .9rem;
    font-weight: 600;
    text-decoration: none;
    transition: background .15s ease, color .15s ease
}

.collection-siblings a:hover,
.collection-siblings a:focus-visible {
    background: var(--sage);
    color: #fff
}

/* The worked example beside the photo upload, and the two versions that come
   back from one. Without this the pictures render at their own 1200px and the
   third one hangs off the side of the page. */
.photo-example-image {
    display: block;
    width: 100%;
    height: auto;
    border-radius: .75rem;
    border: 1px solid var(--line);
    background: var(--cream)
}

.photo-example figcaption {
    text-align: center
}
