/*
Theme Name: Voya
Theme URI: https://voyaspecialty.com
Description: Child theme for PB Boilerplate, built for Voya Coffee (voyaspecialty.com).
Author: Publishing Bureau
Author URI: https://publishingbureau.co.uk
Template: pb-boilerplate
Version: 1.40.1
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 8.0
Text Domain: voya
*/

/* ==========================================================================
   Design tokens

   The palette, type scale, font families and most element styles live in
   theme.json — edit them there, not here. This file carries only what
   theme.json cannot express.
   ========================================================================== */

:root {
    /* Layout */
    --header-height: 100px;

    /* Tooth depth of the torn edges — see the Torn edges section below. From
       the design's "white jagged divider.svg": a wave of roughly 8px over a
       1200 artboard, so 0.65% of the width. Kept in vw so the teeth hold
       their proportions at every viewport rather than turning spiky on a
       phone, and capped so they stop growing on a wide screen.

       The value itself lives in theme.json (settings.custom.jagged), which
       emits it to the editor as well — assets/css/editor.css draws the same
       teeth and would otherwise need its own copy of the number. */
    --voya-jagged: var(--wp--custom--jagged);

    /* How far the Offerings filter panel rides up over the hero above it.
       Shared, so the media query below can ease it on a short screen. */
    --voya-panel-lift: min(8rem, 10vw);

    /* ----------------------------------------------------------------------
       Parent theme furniture.

       The parent's header and footer rules are written against these custom
       properties, so pointing them at Voya's palette restyles both without
       restating a single rule. Anything the properties cannot reach is in the
       Header and Footer sections further down.
       ---------------------------------------------------------------------- */
    --header--background--colour: #ffffff;
    --header--border--colour: transparent;
    --header--link--colour: #244844;
    --header--nav--font-size: 1.25rem;   /* 20px, per the design */
    --header--nav--line-height: 1.2;
    --header--nav--padding-y: 12px;
    --footer--background--colour: #ffffff;

    /* How far a button rises on hover. Also consumed by theme.json as
       settings.custom.buttonLift so the value has a single source. */
    --voya-button-lift: 2px;

    /* Motion */
    --voya-transition: 0.2s ease;

    /* ----------------------------------------------------------------------
       Legacy parent-theme colour slugs.

       The parent stylesheet references these custom properties over 45 times
       (--highlight alone 25 times), but they are not Voya brand colours and so
       are deliberately absent from the child palette in theme.json — putting
       them there would clutter the editor colour picker with names that mean
       nothing on this site.

       Remapping them here keeps every parent rule resolving to an on-brand
       colour. Because WordPress only emits --wp--preset--color--* for slugs
       that exist in the palette, these definitions are the sole source for
       these five, so there is no cascade race with global styles.
       ---------------------------------------------------------------------- */
    --wp--preset--color--highlight: #901928;  /* accents, links, focus rings */
    --wp--preset--color--dark-grey: #244844;  /* darker text, borders */
    --wp--preset--color--grey: color-mix(in srgb, #244844 65%, #ffffff);
    --wp--preset--color--blue: #56b36f;       /* social link circles */
    --wp--preset--color--navy: #070e0e;
}

/* ==========================================================================
   Text selection
   Design: "Selected text: #56B36F"
   ========================================================================== */

::selection {
    background-color: var(--wp--preset--color--green);
    color: var(--wp--preset--color--white);
}

::-moz-selection {
    background-color: var(--wp--preset--color--green);
    color: var(--wp--preset--color--white);
}

/* ==========================================================================
   Child theme custom styles

   Site furniture (header, footer, hero, offerings) goes below as those
   sections are built. Block and element styles live in assets/css/blocks.css
   so the block editor can load the same rules.
   ========================================================================== */

/* ==========================================================================
   Torn edges

   Add "voya-jagged-top" and/or "voya-jagged-bottom" to a block's Additional
   CSS class. A section declares which of its *own* edges are torn.

   A torn seam cuts BOTH sections that meet at it, with complementary shapes:
   the upper section's bottom and the lower section's top follow the same
   zigzag line, and the lower section is pulled up by one tooth so the two
   tile exactly. voya-jagged-bottom therefore reaches across to its next
   sibling to cut the matching top.

       voya-jagged-top     cut my own top, ride up over the section above
       voya-jagged-bottom  cut my own bottom, and cut my next sibling to match

   Cutting both is what makes this work whatever the sections are made of, and
   two earlier versions each got it wrong by cutting only one:

   - Cutting only the section carrying the class needed it raised above its
     neighbour to cover it. Two torn-bottom sections in a row then both sat at
     z-index 1, and the later one painted over the teeth of the one above.
   - Cutting only the lower section needed nothing stacked, but does nothing
     at all when that section has no background of its own — as the white
     Groups between Voya's photo bands do not. The tear silently vanished.

   Because the two cuts tile rather than overlap, no z-index is involved. Do
   not add one: that is what brought back the first bug.

   The edges are cut, not covered with the design's white divider SVG, so a
   torn seam works between any two colours and the video hero — which cannot
   carry a baked-in edge — is handled the same way as everything else.

   voya-jagged-bottom on the last block of a page still cuts its own bottom;
   there is simply no sibling to cut to match.

   The rules below are the front end's. The editor gets its own, simpler
   treatment in assets/css/editor.css — it cannot interlock blocks without
   collapsing the gaps the block list needs, so it jags each block on its own.
   Change the geometry here and change it there too; the tooth depth itself is
   shared through theme.json.
   ========================================================================== */

.voya-jagged-top,
.voya-jagged-bottom,
.voya-jagged-bottom + * {
    /*
     * Flat unless a rule below replaces that edge. Assembling the polygon
     * from two custom properties is what lets a section be cut top and bottom
     * at once — by its own class, by its neighbour's, or by both — without a
     * combinatorial set of whole clip-paths.
     */
    --voya-edge-top: 0 0, 100% 0;
    --voya-edge-bottom: 100% 100%, 0 100%;

    clip-path: polygon(var(--voya-edge-top), var(--voya-edge-bottom));
}

/* Eleven even teeth. Riding up one tooth is what makes this edge land on the
   same line as the torn bottom above it. */
.voya-jagged-top,
.voya-jagged-bottom + * {
    margin-top: calc(var(--voya-jagged) * -1);

    --voya-edge-top:
        0 0,
        9.1% var(--voya-jagged),
        18.2% 0,
        27.3% var(--voya-jagged),
        36.4% 0,
        45.5% var(--voya-jagged),
        54.5% 0,
        63.6% var(--voya-jagged),
        72.7% 0,
        81.8% var(--voya-jagged),
        90.9% 0,
        100% var(--voya-jagged);
}

/* The complement of the above, point for point. */
.voya-jagged-bottom {
    --voya-edge-bottom:
        100% 100%,
        90.9% calc(100% - var(--voya-jagged)),
        81.8% 100%,
        72.7% calc(100% - var(--voya-jagged)),
        63.6% 100%,
        54.5% calc(100% - var(--voya-jagged)),
        45.5% 100%,
        36.4% calc(100% - var(--voya-jagged)),
        27.3% 100%,
        18.2% calc(100% - var(--voya-jagged)),
        9.1% 100%,
        0 calc(100% - var(--voya-jagged));
}

/* --------------------------------------------------------------------------
   Exception: a section whose contents lift over the torn seam

   The Offerings filter panel floats over the hero above it. It cannot lift
   out of its own section while that section is cut to match the hero's torn
   foot, because a clip-path clips descendants too — pulled up far enough to
   overlap, the panel would simply be clipped away.

   So this one seam is drawn the other way round. The lower section keeps its
   square top and the torn section above stacks over it instead, which gives
   the same seam: the hero's teeth show, and its notches reveal the pale green
   behind. The panel is then free to lift clear of both.

   The z-index caveat from the Torn edges block still applies — this works
   because it is a single seam with a section that does not itself tear at the
   bottom. It is not a pattern to spread.
   -------------------------------------------------------------------------- */

.voya-jagged-bottom + *:has(.voya-offerings__panel) {
    clip-path: none;
}

.voya-jagged-bottom:has(+ * .voya-offerings__panel) {
    z-index: 1;
}

/*
 * The lift is width-based, but the hero it rides over is sized in vh — so on
 * a short screen the hero shrinks while the lift does not, and the panel
 * covers the hero's own text. Measured 63px of overlap at 1280x620. Eased
 * here rather than padding the hero on every screen to suit the worst case.
 */
@media (max-height: 800px) {

    :root {
        --voya-panel-lift: 3rem;
    }
}

/* ==========================================================================
   Hero

   The homepage video Cover, which carries className "voya-hero".
   ========================================================================== */

/*
 * The parent pads the top of every main region by 40px, which is right for a
 * page opening on a heading but leaves a white strip above a full-bleed hero —
 * and pushes the hero's foot below the fold, undoing the height set below.
 *
 * Matched structurally rather than with a .home class, because the Offerings
 * page opens on a full-width Cover too, and any future one will as well.
 */
.site-main:has(.entry-content > .wp-block-cover.alignfull:first-child) {
    padding-top: 0;
}

/*
 * The torn foot comes from voya-jagged-bottom, on the block itself. All that
 * is left here is the height.
 *
 * Full viewport, less the header and less one tooth — the tooth because the
 * torn edge cuts upward from the block's own bottom, and the design leaves
 * about that much page showing beneath the deepest troughs.
 *
 * Two min-height declarations rather than a fallback chain: svh is the
 * *small* viewport, the height with a mobile browser's toolbar showing. vh
 * measures it with the toolbar hidden, which on a phone makes the hero taller
 * than the screen actually is. Browsers without svh drop the second line and
 * keep the first.
 */
.wp-block-cover.voya-hero {
    min-height: calc(100vh - var(--header-height) - var(--voya-jagged));
    min-height: calc(100svh - var(--header-height) - var(--voya-jagged));
}

/*
 * The admin bar is fixed and pushes the document down, so without this the
 * page overflows by exactly its height whenever anyone is logged in — which
 * is every time the site is reviewed.
 */
.admin-bar .wp-block-cover.voya-hero {
    min-height: calc(100vh - var(--header-height) - var(--voya-jagged) - 32px);
    min-height: calc(100svh - var(--header-height) - var(--voya-jagged) - 32px);
}

@media screen and (max-width: 782px) {

    .admin-bar .wp-block-cover.voya-hero {
        min-height: calc(100vh - var(--header-height) - var(--voya-jagged) - 46px);
        min-height: calc(100svh - var(--header-height) - var(--voya-jagged) - 46px);
    }
}

/* ==========================================================================
   Header

   A white bar the full width of the viewport, its contents held to the wide
   size so they sit slightly outside the content column — as the design draws
   them, inset from the artboard edge rather than aligned to the text.
   ========================================================================== */

.site-header {
    border-bottom: 0;
}

.header-container {
    max-width: var(--wp--style--global--wide-size);
    gap: 1rem;
}

@media (min-width: 783px) {

    .header-container {
        padding-right: 2rem;
        padding-left: 2rem;
        gap: 2rem;
    }
}

/* --------------------------------------------------------------------------
   Logo
   -------------------------------------------------------------------------- */

.site-logo {
    display: inline-flex;
    color: var(--wp--preset--color--deep-green);
    text-decoration: none;
    transition: color var(--voya-transition);
}

.site-logo:hover,
.site-logo:focus-visible {
    color: var(--wp--preset--color--green);
}

/* The mark is a single path filled with currentColor, so it takes the link
   colour above. Width drives it; height follows the viewBox. */
.site-logo svg {
    display: block;
    width: 130px;
    height: auto;
}

@media (min-width: 783px) {

    .site-logo svg {
        width: 178px;
    }
}

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */

.main-navigation {
    gap: 1rem;
    justify-content: flex-end;
}

/*
 * Scoped to the menu list, and excluding the social row inside it.
 *
 * The social icons are now an <li> within #primary-menu so that they collapse
 * with the mobile menu, which puts them in reach of these rules. An underline
 * under an icon is not what anyone wants, so .social-link is excluded rather
 * than the scope being widened back out.
 */
.main-navigation #primary-menu a:not(.social-link) {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 800;
    text-transform: uppercase;
    text-decoration: none;
}

/*
 * Hover and focus: green text over a green rule. text-decoration rather than a
 * pseudo-element because the parent already uses ::after on these links for
 * the dropdown caret, and because it underlines the word rather than the
 * whole padded box — which is what the design shows.
 */
.main-navigation #primary-menu a:not(.social-link):hover,
.main-navigation #primary-menu a:not(.social-link):focus-visible {
    color: var(--wp--preset--color--green);
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 6px;
}

/* The current page keeps its dark text so it stays distinct from a hover. */
.main-navigation #primary-menu .current-menu-item > a,
.main-navigation #primary-menu .current-page-ancestor > a {
    color: var(--header--link--colour);
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--green);
    text-decoration-thickness: 2px;
    text-underline-offset: 6px;
}

.main-navigation #primary-menu .current-menu-item > a:hover,
.main-navigation #primary-menu .current-page-ancestor > a:hover {
    color: var(--wp--preset--color--green);
}

/* --------------------------------------------------------------------------
   404

   A full-bleed dark panel rather than text on white, following the pattern
   the other Publishing Bureau 404s use: a ghosted status code behind the
   heading, one line of copy, one way onward, and search underneath.

   The panel breaks out of the content column with a viewport-width trick
   rather than by moving the markup, because the section sits inside
   .site-main and the theme constrains that.
   -------------------------------------------------------------------------- */

.voya-404 {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    padding: 4rem 1.25rem 6rem;
    background: var(--wp--preset--color--deep-green);
    color: var(--wp--preset--color--white);
    text-align: center;
    overflow: hidden;
}

.voya-404__inner {
    position: relative;
    max-width: 40rem;
    margin-inline: auto;
}

/* --------------------------------------------------------------------------
   The cup that ends the sentence

   Set as the full stop after "break". Sized in em so it tracks the heading's
   clamp, and nudged onto the baseline rather than sitting on it, since the
   mark's visual weight is lower than its box.
   -------------------------------------------------------------------------- */

.voya-404__stop {
    display: inline-block;
    margin-left: 0.12em;
}

/*
 * The drawn cup stops about an eighth of the way up from the foot of its
 * viewBox — the space is there for the saucer this mark does not have — so
 * baseline alignment leaves it hovering. Dropped far enough that the cup sits
 * on the line of the text rather than above it.
 */
.voya-404__cup {
    width: 0.8em;
    height: 0.8em;
    vertical-align: -0.1em;
}

/*
 * The wisps rise and fade, then start again. Seven seconds and a few pixels
 * of travel — enough to read as steam if you look, invisible if you do not.
 * The only moving thing on the page, so anything faster would pull the eye
 * off the sentence it is punctuating.
 */
.voya-404__cup .voya-cup__steam {
    animation: voya-steam 7s ease-in-out infinite;
}

.voya-404__cup .voya-cup__steam--2 {
    animation-delay: -3.5s;
}

@keyframes voya-steam {

    0% {
        opacity: 0;
        transform: translateY(1px);
    }

    30% {
        opacity: 1;
    }

    70% {
        opacity: 0.7;
    }

    100% {
        opacity: 0;
        transform: translateY(-3px);
    }
}

/* Decoration, so it stops entirely when motion is not wanted. */
@media (prefers-reduced-motion: reduce) {

    .voya-404__cup .voya-cup__steam {
        animation: none;
    }
}

/*
 * The status code, sat behind the heading. Sized in vw so it stays a
 * backdrop rather than a headline at any width.
 */
.voya-404__code {
    margin: 0;
    font-family: var(--wp--preset--font-family--heading);
    font-size: clamp(7rem, 22vw, 16rem);
    font-weight: 800;
    line-height: 0.8;
    color: rgb(255 255 255 / 8%);
    user-select: none;
}

.voya-404__title {
    margin: 1.5rem 0 0;
    color: var(--wp--preset--color--white);
}

.voya-404__lead {
    margin: 1rem 0 2.5rem;
    font-size: var(--wp--preset--font-size--large);
    color: rgb(255 255 255 / 80%);
}

.voya-404__actions {
    margin: 0 0 3rem;
}

.voya-404__search {
    max-width: 26rem;
    margin-inline: auto;
}

.voya-404__search-label {
    margin: 0 0 0.75rem;
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--small);
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;

    /* 70%, not 60%: at 60 this lands on 4.79:1, which passes AA for 14px bold
       but leaves no margin if the green is ever adjusted. */
    color: rgb(255 255 255 / 70%);
}

.voya-404__home {
    margin: 2.5rem 0 0;
}

.voya-404__home a {
    color: rgb(255 255 255 / 80%);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.voya-404__home a:hover,
.voya-404__home a:focus-visible {
    color: var(--wp--preset--color--white);
}

/* --------------------------------------------------------------------------
   Search form

   get_search_form() renders the classic markup (.search-form / .search-field /
   .search-submit), not the Search block, so none of the block button styling
   reaches it — the submit was rendering in WordPress admin blue. Styled here
   rather than on the 404 alone, because the same form appears on the search
   results page.

   The parent styles this form only inside .nav-search__form-wrapper, where it
   sits on its own dark panel.
   -------------------------------------------------------------------------- */

.voya-404 .search-form,
.search-results .search-form,
.search-no-results .search-form {
    display: flex;
    gap: 0.5rem;
}

.voya-404 .search-form label,
.search-results .search-form label,
.search-no-results .search-form label {
    flex: 1;
}

.voya-404 .search-field,
.search-results .search-field,
.search-no-results .search-field {
    width: 100%;
    border: 1px solid #c8d1d0;
    border-radius: 0;
    padding: 0.5rem 0.75rem;
    font: inherit;
    color: var(--wp--preset--color--deep-green);
    background: var(--wp--preset--color--white);
}

.voya-404 .search-field:focus-visible,
.search-results .search-field:focus-visible,
.search-no-results .search-field:focus-visible {
    outline: 2px solid var(--wp--preset--color--green);
    outline-offset: 1px;
}

.voya-404 .search-submit,
.search-results .search-submit,
.search-no-results .search-submit {
    flex: none;
    border: 2px solid var(--wp--preset--color--burgundy);
    border-radius: 0;
    padding: 0.5rem 1.25rem;
    background: var(--wp--preset--color--burgundy);
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 800;
    color: var(--wp--preset--color--white);
    cursor: pointer;
    transition: background-color var(--voya-transition), border-color var(--voya-transition);
}

.voya-404 .search-submit:hover,
.voya-404 .search-submit:focus-visible,
.search-results .search-submit:hover,
.search-results .search-submit:focus-visible,
.search-no-results .search-submit:hover,
.search-no-results .search-submit:focus-visible {
    background: var(--wp--preset--color--green);
    border-color: var(--wp--preset--color--green);
}

/* --------------------------------------------------------------------------
   Order buttons — one per form

   Every coffee comes green or roasted, so the single button became two. They
   share the row rather than stacking, which keeps the card's foot the height
   it was designed at.
   -------------------------------------------------------------------------- */

/*
 * Labelled, because two outlined boxes with one word in each read as badges
 * on a card that already uses exactly that for the category. The label is
 * styled like "Tasting notes" so it joins the card's existing vocabulary
 * rather than introducing a new one.
 */
.voya-offering-card__order-label,
.voya-offering__order-label {
    margin: 0 0 0.5rem;
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.9rem;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--wp--preset--color--deep-green);
}

/*
 * On a card the label sits beside the buttons rather than above them: the
 * foot is a stack now, and a label on its own line would cost a third row.
 * It wraps back above them if the card is ever too narrow to seat both.
 */
.voya-offering-card__order-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem 0.75rem;
}

.voya-offering-card__order-label {
    margin-bottom: 0;
    text-align: right;
}

.voya-offering-card__order-forms {
    display: flex;
    gap: 0.5rem;
}

/* The single offering keeps the qualifier spelled out, on the price line. */
.voya-offering__price-line {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.voya-offering__order-forms {
    display: grid;
    gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   Single offering

   The card opened out. It borrows the card's accent, badge, dashed spec rules
   and burgundy tasting notes so the two read as the same object at different
   sizes, rather than restating them from scratch.
   -------------------------------------------------------------------------- */

.voya-offering {
    max-width: var(--wp--style--global--content-size, 1200px);
    margin-inline: auto;
    padding-inline: var(--wp--style--root--padding-right, 1.25rem);
}

.voya-offering__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;

    /* The accent bar the card wears along its top edge. */
    border-top: 6px solid var(--voya-card-accent, var(--wp--preset--color--green));
    padding-top: 1.5rem;
}

.voya-offering__badge {
    display: inline-block;
    margin: 0 0 0.75rem;
    padding: 0.25rem 0.625rem;
    background: var(--voya-card-accent, var(--wp--preset--color--green));
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.8125rem;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--wp--preset--color--white);
}

.voya-offering__title {
    margin: 0;
}

.voya-offering__origin {
    margin: 0.25rem 0 0;
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--large);
    text-transform: uppercase;
    color: var(--wp--preset--color--deep-green);
}

.voya-offering__icon {
    flex: none;
    width: 5rem;
    height: 5rem;
}

@media (min-width: 48rem) {

    .voya-offering__icon {
        width: 7.5rem;
        height: 7.5rem;
    }
}

.voya-offering__body {
    display: grid;
    gap: 2.5rem;
    margin-top: 2rem;
}

/* Two columns once there is room: the writing beside the figures. */
@media (min-width: 56rem) {

    .voya-offering__body {
        grid-template-columns: minmax(0, 1fr) 20rem;
        gap: 3.5rem;
    }
}

.voya-offering__content > :first-child,
.voya-offering__more > :first-child {
    margin-top: 0;
}

.voya-offering__more {
    margin-top: 1.5rem;
}

.voya-offering__specs {
    margin: 0 0 2rem;
}

.voya-offering__spec {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0;

    /* The card's dashed rule, restated so the two match exactly. */
    background-image: repeating-linear-gradient(to right, #c8d1d0 0 6px, transparent 6px 12px);
    background-repeat: no-repeat;
    background-size: 100% 1px;
    background-position: left bottom;
}

/*
 * The rows carry equal padding so the dashed rules sit evenly, but that
 * pushes the first label 8px below the first line of the prose beside it.
 * Both columns start at the same y and share a line-height, so dropping the
 * padding on this one row lines the two up exactly.
 */
.voya-offering__spec:first-child {
    padding-top: 0;
}

.voya-offering__spec-label {
    color: var(--wp--preset--color--deep-green);
}

.voya-offering__spec-value {
    margin: 0;
    font-weight: 700;
    text-align: right;
    color: var(--wp--preset--color--deep-green);
}

.voya-offering__notes {
    margin-bottom: 2rem;
}

.voya-offering__notes-label {
    margin: 0 0 0.25rem;
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.9rem;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--wp--preset--color--deep-green);
}

/* Always burgundy, whatever the category accent. */
.voya-offering__notes-list {
    margin: 0;
    font-weight: 700;
    color: var(--wp--preset--color--burgundy);
}

.voya-offering__price {
    margin: 0 0 1.5rem;
}

.voya-offering__price-value {
    display: block;
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--x-large);
    font-weight: 800;
    color: var(--wp--preset--color--deep-green);
}

.voya-offering__price-unit,
.voya-offering__price-note {
    display: block;
    font-family: var(--wp--preset--font-family--body);
    font-size: 0.9375rem;
    color: var(--wp--preset--color--deep-green);
}

/* Quieter than the sack size: it qualifies the figure it sits beside rather
   than describing what is being bought. */
.voya-offering__price-note {
    opacity: 0.7;
}

.voya-offering__order {
    width: 100%;
    border: 2px solid var(--wp--preset--color--burgundy);
    padding: 0.75rem 1.25rem;
    background: var(--wp--preset--color--burgundy);
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--small);
    font-weight: 800;
    text-transform: uppercase;
    color: var(--wp--preset--color--white);
    cursor: pointer;
    transition: background-color var(--voya-transition), color var(--voya-transition);
}

.voya-offering__order:hover,
.voya-offering__order:focus-visible {
    background: var(--wp--preset--color--deep-green);
    border-color: var(--wp--preset--color--deep-green);
}

.voya-offering__order.is-in-basket {
    background: var(--wp--preset--color--deep-green);
    border-color: var(--wp--preset--color--deep-green);
}

/* Above the title, so the way out is visible before the reading starts. */
.voya-offering__back {
    margin: 0 0 1.5rem;
}

/* --------------------------------------------------------------------------
   Checkout dialog

   A native <dialog>. ::backdrop is the browser's own overlay, so no separate
   scrim element is needed.
   -------------------------------------------------------------------------- */

.voya-checkout {
    width: min(30rem, calc(100vw - 2rem));
    max-height: calc(100vh - 4rem);
    border: 1px solid var(--wp--preset--color--deep-green);
    padding: 2rem;
    background: var(--wp--preset--color--white);
    color: var(--wp--preset--color--deep-green);
    overflow-y: auto;
}

/*
 * Applied by main.js while the dialog is open. position:fixed rather than
 * overflow:hidden because iOS Safari ignores the latter on body; the script
 * holds the scroll position and puts it back on close.
 */
body.voya-scroll-locked {
    position: fixed;
    width: 100%;
    overflow: hidden;
}

/* The dialog itself must still scroll — it is taller than a phone screen. */
.voya-checkout {
    overscroll-behavior: contain;
}

.voya-checkout::backdrop {
    background: rgb(36 72 68 / 60%);
}

/* Closed dialogs are display:none by the UA stylesheet; this only matters for
   the no-<dialog> fallback, which sets the open attribute by hand. */
.voya-checkout:not([open]) {
    display: none;
}

.voya-checkout__close-form {
    display: flex;
    justify-content: flex-end;
    margin: -1rem -1rem 0 0;
}

.voya-checkout__close {
    border: 0;
    background: none;
    padding: 0.25rem 0.5rem;
    font-size: 1.75rem;
    line-height: 1;
    color: inherit;
    cursor: pointer;
}

.voya-checkout__close:hover,
.voya-checkout__close:focus-visible {
    color: var(--wp--preset--color--green);
}

.voya-checkout__title {
    margin: 0 0 1rem;
}

.voya-checkout__list {
    margin: 0 0 1.5rem;
    padding: 0;
    list-style: none;
}

.voya-checkout__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    border-bottom: 1px solid #c8d1d0;
    padding: 0.5rem 0;
    font-size: var(--wp--preset--font-size--large);
    font-weight: 700;
}

.voya-checkout__remove {
    flex: none;
    border: 0;
    background: none;
    padding: 0 0.25rem;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--wp--preset--color--burgundy);
    cursor: pointer;
}

/* Sits between the list and the form. Small, but bold — it is a condition of
   the order rather than a passing note. */
.voya-checkout__sizes {
    margin: 0 0 1.5rem;
    font-size: var(--wp--preset--font-size--small);
    font-weight: 700;
    color: var(--wp--preset--color--deep-green);
}

.voya-checkout__sizes[hidden] {
    display: none;
}

.voya-checkout__field {
    margin: 0 0 1rem;
}

/*
 * Left to itself a select is drawn by the platform, not by us: iOS renders it
 * as a rounded pill and Safari on macOS makes it shorter than the inputs
 * beside it, because neither applies our padding the way a text field does.
 * appearance:none hands the box back, at the price of also removing the
 * chevron — hence the one drawn in as a background image.
 */
.voya-checkout__field select {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    border: 1px solid #c8d1d0;
    border-radius: 0;

    /* Matches the inputs, plus room on the right for the chevron. */
    padding: 0.5rem 2.25rem 0.5rem 0.5rem;
    font: inherit;
    line-height: inherit;
    color: inherit;
    background-color: var(--wp--preset--color--white);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23244844' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 0.75rem auto;
}

/*
 * Nothing chosen yet. The field is required, so an empty value is :invalid —
 * which is a reliable way to tell "Country" apart from a real choice and grey
 * it to match the placeholders in the fields above.
 */
.voya-checkout__field select:invalid {
    color: #5b6f6c;
}

.voya-checkout__field select:focus-visible {
    outline: 2px solid var(--wp--preset--color--green);
    outline-offset: 1px;
}

/*
 * A placeholder is lighter than typed text by default, which puts it near the
 * contrast floor. Pinned to a tone that stays readable, since these are
 * carrying the field names.
 */
.voya-checkout__field ::placeholder {
    color: #5b6f6c;
    opacity: 1;
}

.voya-checkout__done-title {
    margin: 0 0 0.5rem;
    font-size: var(--wp--preset--font-size--large);
    font-weight: 700;
    color: var(--wp--preset--color--green);
}

.voya-checkout__done:focus-visible {
    outline: none;
}

.voya-checkout__done[hidden],
.voya-checkout__list[hidden],
.voya-checkout__empty[hidden] {
    display: none;
}

.voya-checkout__field label {
    display: block;
    margin-bottom: 0.25rem;
    font-weight: 700;
}

.voya-checkout__field input,
.voya-checkout__field textarea {
    width: 100%;
    border: 1px solid #c8d1d0;
    padding: 0.5rem;
    font: inherit;
    color: inherit;
}

.voya-checkout__field input:focus-visible,
.voya-checkout__field textarea:focus-visible {
    outline: 2px solid var(--wp--preset--color--green);
    outline-offset: 1px;
}

.voya-checkout__field [aria-invalid="true"] {
    border-color: var(--wp--preset--color--burgundy);
}

.voya-checkout__error:not(:empty) {
    display: block;
    margin-top: 0.25rem;
    font-size: var(--wp--preset--font-size--small);
    color: var(--wp--preset--color--burgundy);
}

/*
 * The honeypot. Taken out of the layout without display:none or visibility,
 * both of which are the first things a form-filling bot checks for.
 */
.voya-checkout__trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.voya-checkout__privacy {
    margin: 0 0 1rem;
    font-size: var(--wp--preset--font-size--small);
}

.voya-checkout__status:not(:empty) {
    margin: 0 0 1rem;
    font-weight: 700;
    color: var(--wp--preset--color--burgundy);
}

.voya-checkout__status.is-success {
    color: var(--wp--preset--color--green);
}

.voya-checkout__form[hidden] {
    display: none;
}

/* --------------------------------------------------------------------------
   Sample basket control

   Sits beside the menu toggle rather than in the nav list, so the count stays
   visible when the mobile menu is closed.

   Icon and count only, no visible text. A sack was tried first, to echo the
   offerings' iconography, but at this size the silhouette reads as a bag or a
   bulb rather than anything to do with coffee. A cup needs no caption.
   -------------------------------------------------------------------------- */

.voya-basket {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: 0.75rem;
    border: 0;
    background: none;
    padding: 0.25rem;
    color: var(--wp--preset--color--deep-green);
    cursor: pointer;
}

/*
 * Without this the control keeps rendering while empty: [hidden] is a
 * presentation hint that any display value overrides, and the rule above sets
 * inline-flex. Same trap as the offerings filter — see blocks/voyaofferings.
 */
.voya-basket[hidden] {
    display: none;
}

/*
 * Larger than the social glyphs (1.125rem) on purpose: this is an action, not
 * a decoration.
 */
.voya-basket__icon {
    width: 1.75rem;
    height: 1.75rem;
    flex: none;
}

.voya-basket__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.375rem;
    height: 1.375rem;
    border-radius: 50%;
    padding: 0 0.35rem;
    background: var(--wp--preset--color--burgundy);
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
    color: var(--wp--preset--color--white);
}

.voya-basket:hover,
.voya-basket:focus-visible {
    color: var(--wp--preset--color--green);
}

/* --------------------------------------------------------------------------
   Order sample button — in-basket state
   -------------------------------------------------------------------------- */

/*
 * The button toggles, so it has to be able to say it is already done. Colour
 * alone would not carry that, hence the label change in main.js.
 */
/*
 * A tick as well as the colour change. Colour alone is not a state anyone
 * should have to perceive — and with two buttons side by side, "which one did
 * I press" is exactly the question being answered.
 */
.voya-offering-card__order.is-in-basket,
.voya-offering__order.is-in-basket {
    background: var(--wp--preset--color--deep-green);
    border-color: var(--wp--preset--color--deep-green);
    color: var(--wp--preset--color--white);
}

.voya-offering-card__order.is-in-basket::before,
.voya-offering__order.is-in-basket::before {
    content: "\2713\00a0";
}

/* --------------------------------------------------------------------------
   Social row

   The parent draws social links as filled circles. The design wants bare
   glyphs, which its custom properties can express — no rules to restate.

   The wrapper is voya-header-links, NOT header-social: content blockers carry
   cosmetic rules aimed at that name, and hide the row outright. See the note
   in inc/branding.php before renaming it back to something more obvious.
   -------------------------------------------------------------------------- */

.voya-header-links {
    --wp--custom--social-links--circle-size: 2rem;
    --wp--custom--social-links--background: transparent;
    --wp--custom--social-links--icon-size: 1.125rem;

    flex-wrap: nowrap;
    gap: 0.25rem;
}

/*
 * Colour is set here rather than through the parent's icon-color properties.
 * The row sits inside .main-navigation, whose link rule is more specific than
 * .social-link, so the properties would be read and then overruled.
 */
/*
 * The parent's .main-navigation a rule outweighs .social-link's own
 * inline-flex, leaving these as blocks carrying nav padding — so align-items
 * had nothing to centre and the inline SVG sat on the text baseline, six
 * pixels below the nav's optical centre. Restated at a weight that holds.
 */
.main-navigation .voya-header-links .social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    color: var(--wp--preset--color--near-black);
}

/* Block, so the glyph is not baseline-aligned inside its box. */
.main-navigation .voya-header-links .social-link svg {
    display: block;
}

.main-navigation .voya-header-links .social-link:hover,
.main-navigation .voya-header-links .social-link:focus-visible {
    color: var(--wp--preset--color--green);
}

/*
 * The row is an <li> in the menu list, so it inherits the list's layout. On
 * desktop that puts it inline after the last page, which is where it has
 * always sat; the margin restores the gap it used to get from being a
 * separate element.
 */
.menu-item-social {
    display: flex;
    align-items: center;
    margin-left: 1.5rem;
}

/*
 * Below the nav breakpoint the list becomes a full-screen panel and stacks,
 * so the row wants to be a row again rather than a stacked item — on its own
 * line under the last page, separated by a rule so it does not read as
 * another menu entry.
 *
 * 991px matches the parent's Customiser breakpoint (Header -> navigation
 * breakpoint). Hardcoded here because that value is emitted inline in
 * wp_head and cannot be read from a stylesheet; if the setting changes, this
 * has to change with it.
 */
@media screen and (max-width: 991px) {

    .menu-item-social {
        justify-content: center;
        margin: 1rem 0 0;
        border-top: 1px solid #c8d1d0;
        padding-top: 1.5rem;
    }

    .menu-item-social .voya-header-links {
        gap: 1.25rem;
    }

    .menu-item-social .social-link svg {
        width: 1.5rem;
        height: 1.5rem;
    }
}

/* --------------------------------------------------------------------------
   Mobile menu

   Nothing here sets up the mobile menu itself. The parent already has a
   full-screen overlay (assets/css/main.css) opening below the header, and the
   breakpoint it switches at is a Customiser setting — Header → Navigation
   breakpoint, 992px by default — emitted as inline CSS in wp_head. Hard-coding
   a breakpoint here would fight both.

   The items pick up Voya's type and hover from the .main-navigation rules
   above, and the overlay already stacks and left-aligns them, so there is
   nothing left to declare. Kept as a note so the absence reads as a decision
   rather than an oversight.
   -------------------------------------------------------------------------- */

/* ==========================================================================
   Footer

   A sign-off rather than a sitemap: mark, copyright, build credit, centred.
   ========================================================================== */

.site-footer {
    margin-top: 0;
    padding-top: 3rem;
    padding-bottom: 4rem;
    border-top: 0;
    text-align: center;
}

.site-footer__inner {
    max-width: var(--wp--style--global--content-size);
    margin: 0 auto;
}

/* The link inside is inline-flex, so it centres by layout rather than by the
   text-align on .site-footer. */
.site-footer__logo {
    display: flex;
    justify-content: center;
}

.site-footer__copyright {
    margin: 2.5rem 0 0;
    font-size: var(--wp--preset--font-size--large);
    color: var(--wp--preset--color--deep-green);
}

.site-footer__legal,
.site-footer__credit {
    margin: 0.5rem 0 0;
    font-size: var(--wp--preset--font-size--medium);
    color: var(--wp--preset--color--deep-green);
}

/*
 * Underlined by default. Global link styles underline only on hover, which is
 * fine for links inside prose the reader is scanning, but this one sits in a
 * short centred line where colour alone would be the only cue that it is a
 * link.
 */
.site-footer__legal a,
.site-footer__credit a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.site-footer__legal a:hover,
.site-footer__legal a:focus-visible,
.site-footer__credit a:hover,
.site-footer__credit a:focus-visible {
    text-decoration-thickness: 2px;
}
