/* Block: service-hero */
.service-hero {
    /* The site header is fixed, so the hero simply starts at the top and
       carries the bar's height as padding. */
    --service-hero-offset: var(--tgc-header-h);

    position: relative;
    z-index: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(968 * var(--tgc-u));
    padding: calc(var(--service-hero-offset) + calc(120 * var(--tgc-u))) var(--tgc-gutter) calc(210 * var(--tgc-u));
    border-radius: 0 0 calc(80 * var(--tgc-u)) calc(80 * var(--tgc-u));
    background-color: var(--tgc-violet);
    color: var(--theme-white);
    text-align: center;
}

.service-hero--short {
    min-height: calc(732 * var(--tgc-u));
    padding-bottom: calc(140 * var(--tgc-u));
}

.service-hero__inner {
    width: 100%;
    max-width: var(--tgc-container);
    margin: 0 auto;
}

.service-hero__motif {
    position: relative;
    display: flex;
    justify-content: center;
}

/*
 * The entrance (scripts/tgc-service-intro.js). The mark and title are held
 * back until the script says the mark has formed; without JavaScript the
 * .js class is never set and the hero is simply there.
 */
.js .service-hero:not(.is-mark-ready) .service-hero__motif .motif__mark {
    opacity: 0;
}

.service-hero__motif .motif__mark {
    transition: opacity 0.38s ease-out;
}

/* Handed over from the stand-ins: the mark is simply there under them while
   they fade off it. The fade above is for when the entrance is skipped. */
.service-hero.is-handover .service-hero__motif .motif__mark {
    transition: none;
}

.js .service-hero:not(.is-title-in) .service-hero__title {
    opacity: 0;
    transform: translateY(calc(18 * var(--tgc-u)));
}

.service-hero.is-title-in .service-hero__title {
    transition: opacity 0.7s ease, transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Stand-in circles laid over the mark in its own coordinates. */
.mark-intro {
    position: absolute;
    pointer-events: none;
    color: var(--theme-white);
}

.mark-intro__group {
    position: absolute;
    inset: 0;
}

.mark-intro__piece {
    position: absolute;
    border-radius: 50%;
    will-change: transform;
}

.mark-intro__piece--solid,
.mark-intro__piece--lid,
.mark-intro__piece--bowl-solid {
    background-color: currentColor;
}

.mark-intro__piece--lilac,
.mark-intro__piece--bowl-lilac {
    background-color: var(--tgc-lilac);
}

.mark-intro__piece--ring,
.mark-intro__piece--bowl-ring {
    border: 1px solid currentColor;
}

/* The bowls are lower halves of circles; the lid is the top half that lifts. */
.mark-intro__piece--bowl-solid,
.mark-intro__piece--bowl-lilac,
.mark-intro__piece--bowl-ring {
    border-radius: 0 0 999px 999px;
}

.mark-intro__piece--lid {
    border-radius: 999px 999px 0 0;
}

.service-hero__title {
    margin: calc(22 * var(--tgc-u)) auto 0;
    max-width: calc(1447 * var(--tgc-u));
    font-family: var(--tgc-font-display);
    font-size: var(--tgc-text-statement);
    font-weight: 300;
    line-height: 1.125;
    letter-spacing: -0.03em;
    color: var(--theme-white);
}

.service-hero__title strong {
    font-weight: 600;
}

/*
 * Header treatment.
 * The site header is transparent and sits in normal flow, so the hero is
 * pulled up underneath it. On these pages it has to read white on violet.
 * Scoped with :has() on the hero's data attribute so nothing else in the
 * theme is affected, and so the rule survives any class rename. It stands down
 * while the mobile menu is open (.is-menu-open), which puts the header on a
 * cream panel with ink type — see styles/header.css.
 */


body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .wordmark,
body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .main-nav .nav-menu a,
body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .nav-toggle {
    color: var(--theme-white);
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .wordmark {
    --tgc-wordmark-dot: var(--tgc-lilac);
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .main-nav .nav-menu a:hover,
body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .main-nav .nav-menu .current-menu-item > a {
    color: var(--tgc-violet-soft);
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .nav-toggle__bars,
body:has([data-tgc-hero]) .site-header .nav-toggle__bars::before,
body:has([data-tgc-hero]) .site-header .nav-toggle__bars::after {
    background-color: currentColor;
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .arrow-button__label {
    background-color: var(--theme-white);
    color: var(--tgc-violet);
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .arrow-button__arrow {
    background-color: transparent;
    border-color: var(--theme-white);
    color: var(--theme-white);
}

body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .arrow-button:hover .arrow-button__label {
    background-color: var(--tgc-violet-soft);
}

/* On the white pill the ring fills violet as it slides in, not white. */
body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .arrow-button:hover .arrow-button__arrow {
    border-color: var(--tgc-violet);
    background-color: var(--tgc-violet);
    color: var(--theme-white);
}

/* The drop-down panel stays a light card, so put its own colours back. */
body:has([data-tgc-hero]) .site-header:not(.is-stuck):not(.is-menu-open) .main-nav .sub-menu a {
    color: var(--tgc-ink);
}

/*
 * Scroll take-over hooks.
 * Consumed by scripts/tgc-scroll.js. These are deliberately structure-agnostic:
 * the attribute can sit on a section, a block wrapper or anything else, at any
 * depth. Everything here is CSS-first, so with JavaScript off the page is laid
 * out correctly and simply does not move.
 */
[data-tgc-bg] {
    position: relative;
    z-index: 1;
}

[data-tgc-bg="cream"] {
    background-color: var(--tgc-cream);
}

[data-tgc-bg="white"] {
    background-color: var(--tgc-card);
}

[data-tgc-bg="violet-soft"] {
    background-color: var(--tgc-violet-soft);
}

[data-tgc-bg="violet"] {
    background-color: var(--tgc-violet);
    color: var(--theme-white);
}

/*
 * A band inside a band (the statement sits in the cream group on every
 * service page) takes its parent's ground rather than painting a layer of
 * its own. Otherwise its cream sits over the flying mark, which is drawn
 * between the band's background and its copy.
 */
[data-tgc-bg] [data-tgc-bg] {
    position: static;
    z-index: auto;
    background-color: transparent;
}

/*
 * Sticky motif in the split panels. Zero specificity so the owning component
 * can override any of it without a fight.
 */
:where([data-tgc-sticky]) {
    position: sticky;
    top: calc(120 * var(--tgc-u));
    align-self: start;
}



/*
 * Phones: "treat the header differently on mobile so that it only has the
 * icon at the top on the purple background, then the header and body copy
 * can move up and sit below the purple box. The purple header could also be
 * made shorter." So the violet moves from the section onto the mark's own
 * wrapper, a short full-width box, and the title drops onto the cream under it.
 */
@media (max-width: 768px) {
    .service-hero,
    .service-hero--short {
        display: block;
        min-height: 0;
        padding: 0;
        border-radius: 0;
        background-color: transparent;
        color: var(--tgc-ink);
    }

    /* The entrance plays inside this box here (tgc-service-intro.js), so it is
       clipped to it rather than spilling white over the cream below.
       isolation keeps older Safari clipping the moving dots to the corners. */
    .service-hero__motif {
        padding: calc(var(--service-hero-offset) + 28px) 20px 40px;
        border-radius: 0 0 40px 40px;
        background-color: var(--tgc-violet);
        overflow: hidden;
        isolation: isolate;
    }

    .service-hero__title {
        margin-top: 36px;
        padding: 0 20px;
        font-size: clamp(1.625rem, 7.4vw, 2.25rem);
        line-height: 1.2;
        color: var(--tgc-ink);
    }
}

@media (prefers-reduced-motion: reduce) {
    :where([data-tgc-sticky]) {
        position: static;
    }
}

/* Figma draws the hero motif at 144.288px. The statement's mark is drawn at
   the same size, because on scroll the one hands over to the other in place. */
.service-hero .motif--md,
.statement .motif--md {
    width: calc(144.29 * var(--tgc-u));
}

/*
 * The take-over (scripts/tgc-scroll.js). The cream band has to cover the
 * whole screen as it takes the hero over, so the hero is a full screen tall
 * wherever the pinned take-over runs.
 */
@media (min-width: 969px) {
    .service-hero {
        min-height: 100vh;
        min-height: 100svh;
    }
}

/* The marks the flyer stands in for keep their room but are not drawn. */
.tgc-flight-slot {
    visibility: hidden;
}

/* z-index -1 inside the band's stacking context: see buildFlyer(). */
.tgc-flyer {
    position: fixed;
    top: 0;
    left: 0;
    z-index: -1;
    visibility: hidden;
    pointer-events: none;
    will-change: transform;
}

.tgc-flyer__turn,
.tgc-flyer__idle {
    width: 100%;
    height: 100%;
}

.tgc-flyer__layer {
    position: absolute;
    inset: 0;
    width: 100%;
}

/* Once it has landed beside the copy it turns slowly, or on Development,
   where the stacked bowls have an obvious upright, sways on its base. */
.tgc-flyer__idle--spin {
    animation: tgc-spin 48s linear infinite paused;
}

/*
 * The sway is one swing from side to side, run forwards then back
 * (alternate), so it only eases at the two ends like a pendulum. It used to
 * pass through upright as two separate eased steps, which brought it to a
 * dead stop mid-swing on every left-to-right pass. The negative delay starts
 * it half-way through a swing — upright and already moving — so there is no
 * jump when it lands. Same 3.6s for the full there-and-back.
 */
.tgc-flyer__idle--wobble {
    transform-origin: 50% 100%;
    animation: tgc-wobble 1.8s cubic-bezier(0.37, 0, 0.63, 1) -0.9s infinite alternate paused;
}

.tgc-flyer.is-idle .tgc-flyer__idle {
    animation-play-state: running;
}

.tgc-flyer.is-shown {
    animation: tgc-fade-in 0.38s ease-out both;
}

@keyframes tgc-fade-in {
    from {
        opacity: 0;
    }
}

@keyframes tgc-wobble {
    from {
        transform: rotate(-3.5deg);
    }

    to {
        transform: rotate(3.5deg);
    }
}
