/*
 * Home hero.
 *
 * Two decisions carry most of this file.
 *
 * HEIGHT, NOT ASPECT-RATIO. The band used to be `aspect-ratio: 4/1` with a
 * `min-height: 340px`, which looks reasonable and is not. A box with an aspect
 * ratio transfers a definite min-height back through that ratio into a minimum
 * WIDTH: 340px at 16/10 became a 544px-wide band inside a 399px viewport, so
 * the entire home page scrolled sideways on every phone. `max-height` did the
 * mirror image, capping the band at 2480px on a 2560px monitor and leaving a
 * bare strip down the right-hand edge. A definite height cannot do either. It
 * also means the band reserves its exact space before the photograph has
 * loaded, so there is nothing left to shift. The ratio still drives the height
 * -- it is just applied as `100vw / ratio` rather than handed to the box.
 *
 * A PANEL ON WIDE SCREENS, A STACK ON NARROW ONES. The artwork is natively 4:1,
 * so it can lose a little from its sides and nothing from its height. Above
 * 820px that is a mild crop and the wording sits on the photo; below it the
 * wording moves underneath, because covering a 4:1 source into a phone-shaped
 * box would crop away the product itself. See the responsive block at the foot
 * of this file.
 *
 * A PANEL, NOT A WASH. The artwork is bright daylight now. The old scrim was a
 * near-opaque gradient across most of the band, written when every photo was
 * graded near-black, and over a sunny picture it reads as a dark slab someone
 * dropped on top. What replaced it is a brand-black panel with a feathered
 * inner edge: the type sits on a solid surface with contrast guaranteed by
 * construction rather than by the photograph happening to be dark in the right
 * place, and the remaining half of the frame is the photograph, untouched and
 * as bright as it was shot.
 */

.hh-hero {
    --hh-hero-ink: #ffffff;
    --hh-hero-accent: #FEDD00;
    --hh-hero-panel: 12, 13, 15;

    /* Overridden inline, per breakpoint, from the admin settings. */
    --hh-hero-ratio: 4;
    --hh-hero-min: 340px;
    --hh-hero-max: 620px;

    /* How much of the width the black panel covers before it feathers out. */
    --hh-panel-w: clamp(340px, 46%, 780px);

    /*
     * The site header is fixed and opaque (80px plus its 3px rule), and the
     * body only reserves room for the store bar above it, so every section is
     * expected to keep its own content clear of it. Most do that with internal
     * padding. The hero cannot: it is full-bleed with an absolutely positioned
     * photograph, so padding would move the words and leave the picture behind
     * the header -- which is how the top 83px of the band, and with it the peak
     * of the carport roof, was being hidden. The band starts below the header
     * instead, and all of it is visible.
     */
    --hh-hero-headroom: 83px;

    position: relative;
    margin-top: var(--hh-hero-headroom);
    /* 100vw counts the scrollbar, so this over-estimates the height by about a
       scrollbar's width divided by the ratio -- three or four pixels. Worth it:
       unlike a percentage or an aspect-ratio it can never feed back into width. */
    height: clamp(var(--hh-hero-min), calc(100vw / var(--hh-hero-ratio)), var(--hh-hero-max));
    overflow: hidden;
    /* Hand vertical panning back to the page; take only the horizontal. */
    touch-action: pan-y;
    background: #0b0c0e;
    border-bottom: 3px solid var(--hh-hero-accent);
}

/*
 * A transform track, not a crossfade.
 *
 * The earlier note here said a transform track "fights the page's own
 * scrolling on a phone". That is only true if the element captures vertical
 * gestures, and `touch-action: pan-y` on the band is the specific fix: the
 * browser keeps vertical panning for the page and only hands us the
 * horizontal, so the page still scrolls normally through the hero.
 *
 * The track earns it. A slide that follows the thumb and settles is the
 * behaviour a phone user already expects, and it makes the position in the
 * set legible in a way a crossfade never does.
 */
.hh-hero__track {
    position: absolute;
    inset: 0;
    display: flex;
    will-change: transform;
    transition: transform 520ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* While a finger is down the track follows it directly, so the easing has to
   be out of the way; the class is removed on release and it settles. */
.hh-hero__track.is-dragging { transition: none; }

.hh-hero__slide {
    position: relative;
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.hh-hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;          /* object-position is per-slide, set inline */
    display: block;
}

/* The panel. Solid for most of its width, then a short feather so it meets the
   photograph as an edge of light rather than a cut line. 0.96 rather than 1.0
   keeps a trace of the picture running under the type, which stops it reading
   as a rectangle pasted over a photo, and still leaves white text far above
   any contrast requirement. */
.hh-hero__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        90deg,
        rgba(var(--hh-hero-panel), 0.96) 0%,
        rgba(var(--hh-hero-panel), 0.94) calc(var(--hh-panel-w) * 0.68),
        rgba(var(--hh-hero-panel), 0.00) var(--hh-panel-w)
    );
}

.hh-hero__inner {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: clamp(8px, 0.9vw, 16px);
    padding-inline: clamp(20px, 4vw, 96px);
    /* Kept inside the solid part of the panel, not the feather. */
    max-width: calc(var(--hh-panel-w) * 0.92);
}

/*
 * Every line-height below is explicit, and that is the whole reason CLS on this
 * page is what it is. Oswald arrives over the network with font-display: swap,
 * so the first paint uses a fallback whose metrics differ. Where line height is
 * left to the font, each text block changes height when the real face lands and
 * everything under it moves; pinning line-height makes the boxes the same size
 * in either font, so the swap changes the letters and nothing else.
 */

.hh-hero__eyebrow {
    margin: 0;
    color: var(--hh-hero-accent);
    font-size: clamp(11px, 1.05vw, 20px);
    line-height: 1.2;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    padding-bottom: 0.45em;
    border-bottom: 3px solid var(--hh-hero-accent);
}

.hh-hero__title {
    margin: 0;
    color: var(--hh-hero-ink);
    /* The point of moving the words out of the image: this scales with the
       viewport instead of being scaled down with the artwork to 23px. */
    font-size: clamp(30px, 5.2vw, 96px);
    line-height: 0.98;
    font-weight: 900;
    letter-spacing: -0.02em;
    text-transform: uppercase;
    text-wrap: balance;
}

.hh-hero__offer {
    margin: 0.15em 0 0;
    display: inline-block;
    background: var(--hh-hero-accent);
    color: #111;
    font-size: clamp(13px, 1.5vw, 27px);
    line-height: 1.25;
    font-weight: 800;
    padding: 0.42em 0.85em;
    border-radius: 6px;
}

.hh-hero__cta {
    margin-top: clamp(4px, 0.6vw, 12px);
    color: var(--hh-hero-ink);
    font-size: clamp(13px, 1.15vw, 19px);
    line-height: 1.4;
    font-weight: 700;
    text-decoration: none;
    border-bottom: 2px solid rgba(255, 255, 255, 0.42);
    padding-bottom: 2px;
    transition: color 140ms ease, border-color 140ms ease;
}

.hh-hero__cta::after { content: " \2192"; }
.hh-hero__cta:hover { color: var(--hh-hero-accent); border-color: var(--hh-hero-accent); }
.hh-hero__cta:focus-visible { outline: 3px solid var(--hh-hero-accent); outline-offset: 4px; }

/* ---- controls ----
   Revealed by the script. Left in the markup but hidden means that with
   JavaScript off a visitor gets the first slide and no buttons, rather than
   buttons that do nothing. They are absolutely positioned, so un-hiding them
   moves nothing on the page. */

.hh-hero__controls[hidden] { display: none; }

.hh-hero__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 46px;
    height: 46px;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.42);
    cursor: pointer;
    transition: background-color 140ms ease;
    z-index: 2;
}

.hh-hero__nav:hover { background: rgba(0, 0, 0, 0.72); }
.hh-hero__nav:focus-visible { outline: 3px solid var(--hh-hero-accent); outline-offset: 3px; }
.hh-hero__nav--prev { left: 14px; }
.hh-hero__nav--next { right: 14px; }

.hh-hero__nav::before {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 10px; height: 10px;
    border-top: 2px solid #fff;
    border-right: 2px solid #fff;
}

.hh-hero__nav--next::before { transform: translate(-65%, -50%) rotate(45deg); }
.hh-hero__nav--prev::before { transform: translate(-35%, -50%) rotate(-135deg); }

/* Pause and dots travel together so the stop control is never orphaned in a
   corner away from the thing it stops. */
.hh-hero__bar {
    position: absolute;
    left: 50%;
    bottom: 16px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 14px;
    z-index: 2;
}

.hh-hero__dots {
    display: flex;
    align-items: center;
    gap: 9px;
}

.hh-hero__dot {
    width: 9px; height: 9px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: width 200ms ease, background-color 200ms ease;
}

.hh-hero__dot.is-active { width: 26px; border-radius: 5px; background: var(--hh-hero-accent); }
.hh-hero__dot:focus-visible { outline: 2px solid var(--hh-hero-accent); outline-offset: 3px; }

/* Required whenever the band rotates on its own: hover and focus pausing is not
   a control a touch screen can reach. */
.hh-hero__toggle {
    position: relative;
    width: 26px; height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.42);
    cursor: pointer;
    transition: background-color 140ms ease;
}

.hh-hero__toggle:hover { background: rgba(0, 0, 0, 0.72); }
.hh-hero__toggle:focus-visible { outline: 2px solid var(--hh-hero-accent); outline-offset: 3px; }

/* Two bars while it is playing (press to pause), a triangle while it is
   paused (press to play). */
.hh-hero__toggle::before,
.hh-hero__toggle::after {
    content: "";
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 10px;
    background: #fff;
}

.hh-hero__toggle::before { left: 9px; }
.hh-hero__toggle::after  { right: 9px; }

.hh-hero__toggle[data-state="paused"]::after { display: none; }
.hh-hero__toggle[data-state="paused"]::before {
    left: 9px;
    width: 0; height: 0;
    background: none;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-left: 8px solid #fff;
}

/* ---- responsive ----
 *
 * Below 820px the slide stops being a photograph with words on it and becomes a
 * photograph with words UNDER it. That is forced by the artwork, not by taste.
 * The backgrounds are natively 4:1, framed so the whole product is in shot --
 * carport roof peak down to post bases, the pool with its deck and rail -- and
 * `object-fit: cover` into a squarer box crops the SIDES, not the top. At the
 * 1.25:1 box this file used to ask for, a phone would have shown the middle
 * 31% of the picture and cut straight through the thing being advertised.
 *
 * Stacking solves it without new artwork and without compromise on either
 * half: the photo keeps almost its full width so the product stays whole, and
 * the wording gets a solid black panel of its own, which is better contrast
 * than any scrim and lets the headline stay large. Both parts have definite
 * heights, so the band is still exactly one size before anything loads.
 */

@media (max-width: 1100px) {
    .hh-hero { --hh-panel-w: clamp(320px, 62%, 640px); }
}

@media (max-width: 820px) {
    /*
     * The copy sits ON the photograph again.
     *
     * It was stacked below it for a real reason: the wide banner is 4:1, and
     * cover-cropping that into a phone-shaped box shows a narrow slice through
     * the middle of the product. Stacking avoided cutting the product, at the
     * cost of a hero that reads as a thin strip with a caption under it.
     *
     * The fix is the art-directed crop rather than the layout -- a taller phone
     * image whose product sits low with open sky above it. Then the box can be
     * tall, the whole product is in it, and the sky is the space the headline
     * sits on. Slides with no phone crop still get the wide file, so the band
     * degrades to a shorter photo rather than to a broken one.
     */
    .hh-hero {
        height: clamp(var(--hh-hero-min), calc(100vw / var(--hh-hero-ratio)), var(--hh-hero-max));
    }

    .hh-hero picture,
    .hh-hero__img { height: 100%; }

    /* Bottom-anchored, because the phone crop puts its empty sky at the top and
       its product low. A left-weighted panel is a landscape idea and would sit
       straight over the product here. */
    .hh-hero__scrim {
        display: block;
        background: linear-gradient(
            0deg,
            rgba(var(--hh-hero-panel), 0.92) 0%,
            rgba(var(--hh-hero-panel), 0.74) 30%,
            rgba(var(--hh-hero-panel), 0.30) 58%,
            rgba(var(--hh-hero-panel), 0.00) 82%
        );
    }

    .hh-hero__inner {
        top: auto;
        bottom: 0;
        inset-inline: 0;
        max-width: 100%;
        justify-content: flex-end;
        background: none;
        padding-block: 0 clamp(46px, 11vw, 74px);
        padding-inline: clamp(18px, 6vw, 34px);
    }

    .hh-hero__title { font-size: clamp(24px, 7vw, 40px); }
    .hh-hero__offer { font-size: clamp(13px, 3.5vw, 19px); }

    /* Back onto the photo, below the copy. */
    .hh-hero__bar { bottom: 14px; top: auto; }

    /* Swipe replaces them: two 46px targets sit over the product on a phone. */
    .hh-hero__nav { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .hh-hero__slide,
    .hh-hero__dot,
    .hh-hero__nav,
    .hh-hero__toggle { transition-duration: 1ms; }
}
