/* Reset and Base Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'Quicksand', sans-serif;
    color: #333;
    line-height: 1.6;
    overflow-x: hidden;
}

h1, h2, h3 {
    font-family: 'Lora', serif;
}

/* ============================================================
   SIDE NAVIGATION
   Shared component with the home page (styles.css/script.js) — same
   frosted-glass collapsed pill, hover-expand, and clip-path color-matching.
   The only difference: a single "Back" link stands in for the home page's
   in-page nav-links / mobile menu.
   ============================================================ */
.side-nav {
    position: fixed;
    top: 2rem;
    left: 2.5rem; /* 40px page margin */
    z-index: 1000;
    display: flex;
    flex-direction: column;
    background: transparent;
    padding: 24px 12px 12px 12px; /* 24px top, 12px right, 12px bottom, 12px left */
    border-radius: 8px;
    transition: all 0.3s ease;
}

.side-nav:hover {
    background: transparent;
}

/* Nav color variants */
.side-nav.light {
    color: white;
}

.side-nav.dark {
    color: #056AE0;
}

.side-nav.dark .nav-text {
    color: #2D2D2D;
}

.side-nav.dark .brand-text {
    color: #2D2D2D;
}

.nav-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 32px;
    font-weight: 500;
    font-size: 32px;
    white-space: nowrap;
    overflow: hidden;
    color: inherit;
    text-decoration: none;
    padding: 4px 8px; /* 4px vertical, 8px horizontal */
    border-radius: 6px;
    transition: all 0.3s ease;
}

.nav-brand:hover {
    background: transparent; /* No hover state for brand */
}

.side-nav.dark .nav-brand:hover {
    background: transparent; /* No hover state for brand */
}

.brand-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.brand-text {
    opacity: 0;
    transition: opacity 0.3s ease;
    width: 0;
    overflow: hidden;
    white-space: nowrap;
}

.side-nav:hover .brand-text {
    opacity: 1;
    width: auto;
}

/* Mobile/tablet-only clone of .nav-brand's own icon+text, used for its section-matched
   color switching there (see the ≤1024px override, and project-script.js) — desktop
   doesn't need it, since it already gets the same smooth switching for free via the
   whole-nav .nav-overlay clone, which still contains its own copy of .nav-brand. */
.brand-overlay {
    display: none;
}

.nav-links {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0; /* No gap in collapsed state */
    color: inherit;
    text-decoration: none;
    font-size: 24px;
    font-weight: 400;
    padding: 4px 8px; /* 4px vertical, 8px horizontal */
    border-radius: 8px;
    transition: all 0.3s ease;
    white-space: nowrap;
    overflow: visible;
    position: relative;
    width: fit-content; /* Hug content in collapsed state */
}

/* When nav is expanded (hovered), add gap; hug icon + label (8px left / 16px right)
   instead of filling the nav container */
.side-nav:hover .nav-link {
    gap: 12px;
    width: fit-content;
    padding: 4px 16px 4px 8px;
}

.nav-link:hover {
    background: #0B60E0;
}

.side-nav.dark .nav-link:hover {
    background: #F4F4F4;
}

/* Base nav is pinned .dark, but each link's hover pill still needs to read as the "white
   nav on blue" color whenever the clip-path overlay's white layer is the one currently
   visible *at that link's own position* — checked per link (see the nav color-switching
   IIFE in project-script.js, which toggles this class on each .nav-link every frame)
   rather than once for the whole nav, since the blue/white boundary can cross through the
   middle of the nav itself instead of sitting cleanly above or below it. #sideNav (ID)
   beats .side-nav.dark .nav-link:hover's class-only specificity. */
#sideNav .nav-link.link-over-blue:hover {
    background: #0B60E0;
}

.side-nav:hover .nav-link.active {
    width: fit-content;
}

/* Selection reads via the underline only — no pill fill or inset shadow. (Currently
   unused on project pages: the single "Back" link never gets .active, since there's no
   in-page section for it to track — kept identical to the home page for consistency,
   in case that ever changes.) */
.nav-link.active {
    background: transparent;
}

.side-nav.dark .nav-link.active {
    background: transparent;
}

/* Underline: 2px thick, flush against the nav element, rounded caps */
.nav-link.active::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    margin-top: 0px;
    height: 2px;
    border-radius: 999px;
    background: white; /* light nav (white text) */
}

.side-nav.dark .nav-link.active::after {
    background: #056AE0; /* dark nav (primary blue text) */
}

/* An active link is already communicated by its underline — a hover pill on top of it
   is redundant/conflicting. !important because several context-specific hover rules
   (.dark, .link-over-blue) all need to be overridden uniformly. */
.nav-link.active:hover {
    background: transparent !important;
}

.nav-link.active .nav-text {
    font-weight: 500;
}

.nav-icon {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    /* Icon sits in a 40x40 container */
    padding: 8px;
    box-sizing: content-box;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

/* Hide all icon variations by default */
.nav-icon svg,
.brand-icon svg {
    position: absolute;
    display: none;
}

/* .brand-icon has no padding, so its content box and padding box are the same size —
   percentage sizing (against a positioned ancestor's padding box, per spec, for an
   absolutely positioned child) safely scales the icon 1:1 with the container, matching it
   across breakpoints (40x40 desktop, 30x30 tablet/mobile) without hardcoding either value
   here. */
.brand-icon svg {
    width: 100%;
    height: 100%;
}

/* .nav-icon, unlike .brand-icon, keeps an 8px padding at desktop — sized explicitly to its
   24x24 content box instead of width:100%, which would resolve against the padding box
   (40x40) and render the Back icon visibly oversized. .nav-icon's own content box stays
   24x24 at every breakpoint here (only its padding changes, see the ≤1024px override),
   so this one declaration covers desktop, tablet, and mobile alike. */
.nav-icon svg {
    width: 24px;
    height: 24px;
}

/* Show blue icons on dark nav (light backgrounds) by default */
.side-nav.dark .nav-icon .icon-blue,
.side-nav.dark .brand-icon .icon-blue {
    display: block;
}

/* Show white icons on light nav (dark backgrounds) by default */
.side-nav.light .nav-icon .icon-white,
.side-nav.light .brand-icon .icon-white {
    display: block;
}

/* Show blue selected icons when active on dark nav */
.side-nav.dark .nav-link.active .nav-icon .icon-blue {
    display: none;
}

.side-nav.dark .nav-link.active .nav-icon .icon-blue-selected {
    display: block;
}

/* Show white selected icons when active on light nav */
.side-nav.light .nav-link.active .nav-icon .icon-white {
    display: none;
}

.side-nav.light .nav-link.active .nav-icon .icon-white-selected {
    display: block;
}

.nav-text {
    opacity: 0;
    transition: opacity 0.3s ease;
    color: inherit;
    width: 0;
    overflow: hidden;
}

.side-nav:hover .nav-text {
    opacity: 1;
    width: auto;
}

/* --- Nav color switching via clip-path ---
   Duplicated verbatim from the home page (styles.css/script.js), which is confirmed
   working — an earlier project-page-specific variant of this (different hover-expand
   width mechanics, JS-driven hover mirroring) diverged just enough to hit an unresolved
   bug, so this reuses the exact same CSS/JS pattern rather than parallel-maintaining a
   variant. Two full copies of the nav sit stacked at the identical fixed position: the
   real, interactive "base" copy (#sideNav, permanently .dark/blue) always renders; a
   decorative "overlay" clone (permanently .light/white, inserted by project-script.js)
   sits on top, clipped with a live clip-path to only show over the page's blue region.
   Where the overlay is visible it fully repaints over the base copy beneath it, giving a
   hard, pixel-accurate split instead of a class-based swap. Both copies get all their
   color (text, icons, hover pill) from the ordinary .dark/.light rules above — each
   copy's class is just pinned rather than scroll-driven.
   Unlike the home page, project pages have no separate mobile hamburger-menu nav state
   (just minor position tweaks at narrow widths, see the @media blocks below), so this
   runs at all viewport widths — no breakpoint gating needed. */
.nav-overlay {
    pointer-events: none;
    /* Fully visible by default, matching the top of the hero (blue, white nav needed) —
       safe if the geometry script can't run. JS clips this from the bottom once it
       measures the real split. */
    clip-path: inset(0px 0px 0px 0px);
    /* .side-nav sets `transition: all 0.3s ease` for its hover expand/collapse
       animation. The overlay is a clone, so it inherits that — which would silently
       ease every clip-path update over 300ms. This needs to be a hard, instant split. */
    transition: none;
    /* .side-nav never sets align-items, so its flex children (.nav-brand, .nav-links)
       default to align-items: stretch — trying to fill .side-nav's own width, while
       .side-nav's width is itself computed via shrink-to-fit based on those same
       children. That circular dependency is what was clipping "Back"/"Tanner" mid-word
       on hover: browsers resolve it correctly for the original, parse-time DOM (base)
       but not reliably for a JS-cloned subtree inserted after the fact (overlay).
       Forcing flex-start here breaks the circularity for the overlay specifically,
       without touching base's (already-working) layout. */
    align-items: flex-start;
}

.nav-overlay[aria-hidden] * {
    pointer-events: none;
}

/* Base nav's real :hover expands it; mirror that onto the overlay (which can never
   receive a genuine :hover of its own, since pointer-events is off) via :has() rather
   than duplicating the hover state in JS. */
body:has(#sideNav:hover) .nav-overlay .nav-link {
    gap: 12px;
    width: fit-content;
    padding: 4px 16px 4px 8px;
}

body:has(#sideNav:hover) .nav-overlay .nav-text {
    opacity: 1;
    width: auto;
}

body:has(#sideNav:hover) .nav-overlay .brand-text {
    opacity: 1;
    width: auto;
}

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

.hero-section {
    background: white;
    min-height: 50vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4rem 0 2rem;
    position: relative;
    overflow: hidden;
}

.hero-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.hero-content {
    position: relative;
    z-index: 1;
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    padding-left: 12.5rem;
}

.hero-image {
    width: 100%;
}

.hero-image img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0, 10, 20, 0.15);
}

/* ============================================================
   Title Section
   ============================================================ */

.title-section {
    background: white;
    padding: 3rem 2rem 2rem;
}

.title-section .section-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0;
}

.project-title {
    font-size: 3rem;
    color: #2d2d2d;
    font-weight: 400;
    margin: 0;
}

.project-subtitle {
    font-size: 1.5rem; /* 24px */
    color: #74767E;
    font-weight: 400;
    margin-top: 0.5rem;
}

/* Gold underline accent — sits below subtitle (or title if no subtitle present) */
.project-subtitle::after,
.project-title:not(:has(~ .project-subtitle))::after {
    content: '';
    display: block;
    width: 7.5rem; /* 120px */
    height: 2px;
    background: #F5A623;
    margin-top: 1rem;
}

/* Phase heading — optional, for multi-phase project pages */
.phase-title {
    font-family: 'Lora', serif;
    font-size: 2rem;
    font-weight: 400;
    color: #2D2D2D;
    margin-bottom: 0.25rem;
}

.phase-date {
    font-family: 'Quicksand', sans-serif;
    font-size: 1.25rem;
    font-weight: 400;
    color: #74767E;
    display: block;
    margin-bottom: 1.5rem;
}

/* ============================================================
   Project Meta (Role / Timeline / Impact)
   Sits inside the title section's own .section-container, right after
   the subtitle, so it inherits the title's alignment automatically.
   ============================================================ */

.project-meta {
    margin-top: 5rem; /* 80px below the gold underline */
    display: flex;
    flex-direction: column;
    gap: 2.5rem; /* 40px between Role/Timeline row and Impact row */
}

.meta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 2.5rem; /* 40px between Role and Timeline */
}

.meta-item {
    display: grid;
    grid-template-columns: 40px 1fr;
    gap: 1.5rem; /* 24px between the icon column and its text */
    align-items: start;
}

.meta-icon {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    margin-top: 6px;
    display: block;
    justify-self: center;
}

.meta-content {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-width: 34rem;
}

.meta-row--impact .meta-content {
    max-width: none;
}

.meta-label {
    font-family: 'Quicksand', sans-serif;
    font-size: 1.25rem;
    font-weight: 500;
    color: #2D2D2D;
}

.meta-value {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    line-height: 1.8;
    color: #74767E;
}

/* ============================================================
   Content Sections
   ============================================================ */

.content-section {
    background: white;
    padding: 1rem;
}

.section-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem 0;
    padding-left: 12.5rem;
}

.section-title {
    font-size: 2rem;
    margin-bottom: 2rem;
    color: #2d2d2d;
    font-weight: 400;
}

.section-text {
    font-size: 1rem;
    line-height: 1.8;
    color: #555;
    margin-bottom: 1.5rem;
}

.section-text:last-child {
    margin-bottom: 0;
}

/* ============================================================
   Pull Quote
   ============================================================ */

.pull-quote {
    border-left: 2px solid #F5A623;
    margin: 2.5rem 0 2.5rem 2.5rem; /* 40px left margin indents the border */
    padding: 0 2.5rem 0 0.75rem; /* 40px right, 12px between border and text */
}

.pull-quote p {
    font-family: 'Quicksand', sans-serif;
    font-size: 1.25rem; /* 20px */
    font-style: italic;
    color: #2D2D2D;
    line-height: 1.7;
    margin: 0;
}

.pull-quote cite {
    display: block;
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem; /* 16px */
    font-style: normal;
    color: #74767E;
    margin-top: 0.75rem;
}

/* ============================================================
   Two-column text + image layout
   ============================================================ */

.two-col {
    display: grid;
    grid-template-columns: 1fr 40%;
    gap: 3rem;
    align-items: start;
    margin: 2.5rem 0;
}

/* Reverse variant: image left, text right */
.two-col.two-col--reverse {
    grid-template-columns: 40% 1fr;
}

.two-col--reverse .two-col-image {
    order: -1;
}

.two-col-image img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    display: block;
}

/* Remove max-width constraint on text inside two-col */
.two-col .section-text {
    max-width: none;
}

@media (max-width: 768px) {
    .two-col,
    .two-col.two-col--reverse {
        grid-template-columns: 1fr;
    }

    .two-col--reverse .two-col-image {
        order: 0;
    }

    .two-col-image {
        order: 1;
    }
}

/* ============================================================
   Case Study Card
   ============================================================ */

.case-study-card {
    display: grid;
    grid-template-columns: 60% 1fr;
    gap: 3rem;
    align-items: start;
    margin: 2.5rem 0;
}

.case-card-image img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    display: block;
    background: #D9D9D9;
}

.case-card-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
}

.case-card-title {
    font-family: 'Lora', serif;
    font-size: 1.5rem;
    font-weight: 400;
    color: #2D2D2D;
    margin: 0;
}

.case-card-text {
    font-size: 1rem;
    line-height: 1.8;
    color: #555;
    margin: 0;
}

.case-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.meta-tag {
    background: #F4F4F4;
    border-radius: 99px;
    padding: 4px 12px;
    font-size: 0.75rem;
    color: #74767E;
    font-family: 'Quicksand', sans-serif;
    font-weight: 500;
}

.case-card-cta {
    display: inline-block;
    border: 1.5px solid #056AE0;
    color: #056AE0;
    border-radius: 8px;
    padding: 8px 20px;
    font-size: 0.875rem;
    font-family: 'Quicksand', sans-serif;
    font-weight: 500;
    text-decoration: none;
    transition: background 0.2s ease, color 0.2s ease;
}

.case-card-cta:hover {
    background: #056AE0;
    color: white;
}

@media (max-width: 768px) {
    .case-study-card {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   Section List
   ============================================================ */

.section-list {
    list-style: disc;
    padding-left: 1.5rem;
    margin-bottom: 1.5rem;
    color: #555;
}

.section-list li {
    font-size: 1rem;
    line-height: 1.8;
    margin-bottom: 0.5rem;
}

.section-list li:last-child {
    margin-bottom: 0;
}

/* ============================================================
   Full-width Image
   ============================================================ */

.full-width-image {
    margin: 2.5rem 0;
}

.full-width-image img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 8px;
}

/* ============================================================
   Two-column Card pair (equal-width, stacked layout per card)
   ============================================================ */

.two-col-card-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    margin: 2.5rem 0;
}

.two-col-card {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.two-col-card-image img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    display: block;
}

.two-col-card-title {
    font-family: 'Lora', serif;
    font-size: 1.5rem;
    font-weight: 400;
    color: #2D2D2D;
    margin: 0;
}

/* Override .two-col to support equal-width card pair */
.two-col.two-col--equal {
    grid-template-columns: 1fr 1fr;
}

/* ============================================================
   Research Stats Bar
   ============================================================ */

.research-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
    background: #056AE0;
    border-radius: 8px;
    margin: 2.5rem 0;
    overflow: hidden;
}

.research-stat {
    padding: 1.75rem 2rem;
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.research-stat:last-child {
    border-right: none;
}

.research-stat-number {
    font-family: 'Lora', serif;
    font-size: 2.5rem;
    font-weight: 400;
    color: white;
    line-height: 1;
}

.research-stat-label {
    font-family: 'Quicksand', sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.8);
    line-height: 1.4;
}

/* ============================================================
   Stat Metrics Row (large number + orange underline + label)
   Hardcoded text in place of an exported metrics graphic — auto-fit lets it
   reflow naturally at any width instead of needing a fixed breakpoint, so it
   works the same whether a row has 3 or 4 stats.
   ============================================================ */

.stat-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 2.5rem 2rem;
    margin: 2.5rem 0;
}

.stat-metric {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.stat-metric-number {
    font-family: 'Quicksand', sans-serif;
    font-size: 2.75rem;
    font-weight: 500;
    color: #2D2D2D;
    line-height: 1;
    display: inline-block;
    position: relative;
    width: fit-content;
    padding-bottom: 0.5rem;
    margin-bottom: 0.75rem;
}

.stat-metric-number::after {
    content: '';
    position: absolute;
    left: -4px;
    right: -4px;
    bottom: 0;
    height: 3px;
    border-radius: 2px;
    background: #F5A623;
}

.stat-metric-label {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    color: #74767E;
}

@media (max-width: 768px) {
    .research-stats {
        grid-template-columns: 1fr 1fr;
    }

    .research-stat:nth-child(2) {
        border-right: none;
    }

    .research-stat:nth-child(1),
    .research-stat:nth-child(2) {
        border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    }
}

/* ============================================================
   Numbered Findings
   ============================================================ */

.numbered-findings {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    margin: 2.5rem 0;
}

.finding-item {
    display: grid;
    grid-template-columns: 40px 1fr;
    gap: 1.5rem; /* 24px between the number/icon column and its text */
    align-items: start;
}

.finding-icon {
    width: 60px;
    height: 60px;
    flex-shrink: 0;
    display: block;
}

.finding-content {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding-top: 0.25rem;
}

.finding-title {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    color: #2D2D2D;
    line-height: 1.5;
}

.finding-text {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    line-height: 1.8;
    color: #555;
}

/* Numeral variant of .finding-icon — a hardcoded number + orange underline in
   place of an exported image, so the digit is real text (reflows, no image
   request, matches surrounding type). Drop into the same grid slot the
   <img class="finding-icon"> used to occupy. */
.finding-number {
    font-family: 'Quicksand', sans-serif;
    font-size: 1.75rem;
    font-weight: 600;
    color: #2D2D2D;
    line-height: 1;
    display: inline-block;
    position: relative;
    width: fit-content;
    padding-bottom: 0.35rem;
    margin-top: 8px;
    justify-self: center;
}

.finding-number::after {
    content: '';
    position: absolute;
    left: -4px;
    right: -4px;
    bottom: 0;
    height: 3px;
    border-radius: 2px;
    background: #F5A623;
}

/* ============================================================
   Rotating Features List
   ============================================================ */

.rotating-features {
    display: flex;
    flex-direction: column;
    gap: 2rem;
    margin: 2rem 0;
}

.feature-item {
    display: grid;
    grid-template-columns: 40px 1fr;
    gap: 1.5rem; /* 24px between the icon column and its text */
    align-items: start;
}

.feature-icon {
    width: 60px;
    height: 60px;
    flex-shrink: 0;
    display: block;
    justify-self: center;
}

.feature-content {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding-top: 0.25rem;
}

.feature-title {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    color: #2D2D2D;
}

.feature-text {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    line-height: 1.8;
    color: #555;
}


/* ============================================================
   Project Partners / Logos
   ============================================================ */

.project-partners {
    display: flex;
    align-items: center;
    gap: 2rem;
    margin-top: 2rem;
    flex-wrap: wrap;
}

.project-partners img {
    height: 32px;
    width: auto;
    object-fit: contain;
    opacity: 0.7;
}

/* ============================================================
   Three-Column Image Grid (process iterations)
   ============================================================ */

.three-col-images {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.5rem;
    margin: 2.5rem 0;
}

@media (max-width: 768px) {
    .three-col-images {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   Image Placeholders
   ============================================================ */

.img-placeholder {
    background: #D9D9D9;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Quicksand', sans-serif;
    font-size: 0.8rem;
    color: #888;
    text-align: center;
    padding: 1rem;
    width: 100%;
}

.img-placeholder--hero {
    min-height: 380px;
}

.img-placeholder--full {
    min-height: 320px;
}

.img-placeholder--process {
    min-height: 180px;
}

.img-placeholder--card {
    width: 100%;
    aspect-ratio: 12 / 5;
}

/* ============================================================
   Behavior Carousel
   (reusable — pair with the [data-carousel] JS in project-script.js)
   ============================================================ */

.carousel {
    border: 2px solid #1A1D24;
    border-radius: 24px;
    overflow: hidden;
    margin: 2.5rem 0;
    background: #EBF1FF;
}

.carousel-viewport {
    position: relative;
    height: 480px; /* fixed — keeps carousel height consistent regardless of each slide's image aspect ratio */
    padding: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.carousel-slide {
    display: none;
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
}

.carousel-slide.active {
    display: flex;
}

.carousel-slide .img-placeholder {
    background: white;
    border: 1px solid #D9D9D9;
    border-radius: 12px;
    width: 100%;
    height: 100%;
}

.carousel-slide img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
    border-radius: 12px;
}

.carousel-caption {
    background: white;
    border-top: 2px solid #1A1D24;
    padding: 2rem 1.5rem 1.75rem;
}

.carousel-title {
    font-family: 'Quicksand', sans-serif;
    font-size: 1.5rem;
    font-weight: 500;
    color: #2D2D2D;
    margin: 0 0 0.5rem;
}

.carousel-text {
    font-family: 'Quicksand', sans-serif;
    font-size: 1rem;
    line-height: 1.6;
    color: #555;
    margin: 0 0 1.75rem;
    max-width: 900px;
    min-height: 3.2rem; /* reserves space for 2 lines so the caption bar doesn't resize between slides */
}

.carousel-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
}

.carousel-arrow {
    background: none;
    border: none;
    padding: 0.5rem;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #056AE0;
    cursor: pointer;
    transition: opacity 0.2s ease;
}

.carousel-arrow:hover {
    opacity: 0.65;
}

.carousel-dots {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.carousel-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #313A44;
    border: 1.5px solid #313A44;
    padding: 0;
    margin: 0;
    cursor: pointer;
    opacity: 1;
}

.carousel-dot.active {
    background: #F5A623;
    border: 2px solid #313A44;
}

@media (max-width: 768px) {
    .carousel-viewport {
        height: 260px;
        padding: 1.5rem;
    }

    .carousel-caption {
        padding: 1.5rem;
    }

    .carousel-title {
        font-size: 1.4rem;
    }
}

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

.project-footer {
    background: white;
    padding: 3rem 2rem 24px;
    text-align: center;
    color: #666;
    font-size: 0.9rem;
}

.footer-links {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 1rem;
}

.footer-links a {
    color: #056AE0;
    transition: opacity 0.3s ease;
}

.footer-links a:hover {
    opacity: 0.7;
}

/* ============================================================
   MOBILE & TABLET NAV (≤1024px)
   Ported from the home page (styles.css/script.js) for exact visual parity:
   same frosted-glass collapsed pill + separately-floating brand pill, same
   shadow-isolation and clip-path-color-matching techniques. The one
   deliberate difference: there's no hamburger/full-screen-menu state here.
   The home page's collapsed pill opens a menu on tap; this nav holds a
   single "Back" link instead of an in-page menu, so the collapsed pill IS
   that link — tap navigates immediately, there's nothing to open.
   ============================================================ */
@media (max-width: 1024px) {
    :root {
        --nav-edge-offset: 24px;
    }

    /* --- Collapsed pill: just the Back link's icon now — sized to match the
       home page's collapsed hamburger pill exactly (12px padding around a
       24x24 icon = a 48x48 circle). The logo lives in its own separate
       .nav-brand pill (below), no longer stacked inside this one. */
    .side-nav {
        top: var(--nav-edge-offset);
        left: var(--nav-edge-offset);
        width: auto;
        padding: 12px;
        background: rgba(255, 255, 255, 0.15) !important;
        backdrop-filter: blur(12px);
        -webkit-backdrop-filter: blur(12px);
        border-radius: 999px;
        flex-direction: column;
        align-items: flex-start;
        transition: none;
    }

    /* Shadow lives on its own filter-free layer — see the home page's
       identical comment on this rule for why (backdrop-filter + box-shadow
       on the same rounded element is a known Safari rasterization bug). */
    .side-nav::before {
        content: '';
        position: absolute;
        inset: 0;
        border-radius: inherit;
        box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
        z-index: -1;
        pointer-events: none;
    }

    .nav-overlay::before {
        box-shadow: none;
    }

    .side-nav:hover {
        width: auto;
        background: rgba(255, 255, 255, 0.15) !important;
    }

    /* Frosted glass tint follows the same light/dark split the clip-path
       overlay uses for text/icon color, so the pill reads consistently
       instead of nearly disappearing against a background close to its own
       tint color. */
    .side-nav.light {
        background: rgba(5, 106, 224, 0.15) !important;
    }

    .side-nav.dark {
        background: rgba(255, 255, 255, 0.15) !important;
    }

    /* --- Logo pill (separate from the Back-link pill above) ---
       Always visible, always centered. project-script.js (placeNavBrand(),
       called from positionNavBrand()) moves the real element out to a direct
       child of <body> at this breakpoint so it's clear of #sideNav's own
       backdrop-filter — a `position: fixed` descendant nested inside another
       element's backdrop-filter hits a real WebKit bug where its own blur
       samples the wrong backdrop. Moved out to <body>, its top/left resolve
       directly against the real viewport — script.js sets both directly. */
    .nav-brand {
        position: fixed;
        margin-bottom: 0;
        height: 48px;
        padding: 0 16px 0 12px;
        background: rgba(255, 255, 255, 0.15) !important;
        backdrop-filter: blur(12px);
        -webkit-backdrop-filter: blur(12px);
        border-radius: 999px;
        z-index: 1000;
        overflow: visible;
        transition: none;
    }

    .nav-brand::before {
        content: '';
        position: absolute;
        inset: 0;
        border-radius: inherit;
        box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
        z-index: -1;
        pointer-events: none;
    }

    #navBrand .brand-icon {
        width: 30px;
        height: 30px;
    }

    /* #navBrand stays permanently .dark at this breakpoint — same permanent
       pinning as #sideNav itself — with .brand-overlay below doing the
       section-matched color switching instead of toggling this class. */
    #navBrand.dark {
        color: #056AE0;
    }

    #navBrand.dark .brand-text {
        color: #2D2D2D;
    }

    #navBrand.dark .brand-icon .icon-blue {
        display: block;
    }

    #navBrand.dark .brand-icon .icon-white {
        display: none;
    }

    /* .brand-overlay is the same clip-path technique as the whole-nav
       .nav-overlay clone, scoped down to just .nav-brand's own icon+text
       (see project-script.js) — a permanently light (white) clone, clipped
       every scroll frame with the same inset-from-boundary math, for a
       continuous pixel-accurate wipe through the blue/white boundary. */
    .brand-overlay {
        display: flex;
        position: absolute;
        inset: 0;
        align-items: center;
        gap: 12px;
        padding: 0 16px 0 12px;
        pointer-events: none;
    }

    #navBrand .brand-overlay .brand-text {
        color: white;
    }

    #navBrand .brand-overlay .brand-icon .icon-white {
        display: block;
    }

    #navBrand .brand-overlay .brand-icon .icon-blue {
        display: none;
    }

    /* Wordmark stays visible at all times now — no more reveal-on-hover. */
    .brand-text {
        opacity: 1;
        width: auto;
    }

    /* The overlay clone's own copy of .nav-brand would otherwise sit
       permanently visible on top of the real one, now that the real one is
       `position: fixed` and escapes this element's clip-path. The real
       .nav-brand gets its own independent clip (.brand-overlay) instead. */
    .nav-overlay .nav-brand {
        display: none;
    }

    /* --- Collapsed Back link: sized to exactly the icon itself (24x24) —
       #sideNav's own 12px padding is what creates the 48px circle around it,
       not this link's own padding on top of that. No hover-expand text
       reveal here — unlike the home page's in-page links, tapping this
       navigates immediately, so there's nothing gained by revealing the
       label first, and hover isn't a reliable gesture on touch anyway. */
    .nav-links {
        gap: 0;
    }

    .nav-link,
    .side-nav:hover .nav-link {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0;
        width: 24px;
        /* Explicit, not left to content: .nav-text is width:0/opacity:0 here but still an
           in-flow flex item, and its own line-height (inherited from the 24px .nav-link
           font-size, body's line-height:1.6) would otherwise stretch this flex item to
           ~38px tall — leaving #sideNav's pill 48px wide but taller than it is wide,
           instead of the perfect circle the home page's hamburger pill has. */
        height: 24px;
        padding: 0;
        border-radius: 6px;
    }

    .nav-icon {
        padding: 0;
    }

    .nav-text,
    .side-nav:hover .nav-text {
        opacity: 0;
        width: 0;
    }

    /* Subtle hover overlay, matching the home page's hamburger button rather
       than the desktop Back-link's solid fill pill (which would otherwise
       still apply here). */
    .nav-link:hover {
        background: rgba(255, 255, 255, 0.1);
    }

    .side-nav.dark .nav-link:hover {
        background: rgba(30, 111, 217, 0.1);
    }

    #sideNav .nav-link.link-over-blue:hover {
        background: rgba(255, 255, 255, 0.1);
    }
}

/* ============================================================
   Responsive Design
   ============================================================ */

/* Matches the nav's own ≤1024px breakpoint (see MOBILE & TABLET NAV above) — content
   needs to drop its desktop nav-offset padding at the exact width the nav itself collapses
   to the small floating pill, or the 968–1024px range strands the old desktop gutter with
   no expanded nav there to justify it. */
@media (max-width: 1024px) {
    .hero-section {
        min-height: 40vh;
        padding: 3rem 0 1.5rem;
    }

    .hero-content {
        /* Full-width: content now scrolls behind the fixed nav icon instead of being
           pushed clear of it (see the frosted-glass .side-nav rules below, which add a
           blur + shadow so the nav still reads as elevated above content passing
           underneath it), so this just needs a small, even gutter on both sides. */
        padding-left: 1.5rem;
        padding-right: 1.5rem; /* 24px — matches content-section right edge */
    }

    .project-title {
        font-size: 2.5rem;
    }

    .title-section {
        padding: 2rem 1.5rem 1.5rem;
    }

    .content-section {
        padding: 1.5rem; /* 24px on all sides — handles right edge spacing */
    }

    .section-container {
        padding-left: 0;
    }

    .section-title {
        font-size: 1.75rem;
    }

    /* Drop the desktop-only 40px left margin/right padding so the quote's
       border and text line up with the surrounding paragraphs instead of
       sitting narrower than the rest of the content column. */
    .pull-quote {
        margin-left: 0;
        padding-right: 0;
    }
}

@media (max-width: 768px) {
    /* Both nav pills sit 12px from the edge on mobile, vs. 24px on tablet — read by
       the ≤1024px nav rules above, and by project-script.js (positionNavBrand()). */
    :root {
        --nav-edge-offset: 12px;
    }

    /* Wordmark reads large at 32px (inherited from the desktop .nav-brand rule)
       against a 30px icon on a small phone screen — sized down specifically for
       mobile, not tablet, where the larger size still reads fine. */
    .nav-brand {
        font-size: 24px;
    }

    .hero-content {
        padding-left: 1.5rem;  /* 24px — same gutter as the 1024px breakpoint above */
        padding-right: 1.5rem;
    }

    .section-container {
        padding-left: 0;
    }

    .project-title {
        font-size: 2rem;
    }

    .section-title {
        font-size: 1.5rem;
    }

    .two-col,
    .two-col.two-col--reverse,
    .two-col.two-col--equal {
        grid-template-columns: 1fr;
    }

    .case-study-card {
        grid-template-columns: 1fr;
    }

    .finding-item,
    .feature-item {
        grid-template-columns: 32px 1fr;
        gap: 1rem;
    }

    .meta-row {
        flex-direction: column;
        gap: 1.25rem;
    }

    .meta-item {
        grid-template-columns: 32px 1fr;
        gap: 1rem;
    }

    .meta-content {
        max-width: none;
    }

    /* Corner radius scaled to 50% of its desktop value, matching images shrinking down
       to the mobile breakpoint. */
    .hero-image img,
    .two-col-image img,
    .case-card-image img,
    .full-width-image img,
    .two-col-card-image img,
    .img-placeholder {
        border-radius: 4px; /* 8px desktop */
    }

    .carousel {
        border-radius: 12px; /* 24px desktop */
    }

    .carousel-slide .img-placeholder,
    .carousel-slide img {
        border-radius: 6px; /* 12px desktop */
    }
}