@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url('/fonts/Poppins-Light.woff2') format('woff2'),
         url('/fonts/Poppins-Light.ttf') format('truetype');
}

@font-face {
    font-family: 'Poppins';
    font-style: italic;
    font-weight: 300;
    font-display: swap;
    src: url('/fonts/Poppins-LightItalic.woff2') format('woff2'),
         url('/fonts/Poppins-LightItalic.ttf') format('truetype');
}

@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/Poppins-Regular.woff2') format('woff2'),
         url('/fonts/Poppins-Regular.ttf') format('truetype');
}

html {
    font-family: 'Poppins', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
    font-weight: 300;
    /* Only 300/400 are registered above - without this, a UA request for the default bold
       weight (700) would fall back to browser-synthesized ("faux") bold on the Light face
       instead of actually rendering the Regular (400) face strong/b are pinned to below. */
    font-synthesis: none;
    /* Clears .site-header (position: sticky, ~93px tall: 1rem padding top+bottom + 60px logo + 1px
       border) so fragment navigation (e.g. #Neck_girth from MarkdownService heading anchors) doesn't
       land underneath it. */
    scroll-padding-top: 96px;
}

strong,
b {
    font-weight: 400;
}

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

body {
    margin: 0;
}

/* Site-wide: links stay black regardless of visited state - no default browser blue/purple
   anywhere on the site. Elements that already set their own link color (e.g. .button, .basket-
   link via color: inherit) are unaffected since this only sets the base a/a:visited color. */
a:link,
a:visited {
    color: #000;
}

.page {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 1rem;
}

@supports (animation-timeline: view()) {
    .page.has-hero-logo {
        /* .hero-logo (the named timeline's source) and .site-header .logo (the consumer) are
           siblings under .page, not ancestor/descendant, so the named timeline must be
           re-exposed on their common ancestor via timeline-scope or it silently resolves to
           nothing for the consumer. Scoped to .has-hero-logo since only index.rocker.html has
           a .hero-logo element to drive the timeline — on other pages this would otherwise
           leave .site-header .logo animation-timeline pointed at a timeline that never
           resolves, permanently stuck at opacity 0. */
        timeline-scope: --hero-logo-timeline;
    }
}

.site-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 1rem 0 0 0;
    border-bottom: 1px solid #000;
    position: sticky;
    top: 0;
    background: #fff;
    z-index: 1;
}

.logo img {
    display: block;
    height: 60px;
    width: auto;
}

.site-header .logo {
    opacity: 1;
}

@supports (animation-timeline: view()) {
    .page.has-hero-logo .site-header .logo {
        opacity: 0;
        animation: reveal-header-logo linear both;
        animation-timeline: --hero-logo-timeline;
        animation-range: exit;
    }
}

@keyframes reveal-header-logo {
    from {
        opacity: 0;
        transform: scale(0.6);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

.site-header .logo.js-logo-visible {
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.site-header .logo.js-logo-hidden {
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.hero-logo {
    display: flex;
    justify-content: center;
    padding: 3rem 0;
    view-timeline-name: --hero-logo-timeline;
    view-timeline-axis: block;
}

.hero-logo img {
    display: block;
    width: min(300px, 60vw);
    height: auto;
    transform: translateX(-10px);
}

.primary-nav {
    display: none;
    align-items: center;
    align-self: stretch;
    gap: 1.25rem;
}

.primary-nav-link {
    color: inherit;
    text-decoration: none;
}

.categories-nav {
    position: relative;
    align-self: stretch;
    display: flex;
    align-items: center;
}

.categories-toggle {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.categories-link {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

/* Overlay flyout - position:absolute so it never reflows header/page layout. Collapses
   topward (scaleY from a top transform-origin) rather than a plain fade, and does so
   almost instantly - the 0.5s transition-delay below only delays the *start* of that
   collapse after the mouse/tap leaves (the hover/focus/checked rule below sets delay:
   0s, so opening is immediate - the delay only ever applies to hiding). */
.categories-panel {
    position: absolute;
    top: 100%;
    background: #fff;
    border: 1px solid #000;
    padding: 0.5rem;
    width: min(220px, 85vw);
    display: flex;
    flex-direction: column;
    z-index: 5;
    visibility: hidden;
    opacity: 0;
    transform: scaleY(0);
    transform-origin: top;
    transition: opacity 0.12s ease, visibility 0.12s ease, transform 0.12s ease;
    transition-delay: 0.5s;
}

.categories-panel--desktop {
    left: 0;
}

.categories-panel--mobile {
    /* Fixed to the collapsed header's own height (1rem padding-top + 60px logo + 1px
       border) instead of inheriting .categories-panel's top:100%, which is relative to
       .site-header's *current* box - and .site-header grows taller while .site-nav's
       accordion is expanded. Pinning to this fixed offset keeps the panel on the same
       line as the "Categories" trigger regardless of whether the hamburger menu below
       it is open or closed. */
    top: 77px;
    right: 0;
}

.categories-panel-link {
    display: block;
    padding: 0.5rem;
    color: inherit;
    text-decoration: none;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.12s ease, transform 0.12s ease;
    /* Matches .categories-panel's own hide-delay by default, so a link's text doesn't
       vanish ahead of the panel box itself during the 0.5s linger - the "open" rules
       below override this per-link with a short staggered delay instead. */
    transition-delay: 0.5s;
}

.categories-panel-link:hover {
    background: #f5f5f5;
}

/* Desktop: hover, click/tap (the checkbox), or keyboard focus shows the panel
   instantly (transition-delay: 0s overrides the 0.5s hide-delay above). Losing all
   three lets the 0.5s delay play out before the panel actually collapses, giving the
   pointer time to travel from the trigger down into the panel without it disappearing
   mid-move. */
.categories-nav:hover .categories-panel--desktop,
.categories-nav:focus-within .categories-panel--desktop,
#categories-toggle-desktop:checked ~ .categories-panel--desktop {
    visibility: visible;
    opacity: 1;
    transform: scaleY(1);
    transition-delay: 0s;
}

/* Mobile: tap-only. The panel lives outside .site-nav (a sibling of it, not a
   descendant) so it isn't clipped by .site-nav's overflow:hidden/max-height accordion
   collapse - :has() bridges the checkbox (inside .site-nav) and the panel (outside it)
   without needing DOM adjacency. */
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile {
    visibility: visible;
    opacity: 1;
    transform: scaleY(1);
    transition-delay: 0s;
}

/* Per-link stagger - each line fades/slides in a touch after the previous one, but
   only while opening; the base rule above (0.5s delay) takes back over on close so
   lines disappear together with the panel's own collapse, not one by one. */
.categories-nav:hover .categories-panel--desktop .categories-panel-link,
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link,
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link,
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link {
    opacity: 1;
    transform: translateY(0);
}

.categories-nav:hover .categories-panel--desktop .categories-panel-link:nth-child(1),
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link:nth-child(1),
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link:nth-child(1),
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link:nth-child(1) {
    transition-delay: 0s;
}

.categories-nav:hover .categories-panel--desktop .categories-panel-link:nth-child(2),
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link:nth-child(2),
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link:nth-child(2),
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link:nth-child(2) {
    transition-delay: 0.04s;
}

.categories-nav:hover .categories-panel--desktop .categories-panel-link:nth-child(3),
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link:nth-child(3),
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link:nth-child(3),
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link:nth-child(3) {
    transition-delay: 0.08s;
}

.categories-nav:hover .categories-panel--desktop .categories-panel-link:nth-child(4),
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link:nth-child(4),
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link:nth-child(4),
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link:nth-child(4) {
    transition-delay: 0.12s;
}

.categories-nav:hover .categories-panel--desktop .categories-panel-link:nth-child(5),
.categories-nav:focus-within .categories-panel--desktop .categories-panel-link:nth-child(5),
#categories-toggle-desktop:checked ~ .categories-panel--desktop .categories-panel-link:nth-child(5),
.site-header:has(#categories-toggle-mobile:checked) .categories-panel--mobile .categories-panel-link:nth-child(5) {
    transition-delay: 0.16s;
}

/* Opening the basket forces the Categories panel shut (whichever breakpoint's instance
   is active) so the two overlays never show at once - clicking "My basket" doesn't
   uncheck the categories checkbox, it just forces this visual override closed while
   #basket-toggle is checked, then the panel's normal hover/checked state resumes once
   the basket is closed again. The :has(#basket-toggle:checked) selector gives this
   (1,3,0) specificity, which beats every "open" rule above (the highest of which is
   also (1,3,0) but earlier in source order) so it always wins the conflict instead of
   needing !important.
   transition: none (not just transition-delay: 0s) is required here: moving the mouse
   toward the basket icon ends .categories-nav:hover a moment *before* the click lands
   and checks #basket-toggle, which already kicks off the normal 0.5s-delayed close
   transition using the delay that was in effect at that earlier instant. A later
   transition-delay change doesn't retroactively speed up a transition that's already
   pending/running, so only cancelling the transition outright (via transition: none)
   reliably snaps the panel shut the instant the basket opens. */
.site-header:has(#basket-toggle:checked) .categories-panel--desktop,
.site-header:has(#basket-toggle:checked) .categories-panel--mobile {
    visibility: hidden;
    opacity: 0;
    transform: scaleY(0);
    transition: none;
}

.basket-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: auto;
    text-decoration: none;
    color: inherit;
    white-space: nowrap;
    cursor: pointer;
}

.icon {
    display: block;
}

.basket-toggle {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.basket-panel {
    display: none;
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(320px, 100vw);
    background: #fff;
    border-left: 1px solid #000;
    padding: 1rem;
    overflow-y: auto;
    z-index: 2;
}

.basket-toggle:checked ~ .basket-panel {
    display: block;
}

.basket-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.basket-header h3 {
    margin: 0;
}

.basket-close {
    cursor: pointer;
    font-size: 1.25rem;
    line-height: 1;
}

.basket-items {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.basket-item {
    display: flex;
    gap: 1rem;
}

.basket-item-photo {
    display: block;
    width: 80px;
    height: 120px;
    object-fit: cover;
    flex-shrink: 0;
}

.basket-item-details {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;
}

.basket-item-name {
    font-weight: 400;
}

.basket-item-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.basket-item-remove {
    border: 1px solid #000;
    background: none;
    padding: 0.25rem 0.5rem;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

.basket-item-remove:hover {
    box-shadow: inset 0 0 0 1px #000;
}

.basket-total {
    display: flex;
    justify-content: space-between;
    font-weight: 400;
    padding: 0.75rem 0;
    border-top: 1px solid #000;
    margin-bottom: 1rem;
}

/* Delivery + Total shown together (checkout prepare/confirm) - one shared top border instead of
   each row carrying its own, so only a single line separates this block from what's above it. */
.basket-totals {
    border-top: 1px solid #000;
    padding-top: 0.75rem;
    margin-bottom: 1rem;
}

.basket-totals .basket-total-row {
    display: flex;
    justify-content: space-between;
}

.basket-totals .basket-total-row-delivery {
    font-size: 0.8rem;
    margin-bottom: 0.35rem;
}

.basket-totals .basket-total-row-total {
    font-weight: 400;
}

.basket-item-customisations {
    list-style: none;
    margin: 0.25rem 0 0;
    padding: 0;
    font-size: 0.75rem;
    color: #767676;
}

.order-payment-item .basket-item-details {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.order-payment-item .basket-item-customisations {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    flex: 1;
}

.payment-note {
    font-size: 0.75rem;
    color: #767676;
}

.orders-table {
    width: 100%;
    border-collapse: collapse;
}

.orders-table th,
.orders-table td {
    text-align: left;
    padding: 0.5rem;
    border-bottom: 1px solid #000;
}

.order-unpaid-marker {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border: 1px solid #b00020;
    color: #b00020;
    font-size: 0.75rem;
    font-weight: 400;
}

.customisation-missing {
    color: #b00020;
}

.button {
    display: block;
    text-align: center;
    text-decoration: none;
    color: inherit;
    background: none;
    border: 1px solid #000;
    padding: 0.5rem;
    font: inherit;
    font-weight: 400;
    cursor: pointer;
}

/* Inset box-shadow (not a wider border) so the extra pixel doesn't shift layout/size on hover. */
.button:hover {
    box-shadow: inset 0 0 0 1px #000;
}

/* a:link/a:visited (below) has higher specificity than .button's color: inherit, which would
   otherwise force a flat black on any <a class="button">, including a future inverted one (e.g.
   .button-primary applied to a link). Keep anchor-buttons inheriting their color instead. */
a.button:link,
a.button:visited {
    color: inherit;
}

/* Primary call-to-action buttons (checkout's "Review order"/"Confirm order") - full width,
   bold, inverted from the default outline-only .button look. Combined with class="button" so
   it still picks up shared rules (e.g. the :has(.floating-label-field) height-matching fix). */
.button-primary {
    width: 100%;
    background: #000;
    color: #fff;
    transition: background 0.2s ease;
}

.button-primary:hover {
    background: #333;
    box-shadow: none;
}

.auth-form {
    width: 80%;
    margin: 0 auto;
}

/* .button has no width of its own (buttons shrink-to-fit their content even with
   display:block), so match it explicitly to the floating-label-field inputs above it. */
.auth-form .button {
    width: 100%;
}

@media (min-width: 768px) {
    .auth-form {
        width: 50%;
    }
}

.form-field {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
}

.form-field label {
    flex: 0 0 10rem;
}

.form-field input,
.form-field select {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.4rem;
    border: 1px solid #000;
    font: inherit;
}

.form-field select {
    flex: 0 0 auto;
    min-width: 8rem;
}

.form-field .input-small {
    flex: 0 0 4.5rem;
}

.form-field .form-error {
    flex-basis: 100%;
    color: #b00020;
    font-size: 0.875rem;
}

.form-notice {
    color: #2e7d32;
}

.piece-customisations {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    flex: 1 1 auto;
}

.radio-group label {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: none;
}

.radio-group input[type="radio"] {
    flex: none;
    width: auto;
    padding: 0;
    border: none;
}

@media (min-width: 1024px) {
    /* CSS multi-column (not Grid) so each column's height is driven purely by its own content -
       a Grid with grid-template-areas ties row heights across both columns, which would force
       "Your pieces" to align with "Promo & total" whenever "Delivery address" runs long. With an
       auto-height multicol container, browsers fill column 1 top-to-bottom until the forced
       break-before below, then continue in column 2 - giving auth+pieces / address+promo as two
       independently-flowing columns. */
    .checkout-panels {
        column-count: 2;
        column-gap: 1.5rem;
    }

    .checkout-panel-address {
        break-before: column;
    }
}

/* Order-confirmed page: two real columns (left = Pieces + Address, right = Payment/Status),
   not the multi-column break trick above - the left/right grouping here is a literal DOM
   split, not an emergent property of column-balancing rules. */
.order-payment-columns {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.order-payment-column {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

@media (min-width: 1024px) {
    .order-payment-columns {
        flex-direction: row;
        align-items: flex-start;
    }

    .order-payment-column {
        flex: 1 1 0;
        min-width: 0;
    }
}

.checkout-panel {
    border: 1px solid #000;
    padding: 1.25rem;
    margin-bottom: 1.5rem;
    break-inside: avoid;
}

.checkout-panel h2 {
    margin-top: 0;
    font-size: 1.1rem;
}

.checkout-panel h3 {
    font-size: 0.95rem;
}

.checkout-panel .auth-form {
    width: auto;
    margin: 0;
}

/* Login-vs-guest toggle: two radios, one panel each, following the .basket-toggle/.carousel-radio
   CSS-only :checked pattern used elsewhere in this project - no JS. */
.checkout-auth-toggle {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

/* Segmented-control look for checkout radio choices (auth mode, delivery method) - the underlying
   radio can stay visually hidden (e.g. .checkout-auth-toggle above); :has(:checked) still matches
   regardless, so the label itself carries the selected/unselected affordance. */
.checkout-toggle-group label {
    border: 1px solid #000;
    padding: 0.5rem 1rem;
    cursor: pointer;
}

.checkout-toggle-group label:has(:checked) {
    background: #000;
    color: #fff;
}

.checkout-toggle-logo {
    height: 1.5em;
    width: auto;
    display: block;
}

.checkout-panel-auth:has(#auth-mode-login:checked) .checkout-auth-guest-panel {
    display: none;
}

.checkout-panel-auth:has(#auth-mode-guest:checked) .checkout-auth-login-panel {
    display: none;
}

/* Register toggle, nested inside the login form - swaps between the separate login and register
   forms (kept as two genuinely distinct <form>s, since HTML forbids nesting one inside the other
   and sharing a single form across both would make Enter-key implicit submission ambiguous once
   more than one submit button is present). */
.checkout-register-form-wrapper {
    display: none;
}

.checkout-auth-login-panel:has(.checkout-register-toggle:checked) .checkout-login-form-wrapper {
    display: none;
}

.checkout-auth-login-panel:has(.checkout-register-toggle:checked) .checkout-register-form-wrapper {
    display: block;
}

/* Billing address differs toggle - checked means "differs", following the same pattern. */
.checkout-panel-address:not(:has(.billing-differs-toggle:checked)) .checkout-billing-address-section {
    display: none;
}

/* Floating-label inputs, used throughout the checkout form only - login/register/profile keep
   the plain label-left .form-field layout untouched. Input needs placeholder=" " (a literal
   space, not empty) so :placeholder-shown reliably tracks "has no value", and the <label> must
   come after the <input> in markup (sibling, not wrapper) for the + selector below to reach it. */
.floating-label-field {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    margin-bottom: 0.75rem;
}

.floating-label-field input,
.floating-label-field select {
    width: 100%;
    padding: 1.1rem 0.6rem 0.4rem;
    border: 1px solid #000;
    font: inherit;
    background: transparent;
}

.floating-label-field label {
    position: absolute;
    left: 0.7rem;
    top: 0.75rem;
    max-width: calc(100% - 1.4rem);
    font-size: 1rem;
    color: #555;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    transition: top 0.1s ease, font-size 0.1s ease, color 0.1s ease;
}

.floating-label-field input:focus + label,
.floating-label-field input:not(:placeholder-shown) + label {
    top: 0.25rem;
    font-size: 0.7rem;
}

.floating-label-field-textarea {
    margin-bottom: 0.75rem;
}

.floating-label-field-textarea label {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 0.9rem;
    color: #555;
}

.checkout-comment-textarea {
    width: 100%;
    min-height: 4rem;
    padding: 0.6rem;
    border: 1px solid #000;
    font: inherit;
    background: transparent;
    resize: vertical;
}

/* A <select> has no :placeholder-shown equivalent and never looks "empty" the way a blank text
   input does (it always shows a real selection or its own empty option) - so its label is always
   rendered already shrunk, with no grow/shrink animation to key off of. */
.floating-label-field select + label {
    top: 0.25rem;
    font-size: 0.7rem;
}

.floating-label-field input:focus,
.floating-label-field select:focus {
    outline: 2px solid #000;
    outline-offset: -1px;
}

/* Omniva country/city/parcel-machine selects can have long option text (machine name + address) -
   ellipsis instead of overflowing. The box itself already fills the row via the shared
   .floating-label-field input/select rule above, unlike the old .form-field select default. */
.floating-label-field select.checkout-address-select {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Parcel-machine picker: a floating-label-field whose visible text input drives a live,
   client-fetched dropdown (see /js/parcel-machine-picker.js) - same box/positioning
   conventions as .tag-typeahead-suggestions in admin.css, ported here for the public site. */
.parcel-machine-picker-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    margin: 0;
    padding: 0;
    list-style: none;
    background: #fff;
    border: 1px solid #000;
    border-top: none;
    max-height: 16rem;
    overflow-y: auto;
}

.parcel-machine-picker-group {
    padding: 0.4rem 0.6rem;
    color: #555;
    font-size: 0.8rem;
    font-weight: 400;
    cursor: default;
    background: #f5f5f5;
}

.parcel-machine-picker-option {
    padding: 0.4rem 0.6rem;
    cursor: pointer;
}

.parcel-machine-picker-option:hover {
    background: #f5f5f5;
}

.parcel-machine-picker-option-address {
    font-size: 0.8rem;
    color: #555;
}

.parcel-machine-picker-input:disabled {
    cursor: not-allowed;
    background: #f5f5f5;
}

/* Phone country-code picker: same client-filtered-suggestions pattern as the parcel-machine
   picker above (see /js/phone-country-picker.js), minus the city-group variant - there's no
   grouping concept here, just a flat country list. */
.phone-country-picker-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    margin: 0;
    padding: 0;
    list-style: none;
    background: #fff;
    border: 1px solid #000;
    border-top: none;
    max-height: 16rem;
    overflow-y: auto;
}

.phone-country-picker-option {
    padding: 0.4rem 0.6rem;
    cursor: pointer;
}

.phone-country-picker-option:hover {
    background: #f5f5f5;
}

.floating-label-field + .form-error,
.form-row + .form-error {
    display: block;
    color: #b00020;
    font-size: 0.875rem;
    margin-top: -0.4rem;
    margin-bottom: 0.75rem;
}

.form-row {
    display: flex;
    gap: 0.75rem;
}

.form-row-city-postal .form-field-city {
    flex: 3 1 0;
}

.form-row-city-postal .form-field-postal {
    flex: 2 1 0;
}

.form-row-phone .phone-country-picker {
    flex: 0 0 10rem;
}

.form-row-phone .form-row-phone-number {
    flex: 1 1 0;
}

.form-row-promo {
    align-items: flex-start;
    margin-bottom: 0.75rem;
}

.form-row-promo .floating-label-field {
    flex: 1 1 auto;
    margin-bottom: 0;
}

.form-field-day {
    flex: 0 0 6rem;
}

/* Buttons next to/above a floating-label field should match its height - the input's vertical
   padding totals 1.5rem (1.1rem + 0.4rem), so give the button the same vertical total. Scoped via
   :has() to containers that actually hold a floating-label-field, so unrelated .button usages
   (admin pages, basket panel, etc.) are untouched. */
.auth-form:has(.floating-label-field) .button,
.checkout-panel:has(.floating-label-field) .button {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
}

.nav-toggle {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.nav-toggle-label {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 26px;
    height: 18px;
    cursor: pointer;
}

.nav-toggle-label span {
    display: block;
    height: 2px;
    background: currentColor;
}

.site-nav {
    flex-basis: 100%;
    max-height: 0;
    overflow: hidden;
}

.nav-toggle:checked ~ .site-nav {
    max-height: 200px;
}

.site-nav ul {
    list-style: none;
    margin: 0;
    padding: 0.75rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.site-nav a {
    text-decoration: none;
    color: inherit;
}

@media (min-width: 768px) {
    .nav-toggle-label {
        display: none;
    }

    .primary-nav {
        display: flex;
    }

    .mobile-only {
        display: none;
    }

    .site-nav {
        order: 1;
        flex-basis: auto;
        max-height: none;
        overflow: visible;
        margin-left: auto;
    }

    .basket-link {
        order: 2;
        margin-left: 0;
    }

    .site-nav ul {
        flex-direction: row;
        padding: 0;
        gap: 1.5rem;
    }
}

.piece-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
}

@media (min-width: 768px) {
    .piece-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

.piece-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.piece-card img {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: contain;
}

.piece-card-photo {
    position: relative;
    width: 100%;
}

.piece-card-photo-primary {
    opacity: 1;
    transition: opacity 0.2s ease;
}

.piece-card-photo-hover {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.piece-card:hover .piece-card-photo-primary {
    opacity: 0;
}

.piece-card:hover .piece-card-photo-hover {
    opacity: 1;
}

.piece-card .piece-name,
.piece-card .piece-price {
    margin: 0.5rem 0 0;
}

.piece-card-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-decoration: none;
    color: inherit;
}

.catalogue-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.catalogue-toolbar select,
.catalogue-price-input {
    padding: 0.4rem;
    border: 1px solid #000;
    font: inherit;
}

.catalogue-price-input {
    flex: 0 1 8rem;
    min-width: 0;
}

.catalogue-empty {
    text-align: center;
    padding: 2rem 0;
}

.breadcrumbs {
    font-size: 0.85rem;
    margin-bottom: 1rem;
}

.breadcrumbs a {
    color: inherit;
}

.breadcrumbs-sep {
    margin: 0 0.4rem;
    color: #767676;
}

.piece-detail {
    display: flex;
    flex-direction: column;
    gap: 2rem;
    padding: 2rem 0;
}

.piece-detail-photo {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.piece-main-photo-wrapper {
    position: relative;
}

.piece-detail-main-photo {
    display: block;
    width: 100%;
    height: auto;
}

.photo-nav {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 50%;
    border: none;
    background: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    font-size: 2rem;
    line-height: 1;
    color: #000;
    display: flex;
    align-items: center;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.photo-nav:hover {
    opacity: 1;
}

.photo-nav-prev {
    left: 0;
    justify-content: flex-start;
}

.photo-nav-prev::before {
    content: "\2039";
    padding-left: 0.5rem;
}

.photo-nav-next {
    right: 0;
    justify-content: flex-end;
}

.photo-nav-next::before {
    content: "\203a";
    padding-right: 0.5rem;
}

.piece-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.piece-thumb {
    display: block;
    flex: 0 0 calc((100% - 3 * 0.5rem) / 4);
    min-width: 0;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    border: 1px solid #000;
    cursor: pointer;
}

.piece-thumb-selected {
    border-width: 3px;
}

.piece-detail-info h1 {
    margin-top: 0;
}

.piece-detail-collection {
    margin: 0 0 1rem;
    color: #767676;
}

.piece-detail-description {
    margin-bottom: 2rem;
}

.piece-detail-materials {
    margin: 0;
    color: #767676;
}

.piece-detail-actions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.piece-detail-price {
    font-weight: 400;
    font-size: 1.25rem;
    margin: 0;
}

@media (min-width: 768px) {
    .piece-detail {
        flex-direction: row;
        align-items: flex-start;
    }

    .piece-detail-photo {
        flex: 0 0 40%;
        min-width: 0;
    }

    .piece-detail-main-photo {
        aspect-ratio: 2 / 3;
        object-fit: cover;
    }

    .piece-detail-info {
        flex: 1;
    }
}

.site-footer {
    margin-top: 3rem;
    padding: 2rem 0;
    border-top: 1px solid #000;
}

.footer-columns {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

.footer-logo {
    display: flex;
    justify-content: center;
}

.footer-logo img {
    display: block;
    height: 80px;
    width: auto;
}

.footer-links {
    display: flex;
    justify-content: space-between;
    padding: 0 1.5rem;
}

.footer-column h4 {
    margin: 0 0 0.5rem;
}

.footer-column ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.footer-column a {
    text-decoration: none;
    color: inherit;
}

.footer-social {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    max-width: 16rem;
    margin: 2rem auto 0;
}

.footer-social a {
    color: inherit;
    display: inline-flex;
}

@media (min-width: 768px) {
    .footer-columns {
        flex-direction: row;
        justify-content: space-around;
        align-items: flex-start;
    }

    .footer-links {
        display: contents;
    }
}

img.md {
    max-width: 50%;
    margin: auto;
    display: block;
}

.carousel {
    position: relative;
    padding-bottom: 1.5rem;
}

.carousel-radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.carousel-track {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
}

.carousel-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}

.carousel-image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.carousel-caption {
    position: absolute;
    bottom: 1rem;
    max-width: 60%;
    padding: 0.5rem 0.75rem;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
}

.carousel-caption-left {
    left: 1rem;
}

.carousel-caption-right {
    right: 1rem;
}

.carousel-dots {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.carousel-dot {
    display: block;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
    border: 1px solid #000;
    background: transparent;
    cursor: pointer;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}

.prose {
    text-align: justify;
    font-size: 1rem;
    line-height: 1.75;
}

.press-strip {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem 1.5rem;
    padding: 0 1rem 2.5rem;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #767676;
}

.press-strip span:not(:last-child)::after {
    content: "·";
    margin-left: 1.5rem;
    color: #767676;
}

.category-explorer {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
}

@media (min-width: 768px) {
    .category-explorer {
        grid-template-columns: repeat(4, 1fr);
        gap: 1.5rem;
    }
}

.category-tile {
    position: relative;
    display: block;
    text-decoration: none;
    color: inherit;
}

.category-tile img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    transition: filter 0.2s ease;
}

.category-tile:hover img,
.category-tile:focus-visible img,
.category-tile:active img {
    filter: brightness(1.15);
}

.lowercase {
    text-transform: lowercase;
}

.category-tile-label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 0.6rem 0.5rem;
    text-align: center;
    font-size: 0.85rem;
    letter-spacing: 0.04em;
    text-transform: lowercase;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
}

.video-feature {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.video-feature-player {
    display: block;
    width: 100%;
    max-height: 70vh;
    background: #000;
}

.development-notice {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    align-items: center;
    background: #f5f5f5;
    border: 1px solid #000;
    padding: 1.5rem;
    margin: 1.5rem 0;
    text-align: center;
}

.development-notice-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: inherit;
    text-decoration: none;
}

.video-feature-caption {
    margin: 0;
    text-align: center;
    font-size: 0.85rem;
    color: #767676;
}