/*
Theme Name: Victo Child
Theme URI: https://victo.local/
Description: Child theme for Hello Elementor.
Author: Hayden Stapleton
Author URI: https://victo.local/
Template: hello-elementor
Version: 1.1.0
Text Domain: victo-child
*/


/* Web Fonts — TT Hoves Pro (licensed, self-hosted)
   Regular 400 + Medium 500 only (the two weights the design system uses).
   woff2 for all modern browsers, woff as fallback. Licence PDFs live outside
   the theme in "TT Hoves Pro/licences/".
--------------------------------------------- */
@font-face {
    font-family: "TT Hoves Pro";
    src: url("fonts/TT_Hoves_Pro_Regular.woff2") format("woff2"),
         url("fonts/TT_Hoves_Pro_Regular.woff") format("woff");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "TT Hoves Pro";
    src: url("fonts/TT_Hoves_Pro_Medium.woff2") format("woff2"),
         url("fonts/TT_Hoves_Pro_Medium.woff") format("woff");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}


/* Global Font Styles
--------------------------------------------- */

/* Desktop font sizes */
:root {
    --heading-display:    2.1875rem; /* 35 — shared with H1 */
    --heading-h1:         var(--heading-display);
    --heading-h2:         1.875rem;  /* 30 */
    --heading-h3:         1.5rem;    /* 24 */
    --heading-h4:         1.375rem;  /* 22 */
    --heading-h5:         1.375rem;  /* 22 */
    --heading-h6:         1.125rem;  /* 18 */

    --body-body-lg:       1.25rem;   /* 20 */
    --body-body-md:       1rem;      /* 16 */
    --body-body-sm:       0.875rem;  /* 14 */
    --body-body-xsm:      0.75rem;   /* 12 */

    --component-caption:  0.75rem;   /* 12 */
    --component-button-buttondefault: 0.625rem;  /* 10 */

    --line-display:       3.25rem;   /* 52 (1.5 @ 35) */
    --line-h1:            var(--line-display);
    --line-h2:            2.25rem;   /* 36 */
    --line-h3:            2.25rem;   /* 36 */
    --line-h4:            1.925rem;  /* 30.8 (1.4) */
    --line-h5:            1.925rem;  /* 30.8 (1.4) */
    --line-h6:            1.625rem;  /* 26 */
    --line-body-lg:       1.5rem;    /* 24 */
    --line-body-md:       1.25rem;   /* 20 */
    --line-body-sm:       1.25rem;   /* 20 */
    --line-caption:       1.25rem;   /* 20 */
    --line-button:        0.75rem;   /* 12 */
}


/* Colour Variables
--------------------------------------------- */
:root {
    --black:          #000000;
    --white:          #ffffff;

    /* Brand / Dark */
    --dark-b400:      #101d23;
    --dark-b300:      #182c38; /* Foundation/Dark/B300 */
    --dark-b200:      #303e4d;

    /* Neutrals */
    --grey-g300:      #96a5a3; /* Foundation/Grey/G300 */
    --grey-g75:       #d4dad9; /* Foundation/Grey/G75 */

    /* Accent — TBD, confirm from brand kit */
    --accent-orange:  #e8712a;

    /* Semantic aliases */
    --text-heading:   var(--dark-b300);
    --text-body:      var(--dark-b300);
    --text-muted:     var(--grey-g300);
    --text-inverse:   var(--white);
    --bg-default:     var(--white);
    --bg-alt:         var(--grey-g75);
    --bg-inverse:     var(--dark-b300);
    --border-subtle:  var(--grey-g75);

    /* Global Fonts */
    --bodyFont:   "TT Hoves Pro", "Helvetica Neue", Arial, sans-serif;
    --titleFont:  "TT Hoves Pro", "Helvetica Neue", Arial, sans-serif;
}




/* Spacing Variables
--------------------------------------------- */
:root {
    --base-size: 4px;

    --size-0\.5: calc(var(--base-size) * 0.5);
    --size-1:  calc(var(--base-size) * 1);   /* 4 */
    --size-2:  calc(var(--base-size) * 2);   /* 8 */
    --size-3:  calc(var(--base-size) * 3);   /* 12 */
    --size-4:  calc(var(--base-size) * 4);   /* 16 */
    --size-5:  calc(var(--base-size) * 5);   /* 20 */
    --size-6:  calc(var(--base-size) * 6);   /* 24 */
    --size-8:  calc(var(--base-size) * 8);   /* 32 */
    --size-10: calc(var(--base-size) * 10);  /* 40 */
    --size-12: calc(var(--base-size) * 12);  /* 48 */
    --size-14: calc(var(--base-size) * 14);  /* 56 */
    --size-16: calc(var(--base-size) * 16);  /* 64 */
    --size-18: calc(var(--base-size) * 18);  /* 72 */
    --size-20: calc(var(--base-size) * 20);  /* 80 */
    --size-24: calc(var(--base-size) * 24);  /* 96 */
    --size-32: calc(var(--base-size) * 32);  /* 128 */
    --size-48: calc(var(--base-size) * 48);  /* 192 */
    --size-80: calc(var(--base-size) * 80);  /* 320 */
}


/* Global Configuration — DESKTOP
--------------------------------------------- */
:root {
    --page-width: 1536px;

    /* Section Padding */
    --section-padding-smaller: var(--size-12); /* 48 */
    --section-padding:         var(--size-32); /* 128  — sp-v-default */
    --section-padding-larger:  var(--size-48); /* 192  — sp-y-lrg */
    --section-padding-sides:   var(--size-80); /* 320  — sp-h-default */

    /* Component Padding */
    --cp-3xs: var(--size-1);   /* 4 */
    --cp-2xs: var(--size-2);   /* 8 */
    --cp-xs:  var(--size-3);   /* 12 */
    --cp-s:   var(--size-4);   /* 16 */
    --cp-m:   var(--size-5);   /* 20 */
    --cp-l:   var(--size-8);   /* 32 */
    --cp-xl:  var(--size-12);  /* 48 */
    --cp-2xl: var(--size-16);  /* 64 */
    --cp-3xl: var(--size-24);  /* 96 */

    /* Column gaps */
    --column-sm: var(--size-4);  /* 16 */
    --column-md: var(--size-5);  /* 20 */
    --column-lg: var(--size-12); /* 48 */

    /* Radius */
    --radius-s:    4px;
    --radius-m:    8px;
    --radius-l:    12px;
    --radius-full: 999px;

    /* Button */
    --button-height-default:  31px;
    --button-padding-default: var(--cp-s);
    --button-radius:          var(--radius-full);
}

@media all and (max-width: 1750px) {
    :root { --section-padding-sides: var(--size-24); } /* 96 */
}

/* TABLET */
@media all and (max-width: 1440px) {
    :root {
        --page-width: 1024px;

        --section-padding-smaller: var(--size-8);  /* 32 */
        --section-padding:         var(--size-24); /* 96 */
        --section-padding-larger:  var(--size-32); /* 128 */
        --section-padding-sides:   var(--size-24); /* 96 */

        --cp-l:   var(--size-5);  /* 20 */
        --cp-xl:  var(--size-8);  /* 32 */
        --cp-2xl: var(--size-12); /* 48 */
        --cp-3xl: var(--size-16); /* 64 */

        --column-lg: var(--size-8); /* 32 */
    }
}

@media (max-width: 1200px) {
    :root { --section-padding-sides: var(--size-16); }
}

/* MOBILE */
@media all and (max-width: 767px) {
    :root {
        --page-width: 375px;

        --section-padding-smaller: var(--size-8);  /* 32 */
        --section-padding:         var(--size-16); /* 64 */
        --section-padding-larger:  var(--size-24); /* 96 */
        --section-padding-sides:   var(--size-6);  /* 24 */

        --cp-xl:  var(--size-6);  /* 24 */
        --cp-2xl: var(--size-8);  /* 32 */
        --cp-3xl: var(--size-12); /* 48 */
    }
}


/* Section Padding Utility Classes
--------------------------------------------- */
.elementor .section-padding-small  { padding: var(--section-padding-smaller) var(--section-padding-sides); padding-inline-start: var(--section-padding-sides); padding-inline-end: var(--section-padding-sides); }
.elementor .section-padding        { padding: var(--section-padding)         var(--section-padding-sides); padding-inline-start: var(--section-padding-sides); padding-inline-end: var(--section-padding-sides); }
.elementor .section-padding-large  { padding: var(--section-padding-larger)  var(--section-padding-sides); padding-inline-start: var(--section-padding-sides); padding-inline-end: var(--section-padding-sides); }

.elementor .section-padding.top,
.elementor .section-padding-small.top,
.elementor .section-padding-large.top        { padding-bottom: 0; }
.elementor .section-padding.bottom,
.elementor .section-padding-small.bottom,
.elementor .section-padding-large.bottom     { padding-top: 0; }
.elementor .section-padding.sides-only,
.elementor .section-padding-small.sides-only,
.elementor .section-padding-large.sides-only { padding-top: 0; padding-bottom: 0; }

:root {
    --header-offset: 169px;
}

@media (max-width: 1280px) {
    :root {
        --header-offset: 90px;
    }
}

body .header-offset {
    margin-top: var(--header-offset);
}


/* Typography Utility Classes — Elementor-compatible
--------------------------------------------- */

/* Display and H1 share the same style */
.text-display, .text-h1, h1,
.elementor h1.elementor-heading-title,
.elementor .text-h1,
.elementor .text-display {
    font-family: var(--titleFont);
    font-size:   var(--heading-display);
    font-weight: 400;
    line-height: var(--line-display);
}

.text-h2, h2,
.elementor h2.elementor-heading-title,
.elementor .text-h2 {
    font-family: var(--titleFont);
    font-size:   var(--e-global-typography-fd6b464-font-size);
    font-weight: 400;
    line-height: var(--e-global-typography-fd6b464-line-height);
}

.text-h3, h3,
.elementor h3.elementor-heading-title,
.elementor .text-h3 {
    font-family: var(--titleFont);
    font-size:   var(--e-global-typography-b7fce3a-font-size);
    font-weight: var(--e-global-typography-b7fce3a-font-weight);
    line-height: var(--e-global-typography-b7fce3a-line-height);
}

/* H4–H6 use Medium (500) per Figma Font Family/Headings */
.text-h4, h4,
.elementor h4.elementor-heading-title,
.elementor .text-h4 {
    font-family: var(--titleFont);
    font-size:   var(--heading-h4);
    font-weight: 500;
    line-height: var(--line-h4);
}

.text-h5, h5,
.elementor h5.elementor-heading-title,
.elementor .text-h5 {
    font-family: var(--titleFont);
    font-size:   var(--heading-h5);
    font-weight: 500;
    line-height: var(--line-h5);
}

.text-h6, h6,
.elementor h6.elementor-heading-title,
.elementor .text-h6 {
    font-family: var(--titleFont);
    font-size:   var(--heading-h6);
    font-weight: 500;
    line-height: var(--line-h6);
}

.text-body-large,
.elementor .text-body-large {
    font-family: var(--bodyFont);
    font-size:   var(--body-body-lg);
    font-weight: 400;
    line-height: var(--line-body-lg);
}

.text-body-medium, body,
.elementor .text-body-medium {
    font-family: var(--bodyFont);
    font-size:   var(--body-body-md);
    font-weight: 400;
    line-height: var(--line-body-md);
}

.text-body-small,
.elementor .text-body-small {
    font-family: var(--bodyFont);
    font-size:   var(--body-body-sm);
    font-weight: 400;
    line-height: var(--line-body-sm);
}

.text-caption, .text-tag,
.elementor .text-caption,
.elementor .text-tag {
    font-family:    var(--bodyFont);
    font-size:      var(--e-global-typography-fd2da23-font-size);
    font-weight:    500;
    line-height:    var(--e-global-typography-fd2da23-line-height);
    letter-spacing: var(--e-global-typography-fd2da23-letter-spacing);
    text-transform: uppercase;
}

.text-button, .elementor-button,
.elementor .text-button,
.elementor [type="submit"],
.elementor [type="button"] {
    font-family:    var(--bodyFont);
    font-size:      var(--component-button-buttondefault);
    font-weight:    500;
    line-height:    var(--line-button);
    letter-spacing: 0.1em; /* 1px at 10 */
    text-transform: uppercase;
}

/* Overlay menu links reuse the Display style */
.text-menu, .elementor .text-menu {
    font-family: var(--titleFont);
    font-size:   var(--heading-display);
    font-weight: 400;
    line-height: 1.5;
}


/* Base Elements
--------------------------------------------- */
html { font-size: 16px; }

body {
    color: var(--text-body);
    background: var(--bg-default);
	text-wrap: pretty;
}

a { color: inherit; }

.elementor-widget-text-editor p:last-of-type {
    margin-bottom: 0;;
}
.elementor-widget-text-editor p {
	text-wrap: pretty;
}


/* Button Customisation
--------------------------------------------- */
.elementor .elementor-button:focus,
.elementor .elementor-button:active,
.elementor .elementor-button:focus-visible {
    outline: none;
    box-shadow: none;
}

.elementor-button-text {
    padding: 12px 12px 12px 16px;
}
.elementor-button-icon {
    padding: 12px;
}
.elementor-button-icon {
    border-left: 1px solid var(--dark-b400);
}
.elementor .elementor-button-icon .e-font-icon-svg,
.elementor .elementor-button-icon svg {
    height: 12px;
    width: 12px;
    fill: var(--dark-b400);
    font-size: 12px;
}
.elementor .elementor-button:hover .elementor-button-icon .e-font-icon-svg,
.elementor .elementor-button:focus .elementor-button-icon .e-font-icon-svg,
.elementor .elementor-button:hover .elementor-button-icon svg,
.elementor .elementor-button:focus .elementor-button-icon svg {
    fill: var(--white);
}
.elementor-button:hover .elementor-button-icon,
.elementor-button:focus .elementor-button-icon {
    border-left: 1px solid var(--white);
}
span.elementor-button-content-wrapper {
    gap: 0;
}

.elementor .button-grey .elementor-button {
    border-color: var(--grey-g300);
    background-color: transparent;
    color: var(--grey-g300);
}
.elementor .button-grey .elementor-button:hover,
.elementor .button-grey .elementor-button:focus {
    border-color: var(--grey-g300);
    background-color: var(--grey-g300);
    color: var(--dark-b300);
}
.elementor .button-grey .elementor-button .elementor-button-icon svg {
    fill: var(--grey-g300);
}
.elementor .button-grey .elementor-button:hover .elementor-button-icon svg,
.elementor .button-grey .elementor-button:focus .elementor-button-icon svg {
    fill: var(--dark-b300);
}
.elementor .button-grey .elementor-button .elementor-button-icon {
    border-left: 1px solid var(--grey-g300);
}
.elementor .button-grey .elementor-button:hover .elementor-button-icon,
.elementor .button-grey .elementor-button:focus .elementor-button-icon {
    border-left: 1px solid var(--dark-b300);
}

.elementor .button-subtle .elementor-button:hover,
.elementor .button-subtle .elementor-button:focus {
    border-color: var(--grey-g75);
    color: var(--grey-g75);
}
.elementor .button-subtle .elementor-button:hover .elementor-button-icon svg,
.elementor .button-subtle .elementor-button:focus .elementor-button-icon svg {
    fill: var(--grey-g75);
}
.elementor .button-subtle .elementor-button:hover .elementor-button-icon,
.elementor .button-subtle .elementor-button:focus .elementor-button-icon {
    border-left: 1px solid var(--grey-g75);
}
/* Menu toggle button — white when menu is open */
html.victo-menu-open .victo-menu-toggle .elementor-button {
    border-color: var(--white);
    color: var(--white);
}
html.victo-menu-open .victo-menu-toggle .elementor-button-icon {
    border-left-color: var(--white);
}
html.victo-menu-open .victo-menu-toggle .elementor-button-icon .e-font-icon-svg,
html.victo-menu-open .victo-menu-toggle .elementor-button-icon svg {
    fill: var(--white);
}
.menu-open header h1 {
    color: white;
}

.button-arrow .elementor-button svg {
    transform: translate3d(0, 0, 0);
    transition: transform 0.2s ease;
    will-change: transform;
    backface-visibility: hidden;
}
/* Prev arrows reuse the right-arrow icon flipped 180deg. Elementor's
   per-element custom CSS applies that flip, but `transform` is a single
   property, so the hover nudge below used to replace it and the arrow
   snapped back to pointing right (permanently on touch, where :hover
   sticks after a tap). Own the flip here so it survives every state. */
.button-arrow.project-carousel-prev .elementor-button svg,
.button-arrow.project-image-carousel-prev .elementor-button svg,
.button-arrow.custom-swiper-prev .elementor-button svg {
    transform: translate3d(0, 0, 0) rotate(180deg);
}
@media (hover: hover) {
    .button-arrow .elementor-button:hover svg {
        transform: translate3d(3px, 0, 0);
    }
    .button-arrow.project-carousel-prev .elementor-button:hover svg,
    .button-arrow.project-image-carousel-prev .elementor-button:hover svg,
    .button-arrow.custom-swiper-prev .elementor-button:hover svg {
        transform: translate3d(-3px, 0, 0) rotate(180deg);
    }
}


/* Project Carousel — [project-carousel]
--------------------------------------------- */
:root {
    --project-card-gap:          20px;
    --project-cards-per-page:    4;
    --project-card-ratio:        273 / 389;
    --project-card-overlay:      rgba(150, 165, 163, 0.85);
    --project-card-anim-draw:    900ms;
    --project-card-anim-fade:    300ms;
    --project-card-ease:         cubic-bezier(0.22, 1, 0.36, 1);
    --project-card-ease-draw:    cubic-bezier(0.65, 0, 0.35, 1);
}

@media (max-width: 1440px) {
    :root { --project-cards-per-page: 3; }
}

@media (max-width: 767px) {
    :root { --project-cards-per-page: 1; --project-card-gap: 12px; }
}

.project-carousel {
    overflow: hidden;
    width: 100%;
}

.project-carousel__track {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - (var(--project-cards-per-page) - 1) * var(--project-card-gap)) / var(--project-cards-per-page));
    gap: var(--project-card-gap);
    transition: transform 600ms var(--project-card-ease);
    will-change: transform;
    touch-action: pan-y; /* horizontal drag is ours, vertical scroll stays native (Safari) */
}

/* Drag/swipe (victo-swipe.js): follow the finger, no easing. */
.project-carousel__track.is-dragging {
    transition: none;
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}
.project-carousel__track.is-dragging .project-card {
    transition: none !important;
    cursor: grabbing;
}

.project-card {
    position: relative;
    display: block;
    aspect-ratio: var(--project-card-ratio);
    padding: var(--cp-s);
    background-color: var(--grey-g75);
    /* Regular (portrait) cards prefer the ACF portrait_image; wide cards
       always use the featured image. Both are set inline by
       victo_child_render_project_card(). */
    background-image: var(--card-img-portrait, var(--card-img));
    background-size: cover;
    background-position: center;
    color: var(--white);
    text-decoration: none;
    overflow: hidden;
    isolation: isolate;
}

/* Wide cards use the featured image on tablet/desktop only. On mobile every
   card is a single-column square, so all cards prefer the portrait image. */
@media (min-width: 768px) {
    .project-listing__grid .project-card.is-wide,
    .project-carousel.is-featured .project-card.is-active {
        background-image: var(--card-img);
    }
}

.project-card__title {
    position: absolute;
    top: var(--cp-s);
    left: var(--cp-s);
    right: var(--cp-s);
    z-index: 2;
    text-align: center;
    color: var(--white);
    transition: color var(--project-card-anim-fade) var(--project-card-ease);
}

.project-card__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: var(--project-card-overlay);
    opacity: 0;
    transition: opacity 400ms var(--project-card-ease);
    pointer-events: none;
}

.project-card__cta {
    position: absolute;
    left: var(--cp-s);
    right: var(--cp-s);
    bottom: var(--cp-s);
    z-index: 2;
    text-align: center;
    color: var(--white);
    opacity: 0;
    transition:
        color var(--project-card-anim-fade) var(--project-card-ease),
        opacity var(--project-card-anim-fade) var(--project-card-ease);
}

/* Hide an Elementor Swiper's native arrows when driven by custom nav arrows.
   pointer-events:none stops the invisible arrows from intercepting clicks;
   programmatic .click() from main.js still works. */
.custom-swiper-nav .elementor-swiper-button-prev,
.custom-swiper-nav .elementor-swiper-button-next {
    opacity: 0;
    pointer-events: none;
}

/* Process carousel (Elementor nested carousel + custom nav) on phones: the
   Elementor-side spacing (20px card padding, 20px between heading / image /
   copy) made the tallest card ~450px. Tighten so every card sits comfortably
   inside one phone screen. !important because Elementor's per-element post
   CSS sets these through custom properties at the same specificity. */
@media (max-width: 767px) {
    .custom-swiper-nav .swiper-slide .e-con-full {
        padding: 16px !important;
        gap: 12px !important;
        --gap: 12px;
        --row-gap: 12px;
    }
    .custom-swiper-nav .swiper-slide .elementor-widget-image img {
        aspect-ratio: 3 / 2;
        object-fit: cover;
    }
}

.project-card__logomark {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 64px;
    height: 64px;
    transform: translate(-50%, -50%);
    color: var(--white);
    pointer-events: none;
    overflow: visible;
    shape-rendering: geometricPrecision;
}

.project-card__logomark-stroke {
    stroke-dasharray: var(--victo-path-length, 250);
    stroke-dashoffset: var(--victo-path-length, 250);
    opacity: 0;
    will-change: opacity, stroke;
}

.project-card__logomark-fill {
    opacity: 0;
    will-change: opacity;
    transform: translateZ(0);
}

/* Hover / focus state — desktop only (pointer hover supported) */
@media (hover: hover) {
    .project-card:hover .project-card__overlay,
    .project-card:focus-visible .project-card__overlay { opacity: 1; }

    .project-card:hover::after,
    .project-card:focus-visible::after,
    .project-card:hover::before,
    .project-card:focus-visible::before { opacity: 0; }

    .project-card:hover .project-card__title,
    .project-card:focus-visible .project-card__title { color: var(--dark-b200); }

    .project-card:hover .project-card__cta,
    .project-card:focus-visible .project-card__cta { opacity: 1; }

    .project-card:hover .project-card__logomark-stroke,
    .project-card:focus-visible .project-card__logomark-stroke {
        animation:
            victo-stroke-show 1ms linear forwards,
            victo-stroke-draw var(--project-card-anim-draw) var(--project-card-ease-draw) 80ms forwards;
    }
}

/* Subtle bottom gradient for CTA legibility on light images */
.project-card::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 120px;
    z-index: 1;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.45) 100%);
    opacity: 1;
    transition: opacity 400ms var(--project-card-ease);
    pointer-events: none;
}

/* Subtle top gradient for title legibility on light images */
.project-card::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 96px;
    z-index: 1;
    background: linear-gradient(to top, rgba(24, 44, 56, 0) 0%, rgba(24, 44, 56, 0.35) 100%);
    opacity: 1;
    transition: opacity 400ms var(--project-card-ease);
    pointer-events: none;
}

@keyframes victo-stroke-show {
    to { opacity: 1; }
}

@keyframes victo-stroke-draw {
    from { stroke-dashoffset: var(--victo-path-length, 250); }
    to   { stroke-dashoffset: 0; }
}

/* Mobile: no hover overlay; keep title visible on image */
@media (max-width: 767px) {
    .project-card {
        aspect-ratio: 1 / 1;
        min-height: 300px;
        height: auto;
    }

    .project-card__overlay,
    .project-card__logomark { display: none; }

    .project-card__title {
        padding: 4px 8px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .project-carousel__track,
    .project-card__overlay,
    .project-card__title {
        transition-duration: 0ms;
    }
    .project-card:hover .project-card__logomark-stroke,
    .project-card:focus-visible .project-card__logomark-stroke { animation: none; opacity: 1; stroke-dashoffset: 0; }
    .project-card:hover .project-card__logomark-fill,
    .project-card:focus-visible .project-card__logomark-fill { animation: none; opacity: 0; }
}

/* Project Carousel — featured mode (absolute-positioned card model).
   Every card lives at `position: absolute` and derives its own transform from
   `--card-index` (set per-card by JS) minus `--active-index` (set on the carousel
   by JS). Cards after the active one pick up an extra `--pc-step` offset via the
   sibling selector. No track translate, no flex reflow — one synchronized motion. */
.project-carousel.is-featured {
    container-type: inline-size;
    --project-cards-per-page: 4;
    /* Use 100cqw, not 100%: this variable is consumed inside transform: translateX(),
       where percentages resolve against the element's own width, not the container's. */
    --pc-col-w: calc((100cqw - 3 * var(--project-card-gap)) / 4);
    --pc-step: calc(var(--pc-col-w) + var(--project-card-gap));
    --pc-active-w: calc(2 * var(--pc-col-w) + var(--project-card-gap));
    --pc-card-h: calc(var(--pc-col-w) * 421 / 305);
    --active-index: 0;
}

.project-carousel.is-featured .project-carousel__track {
    position: relative;
    display: block;
    height: var(--pc-card-h);
    grid-auto-flow: unset;
    grid-auto-columns: unset;
    transform: none !important;
}

.project-carousel.is-featured .project-card {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: var(--pc-col-w);
    aspect-ratio: auto;
    --active-offset: 0px;
    transform: translateX(calc(
        (var(--card-index, 0) - var(--active-index, 0)) * var(--pc-step)
        + var(--active-offset)
    ));
    will-change: transform, width;
    transition:
        transform 600ms var(--project-card-ease),
        width     600ms var(--project-card-ease);
}

.project-carousel.is-featured .project-card.is-active {
    width: var(--pc-active-w);
}

.project-carousel.is-featured .project-card.is-active ~ .project-card {
    --active-offset: var(--pc-step);
}

/* Snap (loop reset, prev wrap, resize) — kill card transitions for one frame. */
.project-carousel.is-snapping .project-card {
    transition: none !important;
}

/* Below 900px: 3-col grid, 2 visible cards (2 + 1). */
@media (max-width: 900px) {
    .project-carousel.is-featured {
        --project-cards-per-page: 3;
        --pc-col-w: calc((100cqw - 2 * var(--project-card-gap)) / 3);
    }
}

/* Mobile: revert to 1-card-at-a-time. With `--pc-step: 100%` and no extra
   offset, each card sits at (card-index − active-index) × 100% — exactly the
   default single-card-per-page behavior. */
@media (max-width: 767px) {
    .project-carousel.is-featured {
        --project-cards-per-page: 1;
        --pc-col-w: 100cqw;
        --pc-step: 100cqw;
        --pc-active-w: 100cqw;
        --pc-card-h: 100cqw;
    }
    /* Track has no in-flow children (cards are position:absolute), so
       `aspect-ratio` on an auto-height block collapses. Pin an explicit
       height equal to the container width — keeps the 1:1 square the
       mobile design wants without depending on flow content. */
    .project-carousel.is-featured .project-carousel__track {
        height: 100cqw;
    }
    .project-carousel.is-featured .project-card,
    .project-carousel.is-featured .project-card.is-active {
        width: 100%;
        height: 100%;
        aspect-ratio: auto;
    }
    .project-carousel.is-featured .project-card.is-active ~ .project-card {
        --active-offset: 0px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .project-carousel.is-featured .project-card {
        transition-duration: 0ms;
    }
}


/* Project Image Carousel — [project-image-carousel]
--------------------------------------------- */
:root {
    --project-image-carousel-gap:       20px;
    --project-image-carousel-max:       496px;
    --project-image-carousel-ratio:     496 / 515;
}

@media (max-width: 767px) {
    :root { --project-image-carousel-gap: 12px; }
}

.project-image-carousel {
    position: relative;
    width: 100%;
    overflow: visible;
}

.project-image-carousel__track {
    display: flex;
    gap: var(--project-image-carousel-gap);
    transition: transform 600ms var(--project-card-ease);
    will-change: transform;    touch-action: pan-y; /* horizontal drag is ours, vertical scroll stays native (Safari) */
}

.project-image-carousel__track.is-dragging {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}

.project-image-carousel__track.is-dragging img { cursor: grabbing; }

.project-image-carousel__slide {
    position: relative;
    flex: 0 0 min(100%, var(--project-image-carousel-max));
    margin: 0;
    overflow: hidden;
}

.project-image-carousel__slide img {
    display: block;
    -webkit-user-drag: none;
    width: 100%;
    height: auto;
    aspect-ratio: var(--project-image-carousel-ratio);
    object-fit: cover;
    object-position: center;
    cursor: zoom-in;
}

/* Small "+" lightbox trigger overlaid on each slide. Double class selector
   so it beats the Elementor kit's global `button` styling (pill radius,
   border, hover fill). */
.project-image-carousel__slide .project-image-carousel__zoom {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    opacity: 0;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--white);
    color: var(--dark-b300);
    font: inherit;
    line-height: 0;
    cursor: zoom-in;
    box-shadow: 0 2px 8px rgba(16, 29, 35, 0.2);
    transition:
        opacity 200ms var(--project-card-ease),
        background-color 200ms var(--project-card-ease),
        color 200ms var(--project-card-ease),
        transform 200ms var(--project-card-ease);
    -webkit-appearance: none;
    appearance: none;
}

/* Reveal on slide hover / keyboard focus; always visible on touch devices. */
.project-image-carousel__slide:hover .project-image-carousel__zoom,
.project-image-carousel__slide .project-image-carousel__zoom:focus-visible {
    opacity: 1;
}

@media (hover: none) {
    .project-image-carousel__slide .project-image-carousel__zoom {
        opacity: 1;
    }
}

.project-image-carousel__slide .project-image-carousel__zoom:hover,
.project-image-carousel__slide .project-image-carousel__zoom:focus-visible {
    border: 0;
    border-radius: 50%;
    background: var(--dark-b300);
    color: var(--white);
    transform: translate(-50%, -50%) scale(1.06);
}


.project-image-carousel__slide .project-image-carousel__zoom svg {
    width: 18px;
    height: 18px;
}

@media (max-width: 767px) {
    .project-image-carousel__slide .project-image-carousel__zoom {
        width: 36px;
        height: 36px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .project-image-carousel__track { transition-duration: 0ms; }
}


/* Image Lightbox — opened from [project-image-carousel] slides
--------------------------------------------- */
.victo-lightbox {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(16px, 5vw, 64px);
    background: rgba(16, 29, 35, 0.94);
    opacity: 0;
    transition: opacity 300ms var(--project-card-ease);
    cursor: zoom-out;
    touch-action: none; /* swipe between images; page can't scroll behind the overlay anyway */
    overflow: hidden;
}

.victo-lightbox.is-dragging,
.victo-lightbox.is-dragging .victo-lightbox__img {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}

.victo-lightbox[hidden] {
    display: none;
}

.victo-lightbox.is-open {
    opacity: 1;
}

.victo-lightbox__img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    cursor: default;
    -webkit-user-drag: none;
    opacity: 0;
    transform: scale(0.98);
    transition:
        opacity 300ms var(--project-card-ease),
        transform 300ms var(--project-card-ease);
}

.victo-lightbox.is-loaded .victo-lightbox__img {
    opacity: 1;
    transform: scale(1);
}

.victo-lightbox__close {
    position: absolute;
    top: 16px;
    right: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--white);
    cursor: pointer;
    transition: opacity 200ms var(--project-card-ease);
    -webkit-appearance: none;
    appearance: none;
}

.victo-lightbox__close:hover {
    opacity: 0.7;
}

.victo-lightbox__close:focus-visible {
    outline: 2px solid var(--accent-orange);
    outline-offset: 2px;
}

.victo-lightbox__close svg {
    width: 28px;
    height: 28px;
}

body.victo-lightbox-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .victo-lightbox,
    .victo-lightbox__img,
    .victo-lightbox__close {
        transition-duration: 0ms;
    }
    .victo-lightbox__img {
        transform: none;
    }
}


/* Project Meta Data — [project-meta-data]
--------------------------------------------- */
.project-meta-data {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.project-meta-data__item {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid #96A5A359;
}

.project-meta-data__item:last-child {
    border-bottom: 0;
}

.project-meta-data p.project-meta-data__label,
.project-meta-data p.project-meta-data__value,
.elementor .project-meta-data p.project-meta-data__label,
.elementor .project-meta-data p.project-meta-data__value {
    margin-top: 0;
    margin-bottom: 0;
    color: var(--dark-b300);
}


/* Form Controls — Custom Checkboxes & Radios
--------------------------------------------- */
:root {
    --control-size:              16px;
    --control-border-width:      1.5px;
    --control-color:             var(--grey-g300);
    --control-mark-color:        var(--grey-g300);
    --control-radius-checkbox:   var(--radius-full);
    --control-radius-radio:      var(--radius-full);
    --control-gap:               10px;
    --control-group-gap:         var(--cp-m);
    --control-focus-ring-width:  2px;
    --control-focus-ring-offset: 2px;
    --control-focus-ring-color:  var(--grey-g300);
    --control-transition:        150ms ease;
}

/* Base reset — strips native appearance, sets custom box */
input[type="checkbox"],
input[type="radio"] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--control-size);
    height: var(--control-size);
    min-width: var(--control-size);
    min-height: var(--control-size);
    margin: 0;
    padding: 0;
    border: var(--control-border-width) solid var(--control-color);
    background: transparent;
    color: var(--control-color);
    cursor: pointer;
    vertical-align: middle;
    flex-shrink: 0;
    position: relative;
    transition: border-color var(--control-transition),
                background-color var(--control-transition);
}

input[type="radio"] {
    border-radius: var(--control-radius-radio);
}

input[type="checkbox"] {
    border-radius: var(--control-radius-checkbox);
}

/* Radio checked — inner dot */
input[type="radio"]::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--control-mark-color);
    transform: translate(-50%, -50%) scale(0);
    transition: transform var(--control-transition);
}

input[type="radio"]:checked::before {
    transform: translate(-50%, -50%) scale(1);
}

/* Checkbox checked — solid circle fill */
input[type="checkbox"]::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--control-mark-color);
    transform: translate(-50%, -50%) scale(0);
    transition: transform var(--control-transition);
}

input[type="checkbox"]:checked::before {
    transform: translate(-50%, -50%) scale(1);
}

/* Focus-visible — accessible keyboard ring */
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: var(--control-focus-ring-width) solid var(--control-focus-ring-color);
    outline-offset: var(--control-focus-ring-offset);
}

/* Hover — desktop only */
@media (hover: hover) {
    input[type="checkbox"]:hover,
    input[type="radio"]:hover {
        opacity: 0.75;
    }
}

/* Disabled */
input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    input[type="checkbox"],
    input[type="radio"],
    input[type="checkbox"]::before,
    input[type="radio"]::before {
        transition-duration: 0ms;
    }
}

/* Elementor — specificity overrides for sizing */
.elementor-field-type-checkbox input[type="checkbox"],
.elementor-field-type-radio input[type="radio"],
.elementor-field-subgroup input[type="checkbox"],
.elementor-field-subgroup input[type="radio"] {
    width: var(--control-size);
    height: var(--control-size);
    min-width: var(--control-size);
    min-height: var(--control-size);
    flex: 0 0 auto;
}

/* Elementor — option layout (input + label) */
.elementor-field-subgroup .elementor-field-option {
    display: flex;
    align-items: center;
    gap: var(--control-gap);
}

/* Elementor — option group spacing */
.elementor-field-subgroup {
    gap: var(--control-group-gap);
}

/* Elementor — label typography */
.elementor-field-subgroup .elementor-field-option label {
    margin: 0;
    font-family: var(--bodyFont);
    font-size: var(--body-body-sm);
    font-weight: 400;
    line-height: var(--line-body-sm);
    cursor: pointer;
}

/* Contact Form 7 — option layout */
.wpcf7-list-item label {
    display: inline-flex;
    align-items: center;
    gap: var(--control-gap);
    font-family: var(--bodyFont);
    font-size: var(--body-body-sm);
    font-weight: 400;
    line-height: var(--line-body-sm);
    cursor: pointer;
}

.wpcf7-checkbox .wpcf7-list-item,
.wpcf7-radio .wpcf7-list-item {
    margin: 0 var(--control-group-gap) 0 0;
}

/* Gravity Forms — option layout */
.gfield_checkbox li label,
.gfield_radio li label {
    display: inline-flex;
    align-items: center;
    gap: var(--control-gap);
    font-family: var(--bodyFont);
    font-size: var(--body-body-sm);
    font-weight: 400;
    line-height: var(--line-body-sm);
    cursor: pointer;
}

.gfield_checkbox li,
.gfield_radio li {
    margin-bottom: var(--control-group-gap);
}

.gfield_checkbox li:last-child,
.gfield_radio li:last-child {
    margin-bottom: 0;
}


/* Loading Screen Overlay — home page only
--------------------------------------------- */
.victo-loader {
    position: fixed;
    inset: 0;
    z-index: 999999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-default, #ffffff);
    transition: opacity 2s cubic-bezier(0.4, 0, 0.2, 1);
}

.victo-loader.is-done {
    opacity: 0;
    pointer-events: none;
}

.victo-loader .victo-tagline {
    position: absolute;
    margin: 0;
    padding: 0 24px;
    max-width: 90vw;
    text-align: center;
    color: var(--grey-g300, #96a5a3);
    font-family: var(--titleFont);
    font-size: calc(var(--heading-display) * 1.32);
    font-weight: 400;
    line-height: 1.05;
    opacity: 1;
    pointer-events: none;
}

.victo-loader .victo-tagline__line {
    display: block;
    white-space: nowrap;
    transform: translateY(0);
    opacity: 0;
    transition:
        transform 1.946s cubic-bezier(0.22, 1, 0.36, 1) 0.1s,
        opacity 1.06s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
    will-change: transform, opacity;
}

.victo-loader .victo-tagline__line--top {
    transform: translateY(-120vh);
}

.victo-loader .victo-tagline__line--bottom {
    transform: translateY(120vh);
}

.victo-logo {
    transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.victo-loader.phase-wordmark .victo-logo {
    opacity: 0;
}

.victo-loader.phase-wordmark .victo-tagline__line {
    transform: none;
    opacity: 1;
}

html.victo-loader-active {
    overflow: hidden;
}

@media (max-width: 767px) {
    .victo-loader .victo-tagline {
        font-size: calc(var(--heading-h3) * 1.1);
    }
}

@media (min-width: 768px) {
    .victo-loader .victo-tagline {
        display: flex;
        flex-wrap: nowrap;
        align-items: baseline;
        justify-content: center;
        gap: 0.28em;
        max-width: none;
        white-space: nowrap;
    }

    .victo-loader .victo-tagline__line {
        display: inline-block;
    }

    .victo-loader .victo-tagline__line--top {
        transform: translateX(-120vw);
    }

    .victo-loader .victo-tagline__line--bottom {
        transform: translateX(120vw);
    }
}


/* Logo Animation
--------------------------------------------- */
.victo-logo {
    --victo-color: var(--grey-g300, #96a5a3);
    --victo-bg: var(--bg-default, #ffffff);
    --victo-size: 158px;
    --victo-duration: 1;

    display: block;
    width: var(--victo-size);
    height: var(--victo-size);
    overflow: visible;
}

@media (max-width: 767px) {
    .victo-logo {
        --victo-size: 106px;
    }
}

.victo-logo .v-outer,
.victo-logo .v-inner { opacity: 1; }
.victo-logo .v-stroke { display: none; }
.victo-logo .v-outer-group,
.victo-logo .v-inner-group {
    opacity: 1;
    transform: none;
    transform-origin: 50% 50%;
    will-change: transform;
    backface-visibility: hidden;
}

.victo-logo .v-outer { fill: var(--victo-color); }
.victo-logo .v-inner { fill: var(--victo-bg); }

.victo-logo.play .v-outer,
.victo-logo.play .v-inner { opacity: 0; }

.victo-logo.play .v-stroke {
    display: block;
    fill: none;
    stroke: var(--victo-color);
    stroke-width: 0.4;
    stroke-linejoin: miter;
    stroke-linecap: square;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
}

.victo-logo.play .v-outer-group {
    transform-origin: 50% 50%;
    transform: translate3d(0, 0, 0) rotate(-45deg);
    opacity: 0;
    animation:
        victo-rot-cw calc(1.4s / var(--victo-duration)) cubic-bezier(.3, .1, .2, 1) calc(0.1s / var(--victo-duration)) forwards;
}

.victo-logo.play .v-inner-group {
    transform-origin: 50% 50%;
    transform: translate3d(0, 0, 0) rotate(45deg);
    opacity: 0;
    animation:
        victo-rot-ccw calc(1.4s / var(--victo-duration)) cubic-bezier(.3, .1, .2, 1) calc(0.1s / var(--victo-duration)) forwards;
}

.victo-logo.play .v-stroke {
    animation:
        victo-draw calc(1.2s / var(--victo-duration)) cubic-bezier(.5, 0, .2, 1) calc(0.2s / var(--victo-duration)) forwards;
}

.victo-logo.play .v-outer,
.victo-logo.play .v-inner {
    animation:
        victo-fill calc(0.7s / var(--victo-duration)) cubic-bezier(.4, 0, .2, 1) calc(1.5s / var(--victo-duration)) forwards;
}

@keyframes victo-draw    { to { stroke-dashoffset: 0; } }
@keyframes victo-fill    { from { opacity: 0; } to { opacity: 1; } }
@keyframes victo-rot-cw  {
    0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(-45deg); }
    20%  { opacity: 1; }
    100% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg); }
}
@keyframes victo-rot-ccw {
    0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(45deg); }
    20%  { opacity: 1; }
    100% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
    .victo-loader {
        display: none;
    }
}


/* Mobile Menu Overlay
--------------------------------------------- */
.victo-mobile-menu {
    position: fixed;
    inset: 0;
    z-index: 998;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--dark-b300) 90%, transparent);
    opacity: 0;
    visibility: hidden;
    transition: opacity 400ms cubic-bezier(0.25, 0.1, 0.25, 1),
                visibility 0s linear 400ms;
}

.victo-mobile-menu.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 400ms cubic-bezier(0.25, 0.1, 0.25, 1),
                visibility 0s linear 0s;
}

html.victo-menu-open {
    overflow: hidden;
}

.victo-mobile-menu__nav {
    text-align: center;
}

.victo-mobile-menu__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}

.victo-mobile-menu__list .menu-item {
    opacity: 0;
    transform: translateY(-4px);
}

.victo-mobile-menu.is-open .menu-item {
    animation: victo-menu-item-in 400ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
    animation-delay: calc(var(--item-index, 0) * 80ms + 200ms);
}

.victo-mobile-menu__list .menu-item a {
    position: relative;
    display: inline-block;
    font-family: var(--titleFont);
    font-size: var(--heading-display);
    font-weight: 400;
    line-height: 1.5;
    color: var(--grey-g300);
    text-decoration: none;
    transition: color 200ms ease;
}

.victo-mobile-menu__list .menu-item a::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0.15em;
    width: 0;
    height: 1px;
    background: currentColor;
    transform: translateX(-50%);
    transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);
    pointer-events: none;
}

.victo-mobile-menu__list .menu-item a:hover,
.victo-mobile-menu__list .menu-item a:focus-visible {
    color: var(--white);
}

.victo-mobile-menu__list .menu-item a:hover::after,
.victo-mobile-menu__list .menu-item a:focus-visible::after {
    width: 100%;
}

@keyframes victo-menu-item-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .victo-mobile-menu {
        transition: none;
    }
    .victo-mobile-menu.is-open .menu-item {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* Victo Map — [victo-map]
--------------------------------------------- */
.victo-map {
    position: relative;
    width: 100%;
    aspect-ratio: 855 / 500;
    min-height: 500px;
    overflow: hidden;
    background: #e7f3f1;
}
.victo-map .mapboxgl-canvas { outline: none; }
.victo-map .mapboxgl-ctrl-attrib { font-size: 10px; }

@media (max-width: 767px) {
    .victo-map {
        min-height: 380px;
    }
}


/* Project Listing — [project-listing]
--------------------------------------------- */
:root {
    --listing-cols: 4;
    --listing-gap:  var(--project-card-gap);
}

.project-listing {
    width: 100%;
}

.project-listing__filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cp-2xs);
    margin-bottom: var(--cp-m);
}

.project-listing__filters-label {
    color: var(--dark-b300);
    margin-right: var(--cp-2xs);
    text-transform: none;
    letter-spacing: 0;
}

a.project-listing__filter,
.project-listing__filter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--dark-b300);
    color: var(--dark-b300);
    border-radius: var(--radius-full);
    padding: 10px 16px;
    font-family: inherit;
    font-size: 10px;
    line-height: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    box-shadow: none;
    transition: color 200ms var(--project-card-ease), border-color 200ms var(--project-card-ease);
}

a.project-listing__filter:hover,
a.project-listing__filter:focus,
a.project-listing__filter:focus-visible,
a.project-listing__filter.is-active,
.project-listing__filter:hover,
.project-listing__filter:focus-visible,
.project-listing__filter.is-active {
    background: var(--dark-b300);
    border-color: var(--dark-b300);
    color: var(--white);
    text-decoration: none;
    outline: none;
}

.project-listing__grid {
    display: grid;
    grid-template-columns: repeat(var(--listing-cols), 1fr);
    gap: var(--listing-gap);
}

.project-listing__grid .project-card {
    aspect-ratio: 305 / 421;
    opacity: 0;
    transform: translateY(24px);
    transition:
        opacity 700ms var(--project-card-ease),
        transform 700ms var(--project-card-ease);
}

.project-listing__grid .project-card.is-revealed {
    opacity: 1;
    transform: translateY(0);
    transition-delay: calc(var(--reveal-i, 0) * 80ms);
}

.project-listing__grid .project-card.is-wide {
    grid-column: span 2;
    aspect-ratio: 630 / 421;
}

.project-listing__grid .project-card.is-hidden {
    display: none;
}

/* Unlinked card (card_link_type = none): no hover state, no pointer. */
.project-card.project-card--static {
    pointer-events: none;
    cursor: default;
}

@media (prefers-reduced-motion: reduce) {
    .project-listing__grid .project-card {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

.project-listing__load-more {
    display: flex;
    justify-content: center;
    margin-top: var(--cp-xl);
}

.project-listing__load-more .elementor-button-content-wrapper {
    flex-direction: row-reverse;
}


@media (max-width: 1280px) and (min-width:900px) {  
	.project-listing__grid .project-card {
		aspect-ratio: 305 / 340;
	}
	.project-listing__grid .project-card.is-wide {
		aspect-ratio: 787 / 421;
	}
}


@media (max-width: 767px) {
    :root { --listing-cols: 2; }
    .project-listing__grid .project-card,
    .project-listing__grid .project-card.is-wide {
        grid-column: auto;
        aspect-ratio: 1 / 1;
        min-height: 360px;
    }
    .project-listing__grid .project-card.is-wide {
        grid-column: span 2;
    }
}

@media (max-width: 480px) {
    :root { --listing-cols: 1; }
    .project-listing__grid .project-card,
    .project-listing__grid .project-card.is-wide {
        aspect-ratio: unset;
        min-height: 480px;
    }
    .project-listing__grid .project-card.is-wide {
        grid-column: span 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    .project-listing__filter {
        transition-duration: 0ms;
    }
}


a.victo-mobile-menu__close {
    display: none !important;
}

/* History Carousel — Elementor widget "victo-history-carousel"
   ------------------------------------------------------------------
   Layout model (desktop, from Figma 4152:1087):
     [heading col: indent 192px] [text 410px] [gap 64] [image 404x622] | [gap 64] [next slide…]
   The heading is fixed at the top-left of the stage; the track (slides)
   starts after --vh-indent. Following slides overflow to the right and are
   clipped at the *viewport* edge via --vh-bleed-right (set by JS). Slides
   before the active one fade out so they don't pass under the heading. */
:root {
    --vh-indent:     var(--size-48);  /* 192 — Figma sp-y-lrg */
    --vh-heading-w:  500px; /* 390 in Figma; +10 so TT Hoves wraps after "Australian" */
    --vh-text-w:     410px;
    --vh-img-w:      404px;
    --vh-img-ratio:  404 / 622;
    --vh-gap:        var(--cp-2xl);   /* 64 — text ↔ image */
    --vh-slide-gap:  var(--cp-2xl);   /* 64 — between slides */
    --vh-era-size:   4.5rem;          /* 72 */
    --vh-rule-pad:   var(--cp-xl);    /* 48 */
    --vh-nav-gap:    var(--size-8);   /* 32 — image ↔ nav */
    --vh-ease:       cubic-bezier(0.22, 1, 0.36, 1); /* expo-out: track travel */
    --vh-ease-soft:  cubic-bezier(0.4, 0, 0.2, 1);   /* fades, dims */
    --vh-dur:        900ms;
    --vh-dim:        0.55;  /* upcoming (peeking) slides */
}

@media (max-width: 1440px) {
    :root {
        --vh-indent:    var(--size-32); /* 128 */
        --vh-heading-w: 320px;
        --vh-text-w:    320px;
        --vh-img-w:     330px;
        --vh-era-size:  3.5rem;         /* 56 */
    }
}

@media (max-width: 1024px) {
    :root {
        --vh-indent:    var(--size-12); /* 48 */
        --vh-heading-w: 280px;
        --vh-text-w:    260px;
        --vh-img-w:     280px;
        --vh-gap:       var(--size-8);  /* 32 — 48+260+32+280 = 620 fits a 640 container at 768 */
        --vh-era-size:  3rem;           /* 48 */
    }
}

.victo-history {
    --vh-color:      var(--dark-b200);
    --vh-rule-color: var(--vh-color);
    --vh-bleed-right: 0px;
    position: relative;
    width: 100%;
    color: var(--vh-color);
}

/* Clip box: starts at the container's left edge (so slides that have moved
   past are cut there) and stretches to the viewport's right edge (so the
   following slides peek in). overflow-x: clip only — nothing is cut vertically. */
.victo-history__viewport {
    margin-right: calc(-1 * var(--vh-bleed-right));
    overflow-x: clip;
    overflow-y: visible;
}

.victo-history__stage {
    position: relative;
    width: calc(100% - var(--vh-bleed-right));
    padding-left: var(--vh-indent);
}

/* Doubled selectors below out-rank the theme's global h2 / button / img rules
   (`.elementor img { height: auto }`, `.elementor h2`, button resets). */
.victo-history .victo-history__heading {
    position: absolute;
    z-index: 1;
    top: 0;
    left: 0;
    width: var(--vh-heading-w);
    margin: 0;
    font-family: var(--titleFont);
    font-size:   var(--heading-h2);
    font-weight: 400;
    line-height: var(--line-h2);
    letter-spacing: 0;
    color: var(--vh-color);
}

.victo-history__track {
    display: flex;
    align-items: flex-end;
    gap: var(--vh-slide-gap);
    width: max-content;
    transition: transform var(--vh-dur) var(--vh-ease);
    will-change: transform;
    touch-action: pan-y; /* see js/victo-swipe.js */
    cursor: grab;
}

.victo-history__track.is-dragging {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}

.victo-history__track img { -webkit-user-drag: none; }

/* Slide states — active: full; upcoming: dimmed, image a touch small, copy a
   touch low; past: fades out and drifts left as the track carries it under the
   heading. The image and copy settle separately so a slide arrives with a
   small stagger instead of one flat opacity swap. */
.victo-history__slide {
    display: flex;
    align-items: flex-end;
    gap: var(--vh-gap);
    flex: 0 0 auto;
    opacity: var(--vh-dim);
    transition:
        opacity   var(--vh-dur) var(--vh-ease-soft),
        transform var(--vh-dur) var(--vh-ease);
}
.victo-history__slide.is-active {
    opacity: 1;
}
.victo-history__slide.is-past {
    opacity: 0;
    transform: translateX(-32px);
    pointer-events: none;
    transition-duration: 550ms, var(--vh-dur);
}

.victo-history__text {
    display: flex;
    flex-direction: column;
    gap: var(--cp-m);
    width: var(--vh-text-w);
}

.victo-history .victo-history__text .victo-history__era {
    margin: 0; /* out-ranks the global <p> margin */
    padding-top: var(--vh-rule-pad);
    border-top: 1px solid var(--vh-rule-color);
    font-family: var(--titleFont);
    font-size: var(--vh-era-size);
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--vh-color);
}

.victo-history__desc {
    max-width: 380px;
    font-family: var(--bodyFont);
    font-size: var(--body-body-md);
    line-height: var(--line-body-md);
    color: var(--vh-color);
}

/* The copy settles into place a beat after the slide lands. (The era keeps
   still: it carries the divider rule, which must stay level across slides.) */
.victo-history__desc {
    transform: translateY(0px);
    transition: transform var(--vh-dur) var(--vh-ease);
}
.victo-history__slide.is-active .victo-history__desc { transform: translateY(0); transition-delay: 120ms; }
.victo-history .victo-history__desc p { margin: 0; }
.victo-history .victo-history__desc p + p { margin-top: 0.75em; }

.victo-history__media {
    flex: 0 0 var(--vh-img-w);
    width: var(--vh-img-w);
    aspect-ratio: var(--vh-img-ratio);
    border-radius: var(--radius-l);
    overflow: hidden;
    background: var(--grey-g75);
    /* Safari: a luminosity-blended child is composited against the nearest
       stacking context. Without one here WebKit blends it straight into the
       page and ignores the slide's opacity transition, so the image never fades.
       The box is already opaque grey, so isolating it changes nothing visually
       but lets the whole box fade as one layer. */
    isolation: isolate;
    transform: scale(0.965);
    transform-origin: 50% 100%;
    transition: transform var(--vh-dur) var(--vh-ease);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
.victo-history__slide.is-active .victo-history__media { transform: scale(1); }

.victo-history .victo-history__img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
    border-radius: 0;
}

.victo-history.is-luminosity .victo-history__img {
    mix-blend-mode: luminosity;
}

/* Nav: arrows + dots, centred under the image column of the active slide.
   Sizes are Figma (21.6 / 15 / gap 10) scaled up 20%. */
.victo-history__nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    width: var(--vh-img-w);
    margin-left: calc(var(--vh-indent) + var(--vh-text-w) + var(--vh-gap));
    margin-top: var(--vh-nav-gap);
    color: var(--vh-color);
}

.victo-history .victo-history__nav .victo-history__arrow,
.victo-history .victo-history__nav .victo-history__dot {
    all: unset; /* drop the theme's global <button> pill styling */
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    margin: 0;
    color: inherit;
    line-height: 1;
    cursor: pointer;
    transition: opacity 300ms var(--vh-ease-soft), transform 300ms var(--vh-ease-soft);
}
.victo-history .victo-history__nav .victo-history__arrow { font-size: 26px; }
.victo-history .victo-history__nav .victo-history__arrow:disabled { opacity: 0.3; cursor: default; }
.victo-history .victo-history__nav .victo-history__arrow:not(:disabled):hover { opacity: 0.6; }
.victo-history .victo-history__nav .victo-history__arrow:focus-visible,
.victo-history .victo-history__nav .victo-history__dot:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; }

.victo-history__dots {
    display: flex;
    align-items: center;
    gap: 12px;
}
.victo-history .victo-history__nav .victo-history__dot { font-size: 18px; opacity: 0.55; }
.victo-history .victo-history__nav .victo-history__dot:hover,
.victo-history .victo-history__nav .victo-history__dot.is-active { opacity: 1; }
.victo-history .victo-history__nav .victo-history__dot.is-active { transform: scale(1.1); }
.victo-history__dot .victo-history__dot-on  { display: none; }
.victo-history__dot.is-active .victo-history__dot-on  { display: inline-block; }
.victo-history__dot.is-active .victo-history__dot-off { display: none; }
.victo-history__nav svg { width: 1em; height: 1em; }
.victo-history__nav i { font-style: normal; }

/* Mobile: heading in flow, slides stack image-over-text, one slide per view.
   The track becomes a grid with 100%-wide columns (like .project-carousel):
   a percentage column resolves against the stage, and the image height then
   follows from a definite width. The desktop flex/max-content track + a
   percentage-width aspect-ratio image made Chrome under-report the widget's
   height during flex intrinsic sizing, so the Elementor wrapper came out ~96px
   short and the nav painted underneath the next section. */
@media (max-width: 767px) {
    .victo-history {
        --vh-indent: 0px;
        --vh-era-size: 2rem;  /* 32 */
        --vh-rule-pad: 12px;
    }
    .victo-history__viewport { margin-right: 0; } /* no peek on mobile */
    .victo-history__stage { width: 100%; padding-left: 0; }
    /* Whole widget is budgeted to fit one phone screen (~560px on a 390-wide
       phone): h4-size heading, 4:3 image capped to a share of the small
       viewport height, tighter rhythm. */
    .victo-history .victo-history__heading {
        position: static;
        width: auto;
        max-width: 22rem;
        margin-bottom: var(--cp-m);
        font-size: var(--heading-h4); /* 22 */
        line-height: 1.3;
    }
    .victo-history__track {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 100%;
        align-items: start;
        gap: var(--cp-l);
        width: 100%;
    }
    .victo-history__slide {
        flex-direction: column;
        align-items: stretch;
        gap: 16px;
        width: auto;
        min-width: 0;
    }
    .victo-history__text { width: auto; gap: 12px; }
    .victo-history .victo-history__text .victo-history__era { line-height: 1.1; }
    .victo-history__desc { max-width: none; }
    .victo-history__media {
        order: -1; /* image above the text */
        flex: 0 0 auto;
        width: 100%;
        max-width: none;
        height: auto;
        aspect-ratio: 4 / 3;
        max-height: 34vh;  /* short phones (SE): cap the image so the copy stays on screen */
        max-height: 34svh; /* Safari 15.4+: small viewport, i.e. with the toolbars shown */
    }
    .victo-history__nav {
        width: auto;
        margin-left: 0;
        margin-top: 12px;
        justify-content: flex-start;
    }
}

@media (prefers-reduced-motion: reduce) {
    .victo-history__track,
    .victo-history__slide,
    .victo-history__media,
    .victo-history__desc,
    .victo-history .victo-history__nav .victo-history__arrow,
    .victo-history .victo-history__nav .victo-history__dot { transition-duration: 0ms; transition-delay: 0ms; }
    .victo-history__slide.is-past { transform: none; }
    .victo-history__media { transform: none; }
    .victo-history__desc { transform: none; }
}



@media all and (max-width:767px){
	.cta-description p {
		font-size: 16px !important;
		line-height: 24px !important;
		text-wrap: pretty;
	}
	.cta-heading h2 {
		font-size: 28px !important;
		text-wrap: pretty;
	}
}