/* ==========================================================================
   Layout — container, grid, and section structure.
   Mobile-first: single-column defaults, min-width queries add columns.
   ========================================================================== */

.container {
    width: 100%;
    max-width: var(--container-width);
    margin-inline: auto;
    padding-inline: var(--container-padding);
}

.section {
    padding-block: var(--space-2xl);
}

.section--tight {
    padding-block: var(--space-xl);
}

/* Full-bleed alternating tint for long, plain-text-only pages (currently
   the homepage) — breaks up a long run of visually-identical sections
   into readable "chapters" as you scroll, the same way .section--light
   already does for a single boxed callout, just spanning the section's
   entire width/height instead of an inset panel. Deliberately not used
   on sections that already contain their own .section--light panel
   (that panel provides its own contrast against a plain background —
   painting the outer section the same tint would make the panel blend
   in and disappear instead of standing out). */
.section--alt {
    background: var(--color-surface-light);
}

.section-heading {
    margin-bottom: var(--space-lg);
    max-width: 640px;
}

.section-heading__eyebrow {
    display: inline-block;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-accent-text);
    margin-bottom: var(--space-xs);
}

.section-heading p {
    margin-top: var(--space-sm);
    font-size: var(--fs-md);
    line-height: 1.5;
}

@media (min-width: 768px) {
    .section-heading p {
        font-size: var(--fs-lg);
    }
}

.grid {
    display: grid;
    gap: var(--space-lg);
    grid-template-columns: 1fr;
    perspective: var(--perspective);
}

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

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

    .grid--4 {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* Generic button-row utility — used by every section that ends in one or
   more CTAs (hero variants, services, projects, contact, 404), not just
   the hero itself. */
.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    perspective: var(--perspective);
}

/* Hero-intro — the shared "big personal-brand" composition: an italic
   serif greeting line and a huge bold name/role pairing at the bottom,
   with either a portrait or (homepage only, see .hero-intro__video below)
   a background video behind it. Used by the homepage hero (index.php)
   and the About page intro (pages/about.php) with different copy but
   identical structure/classes.

   Deliberately NOT given the .container class itself (unlike every other
   section) so the background video can span the full viewport width
   edge-to-edge. .hero-intro__content is the part that's width-constrained
   — see index.php/about.php, which put .container on that inner wrapper
   instead of on .hero-intro. .hero-intro's own height just follows that
   wrapper's height, since the video/overlay are absolutely positioned and
   don't participate in normal flow. */
.hero-intro {
    position: relative;
    overflow: hidden;
}

/* Homepage-only modifier (see index.php) — bleeds the background video up
   behind the sticky header instead of starting below it, using the
   header's real measured height (--header-height, set by
   initHeaderHeightVar() in main.js) rather than a guessed pixel value
   that would drift out of sync across breakpoints. The matching
   padding-top increase on .hero-intro__content below cancels this back
   out for the *text* — the greeting line ends up at the same on-screen
   position either way, so only the video visibly extends into the
   header's space, nothing shifts underneath it. Before JS runs (or with
   it disabled) --header-height is unset, both rules fall back to 0, and
   the hero just renders exactly as it did before this feature. */
.hero-intro--video {
    margin-top: calc(-1 * var(--header-height, 0px));
}

.hero-intro--video .hero-intro__content {
    padding-top: calc(var(--space-2xl) + var(--header-height, 0px));
}

.hero-intro--video .hero-intro__name {
    font-size: clamp(3.5rem, 12vw, 8rem);
    text-align: center;
}

/* justify-content: space-between spreads the greeting/meta/headline rows
   across the section on the homepage (which has no portrait to anchor
   to anymore). On the About page this is a no-op: .hero-intro__portrait
   still has flex: 1 1 auto there, so it consumes all the slack itself
   before justify-content ever gets space to distribute. */
.hero-intro__content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--space-lg);
    min-height: 80vh;
    padding-block: var(--space-2xl);
}

/* The text-shadow on .hero-intro__script/__name/__role below is a soft
   light "halo" (not a dark drop-shadow) behind dark text — it keeps the
   letterforms readable against whatever's actually playing in the video
   at a given moment without needing a heavy opaque wash over it, the
   same job the portrait's drop-shadow does for its silhouette. */
.hero-intro__script {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-md);
    font-family: var(--font-heading);
    font-style: italic;
    font-weight: 400;
    font-size: clamp(2.75rem, 9vw, 7rem);
    line-height: 1;
    text-align: center;
    color: var(--color-text);
    text-shadow: 0 4px 28px rgba(251, 243, 232, 0.85);
}

/* Homepage-only background video (see index.php) — covers the whole hero
   behind the text, extending up behind the header too when
   .hero-intro--video is present (see that rule above). autoplay/muted/
   loop/playsinline is required for silent-autoplay to actually work
   across browsers/iOS; initHeroVideo() in main.js additionally pauses it
   for prefers-reduced-motion, since the video element's own autoplay
   attribute doesn't respect that on its own.

   The overlay is kept deliberately light — just enough of a cream wash
   (mirroring --color-bg, see variables.css) plus a faint warm/gold tint
   from the site's own accent gradient for it to read as "this site's
   video" rather than a flat neutral scrim, not the heavier wash this
   started as, so the video's actual colour still comes through as the
   dominant visual. Legibility for the text on top leans on the
   text-shadow/solid-chip treatments on the individual elements instead
   of one heavy blanket overlay. */
.hero-intro__video {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
}

.hero-intro__video-overlay {
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        linear-gradient(135deg, rgba(255, 107, 74, 0.1), rgba(255, 178, 56, 0.06) 60%, transparent 100%),
        linear-gradient(
            180deg,
            rgba(251, 243, 232, 0.08),
            rgba(251, 243, 232, 0.05) 40%,
            rgba(251, 243, 232, 0.32) 75%,
            rgba(251, 243, 232, 0.5)
        );
}

/* Portrait — a real background-removed cutout (assets/img/imran-cutout-hero.png,
   a tightly-cropped transparent PNG — see CHANGELOG.md for how the
   original was generated), not a crop mask. No border-radius, no border,
   no box-shadow "card" edge — any of those would draw a visible box
   around the transparent canvas, which defeats the point of an actual
   cutout. Instead: a soft blurred glow behind the figure and a stacked
   drop-shadow filter (which follows the subject's actual silhouette,
   unlike box-shadow which would box the whole transparent square) so it
   reads as genuinely floating/popping off the page — the transform below
   adds a permanent forward translateZ offset (not just on hover) for
   that "pop" depth, on top of the same pointer-tilt system every other
   prominent element uses (see initTilt() in main.js).

   flex: 1 1 auto makes this row grow to fill whatever real vertical
   space is left between the greeting line above and the pill/headline
   rows below (rather than a guessed height or vh value), so the image
   sits flush against the availability pill at its natural bottom edge —
   the same reliable, content-driven sizing as the rest of the layout,
   just applied to an image instead of text. align-items: flex-end keeps
   it anchored to that bottom edge; any slack shows as breathing room
   under the greeting text instead of a gap before the pill. */
.hero-intro__portrait {
    position: relative;
    z-index: 2;
    flex: 1 1 auto;
    min-height: 220px;
    /* Caps how tall the flex item is allowed to grow to. Without this,
       flex: 1 1 auto lets the portrait (and therefore the whole
       .hero-intro__content column, which only has a min-height floor,
       not a ceiling) expand well past one viewport on tall/narrow
       windows, pushing the actual name/role headline below the fold on
       first load. 40vh keeps the four stacked rows (script, portrait,
       meta, headline) fitting inside a single screen on common
       viewports instead of overflowing it. */
    max-height: 40vh;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.hero-intro__portrait::before {
    content: '';
    position: absolute;
    inset: 10% 22%;
    z-index: -1;
    border-radius: 50%;
    background: var(--gradient-accent);
    opacity: 0.35;
    filter: blur(44px);
}

/* Positioned absolutely (rather than as a normal flex child sized with
   height: 100%) specifically to dodge a flexbox percentage-height bug:
   .hero-intro__portrait's own height comes from `flex: 1 1 auto` +
   max-height, not a literal `height` value, and a flex item sized that
   way does not count as a "definite" height for a normal-flow child's
   height: 100% to resolve against — the browser falls back to the
   image's native pixel size instead, roughly doubling it and blowing it
   out over the greeting line above and the headline below. An absolutely
   positioned child's containing block is .hero-intro__portrait's actual
   laid-out box (position: relative, set above) regardless of how that
   box's height was arrived at, so height: 100% resolves correctly here.
   left: 50% + translateX(-50%) replaces the old justify-content: center
   for horizontal centering now that the image is out of flow. */
.hero-intro__portrait-img {
    display: block;
    position: absolute;
    bottom: 0;
    left: 50%;
    height: 100%;
    width: auto;
    max-width: none;
    filter: drop-shadow(0 12px 20px rgba(25, 26, 46, 0.22))
        drop-shadow(0 30px 40px rgba(25, 26, 46, 0.28));
    transform: translateX(-50%) perspective(var(--perspective))
        rotateX(var(--tilt-x)) rotateY(var(--tilt-y))
        translateZ(calc(var(--tilt-z) + 20px)) scale(var(--tilt-scale));
    transition: transform 120ms ease-out, filter var(--transition-fast);
}

.hero-intro__meta {
    flex: 0 0 auto;
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: var(--space-md);
}

.hero-intro__pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-md);
    border-radius: 999px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    font-size: var(--fs-sm);
    font-weight: 600;
}

.hero-intro__pill-dot {
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--color-accent-2);
    box-shadow: 0 0 0 4px rgba(255, 178, 56, 0.25);
}

.hero-intro__specialisation {
    max-width: 320px;
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
    text-align: right;
}

.hero-intro__headline {
    flex: 0 0 auto;
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: var(--space-md);
}

.hero-intro__name,
.hero-intro__role {
    margin: 0;
    font-family: var(--font-body);
    font-weight: 800;
    text-transform: uppercase;
    line-height: 0.95;
    letter-spacing: -0.01em;
    text-shadow: 0 4px 28px rgba(251, 243, 232, 0.85);
}

.hero-intro__name {
    font-size: clamp(2.5rem, 9vw, 5.5rem);
}

.hero-intro__role {
    font-size: clamp(1.5rem, 5vw, 3rem);
    text-align: right;
    color: var(--color-text);
}

@media (min-width: 768px) {
    .hero-intro__content {
        min-height: 90vh;
    }

    .hero-intro__script {
        gap: clamp(3rem, 16vw, 10rem);
    }

    .hero-intro__portrait {
        min-height: 340px;
        max-height: 46vh;
    }

    .hero-intro__portrait-img {
        filter: drop-shadow(0 10px 18px rgba(25, 26, 46, 0.22))
            drop-shadow(0 34px 46px rgba(25, 26, 46, 0.3));
        transform: translateX(-50%) perspective(var(--perspective))
            rotateX(var(--tilt-x)) rotateY(var(--tilt-y))
            translateZ(calc(var(--tilt-z) + 32px)) scale(var(--tilt-scale));
    }
}
