/* component-classes.css
   All styling for wp-content/themes/<theme>/inc-blocks/*.php components.
   No inline <style> blocks in component files - this is the only place
   component-specific CSS lives. One section per component, named after
   its inc-blocks filename. Loads after bog-and-thunder.css, so a rule here can
   win over a utility class. */

/* -- SHARED -- */
/* Images fill their box. WordPress writes width/height attributes, and
   that height hint beats aspect-ratio unless height is set here. */
article img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
}

/* Header row: title + caption on the left, arrow link on the right,
   baseline of the link level with the caption. */
.component-header {
    display: flex;
    flex-wrap: wrap;
    /* The link lines up with the top of the heading rather than the foot
       of the caption: against a long caption a bottom-aligned link drifts
       a long way down the page from the thing it belongs to. */
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--global-spacing-25);
    margin-bottom: var(--global-spacing-50);
}
.component-header-text {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
    max-width: 44rem;
}
.component-header-link {
    /* Optically level with the heading's first line rather than its box. */
    padding-top: 0.35em;
}

/* Card grids. Columns step down 4 -> 2 -> 1 and 3 -> 2 -> 1. */
.card-grid {
    display: grid;
    gap: var(--global-spacing-50) var(--grid-gap);
    align-items: start;
}
.card-grid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}
.card-grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.card-grid-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
/* Every second column drops by --stagger. transform rather than margin,
   so the drop does not stretch the grid row and every row keeps the same
   offset; the grid's bottom padding makes room for the last row. */
.card-grid-stagger {
    padding-bottom: var(--stagger);
}
.card-grid-stagger > :nth-child(2n) {
    transform: translateY(var(--stagger));
}
@media (max-width: 992px) {
    .card-grid-3,
    .card-grid-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .card-grid {
        --stagger: 80px;
    }
}
@media (max-width: 576px) {
    .card-grid-2,
    .card-grid-3,
    .card-grid-4 {
        grid-template-columns: minmax(0, 1fr);
    }
    .card-grid-stagger {
        padding-bottom: 0;
    }
    .card-grid-stagger > :nth-child(2n) {
        transform: none;
    }
}

/* The whole card is the link. Rather than wrapping everything in one
   anchor (which would hand a screen reader the title, the summary and the
   date as a single unreadable link name), the title's link is stretched
   across the card with a pseudo-element: one link, one sensible name, and
   the entire card is clickable.
   Anything else inside the card that is genuinely its own link - the
   events card's "Get tickets" - is lifted above it. */
.post-card {
    position: relative;
    transition: transform 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
}
/* The overlay link covers the card. It is an element rather than a
   pseudo-element on the title's link, because .text-reveal carries
   will-change: transform - that makes the heading a containing block, so a
   stretched pseudo only ever covered the title text itself. */
.post-card-overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
}
.post-card-link {
    position: relative;
    z-index: 2;
}
/* Hover: the card lifts, and a green wash fades onto the image. Tied to
   the card, not the image, so hovering the text does the same thing;
   focus-within gives a keyboard the same signal. */
.post-card:has(a):hover,
.post-card:has(a):focus-within {
    transform: translateY(-10px);
}
/* The staggered column is already held down by a transform of its own, so
   a plain translate on hover would throw the card up by the whole stagger
   (up to 200px) instead of lifting it. Keep the offset, lift from there. */
.card-grid-stagger > :nth-child(2n):has(a):hover,
.card-grid-stagger > :nth-child(2n):has(a):focus-within {
    transform: translateY(calc(var(--stagger) - 10px));
}
.post-card-media {
    position: relative;
    display: block;
    overflow: hidden;
}
.post-card-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--moss-green);
    opacity: 0;
    transition: opacity 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
    pointer-events: none;
}
.post-card:has(a):hover .post-card-media::after,
.post-card:has(a):focus-within .post-card-media::after {
    opacity: 0.45;
}
@media (prefers-reduced-motion: reduce) {
    .post-card,
    .post-card-media::after {
        transition: none;
    }
    .post-card:hover,
    .post-card:focus-within {
        transform: none;
    }
}
/* The experience cards keep a portrait crop, but on a wide screen 5/6 of
   a third of the page is tall enough to push the whole section past the
   window - and a stacked section only pins once its bottom is in view, so
   the text under each image got a sliver of screen before the next
   section slid over it. Capping the height against the window keeps the
   card, text and all, inside one screen. The crop does the rest. */
.post-card-image-fixed {
    aspect-ratio: 5 / 6;
    object-fit: cover;
    height: auto;
    max-height: 55vh;
}
/* The space under the image is the same as the space between the title
   and the text below it - one rhythm down the card, rather than a wider
   gap above the title than below it.
   Bootstrap gives every heading a 0.5rem bottom margin; in these stacks
   the spacing comes from the flex gap, so that margin is cleared or it
   reopens the difference. */
.post-card-body h3,
.featured-articles-text h3,
.product-card-body h3,
.featured-image-text-item h3 {
    margin-bottom: 0;
}
.post-card-body {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
    padding-top: var(--global-spacing-12);
}
.post-card-title a {
    text-decoration: none !important;
}
.post-card-subtitle {
    font-style: italic;
    margin-bottom: calc(var(--global-spacing-12) * -1);
}
.post-card-link {
    padding-top: var(--global-spacing-6);
}

/* Stand-in for content that needs something not built yet (form plugin,
   Spotify link). Deliberately looks unfinished. */
.component-placeholder {
    padding: var(--global-spacing-50) var(--global-spacing-25);
    border: 1px dashed currentColor;
    text-align: center;
    opacity: 0.7;
}
/* -- SHARED END -- */

/* -- CALL TO ACTION -- */
.call-to-action {
    position: relative;
    overflow: hidden;
    min-height: 90vh;
}
.call-to-action-image {
    position: absolute;
    inset: 0;
    height: 100% !important;
    object-fit: cover;
}
.call-to-action-row {
    position: relative;
    z-index: 1;
}
.call-to-action-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-25);
}
/* -- CALL TO ACTION END -- */

/* -- DETAILS TEXT -- */
.details-text-side {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-50);
}
/* Label in the serif, value in the uppercase link style, on one line. */
.details-text-list {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-3);
    margin: 0;
}
.details-text-item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35em;
}
.details-text-item dt,
.details-text-item dd {
    margin: 0;
}
.details-text-item dd {
    font-size: var(--font-size-nav);
}
/* Statement: large centred display copy. */
.details-text-statement .details-text-body,
.details-text-statement .details-text-body p {
    text-align: center;
}
.details-text-statement .details-text-body {
    max-width: 75%;
    margin-inline: auto;
}
/* Bullets back on. reset.css strips list styling with a high-specificity
   ul:not(...) rule, so this needs the component class as well as
   !important to win. */
.details-text .details-text-body ul {
    margin: 0.6em 0 0;
    padding-left: 1.2em !important;
    list-style: disc !important;
}
.details-text .details-text-body li + li {
    margin-top: 0.25em;
}
.details-text-after {
    margin-top: var(--global-spacing-50);
}
/* -- DETAILS TEXT END -- */

/* -- EXPLORE MORE -- */
.explore-more .component-header {
    margin-bottom: var(--global-spacing-50);
}
.explore-more-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--global-spacing-50) var(--grid-gap);
}
.explore-more-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-25);
    text-decoration: none !important;
}
.explore-more-media {
    position: relative;
    overflow: hidden;
    width: 100%;
}
.explore-more-image {
    aspect-ratio: 5 / 6;
    object-fit: cover;
}
/* The item is already one anchor, so only the hover treatment is needed. */
.explore-more-item {
    transition: transform 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.explore-more-item:hover,
.explore-more-item:focus-visible {
    transform: translateY(-10px);
}
.explore-more-item:hover .explore-more-media::after,
.explore-more-item:focus-visible .explore-more-media::after {
    opacity: 0.45;
}
@media (prefers-reduced-motion: reduce) {
    .featured-articles-item,
    .explore-more-item,
    .featured-articles-media::after,
    .explore-more-media::after {
        transition: none;
    }
    .featured-articles-item:hover,
    .featured-articles-item:focus-within,
    .explore-more-item:hover,
    .explore-more-item:focus-visible {
        transform: none;
    }
}
@media (max-width: 768px) {
    .explore-more-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* -- EXPLORE MORE END -- */

/* -- FEATURED ARTICLES -- */
/* Full width: three images butted edge to edge, each at its own height,
   their text on the gutter beneath. */
.featured-articles-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
}
/* Same card behaviour as the post cards: the whole item is the link, and
   it lifts with a green wash over the image on hover. */
.featured-articles-item {
    position: relative;
    transition: transform 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.featured-articles-item:hover,
.featured-articles-item:focus-within {
    transform: translateY(-10px);
}
.featured-articles-media {
    position: relative;
    overflow: hidden;
}
.featured-articles-media::after,
.explore-more-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--moss-green);
    opacity: 0;
    transition: opacity 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
    pointer-events: none;
}
.featured-articles-item:hover .featured-articles-media::after,
.featured-articles-item:focus-within .featured-articles-media::after {
    opacity: 0.45;
}
.featured-articles-text {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
    /* Matches the gap, as on the post cards. */
    padding-top: var(--global-spacing-12);
}
.featured-articles-text h3 a {
    text-decoration: none !important;
}
@media (max-width: 768px) {
    .featured-articles-grid {
        grid-template-columns: minmax(0, 1fr);
        row-gap: var(--global-spacing-50);
    }
}
/* -- FEATURED ARTICLES END -- */

/* -- FEATURED EVENTS -- */
/* All shared - .component-header, .card-grid, .post-card-events. */
/* -- FEATURED EVENTS END -- */

/* -- FEATURED EXPERIENCES -- */
.featured-experiences-rows {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-50);
}
.featured-experiences-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-12);
    padding-block: var(--global-spacing-25);
}
.featured-experiences-text h3 a {
    text-decoration: none !important;
}
.featured-experiences-text .arrow-link {
    margin-top: var(--global-spacing-12);
}
/* -- FEATURED EXPERIENCES END -- */

/* -- FEATURED IMAGE TEXT -- */
.featured-image-text-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
}
/* A row of one or two against the right edge: the run simply starts
   further along the same three columns. */
.featured-image-text-grid > :first-child {
    grid-column-start: var(--grid-start, 1);
}
@media (max-width: 768px) {
    /* Stacked on a phone, with the images butted straight up against each
       other - no row gap, so the three read as one run of images. */
    .featured-image-text-grid {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0;
    }
    /* And each one pins while the next slides up over it, the same way
       the sections stack. Opaque, or the item underneath shows through
       the text below the image. --stack-top comes from js/script.js for
       an item taller than the window (see the section stack). */
    .featured-image-text-item {
        position: sticky;
        /* Its own variable, not --stack-top: that one is set on the
           section and would be inherited straight through to here. */
        top: var(--item-stack-top, 0px);
        background-color: var(--section-bg);
        /* Room under the text. An item taller than the window pins with its
           foot on the foot of the screen, so without this the last line sat
           under the phone's own toolbar until the next image covered it.
           Padding is part of the height the stacking script measures, so the
           text now stops this far up. safe-area-inset-bottom adds the home
           bar on phones that have one. */
        padding-bottom: calc(var(--global-spacing-75) + env(safe-area-inset-bottom, 0px));
    }
}
/* -- FEATURED IMAGE TEXT END -- */

/* -- FEATURED MAGAZINE -- */
/* Centred throughout: the statement and tagline, the cover at about half
   the page width, then the issue's own text. */
.featured-magazine-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-50);
}
.featured-magazine-intro {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-25);
    /* A share of the section rather than a fixed measure, so the block
       holds its proportion as the page grows. The other centred
       statements below match it. */
    max-width: 75%;
    text-align: center;
}
.featured-magazine-intro h2 {
    text-align: center;
}
.featured-magazine-image-link {
    display: block;
    width: min(100%, 42rem);
}
.featured-magazine-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    max-width: 75%;
    text-align: center;
}
.featured-magazine-text h3,
.featured-magazine-text .wysiwyg,
.featured-magazine-text .wysiwyg p {
    text-align: center;
}
.featured-magazine-text .product-links {
    margin-top: var(--global-spacing-12);
}
/* -- FEATURED MAGAZINE END -- */

/* -- FEATURED PODCAST -- */
.featured-podcast-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-25);
}
/* Spotify's own player - it sets its look; only its box is ours. */
.spotify-player {
    display: block;
    width: 100%;
    height: 352px;
    border: 0;
    border-radius: 12px;
}

/* Our own player (Featured Podcast (Feed)) - the same episodes, drawn in
   the section's colours instead of Spotify's. Everything works off
   --section-text / --section-bg, so it sits on any background. */
.feed-player-list {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid currentColor;
}
.feed-player-episode {
    border-bottom: 1px solid currentColor;
}
.feed-player-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--global-spacing-25);
    width: 100%;
    padding: var(--global-spacing-12) 0;
    border: 0;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: opacity 0.2s ease;
}
.feed-player-item:hover,
.feed-player-item:focus-visible {
    opacity: 0.65;
}
.feed-player-item-text {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-3);
    min-width: 0;
}
.feed-player-meta,
.feed-player-eyebrow {
    opacity: 0.7;
}
.feed-player-eyebrow {
    flex: none;
    white-space: nowrap;
}

/* The open episode. grid-template-rows 0fr -> 1fr is the one way to
   animate to a height the content decides for itself; the inner element
   needs the overflow so the contents are clipped while it moves. */
.feed-player-expand {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 0.45s cubic-bezier(0.33, 0.1, 0.25, 1),
        opacity 0.3s ease;
}
.feed-player-expand-inner {
    display: flex;
    gap: var(--global-spacing-25);
    align-items: center;
    overflow: hidden;
}
.feed-player-episode.is-active .feed-player-expand {
    grid-template-rows: 1fr;
    opacity: 1;
}
/* The padding lives on the inner element: on a closed row it would hold
   the panel open at its own height. */
.feed-player-episode.is-active .feed-player-expand-inner {
    padding-bottom: var(--global-spacing-25);
}
.feed-player-art {
    width: 8rem;
    flex: none;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: 8px;
}
.feed-player-controls {
    display: flex;
    align-items: center;
    gap: var(--global-spacing-12);
    flex: 1 1 auto;
}
.feed-player-play {
    flex: none;
    padding: 0.7em 1.6em;
    cursor: pointer;
}
/* The scrubber. The track is drawn as a pseudo-element rather than as a
   faded box: opacity applies to children too, so a 25% track took the
   progress bar down with it and nothing could be seen. The element itself
   is 18px tall to give the pointer something to hit, with the 3px line
   centred inside it. */
.feed-player-scrub {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    height: 18px;
    cursor: pointer;
    touch-action: none;
}
.feed-player-scrub::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 3px;
    background-color: currentColor;
    opacity: 0.25;
}
.feed-player-bar {
    position: relative;
    width: 0;
    height: 3px;
    background-color: currentColor;
}
/* The handle sits at the end of the played section, so there is always
   something showing where you are. */
.feed-player-bar::after {
    content: "";
    position: absolute;
    right: -5px;
    top: 50%;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background-color: currentColor;
    transform: translateY(-50%);
}
.feed-player-scrub:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 4px;
}
.feed-player-time {
    flex: none;
    font-variant-numeric: tabular-nums;
    opacity: 0.7;
}
/* Without JavaScript the browser's own audio controls stand in; the
   script removes them once ours are running. */
.feed-player-audio {
    width: 100%;
    margin-top: var(--global-spacing-12);
}
.feed-player-audio:not([controls]) {
    display: none;
}
@media (prefers-reduced-motion: reduce) {
    .feed-player-expand {
        transition: none;
    }
}
@media (max-width: 576px) {
    .feed-player-expand-inner {
        flex-direction: column;
        align-items: flex-start;
    }
    .feed-player-controls {
        width: 100%;
    }
}
/* -- FEATURED PODCAST END -- */

/* -- FEATURED PRODUCT -- */
/* The same product cards as the Magazine Feed (see .product-card). */
.featured-product-items {
    row-gap: var(--global-spacing-75);
}
/* -- FEATURED PRODUCT END -- */

/* -- FEATURED STORIES -- */
/* All shared - .component-header, .card-grid-stagger, .post-card. */
/* -- FEATURED STORIES END -- */

/* -- FEATURED TRIPS -- */
/* All shared - .component-header, .card-grid, .post-card-trips. */
/* -- FEATURED TRIPS END -- */

/* -- FORM -- */
.form-intro {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-50);
}
.form-placeholder {
    min-height: 420px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* WPForms, styled to the design: outlined pill fields whose placeholder
   carries the label, and a filled pill submit. Everything is drawn in the
   section's own colours (--section-text / --section-bg), so a form works
   on any background. */
.bat-form .wpforms-container {
    margin: 0;
}
.bat-form .wpforms-field-container {
    display: flex;
    flex-wrap: wrap;
    gap: var(--global-spacing-12);
}
.bat-form .wpforms-field {
    flex: 1 1 100%;
    padding: 0;
}
/* First name / Surname share a row (set per field in WPForms > Advanced >
   CSS Classes). */
.bat-form .bat-field-half {
    flex: 1 1 calc(50% - var(--global-spacing-12));
}
/* The label is in the placeholder, as in the design - kept in the markup
   for screen readers and for anyone browsing without CSS. */
.bat-form .wpforms-field-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.bat-form input[type="text"],
.bat-form input[type="email"],
.bat-form input[type="tel"],
.bat-form input[type="url"],
.bat-form input[type="number"],
.bat-form textarea,
.bat-form select {
    width: 100%;
    max-width: 100%;
    padding: 1.1em 1.6em;
    border: 1px solid currentColor;
    border-radius: 999px;
    background-color: transparent;
    color: inherit;
    font-family: var(--font-family-sans);
    font-size: var(--font-size-nav);
    line-height: 1.2;
}
.bat-form textarea {
    min-height: 260px;
    border-radius: var(--global-spacing-25);
    resize: vertical;
}
.bat-form ::placeholder {
    color: inherit;
    opacity: 1;
    font-size: var(--font-size-link);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.bat-form input:focus,
.bat-form textarea:focus {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}
.bat-form .wpforms-submit-container {
    padding: 0;
    margin-top: var(--global-spacing-25);
}
/* Same pill as .pill-button, including the invert on hover. */
.bat-form .wpforms-submit {
    --pill-bg: var(--section-text, var(--dark));
    --pill-fg: var(--section-bg, var(--light));
    display: inline-flex;
    align-items: center;
    padding: 1.1em 2.2em;
    border: 0;
    border-radius: 999px;
    background-color: var(--pill-bg);
    color: var(--pill-fg);
    box-shadow: inset 0 0 0 1px var(--pill-bg);
    font-family: var(--font-family-sans);
    font-size: var(--font-size-link);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 0.25s ease, color 0.25s ease;
}
.bat-form .wpforms-submit:hover,
.bat-form .wpforms-submit:focus-visible {
    background-color: var(--pill-fg);
    color: var(--pill-bg);
}
/* Validation and confirmation messages in the section's own colours. */
.bat-form .wpforms-error,
.bat-form .wpforms-field-label-inline {
    font-family: var(--font-family-sans);
    font-size: var(--font-size-link);
    letter-spacing: 0.05em;
}
.bat-form input.wpforms-error,
.bat-form textarea.wpforms-error {
    border-color: var(--rust);
}
.bat-form .wpforms-confirmation-container-full {
    padding: var(--global-spacing-25);
    border: 1px solid currentColor;
    border-radius: var(--global-spacing-25);
    background: transparent;
    color: inherit;
}

/* Newsletter variant: one row, field underlined rather than outlined,
   button alongside. */
.bat-form-inline .wpforms-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--global-spacing-25);
}
.bat-form-inline .wpforms-field-container {
    flex: 1 1 260px;
}
/* Every field in an inline form is a rule, not a pill - the block sits in
   a row rather than in a column of boxes. */
.bat-form-inline input[type="email"],
.bat-form-inline input[type="text"],
.bat-form-inline input[type="tel"] {
    padding: 0.4em 0;
    border: 0;
    border-bottom: 1px solid currentColor;
    border-radius: 0;
}
/* A name field is two inputs side by side, and WPForms labels them again
   underneath ("First", "Last") - the placeholders already say it. */
.bat-form-inline .wpforms-field-sublabel {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}
.bat-form-inline .wpforms-field-row {
    display: flex;
    gap: var(--global-spacing-25);
}
.bat-form-inline .wpforms-field-row-block {
    flex: 1 1 0;
}
.bat-form-inline .wpforms-field-container {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-25);
}
.bat-form-inline .wpforms-submit-container {
    flex: 0 0 auto;
    margin-top: 0;
}
/* -- FORM END -- */

/* -- HERO BANNER -- */
/* Title Style > Outline (Hero Banner > Styling): the title keeps its own
   colour and gains an outline around it.
   paint-order puts the stroke behind the fill, so it sits outside the
   letterform instead of eating into it - without it a stroke straddles
   the glyph edge and thins the type. The outline takes the section's own
   text colour rather than a picked one, so it is black on the cream pages
   and light over a dark hero. Set in em, so it scales with the type. */
.hero-banner-title-outline {
    paint-order: stroke fill;
    /* --outline-stroke is the fill's opposite, worked out in PHP, so the
       stroke can never match what it is outlining. */
    /* 3.5px at the largest the title ever gets, and proportional below
       it. A flat 3.5px against a phone's smaller type is half again as
       heavy as the same stroke on a desktop, which is why it read as a
       different typeface rather than the same one smaller. */
    -webkit-text-stroke: min(3.5px, 0.04em) var(--outline-stroke, var(--section-text, var(--dark)));
}

/* Exactly one screen - never taller, never shorter. Set here rather than
   with Bootstrap's .vh-100 because that is height:100vh!important, which
   would block the dvh line below. dvh discounts mobile browser chrome, so
   the hero does not run under the address bar and force a scroll. */
.hero-banner {
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    background-color: var(--dark);
}
/* Standard: title and tagline on the page background, photo below. Height
   comes from the content, so the fixed-height rules above are undone. */
.hero-banner-standard {
    height: auto;
    background-color: transparent;
}
.hero-banner-standard-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-25);
    text-align: center;
    /* On top of the padding-block utility on the same wrapper: the title
       clears the fixed header, while the foot keeps the utility's
       spacing. */
    padding-top: 170px;
}
/* A medium title is the longer kind - kept to a readable measure so it
   breaks into balanced lines instead of running the full width. */
/* The smaller title used to stop at 60rem, which on a wide screen is a
   good deal narrower than the three quarters the larger one gets. Both
   now share one measure, so a page reads the same whichever size it is
   set to. */
.hero-banner-standard-text .hero-banner-title.type-h2 {
    max-width: 75%;
}
/* A page title left to run the full width sets one enormous line that
   reads as a banner rather than a heading. Held to three quarters of the
   screen it breaks into two or three lines, which is the proportion the
   design uses. Centred, so the narrower measure stays centred too. */
.hero-banner-standard-text .hero-banner-title {
    max-width: 75%;
    margin-inline: auto;
}
.hero-banner-standard-text .hero-banner-title,
.hero-banner-standard-text .hero-banner-tagline {
    /* Not pinned top and bottom the way the full-screen hero is. */
    margin-top: 0;
    transform: none;
}
.hero-banner-standard-image {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
/* The eyebrow over or under a hero title is the same size as the header
   nav, at every screen width, so the two read as one family. --font-size-nav
   is a fixed rem rather than a clamp, which is what keeps it from growing
   on a very wide screen while the title does. Every .type-link inside a
   hero is one of these eyebrows. */
.hero-banner .type-link {
    font-size: var(--font-size-nav);
}
.hero-banner-image {
    position: absolute;
    inset: 0;
    height: 100% !important;
    object-fit: cover;
}
/* The row and column grow to fill the hero (flex: 1 1 auto - height:100%
   on a flex child resolves against content, not the row), so the tagline
   can be pinned to the foot with margin-top: auto. */
.hero-banner-row {
    position: relative;
    z-index: 1;
    height: 100%;
}
.hero-banner-col {
    display: flex;
    flex-direction: column;
}
.hero-banner-content {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.hero-banner-title {
    margin-top: auto;
    text-align: center;
}
/* Raised 100px with a transform rather than padding/margin: the title is
   centred in the space above the tagline, so moving the tagline in the
   layout would pull the title up with it. A transform moves only the
   tagline. */
.hero-banner-tagline {
    margin-top: auto;
    text-align: center;
    transform: translateY(-100px);
}
/* Split: text panel on the left half, photo filling the right half from
   the top of the window to the foot of the hero. The tagline and title
   sit centred in the panel; the subtitle is pinned to its foot. */
.hero-banner-split {
    height: 100vh;
    height: 100dvh;
    background-color: transparent;
}
.hero-banner-split-row,
.hero-banner-split-text-col,
.hero-banner-split-image-col {
    height: 100%;
}
.hero-banner-split-text {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding-block: calc(var(--header-height) + var(--global-spacing-25)) var(--global-spacing-75);
}
.hero-banner-split-main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--global-spacing-25);
    max-width: 28rem;
}
.hero-banner-split-title,
.hero-banner-split-subtitle {
    text-align: center;
}
.hero-banner-split-subtitle {
    max-width: 24rem;
}
.hero-banner-split-image {
    height: 100% !important;
    object-fit: cover;
}
@media (max-width: 992px) {
    .hero-banner-split {
        height: auto;
    }
    .hero-banner-split-text {
        min-height: 70vh;
    }
    .hero-banner-split-image-col {
        height: 70vh;
    }
}
/* -- HERO BANNER END -- */

/* -- IMAGE TEXT -- */
.image-text-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-25);
}
.image-text-image {
    aspect-ratio: 1 / 1;
    object-fit: cover;
}
/* -- IMAGE TEXT END -- */

/* -- MAGAZINE FEED -- */
/* Covers sit centred in their column at around two thirds of its width,
   with the Issue Label, title and links centred beneath. */
.product-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.product-card-image-link {
    display: block;
    width: 62%;
}
/* Every cover at the magazine's own proportion (the 670 x 806 cover
   artwork), so the row stays level whatever shape of image is uploaded
   and a real cover is never cropped. */
.product-card-image,
.featured-magazine-image {
    aspect-ratio: 670 / 806;
    object-fit: cover;
}
.product-card {
    transition: transform 0.4s cubic-bezier(0.33, 0.1, 0.25, 1);
}
.product-card:hover,
.product-card:focus-within {
    transform: translateY(-10px);
}
@media (prefers-reduced-motion: reduce) {
    .product-card {
        transition: none;
    }
    .product-card:hover,
    .product-card:focus-within {
        transform: none;
    }
}
.product-card-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    /* Matches the gap, as on the post cards. */
    padding-top: var(--global-spacing-12);
}
.product-card-body h3,
.product-card-body h3 a {
    text-align: center;
    text-decoration: none !important;
}
.magazine-feed-items {
    row-gap: var(--global-spacing-75);
}
/* Buy and Learn more side by side, wherever product links appear. */
.product-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    /* A pill and a text link on one row: centred on each other rather
       than on their boxes, which differ in height. */
    align-items: center;
    gap: var(--global-spacing-25);
}
/* -- MAGAZINE FEED END -- */

/* -- MAGAZINE ISSUE (single-magazine.php) -- */
/* The top of a magazine's own page: the cover centred at about half the
   page width, then the issue's text centred. (<main> already clears the
   fixed header - see functions/header_offset.php.) */
.magazine-issue-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-50);
    padding-top: var(--global-spacing-50);
    padding-bottom: var(--global-spacing-100);
}
.magazine-issue-cover {
    width: min(100%, 44rem);
}
.magazine-issue-image {
    aspect-ratio: 670 / 806;
    object-fit: cover;
}
.magazine-issue-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    max-width: 52rem;
    text-align: center;
}
.magazine-issue-text h1,
.magazine-issue-text p {
    text-align: center;
}
.magazine-issue-price {
    font-size: var(--font-size-nav);
    margin-top: var(--global-spacing-12);
}
.magazine-issue-cart {
    margin-top: var(--global-spacing-12);
}
/* The page is centred, so the button sits under the middle of the
   options rather than at their left edge. */
.magazine-issue-cart .magazine-issue-actions {
    justify-content: center;
}
/* -- MAGAZINE ISSUE END -- */

/* -- NEWSLETTER SIGNUP -- */
.newsletter-signup-text {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-50);
}
/* -- NEWSLETTER SIGNUP END -- */

/* -- POST FEED -- */
/* Podcast feed: players two to a row, one on smaller screens. */
/* Four across, stepping down with the other card grids (.card-grid-4). */
.podcast-feed-grid {
    gap: var(--global-spacing-50) var(--grid-gap);
}
/* All shared - .component-header, .card-grid-stagger, .post-card. */
/* -- POST FEED END -- */

/* -- STORY HEADER -- */
/* single-stories.php: the photograph full width, then the story's title
   and summary centred under it. */
/* With a photograph the story opens like a full-screen hero: the picture
   fills the window, the words sit on it, and the breadcrumb floats over
   the top rather than taking a strip above it. Without one it is the
   plain centred block it always was. */
.story-header-full {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    color: var(--light);
}
.story-header-image {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
.story-header-full .story-header-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100% !important;
    aspect-ratio: auto;
}
/* Enough of a wash for the words to hold against any photograph. The
   title sits around the middle, so there has to be something there too -
   a gradient that only darkens the foot leaves it stranded on a bright
   sky, which is exactly what this story's own picture does. */
.story-header-full::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(0, 4, 6, 0.1) 0%,
        rgba(0, 4, 6, 0.35) 45%,
        rgba(0, 4, 6, 0.6) 100%
    );
    pointer-events: none;
}
.story-header-full .story-header-row {
    position: relative;
    z-index: 1;
    height: 100%;
}
.story-header-full .story-header-col {
    display: flex;
    flex-direction: column;
}
.story-header-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-25);
    text-align: center;
}
/* The same arrangement a full-screen hero uses: two auto margins divide
   the free height between them, which centres the title and carries the
   line beneath it down to the foot. */
.story-header-full .story-header-text {
    flex: 1 1 auto;
    gap: 0;
}
.story-header-main {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
}
.story-header-full .story-header-summary {
    margin-top: auto;
    transform: translateY(-100px);
}
.story-header-summary {
    max-width: 75%;
}
/* -- STORY HEADER END -- */

/* -- PODCAST EPISODE -- */
/* single-podcast.php: cover on the left, the episode's own text and the
   full-size player on the right. The one place the Spotify embed is worth
   its height. */
.podcast-episode-inner {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--global-spacing-50);
    align-items: start;
    padding-block: var(--global-spacing-100);
}
.podcast-episode-image {
    aspect-ratio: 1 / 1;
    object-fit: cover;
}
.podcast-episode-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-25);
}
.podcast-episode-player {
    width: 100%;
    margin-top: var(--global-spacing-12);
}
@media (max-width: 768px) {
    .podcast-episode-inner {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* -- PODCAST EPISODE END -- */

/* -- PROFILE -- */
/* Left half centred: title, intro, then a small square portrait. */
/* The name and the line under it belong together, so they sit at the
   tighter step of the scale. The portrait keeps the wider gap, which is
   why it carries its own margin rather than riding on the flex gap. */
.profile-side {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    text-align: center;
}
.profile-side h2,
.profile-side .wysiwyg,
.profile-side .wysiwyg p {
    text-align: center;
}
/* The reset's heading margin on top of the flex gap put 52px between the
   name and the line under it. Megan asked for about 36. */
.profile-side h2 {
    margin-bottom: var(--global-spacing-6);
}
/* The portrait keeps the wider gap it already had, at both breakpoints:
   the gap above it used to be twice --global-spacing-25, and the tighter
   flex gap is subtracted back out so nothing below the intro moves. */
.profile-image-wrap {
    width: min(100%, 18rem);
    margin-top: calc((var(--global-spacing-25) * 2) - var(--global-spacing-12));
}
.profile-image {
    aspect-ratio: 1 / 1;
    object-fit: cover;
}
/* -- PROFILE END -- */

/* -- QUOTE SLIDER -- */
.quote-slider-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    margin-bottom: var(--global-spacing-75);
    text-align: center;
}
.quote-slider-header h2 {
    text-align: center;
}
/* A rule on the left of every slide; the track's first pixel is clipped,
   hiding the rule of whichever slide is first in view - so rules only
   ever sit between quotes, including mid-slide. */
.quote-slider-splide .splide__track {
    clip-path: inset(0 0 0 1px);
}
.quote-slider-slide {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 180px;
    border-left: 1px solid currentColor;
}
.quote-slider-quote {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    margin: 0;
    padding-inline: var(--global-spacing-50);
    text-align: center;
}
.quote-slider-quote .wysiwyg,
.quote-slider-quote .wysiwyg p {
    text-align: center;
}
.quote-slider .splide__pagination__page {
    background: currentColor;
    opacity: 0.3;
}
.quote-slider .splide__pagination__page.is-active {
    background: currentColor;
    opacity: 1;
    transform: none;
}
.quote-slider .splide__pagination {
    position: static;
    padding-top: var(--global-spacing-25);
}
/* On a phone there is no carousel - Splide destroys itself below 768
   (js/script.js) and the quotes become a stacked list, each under a
   short centred rule. */
@media (max-width: 768px) {
    .quote-slider-splide .splide__track {
        clip-path: none;
    }
    .quote-slider-splide .splide__list {
        display: flex;
        flex-direction: column;
    }
    .quote-slider-slide {
        /* Block, not flex, so the rule below sits above the quote rather
           than beside it. */
        display: block;
        min-height: 0;
        border-left: 0;
    }
    .quote-slider-slide + .quote-slider-slide {
        margin-top: var(--global-spacing-50);
    }
    .quote-slider-slide + .quote-slider-slide::before {
        content: "";
        display: block;
        width: min(75%, 320px);
        margin: 0 auto var(--global-spacing-50);
        border-top: 1px solid currentColor;
    }
    .quote-slider-quote {
        padding-inline: 0;
    }
}
/* -- QUOTE SLIDER END -- */

/* -- STEPS BLOCK -- */
.steps-block-header {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-25);
    max-width: 75%;
    margin-bottom: var(--global-spacing-75);
}
.steps-block-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    align-items: start;
    margin: 0;
    padding: 0;
    list-style: none;
}
/* Every step image is square; hovering opens the crop downwards to a
   portrait, revealing more of the same photo and pushing that column's
   text down. padding-bottom rather than height or aspect-ratio because a
   percentage padding transitions smoothly in every browser. */
.steps-block-figure {
    position: relative;
    padding-bottom: 100%;
    overflow: hidden;
    transition: padding-bottom 0.45s ease;
}
.steps-block-figure:hover,
.steps-block-figure:focus-within {
    padding-bottom: 133%;
}
/* The image is always drawn at the expanded height and anchored to the
   top; the figure just clips it. So hovering reveals more of the photo
   without changing its scale - the crop opens, the image does not zoom. */
.steps-block-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    aspect-ratio: 100 / 133;
    object-fit: cover;
    object-position: top;
}
.steps-block-step-text {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-25);
    padding: var(--global-spacing-25);
}
/* No hover on touch - the images simply stay square. */
@media (hover: none) {
    .steps-block-figure:hover {
        padding-bottom: 100%;
    }
}
@media (max-width: 992px) {
    .steps-block-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
@media (max-width: 576px) {
    .steps-block-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* -- STEPS BLOCK END -- */

/* -- TEXT -- */
.text-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--global-spacing-25);
}
.text-centred .text-content {
    align-items: center;
    text-align: center;
}
.text-centred .text-content h2,
.text-centred .text-content .wysiwyg,
.text-centred .text-content .wysiwyg p {
    text-align: center;
}
/* The article variant keeps the centred column but reads left to right:
   a page of prose centred line by line is close to unreadable. The
   heading stays centred, as a title over the column. */
.text-article .text-content {
    align-items: flex-start;
    text-align: left;
}
.text-article .text-content .wysiwyg,
.text-article .text-content .wysiwyg p {
    text-align: left;
}
.text-article .text-content h2 {
    align-self: center;
}
/* The centred variant reads as one block in the middle of its section,
   so on a phone it takes the same +50px on top that every component gets
   at the bottom - otherwise the block sits high with a gap beneath it. */
.text-centred .text-content {
    padding-top: calc(var(--global-spacing-100) + 50px);
}
/* Buttons side by side, wrapping on a narrow screen. */
.text-buttons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--global-spacing-25);
}
.text-centred .text-buttons {
    justify-content: center;
    margin-top: var(--global-spacing-25);
}
/* -- TEXT END -- */

/* -- BUY PANEL -- */
/* The card that opens above Buy on a magazine card or a featured issue:
   buy once or subscribe, and how many. Same width and square shape as the
   promotional popup (--popup-size) so the two read as one object. */
.product-buy-wrap {
  position: relative;
  display: inline-block;
}
/* Only while open, so a closed panel's wrapper never wins a stacking
   fight with the section sliding over it. */
.product-buy-wrap.is-open {
  z-index: 80;
}
/* Buy is the site's standard pill - the same button as Book a Tour - so
   it takes its colours from .pill-button. All a <button> needs on top is
   the font, which it does not inherit on its own, and the cursor. */
.product-buy {
  font-family: inherit;
  cursor: pointer;
}
.buy-panel {
  position: absolute;
  bottom: calc(100% + var(--global-spacing-12));
  left: 0;
  width: min(var(--popup-size), calc(100vw - (var(--gutter) * 2)));
  aspect-ratio: 1 / 1;
  padding: var(--global-spacing-25);
  border-radius: 16px;
  background-color: var(--moss-green);
  color: var(--off-white);
  opacity: 0;
  transform: translateY(0.4em);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.buy-panel.is-open {
  opacity: 1;
  transform: none;
}
.buy-panel-form {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
  gap: var(--global-spacing-25);
}
.buy-panel-head {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-6);
}
.buy-panel-options {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-12);
}
/* Price pushed to the right of its row, whatever the option is called. */
.buy-panel-option {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--global-spacing-12);
  cursor: pointer;
}
.buy-panel-option input {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--off-white);
}
.buy-panel-price {
  justify-self: end;
  white-space: nowrap;
}
/* Stretch rather than centre: the quantity control and Add to cart then
   come out the same height as each other without either being told what
   that height is, so they stay matched if the button's padding or type
   ever changes. */
.buy-panel-actions {
  display: flex;
  align-items: stretch;
  gap: var(--global-spacing-12);
}
.buy-panel-qty {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-12);
  padding: 0.5em 0.9em;
  border: 1px solid currentColor;
  border-radius: 999px;
}
.buy-panel-qty button {
  border: 0;
  padding: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  line-height: 1;
}
/* The number is typed into as well as stepped, so it stays a real input -
   just without the browser's own spinner, which does not fit the pill. */
.buy-panel-qty input {
  width: 2ch;
  border: 0;
  padding: 0;
  background: transparent;
  color: inherit;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
.buy-panel-qty input::-webkit-outer-spin-button,
.buy-panel-qty input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}
.buy-panel-add {
  --pill-bg: var(--off-white);
  --pill-fg: var(--dark);
  flex: 1 1 auto;
  border: 0;
  cursor: pointer;
}
/* On hover the pill would swap to its dark fill, a black block on the
   moss card. It empties instead: the card shows through, the outline and
   the words stay off-white. */
.buy-panel-add:hover,
.buy-panel-add:focus-visible {
  background-color: transparent;
  color: var(--off-white);
}
/* Near the right-hand edge the card would run off screen, so it hangs
   from the right of the button instead. Set by js/script.js. */
.buy-panel.is-right {
  left: auto;
  right: 0;
}
@media (prefers-reduced-motion: reduce) {
  .buy-panel {
    transition: none;
  }
}
/* -- BUY PANEL END -- */

/* -- CART PAGE -- */
/* The cart is WooCommerce's Cart block, so Proceed to Checkout arrives as
   their button: square, dark grey and underlined. Given the site's own
   pill colours and shape so it reads as the same button as Book a Tour
   and Buy. The tokens are borrowed rather than the values copied, so it
   follows if the palette moves. It stays full width, which is the
   block's own layout. */
.wp-block-woocommerce-cart .wc-block-cart__submit-button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.1em 2.2em;
  border: 0;
  border-radius: 999px;
  background-color: var(--dark);
  color: var(--light);
  box-shadow: inset 0 0 0 1px var(--dark);
  text-decoration: none;
  transition: background-color 0.25s ease, color 0.25s ease;
}
/* Inverts the same way the site's other buttons do. */
.wp-block-woocommerce-cart .wc-block-cart__submit-button:hover,
.wp-block-woocommerce-cart .wc-block-cart__submit-button:focus-visible {
  background-color: var(--light);
  color: var(--dark);
}
/* WooCommerce underlines its own buttons from a rule we cannot outrank by
   specificity alone - the same reason .pill-button carries one. */
.wp-block-woocommerce-cart .wc-block-cart__submit-button,
.wp-block-woocommerce-cart .wc-block-cart__submit-button:hover,
.wp-block-woocommerce-cart .wc-block-cart__submit-button:focus-visible {
  text-decoration: none !important;
}

/* On the shop-style pages (cart, checkout, account) page.php prints a
   visible title as a direct child of <main>, before the section that
   carries the header offset - so the title itself started under the fixed
   header. It takes the offset instead, and the section after it drops the
   duplicate. */
.has-header-offset main > .shop-page-title {
  padding-top: calc(var(--header-height) + var(--global-spacing-50));
}
.has-header-offset main > .shop-page-title + article {
  padding-top: 0;
}
/* -- CART PAGE END -- */

/* -- MY ACCOUNT -- */
/* Two screens: logging in (form left, photograph right) and the dashboard
   once you are in (profile left, subscriptions and trips right). Templates
   in woocommerce/myaccount/, lookups in functions/account.php. */

/* --- Logging in --- */
/* Full width, ignoring the page gutter, so the photograph can reach the
   edge of the window. The page title is hidden here: the form carries its
   own heading and two "My Account" headings in a row reads as a mistake. */
.woocommerce-account:not(.logged-in) .shop-page-title {
  display: none;
}
.account-login {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* The full window. The header is fixed, so it sits over this rather
     than pushing it down, which is how the design has the nav reading
     across the photograph. */
  height: 100dvh;
  /* The page wraps its content in the gutter; this cancels it so the
     photograph can reach the left and right edges. Negative margin rather
     than 100vw, which would overshoot by the width of a scrollbar. */
  margin-inline: calc(var(--gutter) * -1);
  overflow: hidden;
}
.account-login-panel {
  display: flex;
  /* Centred with auto margins rather than align-items, so that when the
     panel's contents outgrow a short window - an error message appearing
     above the form, say - the top stays reachable instead of being pushed
     up behind the header. */
  align-items: flex-start;
  padding: var(--global-spacing-50) var(--gutter);
  overflow-y: auto;
}
.account-login-inner {
  margin-block: auto;
}
.account-login-inner {
  width: min(28rem, 100%);
}
.account-login-title {
  margin-bottom: var(--global-spacing-12) !important;
}
.account-login-intro {
  margin-bottom: var(--global-spacing-75) !important;
}
/* WooCommerce's own stylesheet draws a bordered, rounded, padded box
   around the login form. The design has the fields sitting straight on the
   page, so it is undone here rather than by dropping their stylesheet,
   which the account sub-pages still rely on. */
/* Their selector is `.woocommerce form.login`, so this one carries an
   extra class to outrank it rather than reaching for !important. The
   sign-up form gets the same box from `.woocommerce form.register`. */
.woocommerce .account-login form.login,
.woocommerce .account-login form.register {
  padding: 0;
  border: 0;
  border-radius: 0;
  margin: 0;
}

/* Underlined inputs rather than boxes, matching the checkout.
   The reset carries `p { margin-bottom: 0 !important }`, so this field row
   has to answer in kind. */
.account-field {
  margin-bottom: var(--global-spacing-50) !important;
}
/* WooCommerce wraps the password in a span and absolutely positions its
   show/hide eye inside it. Without a positioned, full-width wrapper the
   eye lands over the field's underline. */
.account-field .password-input,
.account-field .woocommerce-password-input {
  position: relative;
  display: block;
  width: 100%;
}
.account-field .show-password-input {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
}
.account-field label {
  display: block;
  margin-bottom: var(--global-spacing-6);
  font-size: var(--font-size-link);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.account-field input {
  width: 100%;
  padding: 0.4em 0;
  border: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
}
.account-field input:focus-visible {
  outline: none;
  border-bottom-width: 2px;
}
.account-login-forgot {
  margin-bottom: var(--global-spacing-50) !important;
}
.account-login-forgot a {
  text-decoration: underline;
}
.account-login-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--global-spacing-25);
  /* Set off from whatever precedes them. On the sign-up screen that is
     WooCommerce's privacy notice, which otherwise runs straight into the
     buttons. */
  margin-top: var(--global-spacing-50);
}
/* WooCommerce's privacy notice is body copy by default, which gives it the
   same weight as the form itself. It is small print. */
.account-login .woocommerce-privacy-policy-text p {
  font-size: var(--font-size-link);
  line-height: 1.5;
  opacity: 0.7;
}
.account-login-submit {
  border: 0;
  cursor: pointer;
  font-family: inherit;
}
.account-login-signup a {
  text-decoration: underline;
}
.account-login-remember {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-12);
  margin-top: var(--global-spacing-50);
  cursor: pointer;
}
/* The photograph fills its half whatever shape it is. */
.account-login-image {
  position: relative;
  overflow: hidden;
}
.account-login-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* The login screen is the whole window, so nothing follows it: the page's
   own bottom padding and the footer would both put it back into a scroll. */
.woocommerce-account:not(.logged-in) main > article .padding-bottom-100 {
  padding-bottom: 0;
}
/* The breadcrumb is hidden here but is still a sibling, so the rule that
   gives the first section room under it would otherwise add a strip. */
/* `body` is here to beat the breadcrumb rule further down the file, which
   otherwise ties on specificity and wins on source order. */
body.woocommerce-account:not(.logged-in) main > article:first-of-type {
  padding-top: 0;
}
.woocommerce-account:not(.logged-in) .site-footer {
  display: none;
}
/* Same reason: the trail would take a strip above a screen that is meant
   to be exactly one window, and put the whole thing back into a scroll.
   There is nowhere to go from the login page but into the account. */
.woocommerce-account:not(.logged-in) .breadcrumbs {
  display: none;
}

/* On a phone the photograph would push the form off the screen, so it goes. */
@media (max-width: 900px) {
  .account-login {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .account-login-image {
    display: none;
  }
}

/* --- The dashboard --- */
/* Profile on the left, the two stacked panels on the right. A rule under
   the page title, as in the design.
   The title is a direct child of <main>, outside the gutter wrapper the
   rest of the page sits in, so it carries the gutter itself or it starts
   at the window edge. */
.woocommerce-account.logged-in .shop-page-title {
  /* Sides and bottom only. The shorthand would reset padding-top and undo
     the header offset, which puts the title back under the wordmark. */
  /* Margin rather than padding, so the rule underneath stops at the
     gutter with the content instead of running to the window edge. */
  margin-inline: var(--gutter);
  padding-bottom: var(--global-spacing-25);
  margin-bottom: var(--global-spacing-75);
  border-bottom: 1px solid currentColor;
  text-align: left;
}
/* WooCommerce floats the account content right at 68% to leave room for
   its own navigation down the left. That navigation is removed here
   (functions/account.php), so the float would just leave a third of the
   page empty. */
.woocommerce-account .woocommerce-MyAccount-content {
  float: none;
  width: 100%;
}
.account-dashboard {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--global-spacing-100);
  align-items: start;
}
.account-column {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-100);
}
.account-panel-title {
  margin-bottom: var(--global-spacing-50) !important;
}
/* Each labelled row is a line of its own with a rule under it, which is
   what gives the profile panel its ledger look. */
.account-field-row {
  margin-bottom: var(--global-spacing-50);
}
.account-label {
  display: block;
  padding-bottom: var(--global-spacing-6);
  border-bottom: 1px solid currentColor;
  margin-bottom: var(--global-spacing-12);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}
.account-address {
  line-height: 1.5;
}
.account-address br {
  content: "";
}
.account-item {
  margin-bottom: var(--global-spacing-50);
}
/* Title left, price right, both sitting on the same baseline however long
   the title runs. */
.account-item-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--global-spacing-25);
}
.account-item-price {
  white-space: nowrap;
}
.account-meta {
  display: block;
  margin-top: var(--global-spacing-6);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}
.account-item .pill-button,
.account-panel > .pill-button {
  margin-top: var(--global-spacing-25);
}
.account-empty {
  opacity: 0.7;
}
@media (max-width: 900px) {
  .account-dashboard {
    grid-template-columns: 1fr;
    gap: var(--global-spacing-75);
  }
  .account-column {
    gap: var(--global-spacing-75);
  }
}

/* --- Editing addresses --- */
/* Both addresses stacked on the left, a picture on the right. Saving is
   WooCommerce's, so the markup inside each form is theirs and gets styled
   rather than replaced. */
.account-addresses {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--global-spacing-100);
  align-items: start;
}
.account-addresses-forms {
  display: flex;
  flex-direction: column;
  gap: var(--global-spacing-100);
}
.account-address-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--global-spacing-25) var(--global-spacing-50);
}
/* Most fields take the full width; the pairs that read as one line sit
   side by side. */
.account-addresses .form-row {
  grid-column: 1 / -1;
  margin: 0;
  padding: 0;
}
.account-addresses .form-row-first,
.account-addresses .form-row-last {
  grid-column: span 1;
}
.account-addresses label {
  display: block;
  margin-bottom: var(--global-spacing-6);
  font-size: var(--font-size-link);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}
/* Underlined inputs, as on the login screen and the checkout.
   WooCommerce draws the box through its own custom properties
   (`border: var(--wc-form-border-width) solid var(--wc-form-border-color)`),
   so the box comes off by setting those rather than by out-specifying
   `.woocommerce form .form-row .input-text`. */
.account-addresses {
  --wc-form-border-width: 0;
  --wc-form-border-radius: 0;
  --wc-form-color-background: transparent;
}
/* The underline does have to outrank that selector, which carries three
   classes and two elements. */
.woocommerce-account .account-addresses .form-row input.input-text,
.woocommerce-account .account-addresses .form-row select,
.woocommerce-account .account-addresses .form-row textarea {
  width: 100%;
  padding: 0.4em 0;
  border-bottom: 1px solid currentColor;
  color: inherit;
  font: inherit;
}
.woocommerce-account .account-addresses .form-row input:focus-visible,
.woocommerce-account .account-addresses .form-row select:focus-visible {
  outline: none;
  border-bottom-width: 2px;
}
/* Their required marker is a red asterisk; it only adds noise here.
   Theirs is `.woocommerce form .form-row .required`, so .form-row is
   needed here to outweigh it. */
.woocommerce-account .account-addresses .form-row .required {
  border: 0;
  text-decoration: none;
  color: inherit;
}
.account-address-save {
  margin-top: var(--global-spacing-50);
  border: 0;
  cursor: pointer;
  font-family: inherit;
}
.account-addresses-image {
  position: sticky;
  top: calc(var(--header-height) + var(--global-spacing-25));
  overflow: hidden;
  border-radius: 16px;
}
.account-addresses-image img {
  display: block;
  width: 100%;
  height: auto;
}
@media (max-width: 900px) {
  .account-addresses {
    grid-template-columns: 1fr;
    gap: var(--global-spacing-75);
  }
  .account-addresses-forms {
    gap: var(--global-spacing-75);
  }
  /* The picture is decoration; on a phone it just pushes the forms down. */
  .account-addresses-image {
    display: none;
  }
}

/* WooCommerce's own notices appear on these screens when a save fails or
   succeeds, and arrive with its default styling. Given the site's palette
   rather than left as grey boxes with a coloured bar.
   Width matches the left column of the addresses grid rather than running
   the whole way across: the message belongs to the form it came from. The
   grid is two equal columns with a gap, so half of what is left once the
   gap is taken out. */
.woocommerce-account .woocommerce-message,
.woocommerce-account .woocommerce-error,
.woocommerce-account .woocommerce-info {
  max-width: calc((100% - var(--global-spacing-100)) / 2);
  margin: 0 0 var(--global-spacing-50);
  padding: var(--global-spacing-25);
  border: 1px solid currentColor;
  border-radius: 16px;
  background: transparent;
  color: inherit;
  list-style: none;
  font-size: var(--font-size-link);
}
/* A save that worked reads green; anything else keeps the plain treatment
   so an error is not mistaken for a success. */
.woocommerce-account .woocommerce-message {
  border-color: var(--green-deep);
  background-color: var(--green-pale);
  color: var(--green-deep);
}
/* On the login and sign-up screens the notice sits inside the panel, so it
   takes the panel's width rather than half the page, and an error reads in
   the brand's rust. */
.account-login .woocommerce-message,
.account-login .woocommerce-error,
.account-login .woocommerce-info {
  max-width: none;
  margin-bottom: var(--global-spacing-50);
  font-size: var(--font-size-link);
}
.account-login .woocommerce-error {
  border-color: var(--rust);
  background-color: color-mix(in srgb, var(--rust) 8%, transparent);
  color: var(--rust);
}
.account-login .woocommerce-error li {
  margin: 0;
  list-style: none;
}
/* WooCommerce moves focus to the notice so a screen reader announces it,
   which also draws the browser's blue focus ring. The focus is worth
   keeping; the ring is given the site's own colour. */
.account-login .woocommerce-error:focus,
.account-login .woocommerce-message:focus,
.account-login .woocommerce-info:focus {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}
@media (max-width: 900px) {
  /* One column down here, so the half-width would be a sliver. */
  .woocommerce-account .woocommerce-message,
  .woocommerce-account .woocommerce-error,
  .woocommerce-account .woocommerce-info {
    max-width: none;
  }
}
.woocommerce-account .woocommerce-message::before,
.woocommerce-account .woocommerce-error::before,
.woocommerce-account .woocommerce-info::before {
  content: none;
}
.woocommerce-account .woocommerce-error li {
  margin: 0;
  list-style: none;
}

/* --- The country and county dropdowns --- */
/* WooCommerce replaces these selects with select2, which brings its own
   grey-and-blue styling and a search box. The dropdown panel is appended
   to <body>, outside .account-addresses, so these selectors cannot be
   scoped to the page the way the rest of this section is. */
.select2-container--default .select2-selection--single {
  height: auto;
  padding: 0.4em 0;
  border: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0;
  color: inherit;
  font: inherit;
  line-height: inherit;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
  top: 50%;
  right: 0;
  transform: translateY(-50%);
}
/* The panel itself: the site's ground and a rounded edge rather than a
   white box with a blue outline. */
.select2-container--default .select2-dropdown {
  border: 1px solid var(--dark);
  border-radius: 16px;
  background-color: var(--off-white);
  overflow: hidden;
}
.select2-container--default .select2-search--dropdown {
  padding: var(--global-spacing-12);
}
.select2-container--default .select2-search--dropdown .select2-search__field {
  padding: 0.4em 0;
  border: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
}
.select2-container--default .select2-results__option {
  padding: var(--global-spacing-12);
  font-size: var(--font-size-link);
}
/* Their highlight is a strong blue; the site uses its own ground instead. */
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted[data-selected] {
  background-color: var(--moss-green);
  color: var(--off-white);
}
.select2-container--default .select2-results__option[aria-selected="true"],
.select2-container--default .select2-results__option[data-selected="true"] {
  background-color: var(--sand);
  color: var(--dark);
}

/* --- Shared bits across the account screens --- */
/* A note where a field would otherwise be, e.g. telling a new customer we
   will email them a password link. */
.account-login-note {
  margin-bottom: var(--global-spacing-50) !important;
  opacity: 0.7;
}
.account-subheading {
  margin: var(--global-spacing-75) 0 var(--global-spacing-25) !important;
}
/* Account details has no picture, so its single column should not stay
   half width. */
.account-addresses-single {
  grid-template-columns: 1fr;
  max-width: 40rem;
}
.account-orders-pager {
  display: flex;
  gap: var(--global-spacing-25);
  margin-top: var(--global-spacing-50);
}

/* --- Order received --- */
.order-received {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--global-spacing-100);
  align-items: start;
}
.order-received-message {
  margin-bottom: var(--global-spacing-75) !important;
}
.order-received-meta,
.order-received-address {
  margin: 0 0 var(--global-spacing-50);
}
.order-received-meta-row {
  margin-bottom: var(--global-spacing-25);
}
.order-received-meta-row dd {
  margin: 0;
}
.order-received-address div {
  line-height: 1.5;
}
/* Name, quantity, amount on one line, the amount pinned right. */
.order-received-line,
.order-received-total {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: var(--global-spacing-25);
  align-items: baseline;
  padding: var(--global-spacing-12) 0;
  border-bottom: 1px solid currentColor;
}
.order-received-total {
  grid-template-columns: 1fr auto;
  border-bottom: 0;
}
.order-received-amount {
  white-space: nowrap;
}
.order-received-qty {
  opacity: 0.6;
}
@media (max-width: 900px) {
  .order-received {
    grid-template-columns: 1fr;
    gap: var(--global-spacing-75);
  }
}

/* -- MY ACCOUNT END -- */

/* The way into an episode's own page, under its controls. */
.feed-player-link {
    margin-top: var(--global-spacing-12);
}

/* The same two options as the Buy panel, but inline on a product page
   where there is no panel to open. They borrow .buy-panel-option so the
   two can never look like different controls. */
.buy-options {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
    margin-bottom: var(--global-spacing-25);
}
/* Quantity and Add to cart on one line, the same height as each other. */
.magazine-issue-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--global-spacing-12);
}

/* The magazine opens on its intro, and the page already carries the
   header offset above it, so the component adds nothing more on top. */
.featured-magazine-inner {
    padding-top: 0;
}

/* -- TRIP BOOKING BUTTON -- */
/* The cost sits with the line that describes the trip, at the foot of the
   split hero's panel. */
.hero-banner-split-foot {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
    /* The subtitle above it is centred, and the cost reads as the same
       thought, so it follows rather than hanging off to the left. */
    text-align: center;
}
.hero-banner-details {
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-3);
    margin: 0;
}
.hero-banner-detail {
    display: flex;
    justify-content: center;
    gap: 0.4em;
}
.hero-banner-detail dd {
    margin: 0;
}

/* A statement's button is centred under the words. */
.details-text-statement .details-text-after {
    display: flex;
    justify-content: center;
    margin-top: var(--global-spacing-75);
}
/* Once it has travelled up to a fifth from the foot of the window it
   stays there and comes down the page with you, so the way to book is
   never more than a glance away. The placeholder keeps the gap it left
   behind, or the page would jump by the button's height the moment it
   pinned. js/script.js does the switching. */
.is-pinned-book {
    position: fixed;
    /* Level with the tagline at the foot of a full-screen hero, which sits
       on that hero's own bottom padding. Same token, so the two stay in
       step if the spacing scale ever moves. */
    bottom: var(--global-spacing-50);
    left: 50%;
    transform: translateX(-50%);
    z-index: 60;
    box-shadow: 0 6px 24px rgba(0, 4, 6, 0.18);
}
/* While the floating button is still following you down, the copy of it
   further down the page stays out of the way - otherwise both are on
   screen at once, which is what this replaced. */
.is-docking {
    visibility: hidden;
}
.details-text-sticky-space {
    display: block;
}
@media (prefers-reduced-motion: reduce) {
    .is-pinned-book {
        transition: none;
    }
}
/* -- TRIP BOOKING BUTTON END -- */

/* -- BREADCRUMBS -- */
/* Printed at the top of <main> on every page but the home page. It sits
   above the first section, so it carries the header offset itself: the
   offset rule targets the first article, which is no longer first. */
.breadcrumbs {
  padding: calc(var(--header-height) + var(--global-spacing-50)) var(--gutter) 0;
}
/* A page that opens with a hero is a different problem: the hero is meant
   to run under the header, so the trail cannot take a strip of its own
   without pushing the photo down. It floats over the hero instead, just
   below the header, and sits under the header in the stacking order so it
   can never cover the nav. What colour it needs depends on the hero - a
   full-screen one is a photograph, a split one is a pale panel - so PHP
   works that out the same way the header does and says so with .is-light.
   Left alone, the trail inherits the page's own colour. */
body:not(.has-header-offset) main {
  position: relative;
}
/* Fixed rather than absolute. On a stacking page <main> is display:
   contents, so an absolutely positioned trail has the document for a
   containing block and scrolls with it - while the hero it sits over is
   sticky and does not. Thirty pixels of scroll was enough to slide the
   words half under the opaque bar while the page still looked still.
   Fixed holds it in place, and it fades out the moment you scroll, which
   is the behaviour it had before in every case except being legible. */
body:not(.has-header-offset) .breadcrumbs {
  position: fixed;
  transition: opacity 0.2s ease;
  /* 150px is the most it ever drops, not a fixed distance. On a phone the
     bar is half the height it is on a desktop, so a flat 150px left the
     trail stranded in the middle of the hero. It now sits a comfortable
     gap below the bar, whatever height the bar happens to be, and stops
     at 150px once there is room for it. */
  top: min(150px, calc(var(--header-height) + var(--global-spacing-100)));
  left: 0;
  right: 0;
  z-index: 50;
  padding-top: 0;
}
.breadcrumbs.is-light {
  color: var(--light);
}
/* Scrolled at all: the trail has done its job and should not hang over
   the content. js/script.js sets the class. */
.has-scrolled body:not(.has-header-offset) .breadcrumbs,
body.has-scrolled:not(.has-header-offset) .breadcrumbs {
  opacity: 0;
  pointer-events: none;
}
.breadcrumbs-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--global-spacing-6) var(--global-spacing-12);
  margin: 0;
  padding: 0;
  list-style: none;
}
.breadcrumbs-item {
  display: flex;
  align-items: center;
  gap: var(--global-spacing-12);
  opacity: 0.7;
}
/* The separator belongs to the item that follows, so there is never a
   trailing one. */
.breadcrumbs-item + .breadcrumbs-item::before {
  content: "/";
  opacity: 0.5;
}
/* No underline at rest - a trail of underlined words directly under the
   nav reads as clutter. The global `a` rule is !important, so this has to
   be too. It returns on hover, so the links still announce themselves. */
.breadcrumbs-item a {
  text-decoration: none !important;
}
.breadcrumbs-item a:hover,
.breadcrumbs-item a:focus-visible {
  text-decoration: underline !important;
}
/* Where you are now is not a link and reads a little stronger. */
.breadcrumbs-item [aria-current="page"] {
  opacity: 1;
}
/* The first section no longer needs to clear the header: the trail above
   it already has. */
.has-header-offset main > .breadcrumbs ~ article:first-of-type {
  padding-top: var(--global-spacing-25);
}
/* -- BREADCRUMBS END -- */

/* -- INERT BUTTON -- */
/* A button with nowhere to go yet: a trip that is not open for booking.
   It keeps the pill's shape so nothing shifts when it becomes bookable,
   and reads as a state rather than something to press. */
.pill-button-inert {
    cursor: default;
    opacity: 0.55;
}
.pill-button-inert:hover {
    background: inherit;
    color: inherit;
}
/* -- INERT BUTTON END -- */

/* -- FOOTER LEGAL -- */
/* Terms, closing the Connect column. Quiet: a legal obligation rather
   than something the page is inviting anyone to do. */
.site-footer-legal-link {
    display: inline-block;
    margin-top: var(--global-spacing-25);
    opacity: 0.7;
}
.site-footer-legal-link:hover,
.site-footer-legal-link:focus {
    opacity: 1;
}
/* -- FOOTER LEGAL END -- */

/* -- BUY OPTION NOTE -- */
/* The line under "Pay in instalments" spelling out the schedule. Quieter
   than the option it belongs to, and on its own line so the two prices
   stay in a column. */
.buy-option-note {
    display: block;
    opacity: 0.7;
    text-transform: none;
    letter-spacing: 0;
}
/* -- BUY OPTION NOTE END -- */

/* -- TOUR PURCHASE (single-tour.php) -- */
/* A tour's booking page: the photograph across the top, then the trip's
   name, what it costs and how to pay, centred under it. The same shape as
   a magazine issue, with a landscape picture instead of a cover.
   (<main> already clears the fixed header - functions/header_offset.php.) */
.tour-purchase-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-50);
    padding-top: var(--global-spacing-50);
    padding-bottom: var(--global-spacing-100);
}
.tour-purchase-media {
    width: 100%;
}
.tour-purchase-image {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
.tour-purchase-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--global-spacing-12);
    max-width: 52rem;
    text-align: center;
}
.tour-purchase-text h1,
.tour-purchase-text p {
    text-align: center;
}
.tour-purchase-subtitle {
    font-style: italic;
}
/* Places left is a nudge, not an alarm. */
.tour-purchase-left {
    margin-top: var(--global-spacing-12);
    opacity: 0.7;
}
/* The two ways to pay, and the controls under them, both sit centred in
   the column rather than filling it. */
.tour-purchase-cart .buy-options {
    margin-bottom: var(--global-spacing-25);
    text-align: left;
}
.tour-purchase-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    justify-content: center;
    gap: var(--global-spacing-12);
}
@media (max-width: 768px) {
    .tour-purchase-image {
        aspect-ratio: 4 / 3;
    }
}
/* -- TOUR PURCHASE END -- */

/* -- QUANTITY WITHOUT STEPPERS -- */
/* The magazine's own page lost its - and + at Kate's request. The field
   stays, so it keeps the pill's shape and a little more room to type in
   than the stepped version needed. */
.buy-panel-qty-plain {
    justify-content: center;
}
.buy-panel-qty-plain input {
    width: 3ch;
    text-align: center;
}
/* -- QUANTITY WITHOUT STEPPERS END -- */

/* -- PRE-SALE NOTE -- */
/* When an issue ships, said above the Place order button so it is read
   before the card details rather than after them. */
.checkout-presale-note {
    margin-bottom: var(--global-spacing-12);
    opacity: 0.7;
}
/* -- PRE-SALE NOTE END -- */

/* -- FOOTER CURRENCY SWITCHER -- */
/* A second section under Travel with us, headed like the others, so the
   heading needs the room above it that the first one gets from the
   column. */
.site-footer-heading-second {
    margin-top: var(--global-spacing-25);
}
/* The switcher reads as one of the menu items beside it: same size, same
   off-white, no box. Colour and border come from the block's own
   attributes (footer.php); the size cannot, because the block writes
   font-size inline as a fixed number of pixels and the menu items are on
   a clamp. That is what the !important is for, and the only thing. */
/* The box lined up with the column, but the glyphs did not: a select left
   on its native appearance insets its own text by a few pixels, so EUR
   sat in from Group tours above it. appearance:none drops that inset,
   which also drops the arrow, so the caret below is drawn back on. */
.site-footer-currency {
    position: relative;
    display: inline-block;
}
.site-footer-currency select {
    appearance: none;
    -webkit-appearance: none;
    font-family: inherit;
    font-size: var(--font-size-h6) !important;
    line-height: inherit;
    padding: 0 0.9em 0 0 !important;
    cursor: pointer;
}
/* The caret, in the type's own colour and small enough to read as part of
   the word rather than a control beside it. */
.site-footer-currency::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 0.15em;
    width: 0.38em;
    height: 0.38em;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
    opacity: 0.8;
}
/* The open list is drawn by the browser on its own ground, so it needs a
   colour readable there rather than the footer's. */
.site-footer-currency select option {
    color: var(--dark);
    background: var(--light);
}
/* -- FOOTER CURRENCY SWITCHER END -- */

/* -- CURRENCY NOTICE -- */
/* WooPayments tells a visitor their prices have been converted, and
   offers them the way back. Useful, but it arrives as WooCommerce's store
   notice: the same element the "demo store" banner uses, so it comes in
   that notice's purple, absolutely positioned at the top of the page with
   a z-index of 99998 - which put it straight over the fixed header.
   Moved to the foot of the window, where a bar like this belongs, and
   given the site's own colours. */
.woocommerce-store-notice {
    position: fixed !important;
    top: auto !important;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    padding: var(--global-spacing-12) var(--gutter);
    background: var(--moss-green) !important;
    color: var(--off-white) !important;
    font-size: var(--font-size-link);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
}
.woocommerce-store-notice a {
    color: inherit;
    text-decoration: underline;
}
.woocommerce-store-notice a:hover,
.woocommerce-store-notice a:focus {
    text-decoration: none;
}
/* The dismiss link closes it, so it reads as the action rather than as
   more of the sentence. */
.woocommerce-store-notice__dismiss-link {
    margin-left: var(--global-spacing-12);
    opacity: 0.75;
}
/* -- CURRENCY NOTICE END -- */

/* -- IMAGE -- */
/* A photograph on its own. The image keeps its own shape rather than
   being cropped to a ratio: the component is for showing a picture as it
   was taken, and whatever is cropped belongs in Featured Image Text.
   height:auto because WordPress writes width and height attributes, and
   that height hint beats the intrinsic ratio otherwise. */
.image-block-image {
    display: block;
    width: 100%;
    height: auto;
}
/* -- IMAGE END -- */

/* -- PAYMENT PLAN WORDING -- */
/* WooCommerce Subscriptions labels a plan's deposit "Sign-up fee" and the
   month before the first instalment "Free trial". The cart says it in words
   instead (functions/plan_display.php), so these two go. */
.wc-block-components-product-details__free-trial,
.wc-block-components-product-details__sign-up-fee,
.cart_item .subscription-details {
    display: none !important;
}
/* -- PAYMENT PLAN WORDING END -- */

/* -- PHONE MEASURES -- */
/* Three quarters of the width is a desktop proportion: it breaks a big
   centred heading into two or three lines. On a phone the same 75% leaves
   two words to a line at display size, so these blocks take the full
   width there and the gutter does the framing. Same selectors as where
   each measure is set, so this wins by coming later. */
@media (max-width: 768px) {
    .featured-magazine-intro,
    .featured-magazine-text,
    .hero-banner-standard-text .hero-banner-title,
    .hero-banner-standard-text .hero-banner-title.type-h2,
    .details-text-statement .details-text-body,
    .story-header-summary,
    .steps-block-header {
        max-width: none;
    }
}
/* -- PHONE MEASURES END -- */

/* -- ACCOUNT: SUBSCRIPTIONS AND PAYMENT METHODS -- */
/* The subscription pages (woocommerce/myaccount/my-subscriptions.php,
   view-subscription.php) borrow the order pages' classes; these are the
   few pieces they add. */
.account-note {
    margin-top: var(--global-spacing-25);
    opacity: 0.8;
}
.account-note a {
    text-decoration: underline;
}
.account-subscription-payments {
    margin-top: var(--global-spacing-100);
}
.order-received-main .account-login-actions {
    flex-wrap: wrap;
}

/* Change payment method (woocommerce/checkout/form-change-payment-method.php)
   sits in the checkout grid, so the card form looks as it does when paying. */
.change-payment-grid .checkout-summary h2 {
    margin-bottom: var(--global-spacing-25);
}
@media (max-width: 900px) {
    .change-payment-grid {
        grid-template-columns: 1fr;
        row-gap: var(--global-spacing-75);
    }
    .change-payment-grid .checkout-summary {
        position: static;
        order: -1;
    }
}

/* WooCommerce's own grey buttons on the account pages that are still its
   templates - saved cards, adding a card, the temporary-password notice -
   take the site's outline pill instead. Same values as .pill-button and
   .type-link, so the two cannot be told apart. */
.woocommerce-account .woocommerce .button:not(.pill-button),
.woocommerce-account .woocommerce-message .button,
.woocommerce-account .woocommerce-info .button {
    display: inline-flex;
    align-items: center;
    gap: 0.6em;
    padding: 1.1em 2.2em;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--dark);
    box-shadow: inset 0 0 0 1px var(--dark);
    font-family: var(--font-family-sans);
    font-size: var(--font-size-link);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none !important;
    cursor: pointer;
}
.woocommerce-account .woocommerce .button:not(.pill-button):hover,
.woocommerce-account .woocommerce .button:not(.pill-button):focus-visible {
    background: var(--dark);
    color: var(--light);
}
/* Saved cards: a ledger like the profile panel rather than a boxed table. */
.woocommerce-account .woocommerce-MyAccount-paymentMethods {
    width: 100%;
    border: 0 !important;
    border-radius: 0 !important;
    border-collapse: collapse;
    margin-bottom: var(--global-spacing-50);
}
.woocommerce-account .woocommerce-MyAccount-paymentMethods th,
.woocommerce-account .woocommerce-MyAccount-paymentMethods td {
    padding: var(--global-spacing-12) var(--global-spacing-12) var(--global-spacing-12) 0;
    border: 0 !important;
    border-bottom: 1px solid color-mix(in srgb, currentColor 25%, transparent) !important;
    background: transparent;
    text-align: left;
    vertical-align: middle;
}
.woocommerce-account .woocommerce-MyAccount-paymentMethods th {
    font-family: var(--font-family-sans);
    font-size: var(--font-size-link);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.6;
    border-bottom-color: currentColor;
}
.woocommerce-account .woocommerce-MyAccount-paymentMethods td.payment-method-actions {
    text-align: right;
}
.woocommerce-account .woocommerce-MyAccount-paymentMethods .button {
    padding: 0.8em 1.6em;
}
/* A returning customer's saved cards, at checkout and when changing a
   plan's card: a list of choices in the body size, not WooCommerce's
   small print. */
.checkout-grid .woocommerce-SavedPaymentMethods {
    list-style: none;
    margin: var(--global-spacing-12) 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--global-spacing-12);
}
.checkout-grid .woocommerce-SavedPaymentMethods li {
    display: flex;
    align-items: center;
    gap: var(--global-spacing-12);
    font-family: var(--font-family-sans);
    font-size: var(--font-size-body);
}
.checkout-grid .woocommerce-SavedPaymentMethods input[type="radio"] {
    width: 1.1em;
    height: 1.1em;
    margin: 0;
    accent-color: var(--dark);
}
/* -- ACCOUNT: SUBSCRIPTIONS AND PAYMENT METHODS END -- */

/* -- CART CHECKOUT BUTTON -- */
/* The block cart's Proceed to Checkout comes in WooCommerce's lettering;
   every other button on the site is the pill's small spaced capitals. */
.wc-block-cart__submit-button,
.wc-block-cart__submit-button .wc-block-components-button__text {
    font-family: var(--font-family-sans) !important;
    font-size: var(--font-size-link) !important;
    font-weight: 500 !important;
    letter-spacing: 0.1em !important;
    text-transform: uppercase !important;
}
.wc-block-cart__submit-button {
    border-radius: 999px !important;
    background: var(--dark) !important;
    color: var(--light) !important;
    padding: 1.1em 2.2em !important;
}
/* -- CART CHECKOUT BUTTON END -- */
