/* ==========================================================================
   Independence Day offer strip  (SRCHPPC-11514)

   Rebuilt from the approved creatives in /use-video (Desktop.webm 1920x80,
   Mobile.webm 1080x120). Every metric below is measured off those clips:
   the desktop layout is expressed against a 1920x80 design frame and the
   mobile layout against a 1080x120 one, so the strip keeps the creative's
   proportions at any viewport width.

   The tricolour wipe is the clips' own motion. It resolves into two moving
   parts scaling/sliding about fixed reference points, so the whole sequence
   runs on transforms only:
     - .ind-offer__bands  green + white bands, scaled about a point just
                          off the strip's left edge (measured x = -285px).
                          Green leads at the right edge, so the wipe reads
                          green, then white, then the trailing fill.
     - .ind-offer__fill  the trailing fill: its right edge tracks the bands
                          while covering, then its left edge sweeps right to
                          reveal the strip again.
   ========================================================================== */

/* Self-hosted Abhaya Libre ExtraBold — the family ships no italic and only the
   800 weight is used here, for "15% Extra". Licence (SIL OFL) sits next to the
   file as AbhayaLibre-OFL.txt. Shipped as the supplied .ttf; a woff2 would cut
   roughly 60% off the 523KB, which is worth doing if the strip stays past the
   campaign. */
@font-face {
    font-family: "Abhaya Libre";
    src: url(../fonts/AbhayaLibre-ExtraBold.ttf) format("truetype");
    font-weight: 800;
    font-style: normal;
    font-display: swap;
}

.ind-offer {
    --ind-blue: #005EF1;
    --ind-orange: #FC8100;
    --ind-green: #1DA010;
    --ind-band-white: #FCFCFC;
    --ind-serif: "Playfair Display", "Times New Roman", Times, serif;
    /* "15% Extra" is set in Abhaya Libre ExtraBold, not the italic serif. */
    --ind-display: "Abhaya Libre", "Times New Roman", Times, serif;
    --ind-cta-font: "Be Vietnam Pro", var(--body-font, "Roboto", Arial, sans-serif);

    /* 47.24px at the 1920px design width. Stops growing past that.
       Playfair Display ships a true italic, so the italic runs below are the
       designed italic face rather than a synthesised oblique. */
    font-size: clamp(20px, 2.4604vw, 47.24px);
    /* Measured: the wipe leans right-over-left at ~22.6deg on desktop. */
    --ind-skew: -22.6deg;

    /* The copy carries its own scale on top of the layout em, so the CTA, the
       strip height and the wave padding stay on the measured 1920x80 grid
       while the sentence keeps the creative's cap height.
       Playfair Display's cap height is 71/100em against Abhaya Libre's 59/100em
       (measured), so the previous .8894 is restated as .8894 x 59/71 to hold
       the creative's 31px cap height through the family change. */
    --ind-text-scale: .7391;

    position: relative;
    display: block;
    width: 100%;
    /* Shallower than the creative's 1.6935em (80px on the 1920x80 frame) — the
       band reads too deep at full width. The wave art is sized `auto 100%`, so
       it narrows with this, and .ind-offer__inner's padding is restated to the
       new wave widths just below. */
    height: 1.45em;
    overflow: hidden;
    background-color: #EFF5F9;
    background-image:
        url(../img/offer/ind-wave-left.png),
        url(../img/offer/ind-wave-right.png),
        linear-gradient(102deg, rgba(255, 255, 255, 0) 14%, rgba(255, 255, 255, .95) 24%, rgba(255, 255, 255, 0) 33%),
        linear-gradient(102deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, .9) 53%, rgba(255, 255, 255, 0) 64%),
        linear-gradient(102deg, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, .9) 90%, rgba(255, 255, 255, 0) 99%),
        linear-gradient(180deg, #E8F0F5 0%, #F8FCFE 46%, #E7EFF4 100%);
    background-repeat: no-repeat;
    background-position: left center, right center, center, center, center, center;
    /* auto/100% keeps the wave art's aspect, which is what holds it to the
       same share of the strip as in the creative while the strip scales. */
    background-size: auto 100%, auto 100%, cover, cover, cover, cover;
}

/* -------------------------------------------------------------- content -- */

.ind-offer__inner {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.6511em;
    height: 100%;
    /* The creative centres the copy in the clear space *between* the wave art,
       not in the strip — and the two wave panels differ in width, so the
       padding mirrors their rendered widths. Both are sized `auto 100%`, so
       those widths follow the strip height: 430/80 and 330/80 of it, which at
       the 1.45em height gives 7.794em and 5.981em. Retune these whenever the
       height changes or the copy stops sitting centred between the waves. */
    padding: 0 5.981em 0 7.794em;
}

.ind-offer__text {
    margin: 0;
    font-family: var(--ind-serif);
    font-size: calc(1em * var(--ind-text-scale));
    line-height: 1;
    white-space: nowrap;
    color: var(--ind-blue);
    /* The creative sets the copy's baseline 5px below the strip's midline,
       while the CTA stays centred. Abhaya Libre's ascent/descent metrics
       centre it higher than that, so the copy is nudged back down. */
    transform: translateY(.119em);
}

.ind-offer__lead,
.ind-offer__tail {
    font-style: italic;
}

/* Abhaya Libre ExtraBold, sitting inline with the Playfair italic either side.
   The two families draw different cap heights against the same em — Abhaya 59,
   Playfair 71 — so at a shared font-size "15% Extra" would come out a fifth
   short. The 1.2034 step is 71/59, which puts the two on the same cap line;
   the shared inline baseline then keeps them vertically aligned by itself.
   Abhaya's own digits already sit at cap height (57 against 59), so unlike
   Playfair this needs no separate correction on the numerals.
   The margins are the creative's measured 25px/23px gaps restated against the
   deal's now-larger em (.408/1.2034, .595/1.2034) so the spacing is unchanged. */
.ind-offer__deal {
    margin: 0 .3391em 0 .4944em;
    font-family: var(--ind-display);
    font-size: 1.2034em;
    font-weight: 800;
    color: var(--ind-orange);
}

/* ------------------------------------------------------------------ CTA -- */

/* Sizes are quoted against the strip's em, then divided by the button's own
   font-size ratio because `em` here resolves against that smaller font. */
.ind-offer__cta {
    --ind-cta-ratio: .4374;
    --ind-cta-lift: calc(.0847em / var(--ind-cta-ratio));

    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: calc(3.1329em / var(--ind-cta-ratio));
    height: calc(1.0584em / var(--ind-cta-ratio));
    border: calc(.0635em / var(--ind-cta-ratio)) solid var(--ind-blue);
    border-radius: 0;
    background: #fff;
    box-shadow: var(--ind-cta-lift) var(--ind-cta-lift) 0 0 var(--ind-blue);
    font-family: var(--ind-cta-font);
    font-size: calc(1em * var(--ind-cta-ratio));
    font-weight: 500;
    line-height: 1;
    color: var(--ind-blue);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .18s ease, color .18s ease, box-shadow .18s ease, transform .18s ease;
}

/* Hover presses the button down onto its own offset shadow. */
.ind-offer__cta:hover,
.ind-offer__cta:focus-visible {
    background: var(--ind-blue);
    color: #fff;
    box-shadow: 0 0 0 0 var(--ind-blue);
    transform: translate(var(--ind-cta-lift), var(--ind-cta-lift));
}

.ind-offer__cta:focus-visible {
    outline: 2px solid #0a2f6b;
    outline-offset: 2px;
}

/* ----------------------------------------------------------- the wipe --- */

.ind-offer__wipe {
    position: absolute;
    inset: 0;
    z-index: 2;
    overflow: hidden;
    pointer-events: none;
}

.ind-offer__bands,
.ind-offer__fill {
    position: absolute;
    top: 0;
    bottom: 0;
    display: block;
    will-change: transform;
    backface-visibility: hidden;
}

/* The group sweeps left to right, so its rightmost colour is the one that
   reaches any given point first. Green sits at the leading (right) edge and
   white just behind it, which is what makes the strip read green, then white,
   then orange as the wipe passes. Band edges sit at the same fractions of the
   group in both creatives, so only the group's own width changes per
   breakpoint. */
.ind-offer__bands {
    background: linear-gradient(90deg,
            rgba(0, 0, 0, 0) 0 69.672%,
            var(--ind-band-white) 69.672% 78.689%,
            var(--ind-green) 78.689% 100%);
}

/* The trailing fill — last colour to arrive, and the one that holds the strip
   covered before the reveal. */
.ind-offer__fill {
    left: 0;
    width: 100%;
    transform-origin: 0 50%;
    background: var(--ind-orange);
}

/* ------------------------------------------------- desktop choreography -- */

@media (min-width: 992px) {

    .ind-offer__bands {
        left: -149.32%;
        width: 244%;
        transform-origin: 55.11% 50%;
        animation: ind-bands-d 10s linear infinite;
    }

    .ind-offer__fill {
        animation: ind-fill-d 10s linear infinite;
    }
}

/* scaleX values are the measured band spread; keyframe percentages are the
   measured timestamps over a 10s cycle. The sweep itself keeps the creative's
   real-time speed — cover runs 0.07s-0.94s, the strip holds fully covered to
   1.01s, then the reveal runs to 1.55s — and the strip then sits idle until
   the cycle repeats, which is what sets the 10s repeat interval. */
@keyframes ind-bands-d {

    0%,
    0.7002% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) scaleX(.135);
    }

    2.7498% {
        transform: skewX(var(--ind-skew)) scaleX(.46);
    }

    3.75% {
        transform: skewX(var(--ind-skew)) scaleX(.726);
    }

    4.7502% {
        transform: skewX(var(--ind-skew)) scaleX(1.062);
    }

    5.7498% {
        transform: skewX(var(--ind-skew)) scaleX(1.456);
    }

    6.75% {
        transform: skewX(var(--ind-skew)) scaleX(1.872);
    }

    7.9998% {
        transform: skewX(var(--ind-skew)) scaleX(2.5);
    }

    9.4002%,
    9.8898% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) scaleX(3.3);
    }

    9.8904%,
    100% {
        opacity: 0;
        transform: skewX(var(--ind-skew)) scaleX(3.3);
    }
}

@keyframes ind-fill-d {

    0%,
    0.7002% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(0);
    }

    2.7498% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.0449);
    }

    3.75% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.1394);
    }

    4.7502% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.2588);
    }

    5.7498% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.3988);
    }

    6.75% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.5465);
    }

    7.9998% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.7696);
    }

    9.4002% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(1.0537);
    }

    /* fully covered — the reveal starts here */
    9.8898% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(0%) scaleX(1.05);
    }

    10.8702% {
        transform: skewX(var(--ind-skew)) translateX(20.47%) scaleX(.8453);
    }

    11.8698% {
        transform: skewX(var(--ind-skew)) translateX(41.41%) scaleX(.6359);
    }

    12.87% {
        transform: skewX(var(--ind-skew)) translateX(60.99%) scaleX(.4401);
    }

    13.8702% {
        transform: skewX(var(--ind-skew)) translateX(78.54%) scaleX(.2646);
    }

    14.8698% {
        transform: skewX(var(--ind-skew)) translateX(93.65%) scaleX(.1135);
    }

    15.3198% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(104%) scaleX(.01);
    }

    15.3204%,
    100% {
        opacity: 0;
        transform: skewX(var(--ind-skew)) translateX(104%) scaleX(.01);
    }
}

/* -------------------------------------------------- mobile choreography -- */

@media (max-width: 991.98px) {

    .ind-offer {
        /* Scaled up from the 1080px design frame: the strip reads too small on a
           phone at the creative's own ratio, so the em, the strip height and the
           copy's own scale are all stepped up together. */
        font-size: clamp(13px, 4.9vw, 24px);
        height: 3.05em;
        --ind-skew: -25.15deg;
        /* Mobile sets the copy larger against its em than desktop does — the
           1080x120 creative gives "15% Extra" a 61px run over a 40px strip.
           Restated for Playfair Display on the same 59/71 cap-height ratio,
           then stepped up with the rest of the mobile strip. */
        --ind-text-scale: .95;
        /* The left wave is dropped on mobile so the copy can use that space —
           there is not enough width on a phone to carry wave art on both sides
           and still keep the sentence and the CTA legible. Only the right wave
           stays, so the layer list is one shorter than the desktop one and the
           position/size lists have to be restated to match: with five layers,
           a six-value list would shift the right wave onto the left edge. */
        background-image:
            url(../img/offer/ind-wave-right-m.png),
            linear-gradient(102deg, rgba(255, 255, 255, 0) 14%, rgba(255, 255, 255, .95) 24%, rgba(255, 255, 255, 0) 33%),
            linear-gradient(102deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, .9) 53%, rgba(255, 255, 255, 0) 64%),
            linear-gradient(102deg, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, .9) 90%, rgba(255, 255, 255, 0) 99%),
            linear-gradient(180deg, #E8F0F5 0%, #F8FCFE 46%, #E7EFF4 100%);
        background-position: right center, center, center, center, center;
        background-size: auto 100%, cover, cover, cover, cover;
    }

    .ind-offer__inner {
        /* Abhaya ExtraBold sets "15% Extra" wider than the Playfair it replaced,
           so the left inset and the gap give the row back the width it needs at
           320px rather than shrinking the copy the strip was just enlarged for. */
        gap: .65em;
        /* With the left wave gone the copy runs almost to the left edge, so the
           left padding is only a breathing gap.
           The right wave is 205x120 and sized `auto 100%`, so it tracks the strip
           height: at 3.05em it renders 205/120 x 3.05em = 5.21em wide. The right
           padding clears that in full, with a little over, to keep the CTA off
           the artwork rather than just touching it — so it has to be retuned
           whenever the strip height changes. */
        padding: 0 5.4em 0 .35em;
    }

    /* The mobile creative breaks the copy over two centred lines, and sets the
       italic noticeably smaller than "15% Extra" (measured cap heights 22.5px
       vs 29px) — unlike the desktop creative, where both are the same size. */
    .ind-offer__text {
        text-align: center;
        line-height: 1.121em;
        /* Two lines centre almost on the strip's midline here, so the drop is
           much smaller than the single desktop line needs. */
        transform: translateY(.159em);
    }

    .ind-offer__lead,
    .ind-offer__tail {
        font-size: .7366em;
    }

    .ind-offer__lead {
        display: block;
    }

    .ind-offer__deal {
        /* .309em restated against the deal's larger em, as on desktop. */
        margin: 0 .2568em 0 0;
    }

    /* The button box is quoted in strip-em (the ratio cancels out of the calc),
       so these multiples are what actually enlarge it beyond the em step-up;
       the ratio itself only sets the label's size inside the box. */
    .ind-offer__cta {
        --ind-cta-ratio: .52;
        --ind-cta-lift: calc(.0905em / var(--ind-cta-ratio));

        width: calc(3.75em / var(--ind-cta-ratio));
        height: calc(1.4em / var(--ind-cta-ratio));
        border-width: calc(.0679em / var(--ind-cta-ratio));
    }

    .ind-offer__bands {
        left: -265.46%;
        width: 433.8%;
        transform-origin: 55.11% 50%;
        animation: ind-bands-m 10s linear infinite;
    }

    .ind-offer__fill {
        animation: ind-fill-m 10s linear infinite;
    }
}

/* Same band motion, but the narrower strip is covered sooner: the bands only
   need to reach scaleX(2.081) and the whole sequence ends at 0.97s. */
@keyframes ind-bands-m {

    0%,
    0.7002% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) scaleX(.135);
    }

    2.7498% {
        transform: skewX(var(--ind-skew)) scaleX(.46);
    }

    3.75% {
        transform: skewX(var(--ind-skew)) scaleX(.726);
    }

    4.7502% {
        transform: skewX(var(--ind-skew)) scaleX(1.062);
    }

    5.7498% {
        transform: skewX(var(--ind-skew)) scaleX(1.456);
    }

    6.75% {
        transform: skewX(var(--ind-skew)) scaleX(1.872);
    }

    7.17% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) scaleX(2.081);
    }

    7.1706%,
    100% {
        opacity: 0;
        transform: skewX(var(--ind-skew)) scaleX(2.081);
    }
}

/* On the narrow strip the reveal starts at 0.63s — before the green has
   finished covering — so for a moment the strip is back on the left while the
   white band is still leaving on the right. Both edges are driven at once:
   translateX is the left edge, scaleX the width out to the right edge. */
@keyframes ind-fill-m {

    0%,
    0.7002% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(0);
    }

    2.7498% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.0566);
    }

    3.75% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.2245);
    }

    4.7502% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.4368);
    }

    5.7498% {
        transform: skewX(var(--ind-skew)) translateX(-3%) scaleX(.6856);
    }

    /* reveal begins while the right edge is still growing */
    6.3198% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(0%) scaleX(.793);
    }

    6.75% {
        transform: skewX(var(--ind-skew)) translateX(14.4%) scaleX(.774);
    }

    7.17% {
        transform: skewX(var(--ind-skew)) translateX(28.6%) scaleX(.764);
    }

    7.7502% {
        transform: skewX(var(--ind-skew)) translateX(48.1%) scaleX(.569);
    }

    8.7498% {
        transform: skewX(var(--ind-skew)) translateX(82.1%) scaleX(.229);
    }

    9% {
        transform: skewX(var(--ind-skew)) translateX(88.4%) scaleX(.166);
    }

    9.36% {
        opacity: 1;
        transform: skewX(var(--ind-skew)) translateX(104%) scaleX(.01);
    }

    9.3606%,
    100% {
        opacity: 0;
        transform: skewX(var(--ind-skew)) translateX(104%) scaleX(.01);
    }
}

/* ------------------------------------------------------------ a11y ------ */

@media (prefers-reduced-motion: reduce) {

    .ind-offer__wipe {
        display: none;
    }

    .ind-offer__cta {
        transition: none;
    }
}
