/* q4u-heroimage: standalone hero image styles */

/* ─── Frame reset ─────────────────────────────────────────── */

/* Strip padding, margin, background from the TYPO3 frame wrapper */
.frame-type-q4u_heroimage {
    padding: 0 !important;
    margin: 0 !important;
    width: 100%;
    background: transparent !important;
}

.frame-type-q4u_heroimage > .container {
    max-width: none;
    padding: 0;
}

/* Hide the ce-header — title is rendered inside the overlay */
.frame-type-q4u_heroimage .ce-header {
    display: none;
}

/* Hero in colPos 5: pull behind sticky navbar, strip wrapper chrome.

   The pull must equal the space the header occupies in flow. q4u_base's
   header-offset.js measures that and publishes it as --q4u-header-offset; no
   CSS can read a rendered height, so it has to be measured.

   The fallback is the OLD formula deliberately — it is what shipped before, so
   the frame before the script runs looks like today rather than like a new
   guess. That old formula is wrong at every breakpoint: --header-height is
   declared 3rem (48px) in t3bootstrap's main.css and the theme CSS, while the
   header renders 122px on desktop and 70px on a phone, and `+ 6rem` is a fudge
   that lands near the right DESKTOP number (144px vs a true 154px) while
   overshooting a phone by 74px. On a 248px mobile hero that put 58% of the
   image above the document top or behind the navbar, heading included. */
.hero:has(.q4u-heroimage) {
    margin-top: calc(var(--q4u-header-offset, calc(var(--header-height, 3rem) + 6rem)) * -1);
    padding: 0 !important;
    background: transparent !important;
}

.hero:has(.q4u-heroimage) .hero-content {
    max-width: none;
    padding: 0;
}

/* ─── Hero element ────────────────────────────────────────── */

.q4u-heroimage {
    position: relative;
    display: grid;
    /* Exactly one column, pinned to the container width.
       Without this the implicit track is `auto`, i.e. sized to its widest item —
       and the <picture> carries an aspect-ratio from t3bc:picture. So as soon as
       the text makes the row taller, the picture derives its WIDTH from that
       height (height x ratio) and the track grows with it: measured at a 375px
       viewport, a hero whose text pushed it to 686px tall produced a 914px track,
       and `overflow: hidden` then cut the overlay text off mid-word.
       `minmax(0, 1fr)` fills the container and refuses to be inflated by content. */
    grid-template-columns: minmax(0, 1fr);
    width: 100%;
    max-width: var(--q4u-hero-max-width, 1440px);
    margin: 0 auto;
    overflow: hidden;
    /* Only ever seen if the image somehow fails to cover a text-driven height.
       Dark keeps the white overlay text legible rather than flashing the page
       background through. */
    background-color: #1a1a1a;
}

/* ─── Background image ───────────────────────────────────── */

/* The <picture> and the overlay occupy the SAME grid cell, so the hero is as
   tall as whichever of the two is taller.

   The image supplies the minimum height — its own intrinsic ratio, plus the
   per-breakpoint `aspect-ratio` rule t3bc:picture injects, which only takes
   effect because of `display: block` here (<picture> is inline by default, and
   `aspect-ratio` does nothing on an inline non-replaced element).

   Long text then makes the hero taller instead of being clipped. The overlay
   used to be `position: absolute; inset: 0`, so it physically could not affect
   the height: anything past ~4 lines of body text on a phone was cut off by
   `overflow: hidden`, silently. */
.q4u-heroimage > picture {
    grid-area: 1 / 1;
    display: block;
    align-self: stretch;
    min-width: 0;
    /* Caps the same aspect-ratio-derived width the track rule guards against.
       Without it the <picture> still renders 914px wide inside a 375px hero —
       clipped rather than overflowing, but clipped from the LEFT edge, so the
       visible part is the left 41% of the image instead of the centred crop
       `object-fit: cover` is supposed to give. */
    max-width: 100%;
    min-height: 100%;
}

.q4u-heroimage__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ─── Text overlay ───────────────────────────────────────── */

.q4u-heroimage__overlay {
    grid-area: 1 / 1;
    z-index: 1;
    min-width: 0;
    display: flex;
    padding: 48px 64px;
    /* Default gradient: dark at bottom for readability */
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.7) 0%,
        rgba(0, 0, 0, 0.3) 40%,
        rgba(0, 0, 0, 0.05) 70%,
        transparent 100%
    );
}

/* Vertical alignment variants */
.q4u-heroimage__overlay--bottom {
    align-items: flex-end;
}

.q4u-heroimage__overlay--center {
    align-items: center;
    background: linear-gradient(
        to right,
        rgba(0, 0, 0, 0.6) 0%,
        rgba(0, 0, 0, 0.3) 50%,
        transparent 100%
    );
}

.q4u-heroimage__overlay--top {
    align-items: flex-start;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.7) 0%,
        rgba(0, 0, 0, 0.3) 40%,
        rgba(0, 0, 0, 0.05) 70%,
        transparent 100%
    );
}

/* ─── Keep the text clear of the sticky header ───────────── */

/* A hero in colPos 5 is deliberately pulled UNDER the sticky header — that is
   the whole point of the negative margin. The overlay therefore has to reserve
   that space, or the text renders behind the navbar.

   Fixing the pull-up alone did NOT fix this: measured on lab at 375px, a 248px
   hero with bottom-aligned text still put the heading's top 15px under a 70px
   header, because the content block is tall relative to a short hero.

   Scoped to `.hero` on purpose — a hero image placed in ordinary content
   (colPos 0) has no header above it and must keep its normal padding.

   Specificity (0,3,0) beats the responsive `padding` shorthands below, which
   would otherwise reset padding-top at the tablet and mobile breakpoints. */
.hero .q4u-heroimage__overlay {
    padding-top: calc(var(--q4u-header-offset, 0px) + 24px);
}

/* ─── Content container ──────────────────────────────────── */

.q4u-heroimage__content {
    max-width: 600px;
    color: #fff;
}

.q4u-heroimage__title {
    font-size: clamp(1.5rem, 4vw, 3rem);
    font-weight: 700;
    line-height: 1.15;
    margin-bottom: 16px;
    color: inherit;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.q4u-heroimage__text {
    font-size: clamp(1rem, 1.5vw, 1.25rem);
    line-height: 1.5;
    margin-bottom: 24px;
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.q4u-heroimage__text p:last-child {
    margin-bottom: 0;
}

/* ─── Text scrim, 768px and up ───────────────────────────── */

/* From tablet width the overlay gradients stay as they are — they carry the
   hero's depth — but they cannot GUARANTEE contrast, because they darken one
   edge and fade towards the other while the text sits somewhere in between.
   Measured at 1440px, the minimum scrim alpha under the actual text band was
   0.32 for `center` and 0.28 for `half`/`bottom`: worst-case ratios of 2.26:1
   and 1.96:1 over a light image. It reads fine on a mid-grey photo, which is
   why it survived — the failure is conditional on what an editor uploads.

   Rather than darkening the whole image (which on a large screen mutes the
   photograph that is the point of a desktop hero), the guarantee is attached to
   the text block itself. alpha 0.60 over ANY backdrop gives 5.74:1 for the
   heading and 5.02:1 for the 90%-white body text; the gradient underneath can
   only make that darker, never lighter, so the floor holds wherever the block
   is placed. `saturate()` cannot break it either: the worst case is already a
   pure-white backdrop, and saturating white leaves it white.

   The blur/saturate values are the component's existing glass recipe, reused
   verbatim from the .picture-info override below rather than reinvented. */

@media (min-width: 768px) {
    .q4u-heroimage__content {
        padding: 28px 32px;
        border-radius: 8px;
        background-color: rgba(0, 0, 0, 0.6);
        backdrop-filter: blur(8px) saturate(180%);
        -webkit-backdrop-filter: blur(8px) saturate(180%);
    }

    /* The title and the text block both carry a bottom margin for the gap
       between them; on the last one it would show up as lopsided padding. */
    .q4u-heroimage__content > *:last-child {
        margin-bottom: 0;
    }
}

/* ─── Copyright / AI Info Pill ───────────────────────────── */

/* Override default picture-info styles for hero context:
   higher z-index (above gradient overlay), glassmorphism to match
   the slider controls, and white icons for photo background. */
.q4u-heroimage .picture-info {
    z-index: 2;
    background: rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(8px) saturate(180%);
    -webkit-backdrop-filter: blur(8px) saturate(180%);
    box-shadow: none;
}

/* ─── Scrim floor below the desktop breakpoint ───────────── */

/* Below 768px the overlay text runs nearly the full WIDTH of the hero — and,
   once it is long enough to grow the hero, most of its HEIGHT too. A
   directional gradient cannot cover that: it is built to darken one edge and
   fade out towards the other, which works on desktop only because the content
   is capped at 600px and sits in the dark half.

   Measured on `--center` at a 375px viewport: the text spans 6.4% to 93.6% of
   the hero width, while the gradient runs `to right` at alpha 0.6 -> 0.3 -> 0.
   Scrim alpha under the text was 0.562 at its left edge and 0.038 at its right,
   so the end of every line sat on an essentially undarkened photo and the
   contrast ratio was whatever the image happened to give.

   These stops put a floor under the entire overlay instead of a direction.
   0.60 is the worst case (a pure-white image): 5.74:1 for the white heading and
   5.02:1 for the 90%-white body text. The body text is the binding constraint,
   not the heading — it needs alpha 0.58 where the heading clears AA at 0.535.
   Both hold for ANY image, which is the point: contrast here must not depend on
   what an editor uploads. */

@media (max-width: 767.98px) {
    .q4u-heroimage__overlay,
    .q4u-heroimage__overlay--top,
    .q4u-heroimage__overlay--center,
    .q4u-heroimage__overlay--bottom {
        background-image: linear-gradient(
            to top,
            rgba(0, 0, 0, 0.75) 0%,
            rgba(0, 0, 0, 0.6) 100%
        );
    }
}

/* ─── Tablet ─────────────────────────────────────────────── */

/* No `min-height` / `object-fit` patching here any more. Those existed to prop
   up a 16:9 crop that was too short on small screens and then re-cropped it in
   the browser, centred and blind to the focal point. Small screens now get the
   4:3 `mobile` crop variant instead (see HeroImage.html), so the image arrives
   at a usable height already. */

@media (max-width: 991.98px) {
    .q4u-heroimage__overlay {
        padding: 40px 32px;
    }
}

/* ─── Mobile ─────────────────────────────────────────────── */

@media (max-width: 575.98px) {
    .q4u-heroimage__overlay {
        padding: 24px;
    }

    .q4u-heroimage__content {
        max-width: 100%;
    }
}
