/* ==========================================================================
   custom.css — styles authored for this page, moved out of index.html.

   Blocks appear in the SAME order they sat in the markup. That ordering is
   load-bearing: several rules rely on being declared after an earlier one at
   equal specificity, so do not sort or regroup them.

   Linked after style.css and responsive.css so it still wins the cascade,
   exactly as the inline blocks did.
   ========================================================================== */

/* ---- Favicon and Touch Icons was index.html line 21 ---- */
     /* Sticky bar. The theme ships #161616, a neutral black that reads as a
        different, greyer tone next to the deep navy the dark sections use
        (#0B0D14 on the carousel card, #0D0F1E / #15162C on the band behind it).
        ID selector so it beats .header.is-fixed wherever that is declared.
        Kept slightly translucent with a blur so page content tints through
        rather than the bar sitting on top as a flat slab. */
     #header_main.is-fixed {
         border-bottom: 1px solid rgba(255, 255, 255, .10);
         box-shadow: 0 12px 30px rgba(0, 0, 0, .38);
     }

     /* The tint and blur live on a pseudo-element, NOT on the header.
        backdrop-filter makes an element a containing block for its
        position: fixed descendants — and the off-canvas mobile drawer is one
        of those. With the filter on the header, the drawer's `top: 0;
        height: 100%` resolved against the 105px bar instead of the viewport,
        so it opened as a 105px sliver with the page showing through beneath.
        Moving the effect one level down keeps the look and leaves the drawer
        anchored to the viewport. */
     #header_main.is-fixed::before {
         content: "";
         position: absolute;
         inset: 0;
         z-index: -1;
         pointer-events: none;
         background: rgba(11, 13, 20, .92);
         -webkit-backdrop-filter: blur(14px);
         backdrop-filter: blur(14px);
     }

     /* The theme turned the sticky bar transparent below 600px. The logo is
        the white lockup, so over the page's light sections it disappeared —
        the bar keeps its background at every width now, just more opaque
        since there is no room for the copy to breathe on a phone. */
     @media only screen and (max-width: 600px) {
         #header_main.is-fixed::before { background: rgba(11, 13, 20, .96); }
     }

     /* .header is 105px but .header-inner is only as tall as its content, so the menu
        row hugs the top of the bar. Fill the bar so the row centres inside it. */
     #header_main .header-inner {
         height: 105px;
         padding-top: 0;
         padding-bottom: 0;
     }


     #about{
         padding:60px 0 !important;
         /* Decorative hatched ellipse behind the About content. The artwork
            is pale grey line art on transparency (1160x460), so it needs the
            plain page white underneath to read at all — no tint here.
            Oversized and centred so the ring frames the copy and collage
            rather than sitting in a corner. */
         position: relative;
         background-image: url("../img/about-shape-1.png");
         background-repeat: no-repeat;
         background-position: center 42%;
         background-size: 1500px auto;
     }

     @media (max-width: 1199px) {
         #about{
             background-size: 1150px auto;
         }
     }

     @media (max-width: 767px) {
         /* at phone widths the ring is wider than the viewport and reads as
            stray diagonal lines behind the text */
         #about{
             background-image: none;
         }
     }

     .elets-cta {
         position: fixed;
         left: 50%;
         bottom: 24px;
         right: auto;
         transform: translateX(-50%);
         z-index: 1035;
         max-width: 700px;
         display: flex;
         align-items: stretch;
         border-radius: 60px;
         overflow: hidden;
         background: linear-gradient(135deg, #0B1F3A 0%, #14315C 100%);
         box-shadow: 0 10px 30px rgba(11, 31, 58, .35);
         font-family: inherit;
         transition: transform .25s ease, box-shadow .25s ease;
         animation: eletsPulse 2.8s ease-out 1.2s 3;
     }

     .elets-cta:hover {
         transform: translateX(-50%) translateY(-3px);
         box-shadow: 0 16px 38px rgba(11, 31, 58, .45);
     }

     .elets-cta__link {
         display: flex;
         align-items: center;
         justify-content: center;
         gap: 14px;
         padding: 16px 18px;
         color: #fff;
         text-decoration: none;
         font-size: 1.6rem;
         line-height: 1.35;
         flex: 1 1 auto;
         min-width: 0;
     }

     .elets-cta__link:hover,
     .elets-cta__link:focus {
         color: #fff;
         text-decoration: none;
     }

     .elets-cta__link:focus-visible {
         outline: 3px solid #F5B301;
         outline-offset: -3px;
     }

     .elets-cta__badge {
         flex: 0 0 auto;
         background: #F5B301;
         color: #0B1F3A;
         font-weight: 700;
         font-size: .9rem;
         letter-spacing: .04em;
         text-transform: uppercase;
         padding: 6px 14px;
         border-radius: 40px;
         white-space: nowrap;
     }

     .elets-cta__text {
         font-weight: 700;
         flex: 0 1 auto;
         min-width: 0;
     }

     .elets-cta__arrow {
         flex: 0 0 auto;
         width: 44px;
         height: 44px;
         border-radius: 50%;
         background: rgba(255, 255, 255, .14);
         display: flex;
         align-items: center;
         justify-content: center;
         font-size: 1.6rem;
         line-height: 1;
         transition: background .2s ease, transform .2s ease;
     }

     .elets-cta:hover .elets-cta__arrow {
         background: #F5B301;
         color: #0B1F3A;
         transform: translateX(3px);
     }

     @keyframes eletsPulse {

         0%,
         100% {
             box-shadow: 0 10px 30px rgba(11, 31, 58, .35), 0 0 0 0 rgba(245, 179, 1, .5);
         }

         50% {
             box-shadow: 0 10px 30px rgba(11, 31, 58, .35), 0 0 0 12px rgba(245, 179, 1, 0);
         }
     }

     /* Mobile: full-width bottom bar */
     @media (max-width:767.98px) {
         .elets-cta {
             left: 0;
             right: 0;
             bottom: 0;
             max-width: none;
             transform: none;
             border-radius: 14px 14px 0 0;
             animation: none;
             padding-bottom: env(safe-area-inset-bottom);
         }

         .elets-cta:hover {
             transform: none;
         }

         .elets-cta__link {
             padding: 14px 16px;
             font-size: 1.05rem;
             gap: 10px;
         }

         .elets-cta__badge {
             font-size: .78rem;
             padding: 4px 11px;
         }

         .elets-cta__arrow {
             width: 36px;
             height: 36px;
             font-size: 1.3rem;
         }
     }

     @media (max-width:359.98px) {
         .elets-cta__badge {
             display: none;
         }

         .elets-cta__link {
             font-size: .95rem;
         }
     }

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

         .elets-cta,
         .elets-cta__arrow {
             animation: none;
             transition: none;
         }

         .elets-cta:hover {
             transform: translateX(-50%);
         }
     }

     /* Tagline band directly below the hero banner */
     .elets-tagline {
         background: #fff;
         padding: 30px 0;
         text-align: center;
         position: relative;
         overflow: hidden;
     }

     .elets-tagline::before {
         content: "";
         position: absolute;
         inset: 0;
         pointer-events: none;
         background: radial-gradient(58% 130% at 50% 42%,
                 rgba(58, 111, 216, .075) 0%,
                 rgba(245, 179, 1, .055) 44%,
                 rgba(255, 255, 255, 0) 74%);
     }

     .elets-tagline__text {
         margin: 0;
         position: relative;
         font-weight: 700;
         font-size: clamp(1.5rem, 3.8vw, 3.15rem);
         line-height: 1.28;
         letter-spacing: -.015em;
         word-spacing: .06em;
     }

     /* each word rises + un-blurs, staggered via --d.
the gradient lives on the word itself, not the parent: background-clip:text
on an ancestor would swallow the per-word opacity/blur. */
     .elets-tagline__text .w {
         display: inline-block;
         color: #14315C;
         background: linear-gradient(120deg, #0B1F3A 0%, #14315C 45%, #3A6FD8 100%);
         -webkit-background-clip: text;
         background-clip: text;
         -webkit-text-fill-color: transparent;
         opacity: 0;
         transform: translateY(24px);
         filter: blur(6px);
     }

     .elets-tagline.is-visible .w {
         animation: eletsWordIn .7s cubic-bezier(.22, .61, .36, 1) var(--d, 0s) forwards;
     }

     @keyframes eletsWordIn {
         to {
             opacity: 1;
             transform: translateY(0);
             filter: blur(0);
         }
     }

     /* gold accent phrase — shimmer is staggered per word so the highlight
travels across "Premier AI Summit" instead of pulsing all at once */
     .elets-tagline__accent {
         font-style: normal;
         display: inline-block;
         position: relative;
     }

     /* background-image, NOT the `background` shorthand: the shorthand resets
background-clip to border-box and the text renders as a solid gold block */
     .elets-tagline__accent .w {
         color: #F5B301;
         background-image: linear-gradient(100deg, #E8A100 0%, #F5B301 38%, #FFE9A8 50%, #F5B301 62%, #E8A100 100%);
         background-size: 280% 100%;
         -webkit-background-clip: text;
         background-clip: text;
     }

     .elets-tagline.is-visible .elets-tagline__accent .w {
         animation: eletsWordIn .7s cubic-bezier(.22, .61, .36, 1) var(--d, 0s) forwards,
             eletsShimmer 3.4s ease-in-out calc(1.6s + var(--d, 0s)) infinite;
     }

     @keyframes eletsShimmer {
         0% {
             background-position: 120% 0;
         }

         55%,
         100% {
             background-position: -20% 0;
         }
     }

     @media (max-width:767.98px) {
         .elets-tagline {
             padding: 10px 16px;
         }
     }

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

         .elets-tagline__text .w,
         .elets-tagline.is-visible .w,
         .elets-tagline.is-visible .elets-tagline__accent .w {
             opacity: 1;
             transform: none;
             filter: none;
             animation: none;
         }
     }

/* ---- design was index.html line 783 ---- */
            /* Section masthead — left-aligned display type with a Playfair
               italic accent, deliberately unlike the centred gradient band
               this line used to live in. */
            /* Stacked, not side by side: the masthead sits in the copy column
               now, and a hairline running beside the headline needs width the
               column does not have. */
            /* Spans the whole section, so the copy column below it starts at
               the same line as the photographs. Spacing underneath is the
               grid's row-gap rather than a margin here — with both, the two
               stacked and left 86px of air under the rule. */
            .abx__head {
                grid-column: 1 / -1;
            }

            .abx__headline {
                margin: 0;
                font-family: 'Plus Jakarta Sans', sans-serif;
                color: #030014;
                /* px, not rem — this theme sets html{font-size:10px}, so rem
                   values here are 10/16ths of what they look like */
                /* stepped down from 4.4vw: the headline used to run the full
                   section width and now has roughly a third of it */
                font-size: clamp(28px, 2.9vw, 40px);
                font-weight: 700;
                line-height: 1.08;
                letter-spacing: -.03em;
            }

            /* Scroll reveal, shared by every [data-split] headline on the page
               (the About masthead and the Business Opportunities banner). The
               script below splits each one into per-character spans and each
               character fades up out of a blur on a short stagger. Characters
               only exist once the script has run, so with JS off the headlines
               just render as plain text. */
            [data-split] .c {
                display: inline-block;
                opacity: 0;
                filter: blur(8px);
                will-change: opacity, filter;
            }

            [data-split] .w {
                display: inline-block;
                white-space: nowrap;
            }

            [data-split].is-in .c {
                opacity: 1;
                filter: blur(0);
                transition: opacity 1.2s cubic-bezier(.215, .61, .355, 1),
                            filter 1.2s cubic-bezier(.215, .61, .355, 1);
                transition-delay: calc(var(--i) * 22ms);
            }

            /* Short windows have to run the cascade faster, because the
               headline is only on screen for as long as it takes to scroll
               past it. A 36-character headline costs 36*22ms of stagger on
               top of the 1.2s fade, so the last characters need ~2s — about
               1000px of scrolling at a normal wheel pace. A 1040px-tall
               window gives them that and the headline reads as finished by
               the time it reaches the header; a 691px laptop window gives
               roughly half, so it slid under the header with 17 of its 36
               characters still blurred and the effect looked broken rather
               than deliberate. These figures bring the whole cascade in
               around 1s, which fits the travel a laptop actually has.
               Measured at the same pace, all 36 now land. */
            @media (max-height: 900px) {
                [data-split].is-in .c {
                    transition-duration: .65s, .65s;
                    transition-delay: calc(var(--i) * 10ms);
                }
            }

            @media (prefers-reduced-motion: reduce) {
                [data-split] .c {
                    opacity: 1;
                    filter: none;
                }
            }

            /* Block-level companion to [data-split]: lifts a container's children
               in on a stagger and replays every time the group re-appears. The
               hidden state is gated on .is-armed, which the script adds, so the
               content stays visible if the JS never runs. .bizo__title is skipped
               because it does its own per-character cascade. */
            [data-reveal].is-armed > *:not(.bizo__title) {
                opacity: 0;
                transform: translateY(18px);
            }

            [data-reveal].is-armed.is-in > *:not(.bizo__title) {
                opacity: 1;
                transform: translateY(0);
                transition: opacity .7s ease, transform .7s cubic-bezier(.22, 1, .36, 1);
            }

            [data-reveal].is-armed.is-in > *:nth-child(1) { transition-delay: .05s; }
            [data-reveal].is-armed.is-in > *:nth-child(2) { transition-delay: .12s; }
            [data-reveal].is-armed.is-in > *:nth-child(3) { transition-delay: .19s; }
            [data-reveal].is-armed.is-in > *:nth-child(4) { transition-delay: .26s; }

            /* Same reasoning as the [data-split] block above: on a laptop the
               group is past the header before a .7s fade on a .26s stagger has
               played out. Written after the delays it overrides rather than
               beside the split rule, since these are the same specificity and
               source order is what decides. */
            @media (max-height: 900px) {
                [data-reveal].is-armed.is-in > *:not(.bizo__title) {
                    transition-duration: .5s, .5s;
                }

                [data-reveal].is-armed.is-in > *:nth-child(1) { transition-delay: .03s; }
                [data-reveal].is-armed.is-in > *:nth-child(2) { transition-delay: .08s; }
                [data-reveal].is-armed.is-in > *:nth-child(3) { transition-delay: .13s; }
                [data-reveal].is-armed.is-in > *:nth-child(4) { transition-delay: .18s; }
            }

            @media (prefers-reduced-motion: reduce) {
                [data-reveal].is-armed > *:not(.bizo__title) {
                    opacity: 1;
                    transform: none;
                }
            }

            .abx__headline em {
                font-family: 'Playfair Display', serif;
                font-style: italic;
                font-weight: 500;
                color: #6844ED;
                letter-spacing: -.01em;
                /* Playfair's italic side bearings are tight — without this the
                   accent collides with the words either side of it */
                margin: 0 .1em 0 .07em;
            }

            /* hairline under the headline, fading out to the right so it leads
               the eye toward the photographs rather than boxing the copy in */
            .abx__head-rule {
                display: block;
                width: 100%;
                height: 1px;
                margin: 20px 0 0;
                background: linear-gradient(90deg, #D7DBE5 0%, #E9ECF3 60%, rgba(233, 236, 243, 0) 100%);
            }

            @media (max-width: 991px) {
                /* full width again here, so the authored line break would leave
                   a short, ragged second line */
                .abx__headline br {
                    display: none;
                }
            }

            /* About — text block top-left with a staggered photo collage.
               Columns carry their own top offset so the grid reads as
               scattered rather than aligned. */
            .abx {
                display: grid;
                /* copy | photo collage. The stats rail that used to be a
                   third column now runs as its own band under the hero. */
                grid-template-columns: minmax(0, 36%) minmax(0, 1fr);
                /* row gap sits under the full-width masthead, column gap is the
                   channel between the copy and the photographs */
                gap: 32px 60px;
                /* Top, not centre. The masthead used to live in the copy column,
                   which made that column nearly as tall as the collage and let
                   centring pass unnoticed; with the heading lifted out, centring
                   would float the paragraphs halfway down the photographs. */
                align-items: start;
                text-align: left;
                padding: 10px 0 30px;
            }

            .abx__text p {
                color: #5A5F6B;
                font-size: 17px;
                line-height: 1.72;
                margin-bottom: 18px;
            }

            .abx__lead {
                color: #14192B !important;
                font-size: 17px !important;
                line-height: 1.55 !important;
                font-weight: 400;
                letter-spacing: -.01em;

            }

            /* Emphasis in the About copy. The body paragraphs are grey, so weight
               alone barely registers — the darker colour is what makes the phrase
               pull forward. Inside the lead the colour already matches, so there
               it is weight only. */
            .abx__text strong {
                font-weight: 700;
                color: #14192B;
            }

            .abx__lead strong {
                font-weight: 700;
                color: inherit;
            }

            /* ---- About "View More" ------------------------------------
               The panel animates on grid-template-rows 0fr -> 1fr, which
               is the only way to transition to auto height without
               measuring in JS. Both the collapsed state and the button
               are gated on .is-armed, added by the script, so with JS off
               the paragraph stays open and no dead button is rendered. */
            .abx__more {
                display: grid;
                grid-template-rows: 1fr;
            }

            .abx__more-inner {
                overflow: hidden;
                min-height: 0;
            }

            .abx__text.is-armed .abx__more {
                grid-template-rows: 0fr;
                transition: grid-template-rows .45s cubic-bezier(.22, 1, .36, 1);
            }

            .abx__text.is-armed .abx__more-inner {
                opacity: 0;
                transition: opacity .25s ease;
            }

            .abx__text.is-armed.is-open .abx__more {
                grid-template-rows: 1fr;
            }

            .abx__text.is-armed.is-open .abx__more-inner {
                opacity: 1;
                transition: opacity .4s ease .12s;
            }

            /* last paragraph inside the panel keeps its margin off the
               button when open, and contributes nothing when closed */
            .abx__more-inner p:last-child {
                margin-bottom: 18px;
            }

            /* Disclosure control, not a CTA — deliberately lighter than
               .btn-split so it never competes with Express Interest. Reads as
               editorial type with a circular chevron; the circle is the one
               round shape in a section of square photos, which is what makes
               it register as a control rather than a caption. */
            .abx__toggle {
                display: none;
                align-items: center;
                gap: 12px;
                margin-top: 4px;
                /* style.css styles every bare <button> as a purple pill: fixed
                   51px height, 14px radius, 20px/48px padding and an icomoon
                   arrow on ::after. All of it has to come back off here, the
                   ::after especially — it was printing a stray glyph straight
                   through the label. */
                height: auto;
                padding: 0;
                border: 0;
                border-radius: 0;
                background: none;
                font-family: 'Plus Jakarta Sans', sans-serif;
                font-size: 15px;
                font-weight: 600;
                line-height: 1;
                letter-spacing: -.01em;
                color: #14192B;
                cursor: pointer;
                transition: color .28s ease;
            }

            .abx__toggle::after {
                content: none;
            }

            .abx__text.is-armed .abx__toggle {
                display: inline-flex;
            }

            .abx__toggle-label {
                position: relative;
                padding-bottom: 6px;
            }

            /* hairline under the label, same gradient family as the masthead
               rule above — sits at rest and firms up to solid purple on hover */
            .abx__toggle-label::after {
                content: "";
                position: absolute;
                left: 0;
                right: 0;
                bottom: 0;
                height: 1px;
                background: #D7DBE5;
                transition: background .28s ease;
            }

            .abx__toggle-icon {
                display: grid;
                place-items: center;
                width: 30px;
                height: 30px;
                border-radius: 50%;
                border: 1px solid rgba(104, 68, 237, .3);
                color: #6844ED;
                transition: background .28s ease, border-color .28s ease, color .28s ease,
                    transform .4s cubic-bezier(.22, 1, .36, 1);
            }

            .abx__toggle-icon svg {
                width: 14px;
                height: 14px;
            }

            .abx__toggle:hover,
            .abx__toggle:focus-visible {
                color: #6844ED;
            }

            .abx__toggle:hover .abx__toggle-label::after,
            .abx__toggle:focus-visible .abx__toggle-label::after {
                background: #6844ED;
            }

            .abx__toggle:hover .abx__toggle-icon,
            .abx__toggle:focus-visible .abx__toggle-icon {
                background: #6844ED;
                border-color: #6844ED;
                color: #fff;
            }

            /* chevron points up once the panel is open */
            .abx__text.is-open .abx__toggle-icon {
                transform: rotate(180deg);
            }

            .abx__toggle:focus-visible {
                outline: 2px solid rgba(104, 68, 237, .35);
                outline-offset: 6px;
                border-radius: 2px;
            }

            @media (max-width: 767px) {
                .abx__toggle {
                    font-size: 14px;
                }
            }

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

                .abx__text.is-armed .abx__more,
                .abx__text.is-armed .abx__more-inner,
                .abx__toggle,
                .abx__toggle-icon,
                .abx__toggle-label {
                    transition: none;
                }

                .abx__toggle:hover {
                    transform: none;
                }
            }

            .abx__grid {
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 16px;
                align-items: start;
            }

            .abx__col {
                display: flex;
                flex-direction: column;
                gap: 16px;
            }

            /* The right column drops, so the four photos step down across the
               block instead of sitting as a flat 2x2. Both columns are the same
               height (sq + wide either way round), so the offset is the only
               thing breaking the line. */
            .abx__col--2 {
                margin-top: 46px;
            }

            .abx__ph {
                margin: 0;
                overflow: hidden;
                border-radius: 12px;
                background: #EEF1F6;
                /* soft lift off the near-white section background; without it the
                   photos float with no edge at all */
                box-shadow: 0 12px 28px rgba(3, 0, 20, .10), 0 2px 6px rgba(3, 0, 20, .06);
                transition: transform .55s cubic-bezier(.22, 1, .36, 1),
                            box-shadow .55s cubic-bezier(.22, 1, .36, 1);
            }

            .abx__ph img {
                display: block;
                width: 100%;
                height: 100%;
                object-fit: cover;
                transition: transform .7s cubic-bezier(.22, 1, .36, 1);
            }

            /* the frame lifts and the picture pushes in behind it */
            .abx__ph:hover {
                transform: translateY(-6px);
                box-shadow: 0 22px 46px rgba(3, 0, 20, .16), 0 3px 8px rgba(3, 0, 20, .07);
            }

            .abx__ph:hover img {
                transform: scale(1.055);
            }

            .abx__ph--wide {
                aspect-ratio: 3 / 2;
            }

            .abx__ph--sq {
                aspect-ratio: 1 / 1;
            }

            .abx__ph--tall {
                aspect-ratio: 3 / 4;
            }

            .abx__ph--xtall {
                aspect-ratio: 3 / 3.6;
            }

            @media (max-width: 1199px) {
                .abx {
                    grid-template-columns: 1fr;
                    gap: 26px;
                }

            }

            @media (max-width: 767px) {

                /* Flatten the two column stacks so all four photos flow through
                   one 2-up grid, which drops the desktop stagger with them. */
                .abx__col {
                    display: contents;
                }

                .abx__grid {
                    grid-template-columns: repeat(2, 1fr);
                    gap: 10px;
                }

                /* tighter frames at phone scale */
                .abx__ph {
                    border-radius: 9px;
                    box-shadow: 0 6px 16px rgba(3, 0, 20, .09);
                }

                .abx__lead {
                    font-size: 18px !important;
                }

                .abx__text p {
                    font-size: 15px;
                }
            }

/* ------------------------------------------------------------------ stats
   Event numbers band, directly under the hero. Was a right-hand rail in the
   About section; as a full-width band it reads number-first instead of
   label-first.

   Continuous with the hero: #09081A is the exact colour the hero's scrim now
   ramps to at its bottom edge, so the two butt together with no visible seam
   and read as one block. */
.stats {
    background: #09081A;
    padding: 30px 0;
}

.stats__row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    align-items: start;
}

.stats__item {
    padding: 2px 26px;
    text-align: center;
}

.stats__item + .stats__item {
    border-left: 1px solid rgba(255, 255, 255, .13);
}

.stats__num {
    /* inline-block, not block: the hover fill is a background wipe clipped to
       the text, so the box has to hug the glyphs or the wipe starts in empty
       space beside them */
    display: inline-block;
    font-family: 'Plus Jakarta Sans', sans-serif;
    color: #fff;
    font-size: 54px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -2px;
    /* stops the digits jittering while the value counts up */
    font-variant-numeric: tabular-nums;
}

/* green rather than the purple it used on white: the purple goes muddy
   against #09081A, the green is the hero's own accent */
.stats__plus {
    color: #00E58F;
    font-size: .6em;
    letter-spacing: 0;
    margin-left: 2px;
}

.stats__label {
    display: block;
    margin-top: 11px;
    color: rgba(255, 255, 255, .62);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .03em;
    line-height: 1.5;
}

/* Outlined numerals that fill on hover. Gated on @supports so any browser
   without text-stroke keeps solid numbers rather than transparent ones, and on
   (hover:hover) so touch devices — which can never trigger the fill — never
   get the hollow state. */
@supports ((-webkit-text-stroke: 1px #000) and
           ((-webkit-background-clip: text) or (background-clip: text))) {
    @media (hover: hover) and (min-width: 992px) {
        .stats__num,
        .stats__plus {
            -webkit-text-fill-color: transparent;
            background-repeat: no-repeat;
            background-size: 0% 100%;
            -webkit-background-clip: text;
            background-clip: text;
            transition: background-size .65s cubic-bezier(.22, 1, .36, 1);
        }

        .stats__num {
            -webkit-text-stroke: 1.4px rgba(255, 255, 255, .8);
            background-image: linear-gradient(#fff, #fff);
        }

        .stats__plus {
            -webkit-text-stroke: 1.2px #00E58F;
            background-image: linear-gradient(#00E58F, #00E58F);
        }

        /* whole cell is the hover target, so the label reacts too */
        .stats__item:hover .stats__num,
        .stats__item:hover .stats__plus {
            background-size: 100% 100%;
        }

        .stats__label {
            transition: color .45s ease;
        }

        .stats__item:hover .stats__label {
            color: #fff;
        }
    }
}

/* The hidden state is only armed once the script runs, so the numbers stay
   visible if JS never executes. */
.stats__row.is-armed .stats__item {
    opacity: 0;
    transform: translateY(14px);
}

.stats__row.is-armed.is-visible .stats__item {
    opacity: 1;
    transform: none;
    transition: opacity .6s ease, transform .6s cubic-bezier(.22, 1, .36, 1);
    transition-delay: var(--d, 0s);
}

@media (max-width: 991px) {
    .stats { padding: 44px 0 40px; }
    .stats__row { grid-template-columns: repeat(2, 1fr); }
    .stats__item { padding: 22px 16px; }

    /* in a 2x2 the left-hand cells lose the divider and row two gains one */
    .stats__item:nth-child(odd) { border-left: 0; }
    .stats__item:nth-child(n+3) { border-top: 1px solid rgba(255, 255, 255, .13); }

    .stats__num { font-size: 42px; letter-spacing: -1.4px; }
}

@media (max-width: 575px) {
    .stats { padding: 34px 0 30px; }
    .stats__item { padding: 18px 10px; }
    .stats__num { font-size: 34px; letter-spacing: -1.1px; }
    .stats__label { font-size: 12px; margin-top: 8px; }
}

@media (prefers-reduced-motion: reduce) {
    .stats__row.is-armed.is-visible .stats__item {
        transition-duration: .01ms;
    }
}

/* ---- design was index.html line 1291 ---- */
.partnr {
    border: 1px solid rgb(219, 219, 219);
    padding: 15px 10px;
    /* box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; */
    border-radius: 10px;
    min-height: 170px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    margin: 0 0 20px;
}

.partnr p {
    margin: 0 0 10px;
    color: #000;
    font-weight: 600;
    font-size: 17px;
}

/* size by height, not width: the two logos have different native
   widths (150px vs 2084px) but similar ratios, so a shared cap
   height makes them read as optically balanced */
.partnr__logo {
    max-height: 72px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

/* ---- partners band -------------------------------------------
   The section is full-bleed (the .container lives inside it), so
   the backdrop runs edge to edge while the cards stay on grid.
   The artwork is dark, so everything in here that the theme
   ships as near-black is flipped to white further down. */
.partners-ai {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    /* pt-50 in the markup isn't a class this theme defines, so
       the padding is set here rather than relying on it */
    padding: 64px 0 72px;
    /* first layer is a scrim: the artwork has a bright lime
       corner that white text would not survive on its own */
    background:
        linear-gradient(180deg, rgba(9, 11, 20, .62) 0%, rgba(9, 11, 20, .52) 45%, rgba(9, 11, 20, .66) 100%),
        url("../img/partners-bg.png") center / cover no-repeat,
        #14161F;
    /* Artwork holds still while the band scrolls over it. Listed
       per layer — the scrim must keep scrolling with the section
       or it stops covering it. The `background` shorthand above
       resets attachment, so this has to come after it. */
    background-attachment: scroll, fixed;
}

/* iOS Safari ignores fixed attachment and Android browsers repaint
   badly on it; both size the layer to the viewport and leave the
   artwork mis-cropped. Touch and small screens get the normal
   behaviour, as does anyone who has asked for less motion. */
@media (hover: none), (max-width: 991px) {
    .partners-ai { background-attachment: scroll, scroll; }
}

@media (prefers-reduced-motion: reduce) {
    .partners-ai { background-attachment: scroll, scroll; }
}

/* hairlines so the band separates from the white sections above
   and below it */
.partners-ai::before,
.partners-ai::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    z-index: 3;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .22), transparent);
}

.partners-ai::before { top: 0; }
.partners-ai::after { bottom: 0; }

.partners-ai > .container {
    position: relative;
    z-index: 2;
}

/* fine dot grid, masked to fade out before it reaches the edges
   so it never fights with the card borders */
.partners-ai__fx {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background-image: radial-gradient(rgba(255, 255, 255, .12) 1px, transparent 1px);
    background-size: 28px 28px;
    -webkit-mask-image: radial-gradient(ellipse 78% 62% at 50% 50%, #000 25%, transparent 78%);
    mask-image: radial-gradient(ellipse 78% 62% at 50% 50%, #000 25%, transparent 78%);
}

/* the theme's heading and sub-label are near-black, which the
   dark artwork would swallow */
.partners-ai .heading-section .main-title { color: #fff; }
.partners-ai .heading-section .main-title span { color: #C9BDFF; }
#partners .partner_title,
#past-partners .partner_title { color: #fff; }

/* solid white cards — the Red Hat and Flytxt logos are JPGs with
   their own white background baked in, so a transparent card
   would show them as pale rectangles on the tinted band */
#partners .partnr,
#past-partners .partnr {
    background: #fff;
    border-color: rgba(255, 255, 255, .18);
    /* dark shadow, not the tinted one a light band wants */
    box-shadow: 0 12px 32px rgba(0, 0, 0, .34);
    transition: transform .35s cubic-bezier(.22, 1, .36, 1),
                box-shadow .35s ease, border-color .35s ease;
}

#partners .partnr:hover,
#past-partners .partnr:hover {
    transform: translateY(-4px);
    border-color: rgba(201, 189, 255, .75);
    box-shadow: 0 18px 42px rgba(0, 0, 0, .45);
}

/* circuit ticks either side of the "Exhibitor Partners" label */
#partners .partner_title,
#past-partners .partner_title {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

#partners .partner_title::before,
#partners .partner_title::after,
#past-partners .partner_title::before,
#past-partners .partner_title::after {
    content: "";
    width: 46px;
    height: 1px;
    /* lilac, not the #6844ED used on the light band — the solid
       purple is too close in value to the artwork behind it */
    background: linear-gradient(90deg, transparent, #C9BDFF);
}

#partners .partner_title::after,
#past-partners .partner_title::after {
    background: linear-gradient(90deg, #C9BDFF, transparent);
}

@media (max-width: 767px) {
    .partners-ai { padding: 48px 0 56px; }
    #partners .partner_title::before,
    #partners .partner_title::after,
    #past-partners .partner_title::before,
    #past-partners .partner_title::after { width: 26px; }
}

@media (prefers-reduced-motion: reduce) {
    #partners .partnr,
    #past-partners .partnr { transition: none; }
}

/* ---- what awaits you was index.html line 1677 ---- */
/* What Awaits You — a three-up photo carousel on the plain page
   background. No band of its own: the cards carry the contrast,
   so the heading keeps the theme's default near-black. */
/* Same artwork and scrim as the partners band, so the two dark sections read
   as a pair. First layer is a scrim: the artwork has a bright lime corner that
   white text would not survive on its own. */
.awx {
    position: relative;
    overflow: hidden;
    padding: 64px 0 72px;
    background:
        linear-gradient(180deg, rgba(9, 11, 20, .62) 0%, rgba(9, 11, 20, .52) 45%, rgba(9, 11, 20, .66) 100%),
        url("../img/partners-bg.png") center / cover no-repeat,
        #14161F;
    /* Artwork holds still while the band scrolls over it. Listed per layer —
       the scrim must keep scrolling with the section or it stops covering it.
       The `background` shorthand above resets attachment, so this comes after. */
    background-attachment: scroll, fixed;
}

/* iOS Safari ignores fixed attachment and Android browsers repaint badly on
   it; both size the layer to the viewport and leave the artwork mis-cropped. */
@media (hover: none), (max-width: 991px) {
    .awx { background-attachment: scroll, scroll; }
}

/* the section title was near-black for a white page */
.awx .heading-section .main-title { color: #fff; }
.awx .heading-section .main-title span { color: #00FF97; }


/* this section runs wider than the site's 1320px container —
   the photo stage carries copy and a thumbnail strip side by
   side, so it needs the extra room. Only above 1200px; below
   that the default container width is already edge-to-edge.
   The gutter matches the one the main container reserves, so on
   a laptop the carousel sits on the same margin as every other
   section instead of pushing 20px closer to the glass. */
@media (min-width: 1200px) {
    .awx > .themesflat-container {
        width: 1600px;
        max-width: calc(100% - 64px);
    }
}

.awx__stage {
    position: relative;
    /* three across, so the frame has to be much wider than it is
       tall or each third ends up portrait and object-fit: cover
       guts a 3:2 photo. At 7:2 a third lands near 1.15:1. */
    --awx-gap: 16px;
    /* Definite width, or the box overflows its container: with only
       aspect-ratio + min-height set, once the ratio would make the
       stage shorter than min-height the clamped height is transferred
       back through the ratio into the width (400 x 2.5 = 1000px at the
       two-up breakpoint, whatever the container measures). Pinning the
       width keeps height the derived axis and lets min-height simply
       clamp it. */
    width: 100%;
    max-width: 100%;
    aspect-ratio: 7 / 2;
    min-height: 400px;
    max-height: 540px;
    overflow: hidden;
    /* the frame moved onto the individual slides, so the gaps
       between them show the section background through */
    background: transparent;
    isolation: isolate;
}

/* the rail: slides no longer crossfade in place, they slide.
   One page = one full stage width plus the gap that follows it,
   which is why the step is (100% + gap) and not just 100%. */
.awx__track {
    display: flex;
    gap: var(--awx-gap);
    height: 100%;
    will-change: transform;
    transition: transform .7s cubic-bezier(.22, 1, .36, 1);
}

/* every layer inside a slide carries an explicit z-index, and the
   slide itself is a stacking context — without that the copy
   ends up painted under the background image */
.awx__slide {
    position: relative;
    /* n slides across leaves n-1 gaps to subtract */
    flex: 0 0 calc((100% - 2 * var(--awx-gap)) / 3);
    height: 100%;
    overflow: hidden;
    /* the frame each photo carries. box-sizing is border-box
       globally, so the border does not widen the flex basis.
       Toned for the plain page background — a white border
       would simply vanish into it. */
    border: 1px solid rgba(3, 0, 20, .10);
    border-radius: 18px;
    background: #0B0D14;
    box-shadow: 0 16px 38px rgba(16, 8, 56, .16);
    transition: border-color .4s ease, box-shadow .4s ease, transform .4s cubic-bezier(.22, 1, .36, 1);
}

.awx__slide:hover {
    border-color: rgba(104, 68, 237, .45);
    box-shadow: 0 22px 48px rgba(16, 8, 56, .24);
}

.awx__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* only slightly above centre — the frame is close enough to
       the source ratio now that a hard bias cuts heads off */
    /* biased low: the upper third of the frame is the venue screen
       carrying the panellists' names, which competes with the wordmark */
    object-position: 50% 72%;
    /* no Ken Burns scale — it compounded the cover crop and read
       as the photo being zoomed in */
}

/* single bottom-to-top scrim: opaque along the bottom edge where
   the copy sits, clearing to nothing by the top so the photo
   reads. Ramped in several stops rather than one so the falloff
   stays smooth over bright projector screens. */
.awx__scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(to top,
            rgba(6, 8, 15, .96) 0%,
            rgba(6, 8, 15, .88) 18%,
            rgba(6, 8, 15, .68) 38%,
            rgba(6, 8, 15, .40) 58%,
            rgba(6, 8, 15, .16) 78%,
            rgba(6, 8, 15, 0) 100%);
}

.awx__inner {
    position: relative;
    z-index: 2;
    height: 100%;
    display: flex;
    align-items: flex-end;
    /* third-width slides now, so the copy runs the full width of
       its own slide from the left rather than hugging a corner */
    justify-content: flex-start;
    padding: 28px 24px 30px;
}

.awx__copy {
    max-width: 100%;
    text-align: left;
    color: #fff;
}

.awx__index {
    display: inline-block;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .18em;
    color: #00FF97;
    margin-bottom: 12px;
}

.awx__index::after {
    content: "";
    display: inline-block;
    width: 34px;
    height: 1px;
    background: rgba(255, 255, 255, .45);
    vertical-align: middle;
    margin-left: 12px;
}

.awx__title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    color: #00ff97;
    /* down from 40px — that was sized for a full-width slide */
    font-size: 22px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.4px;
    margin: 0 0 10px;
    text-shadow: 0 2px 18px rgba(0, 0, 0, .45);
}

.awx__desc {
    color: rgba(255, 255, 255, .85);
    font-size: 14.5px;
    line-height: 1.6;
    margin: 0;
    text-shadow: 0 1px 12px rgba(0, 0, 0, .45);
}

/* Copy lifts in behind the fade. The hidden state is scoped to
   :not(.is-active) on purpose — if the active slide also carried
   opacity:0 and relied on an override to undo it, the first
   slide can land on the page mid-transition and never paint.
   This way the visible slide has no opacity rule at all. */
.awx__copy > * {
    transition: opacity .6s ease, transform .6s cubic-bezier(.22, 1, .36, 1);
}

.awx__slide:not(.is-active) .awx__copy > * {
    opacity: 0;
    transform: translateY(18px);
}

.awx__slide.is-active .awx__index { transition-delay: .10s; }
.awx__slide.is-active .awx__title { transition-delay: .18s; }
.awx__slide.is-active .awx__desc  { transition-delay: .26s; }

/* Title left, arrows right, on one line above the carousel. */
.awx__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 36px;
}

.awx__head .heading-section {
    /* .heading-section centres by default and carries its own bottom margin;
       the row owns both now */
    margin-bottom: 0;
    text-align: left;
}

/* in the header row now, so it lays out in flow rather than being pinned to
   the bottom of the stage */
.awx__ui {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 20px;
}

/* the theme styles every <button> with padding and an icomoon
   arrow in ::after — both have to be cancelled here */
.awx__btn {
    padding: 0;
    height: auto;
    font-size: 0;
    line-height: 0;
    background-image: none;
}

.awx__btn::after {
    content: none;
    display: none;
}

.awx__nav {
    display: flex;
    gap: 12px;
}

.awx__btn {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    cursor: pointer;
    color: #fff;
    background: rgba(255, 255, 255, .10);
    border: 1px solid rgba(255, 255, 255, .35);
    backdrop-filter: blur(6px);
    transition: background .3s ease, border-color .3s ease, transform .3s ease;
}

.awx__btn svg { width: 20px; height: 20px; }

.awx__btn:hover {
    background: rgba(255, 255, 255, .2);
    transform: translateY(-2px);
}

.awx__btn--next {
    background: #00FF97;
    border-color: #00FF97;
    /* dark chevron: white on this green is unreadable */
    color: #04231A;
}

.awx__btn--next:hover {
    background: #16E68C;
    border-color: #16E68C;
}

/* The per-view ladder is 3 / 2 / 1. These breakpoints and the
   ones in wanted() below must stay in step — the flex-basis
   sets what is visible, the script sets how far a step moves
   and how many dots there are. */
@media (max-width: 1199px) {
    .awx__stage {
        aspect-ratio: 5 / 2;
        min-height: 400px;
        max-height: 560px;
    }
    .awx__slide { flex-basis: calc((100% - var(--awx-gap)) / 2); }
    .awx__inner { padding: 32px 26px 84px; }
    .awx__title { font-size: 26px; }
    .awx__ui { left: 34px; right: 34px; }
}

@media (max-width: 767px) {
    .awx__slide { flex-basis: 100%; }
    /* portrait viewports: a wide ratio would be a sliver here,
       so the stacked copy sets the height and the photo crops */
    .awx__stage {
        aspect-ratio: auto;
        height: 460px;
        min-height: 0;
        max-height: none;
    }
    .awx__inner { padding: 30px 20px 88px; }
    .awx__title { font-size: 26px; letter-spacing: -.6px; }
    .awx__desc { font-size: 14.5px; line-height: 1.6; }
    .awx__ui { left: 20px; right: 20px; bottom: 24px; }
    .awx__btn { width: 40px; height: 40px; }
    .awx__btn svg { width: 17px; height: 17px; }
}

@media (prefers-reduced-motion: reduce) {
    .awx__bg,
    .awx__track,
    .awx__copy > * { transition-duration: .01ms; }
}

/* ---- points of discussion was index.html line 2186 ---- */
/* full-bleed pastel wash — the .themesflat-container inside
   keeps the cards on grid. The artwork is light enough that the
   heading and card text need no scrim or colour changes. */
.pod {
    position: relative;
    overflow: hidden;
    padding: 60px 0;
    background:
        url("../img/discussion-bg.jpg") center / cover no-repeat,
        #FBFAFF;
}

.pod > .themesflat-container {
    position: relative;
    z-index: 2;
}

/* transform is written by the parallax script on every frame,
   so there is deliberately no keyframe animation here — the two
   would fight over the same property */
/* transform is written by the parallax script on every frame, so
   the vertical centring is done with top/margin rather than a
   translate — a translate here would be overwritten on the
   first scroll event and the image would jump down. */
/* Only the strip left of the 1320px container is ever visible —
   the cards are opaque and cover the rest. So the image is
   pulled left far enough that the KNUCKLES AND FINGERS land in
   that strip; at left:-30px it was the wrist showing, which is
   the thinnest and least readable part of the picture. */
.pod__hand {
    position: absolute;
    left: -190px;
    top: 50%;
    margin-top: -168px;   /* half the rendered height */
    width: 480px;
    height: auto;
    z-index: 1;
    pointer-events: none;
    user-select: none;
    will-change: transform;
}

.pod .heading-section { margin-bottom: 48px; }

/* fixed four-column grid rather than the theme's bootstrap rows:
   the cards have to line up on a shared baseline, and equal
   heights come free with grid */
.pod__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.pod__card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 28px 26px 30px;
    background: #fff;
    /* a touch more definition than on plain white — the cards
       now sit on a tinted wash rather than the page colour */
    border: 1px solid rgba(3, 0, 20, .08);
    border-radius: 18px;
    box-shadow: 0 12px 30px rgba(16, 8, 56, .09);
    overflow: hidden;
    transition: transform .4s cubic-bezier(.22, 1, .36, 1),
                box-shadow .4s ease, border-color .4s ease;
}

/* accent rule that wipes in across the top edge on hover */
.pod__card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background: linear-gradient(90deg, #6844ED, #00E58F);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .45s cubic-bezier(.22, 1, .36, 1);
}

.pod__card:hover {
    transform: translateY(-6px);
    border-color: rgba(104, 68, 237, .3);
    box-shadow: 0 20px 42px rgba(16, 8, 56, .14);
}

.pod__card:hover::before { transform: scaleX(1); }

/* the icon tile is the only child now — space-between would
   have no effect, but flex-start states the intent */
.pod__head {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    margin-bottom: 20px;
}

.pod__icon {
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    border-radius: 18px;
    background: rgba(104, 68, 237, .10);
    color: #6844ED;
    transition: background .4s ease, color .4s ease, transform .4s cubic-bezier(.22, 1, .36, 1);
}

.pod__card:hover .pod__icon {
    background: #6844ED;
    color: #fff;
    transform: scale(1.08);
}

.pod__icon svg {
    width: 30px;
    height: 30px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.65;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.pod__title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 19px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -.3px;
    color: #030014;
    margin: 0 0 12px;
}

.pod__desc {
    font-size: 14.5px;
    line-height: 1.65;
    color: #5A5670;
    margin: 0;
}

/* ---- icon draw-in -------------------------------------------
   Every shape carries pathLength="1", so one keyframe draws all
   of them regardless of their real geometry. The hidden state
   is gated behind .is-armed, which the script adds — without
   that, a JS failure would leave every icon invisible. */
.pod__grid.is-armed .pod__icon svg > * {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

.pod__grid.is-armed .pod__card.is-drawn .pod__icon svg > * {
    /* shorter than the scroll-in draw was — on hover this has
       to feel like a response, not a sequence */
    animation: podDraw .7s cubic-bezier(.65, 0, .35, 1) forwards;
}

/* icons built from stacked shapes draw one after the other */
.pod__grid.is-armed .pod__card.is-drawn .pod__icon svg > *:nth-child(2) { animation-delay: .15s; }
.pod__grid.is-armed .pod__card.is-drawn .pod__icon svg > *:nth-child(3) { animation-delay: .28s; }

@keyframes podDraw {
    from { stroke-dashoffset: 1; }
    to   { stroke-dashoffset: 0; }
}

/* Laptop placement. The strip left of the container is the only part
   of the hand that is ever visible — the cards are opaque and cover
   the rest — and on a laptop that strip is 45-130px rather than the
   350px a desktop leaves. The fixed left:-190px put the fingertips at
   x=200, well behind the first card, so all that showed was a sliver
   of mid-knuckle; below 1400px it was hidden outright rather than
   placed.

   Anchoring to the container's own left edge fixes it at every width
   at once: the fingertips park exactly where the cards begin, so
   whatever the strip can show is the readable end of the hand, and it
   grows with the window instead of needing a breakpoint per size. The
   48px nudge is the empty margin the PNG carries to the right of the
   fingertips (they stop at ~84% of its 598px width). */
@media (min-width: 1200px) and (max-width: 1599px) {
    /* 32px of gutter shows two fingertips and reads as a smudge; the
       hand needs ~85px before it is recognisably a hand. This section
       alone therefore reserves a wider margin than the site default.
       It costs the cards 19px each at the narrowest — they hold the
       same line count — and the min() makes the rule bite only below
       about 1340px, so from 1366px up the grid is untouched. Per-section
       widths are already how .awx gets its wider stage. */
    .pod > .themesflat-container {
        width: min(1200px, 100% - 140px);
    }

    .pod__hand {
        left: auto;
        right: calc(50% + min(1200px, 100% - 140px) / 2 - 15px - 42px);
        /* smaller than the desktop 480px on purpose: a narrow strip
           shows a fixed number of pixels, so a smaller image puts
           more of the hand in them rather than one magnified knuckle */
        width: 260px;
        margin-top: -91px;   /* 260 x .7007 / 2 */
        /* the parallax travels rightward, which on a strip this narrow
           would walk the hand behind the cards and out of sight */
        --pod-hand-range: 30px;
    }
}

/* below 1200 the grid drops to three columns and the strip closes up
   completely, so there is nowhere left to put it */
@media (max-width: 1199px) {
    .pod__hand { display: none; }
}

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

@media (max-width: 991px) {
    .pod__grid { grid-template-columns: repeat(2, 1fr); gap: 20px; }
    .pod__card { padding: 24px 22px 26px; }
}

@media (max-width: 575px) {
    .pod { padding: 44px 0; }
    .pod .heading-section { margin-bottom: 32px; }
    .pod__grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
    .pod__card,
    .pod__card::before,
    .pod__icon { transition: none; }
    .pod__card:hover { transform: none; }
    .pod__card:hover .pod__icon { transform: none; }
    /* the parallax script bails out on its own under reduced
       motion, so the hand simply stays where CSS puts it */
    /* leave the icons drawn rather than animating them in */
    .pod__grid.is-armed .pod__icon svg > * { stroke-dashoffset: 0; }
    .pod__grid.is-armed .pod__card.is-drawn .pod__icon svg > * { animation: none; }
}

/* ---- why attend (stacked cards) was index.html line 2785 ---- */
/* #wrapper carries overflow:hidden, which makes it a scroll
   container and stops position:sticky from ever sticking.
   overflow:clip clips identically without creating one. No
   @supports needed — a browser that does not know the value
   just drops the declaration and keeps hidden, and the script
   below catches that case at runtime. */
#wrapper { overflow: clip; }

/* Tinted band. Deliberately NO overflow:hidden here — that would
   make the section a scroll container and kill the sticky
   stacking inside it, which is the same trap #wrapper was in.
   Nothing bleeds outside the box, so it is not needed anyway.
   Cooler and a shade deeper than the Points of Discussion wash
   so the two light bands do not read as the same section. */
.wha {
    position: relative;
    padding: 72px 0 0px;
    background:
        radial-gradient(920px 520px at 14% 0%, rgba(104, 68, 237, .17), transparent 62%),
        radial-gradient(780px 460px at 88% 100%, rgba(0, 168, 232, .14), transparent 64%),
        linear-gradient(180deg, #F5F3FC 0%, #EBE8F8 52%, #F7F5FD 100%);
}

/* AI motif: a neural mesh across the top, thinning to nothing behind the
   heading so the words keep clean ground, plus a circuit cluster answering
   the cyan bloom bottom-right. Decorative only — pseudo-element, so it stays
   out of the markup and out of the accessibility tree. */
.wha::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    /* dot grid matches item-background/dot.png — same ~15px pitch and dot size,
       but tinted purple: that file's dots are white, which is invisible on this
       light band. Two corner patches only, each fading away from its corner, so
       the dots frame the heading and leave the rest of the section clean. */
    background-image:
        url(../img/dot-corner-l.svg),
        url(../img/dot-corner-r.svg);
    background-repeat: no-repeat, no-repeat;
    background-position: left top, right top;
    background-size: 320px 320px, 320px 320px;
}

/* the cards must sit over the motif */
.wha > .themesflat-container {
    position: relative;
    z-index: 1;
}

/* closing hairline against the plain white that follows; the top
   edge needs none, the dark section above is separation enough */
.wha::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(104, 68, 237, .28), transparent);
}

.wha .heading-section { margin-bottom: 48px; }

/* plain block flow, not flex — one less thing between the sticky
   card and its containing block. The small trailing space gives
   the last card a beat at its pin point; 40vh was enough to read
   as a hole under the section. */
.wha__stack { padding-bottom: 90px; }

/* .wha__card only positions. It must never be transformed: the
   scroll script measures it with getBoundingClientRect, and a
   transform here would feed its own output back into the next
   measurement and jitter. All visuals live on .wha__inner. */
.wha__card {
    position: sticky;
    margin-bottom: 26px;
}

.wha__inner {
    position: relative;
    display: grid;
    grid-template-columns: 1.02fr .98fr;
    align-items: stretch;
    min-height: 350px;
    border-radius: 22px;
    overflow: hidden;
    background: #fff;
    /* a shade more definition now the cards sit on a tint
       rather than on the page white */
    border: 1px solid rgba(255, 255, 255, .9);
    box-shadow: 0 24px 58px rgba(16, 8, 56, .16);
    transform-origin: 50% 0;
    will-change: transform;
}

/* Film grain across the whole card, copy panel and photo alike.
   Generated with feTurbulence in an inline SVG so it costs no
   extra request and tiles seamlessly (stitchTiles). Blended with
   overlay rather than laid on flat: mid-grey is neutral under
   overlay, so only the noise deviation shows and the whites stay
   white instead of turning muddy. */
.wha__inner::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: .38;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E");
    background-size: 200px 200px;
}

/* each card pins 22px lower than the previous one, which is what
   leaves the deck edge showing behind the topmost card */
.wha__card:nth-child(1) { top: 100px; }
.wha__card:nth-child(2) { top: 122px; }
.wha__card:nth-child(3) { top: 144px; }
.wha__card:nth-child(4) { top: 166px; }
.wha__card:nth-child(5) { top: 188px; }

.wha__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 50px;
}

.wha__title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.22;
    letter-spacing: -.6px;
    color: #030014;
    margin: 0 0 14px;
}

.wha__desc {
    font-size: 16px;
    line-height: 1.7;
    color: #5A5670;
    margin: 0;
    max-width: 520px;
}

.wha__media {
    position: relative;
    margin: 0;
    min-height: 350px;
    /* stands in until the photo is dropped in, so a missing file
       reads as a colour panel rather than a hole */
    background: linear-gradient(135deg, #EDE8FE 0%, #DCE9FB 55%, #E9E4FD 100%);
}

.wha__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

@media (max-width: 991px) {
    .wha__inner {
        grid-template-columns: 1fr;
        min-height: 0;
    }
    /* image first when stacked, so the card leads with a visual */
    .wha__media { order: -1; min-height: 240px; }
    .wha__body { padding: 34px 30px 38px; }
    .wha__title { font-size: 25px; }
    /* tighter pin offsets — the cards are much taller here */
    .wha__card:nth-child(1) { top: 80px; }
    .wha__card:nth-child(2) { top: 94px; }
    .wha__card:nth-child(3) { top: 108px; }
    .wha__card:nth-child(4) { top: 122px; }
    .wha__card:nth-child(5) { top: 136px; }
}

@media (max-width: 575px) {
    .wha { padding: 48px 0 60px; }
    .wha .heading-section { margin-bottom: 32px; }
    .wha__body { padding: 28px 22px 32px; }
    .wha__title { font-size: 21px; }
    .wha__desc { font-size: 14.5px; }
    .wha__media { min-height: 190px; }
    /* stacking a tall card on a short screen hides the copy, so
       the cards just flow normally here */
    .wha__card { position: relative; top: auto; }
    .wha__stack { padding-bottom: 0; }
}

/* ---- target sectors was index.html line 3204 ---- */
/* Plain white on purpose — it follows the tinted Why Attend band,
   and the chips carry the colour here. */
/* same faint square-grid plate the FAQ band uses, so the two light
   sections read as one family */
.tsec {
    padding: 76px 0 84px;
    background-image: url(../images/item-background/square.png);
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
}

.tsec .heading-section { margin-bottom: 44px; }

/* fades the chips out at both ends instead of cutting them
   off mid-word against the section edge */
.tsec__marquee {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

/* vertical padding, not margin: the row clips its overflow, and
   without room here the chips' hover lift and shadow get cut */
.tsec__row {
    overflow: hidden;
    padding: 9px 0;
}

/* the theme styles bare ul/li, so the reset is explicit */
.tsec__track {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: nowrap;
    width: max-content;
    gap: 14px;
}

/* The animation is gated on .is-looped, which the script adds
   only after it has appended a second copy of the chips. The
   -50% end point is exactly one copy, so the loop is seamless —
   but only once that copy exists, which is why it cannot be on
   .tsec__track directly. No JS: a static row, no jump. */
.tsec__track.is-looped {
    animation: tsecMarquee 48s linear infinite;
}

.tsec__track--rev.is-looped { animation-direction: reverse; }

@keyframes tsecMarquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

.tsec__marquee:hover .tsec__track.is-looped { animation-play-state: paused; }

.tsec__chip {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 13px 24px;
    border-radius: 999px;
    background: #fff;
    border: 1px solid rgba(3, 0, 20, .10);
    box-shadow: 0 6px 18px rgba(16, 8, 56, .05);
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 15.5px;
    font-weight: 600;
    line-height: 1.2;
    color: #221C40;
    transition: transform .32s cubic-bezier(.22, 1, .36, 1),
                box-shadow .32s ease, border-color .32s ease, color .32s ease;
}

/* flex-shrink 0 matters: without it the icon squashes on the
   longer labels once the row runs out of width */
.tsec__ico {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: #6844ED;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform .32s cubic-bezier(.22, 1, .36, 1), stroke .32s ease;
}

.tsec__chip:hover {
    transform: translateY(-3px);
    border-color: rgba(104, 68, 237, .45);
    color: #6844ED;
    box-shadow: 0 14px 32px rgba(16, 8, 56, .12);
}

.tsec__chip:hover .tsec__ico { transform: scale(1.12); }

@media (max-width: 991px) {
    .tsec { padding: 60px 0 66px; }
    .tsec .heading-section { margin-bottom: 34px; }
    .tsec__track { gap: 11px; }
    .tsec__chip { padding: 11px 19px; font-size: 14.5px; }
    /* shorter rows travel the same distance, so speed them up */
    .tsec__track.is-looped { animation-duration: 34s; }
}

@media (max-width: 575px) {
    .tsec { padding: 48px 0 54px; }
    .tsec__track { gap: 9px; }
    .tsec__chip { padding: 10px 16px; font-size: 13.5px; gap: 8px; }
    .tsec__ico { flex-basis: 16px; width: 16px; height: 16px; }
    .tsec__track.is-looped { animation-duration: 26s; }
}

@media (prefers-reduced-motion: reduce) {
    .tsec__chip,
    .tsec__ico { transition: none; }
    .tsec__chip:hover { transform: none; }
    .tsec__chip:hover .tsec__ico { transform: none; }
    /* stop the travel and let the row scroll by hand instead */
    .tsec__track.is-looped { animation: none; }
    .tsec__row { overflow-x: auto; }
}

/* ---- business opportunities was index.html line 3468 ---- */
/* Business Opportunities — full-bleed CTA band with the two hands
   reaching in from either side. Scoped to .bizo so none of the
   theme's .cta-wrapper / .opp rules apply. */
.bizo {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: 132px 0 124px;
    background: #000;
}

/* Hands are decorative and sit behind the copy. They anchor to the
   outer edges and are allowed to bleed off, so the reach never
   crowds the headline at narrower widths. */
.bizo__hand {
    position: absolute;
    z-index: 0;
    top: 50%;
    width: auto;
    height: 108%;
    max-width: none;
    pointer-events: none;
    will-change: transform;
}

/* --p is the band's scroll progress, set per frame by the script
   below and mapped so the whole 0..1 range plays out while the band
   is on screen. The hands reach in and grow slightly as it rises.
   --reach is the travel, so breakpoints can dial the movement down
   without touching the JS. Origins are the outer edges, so the
   scale pushes each hand inward rather than spreading it both ways. */
.bizo__hand--bot {
    left: -16%;
    transform-origin: left center;
    transform:
        translateY(-50%)
        translateX(calc(var(--p, 0) * var(--reach, 210px)))
        scale(calc(.93 + var(--p, 0) * .11));
}

.bizo__hand--human {
    right: -16%;
    transform-origin: right center;
    transform:
        translateY(-50%)
        translateX(calc(var(--p, 0) * var(--reach, 210px) * -1))
        scale(calc(.93 + var(--p, 0) * .11));
}

/* the artwork is cut out on black, so a soft vignette behind the
   copy keeps the fingertips from competing with the headline */
.bizo::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: radial-gradient(56% 76% at 50% 50%, rgba(0, 0, 0, .86) 32%, rgba(0, 0, 0, 0) 76%);
}

.bizo > .themesflat-container {
    position: relative;
    z-index: 2;
}

/* ---- atmosphere ------------------------------------------------
   .bizo__glow  a bloom where the two hands reach for each other, plus a
                rim glow behind each. Its own element rather than a
                pseudo: ::before already carries the vignette that keeps
                the fingertips from competing with the headline, and
                ::after is the grain.
   .bizo::after film grain over the whole frame. The noise is an
                feTurbulence SVG inlined as a data URI — no image
                request, and it tiles because of stitchTiles. Stepped,
                not eased, so it flickers like grain instead of sliding.

   Paint order: glow 0 -> hands 0 -> vignette 1 -> copy 2 -> grain 3. */
.bizo__glow {
    position: absolute;
    inset: -12% -6%;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(38% 46% at 50% 46%, rgba(124, 107, 255, .24), transparent 70%),
        radial-gradient(24% 32% at 50% 52%, rgba(0, 229, 143, .17), transparent 72%),
        radial-gradient(46% 30% at 10% 50%, rgba(104, 68, 237, .16), transparent 70%),
        radial-gradient(46% 30% at 90% 50%, rgba(0, 229, 143, .11), transparent 70%);
    filter: blur(12px);
    animation: bizoBloom 9s ease-in-out infinite alternate;
}

@keyframes bizoBloom {
    from { opacity: .72; transform: scale(1); }
    to   { opacity: 1;   transform: scale(1.05); }
}

.bizo::after {
    content: "";
    position: absolute;
    inset: 0;
    /* above the copy: grain belongs on the whole frame, or it reads as a
       texture on the background rather than on the image */
    z-index: 3;
    pointer-events: none;
    opacity: .16;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 160px 160px;
    animation: bizoGrain .6s steps(1, end) infinite;
}

/* eight offsets, so the tile never lands the same way twice running */
@keyframes bizoGrain {
    0%   { background-position: 0 0; }
    12%  { background-position: -22px 14px; }
    25%  { background-position: 18px -26px; }
    37%  { background-position: -34px -12px; }
    50%  { background-position: 26px 22px; }
    62%  { background-position: -14px 30px; }
    75%  { background-position: 34px -18px; }
    87%  { background-position: -28px -30px; }
}

.bizo__inner {
    max-width: 860px;
    margin: 0 auto;
    text-align: center;
}

.bizo__eyebrow {
    display: inline-block;
    margin-bottom: 20px;
    padding: 6px 16px;
    border-radius: 100px;
    border: 1px solid rgba(255, 255, 255, .22);
    background: rgba(255, 255, 255, .06);
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: #fff;
}

.bizo__title {
    margin: 0 0 16px;
    font-family: 'Plus Jakarta Sans', sans-serif;
    color: #fff;
    font-size: clamp(26px, 3.4vw, 46px);
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -.025em;
}

/* standfirst under the title; narrower than the section so the measure
   stays readable against the centred layout */
.bizo__lead {
    max-width: 700px;
    margin: 0 auto 30px;
    font-size: clamp(15px, 1.15vw, 17px);
    line-height: 1.7;
    color: rgba(255, 255, 255, .72);
}

.bizo__routes {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    margin: 0 0 34px;
    padding: 0;
    list-style: none;
}

.bizo__routes li {
    padding: 7px 18px;
    border-radius: 100px;
    border: 1px solid rgba(255, 255, 255, .18);
    background: rgba(255, 255, 255, .05);
    color: rgba(255, 255, 255, .88);
    font-size: 14.5px;
    font-weight: 500;
    line-height: 1.4;
}


@media (max-width: 1199px) {
    .bizo { padding: 104px 0 98px; --reach: 130px; }
    .bizo__hand { height: 78%; opacity: .5; }
    .bizo__hand--bot { left: -24%; }
    .bizo__hand--human { right: -24%; }
}

@media (max-width: 767px) {
    .bizo { padding: 74px 0 70px; }
    /* at this width the hands would sit straight under the copy */
    .bizo__hand { display: none; }
    .bizo::before { background: none; }
    /* nothing left to light once the hands are gone */
    .bizo__glow { display: none; }
    .bizo__routes { gap: 8px; margin-bottom: 28px; }
    .bizo__routes li { font-size: 13.5px; padding: 6px 14px; }
}

/* no scroll-linked travel for anyone who has asked for less motion —
   pinned to the end state so the composition still reads */
@media (prefers-reduced-motion: reduce) {
    .bizo__hand--bot {
        transform: translateY(-50%) translateX(var(--reach, 210px)) scale(1.04);
    }

    .bizo__hand--human {
        transform: translateY(-50%) translateX(calc(var(--reach, 210px) * -1)) scale(1.04);
    }
}

/* ---- past speakers (carousel) was index.html line 4035 ---- */
/* Past Speakers carousel (Swiper 6.8.1, auto-initialised by
   assets/js/swiper.js from the data-swiper attribute). */
/* room inside the clipped track for the card shadow and the hover lift */
#speakers .swiper-container {
    width: 100%;
    padding: 10px 2px 30px;
}

/* let cards size to their own text instead of the tallest slide */
#speakers .swiper-slide {
    height: auto;
    display: flex;
}

#speakers .speakers_inner {
    width: 100%;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid rgba(23, 20, 35, .07);
    border-radius: 16px;
    overflow: hidden;
    box-shadow:
        0 1px 2px rgba(23, 20, 35, .05),
        0 12px 26px -14px rgba(59, 42, 122, .30);
    transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease;
}

#speakers .swiper-slide:hover .speakers_inner {
    transform: translateY(-5px);
    border-color: rgba(139, 62, 252, .28);
    box-shadow:
        0 2px 4px rgba(23, 20, 35, .06),
        0 22px 40px -18px rgba(59, 42, 122, .45);
}

/* Portraits are transparent cut-outs, so the tile supplies its own ground:
   a neural-net motif that fades out low down, where the shoulders cover it. */
#speakers .speakers_inner img {
    border-bottom: 1px solid #9264df;
    width: 100%;
    padding:10px 0 0;
    /* aspect-ratio: 1 / 1;
    object-fit: cover;
    display: block; */
    margin: 0;
    background-color: #F1EAFD;
    background-image: url(../img/ai-grid.svg);
    background-size: cover;
    background-position: center top;
    /* the cut-outs end in a flat crop at the shoulders; dissolving the last
       strip hides that edge so the portrait settles into the card */
    /* -webkit-mask-image: linear-gradient(to bottom, #000 80%, transparent 99%);
    mask-image: linear-gradient(to bottom, #000 80%, transparent 99%); */
}

/* keep the gutter tight: these names are long and must not wrap needlessly */
#speakers .speakers_inner h3 {
    margin: 0px 8px 5px;
}

#speakers .speakers_inner p {
    margin: 0 8px 16px;
}

/* organisation — block so the top margin applies; the markup's <br> was
   removed since the block already breaks the line */
#speakers .speakers_inner p b {
    display: block;
    color: #6844ed;
    font-weight: 400;
    font-style: italic;
    font-size: 13px;
    margin: 5px 0 0;
}

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

    #speakers .speakers_inner,
    #speakers .swiper-slide:hover .speakers_inner {
        transition: none;
        transform: none;
    }
}

#speakers .speakers-more {
    align-items: center;
    justify-content: center;
}

/* the closing "& many more" tile: same footprint, deliberately not a portrait */
#speakers .many-more {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 190px;
    padding: 24px 16px;
    /* border: 1px dashed rgba(139, 62, 252, .38); */
    border-radius: 16px;
    /* background: linear-gradient(160deg, #F7F3FF, #EFE8FD); */
}

#speakers .many-more p {
    margin: 0;
}

/* controls */
.speakers-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    margin-top: 26px;
}

.speakers-arrow {
    position: relative;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid #DCDFE6;
    background: #fff;
    color: #14192B;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition: background .25s ease, border-color .25s ease, color .25s ease;
}

/* style.css:880 gives every <button> an icomoon arrow via ::after,
   which lands on top of the chevron. Not wanted here. */
.speakers-arrow::after {
    content: none;
}

.speakers-arrow:hover {
    background: #14192B;
    border-color: #14192B;
    color: #fff;
}

.speakers-arrow:focus-visible {
    outline: 2px solid #6844ED;
    outline-offset: 2px;
}

@media (max-width: 767px) {
    .speakers-nav { gap: 14px; margin-top: 20px; }
    .speakers-arrow { width: 38px; height: 38px; font-size: 13px; }
}

/* ---- cta was index.html line 4423 ---- */



/* ==========================================================================
   Container — Bootstrap defaults
   ==========================================================================
   The theme's .themesflat-container is a single fixed 1320px box, so once the
   viewport drops under that it spans edge to edge with only its 15px padding.
   These rules retire that in favour of the container Bootstrap already ships
   (bootstrap.css:757 and :793 onward), so both container classes now step
   through the same widths at the same breakpoints.

   Matches Bootstrap v4.0.0-alpha.6 as bundled here — note the theme customised
   the top step to 1200px/max-width:100% rather than stock 1170px.

   Each step is min(step, 100% - gutter) rather than the bare step, because a
   fixed step goes edge to edge for the whole band between the breakpoint and
   the step width. On a 1229px laptop — a 1536x864 panel at the 125% scaling
   Windows ships by default — the 1200px step landed in a 1214px viewport and
   left a 7px margin. The min() keeps a real gutter through that band and is
   inert once the window is wide enough for the step itself.

   .container is carried along so both classes still step together, which is
   the whole point of this block.

   Specificity is deliberately a single class, so the variants that opt out
   still win: .themesflat-container.full stays 100%, .w1420 stays 1450px, and
   the .awx section keeps its wider stage.
   ========================================================================== */
.themesflat-container,
.container {
    width: auto;
    max-width: 100%;
    padding-right: 15px;
    padding-left: 15px;
}

@media (min-width: 768px) {
    .themesflat-container,
    .container {
        width: min(750px, 100% - 40px);
    }
}

@media (min-width: 992px) {
    .themesflat-container,
    .container {
        width: min(970px, 100% - 56px);
    }
}

@media (min-width: 1200px) {
    .themesflat-container,
    .container {
        width: min(1200px, 100% - 64px);
        max-width: 100%;
    }
}


/* ==========================================================================
   Hero
   ==========================================================================
   Video-backed opening panel modelled on worldfintechsummit.com: corner
   edition ribbon, centred wordmark, date chip, tagline, a pair of outline
   buttons, and a date/venue card pinned underneath. Accent is the same green
   the header CTA already uses (#00E58F), so it reads as part of this site
   rather than a transplant.
   ========================================================================== */
.hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    /* the theme's header is absolute over the page, so the top padding is what
       keeps the wordmark clear of the nav */
    padding: 150px 0 70px;
    min-height: min(100vh, 860px);
    background: #0B0D14;
}

.hero__video {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 50%;
    pointer-events: none;
}

.hero__scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        radial-gradient(58% 52% at 82% 14%, rgba(104, 68, 237, .34), transparent 62%),
        radial-gradient(52% 48% at 12% 88%, rgba(0, 229, 143, .20), transparent 64%),
        radial-gradient(72% 64% at 50% 50%, rgba(9, 8, 24, .30) 0%, rgba(9, 8, 24, .54) 62%, rgba(9, 8, 24, .72) 100%),
        /* ramps to fully opaque over the last sliver so the hero's bottom edge
           is exactly #09081A rather than a video-dependent blend — that is what
           lets the stats band below butt against it with no visible seam */
        linear-gradient(180deg, rgba(9, 8, 24, .72) 0%, rgba(9, 8, 24, .20) 32%, rgba(9, 8, 24, .32) 64%, rgba(9, 8, 24, .80) 88%, rgb(9, 8, 24) 100%);
}

/* AI circuit vector. Sits between the scrim and the copy.

   The geometry is static on purpose — the earlier passes moved the whole
   graphic, which is what made them noisy. Here only two small things animate:
     .hero__ai-pulse  a capsule of light running one trace to its pad
     .hero__ai-pad    the pads breathe on four offset cycles
   Everything else holds still. Pure CSS, no canvas and no script. */
.hero__ai {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    /* one knob for the whole graphic — dialling it here keeps the balance
       between traces, pads and pulses that the individual opacities set */
    opacity: .5;
    /* clears the middle so the traces frame the lockup instead of crossing it,
       and fades the outer edge so nothing collides with the header or the
       date/venue bar */
    -webkit-mask-image: radial-gradient(58% 54% at 50% 48%, transparent 4%, rgba(0, 0, 0, .34) 50%, #000 84%);
    mask-image: radial-gradient(58% 54% at 50% 48%, transparent 4%, rgba(0, 0, 0, .34) 50%, #000 84%);
}

.hero__ai svg {
    display: block;
    width: 100%;
    height: 100%;
}

.hero__ai-grid { opacity: .07; }

.hero__ai-traces {
    fill: none;
    stroke: url(#heroAiGrad);
    stroke-width: 1.2;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .30;
}

/* --- travelling pulse.
   One short dash on an otherwise empty pattern: at offset +28 it sits just
   before the start of the trace, at -length just past the pad, so it enters
   and leaves cleanly rather than popping into existence mid-trace. */
.hero__ai-pulses {
    fill: none;
    stroke: url(#heroAiGrad);
    stroke-linecap: round;
    stroke-linejoin: round;
}

.hero__ai-pulse {
    stroke-width: 2.4;
    stroke-dasharray: 28 4000;
    animation: heroAiPulse linear infinite;
    will-change: stroke-dashoffset;
}

@keyframes heroAiPulse {
    0%   { stroke-dashoffset: 28px; opacity: 0; }
    16%  { opacity: 1; }
    78%  { opacity: 1; }
    100% { stroke-dashoffset: calc(var(--l) * -1); opacity: 0; }
}

.hero__ai-pulse--1 { --l: 532px;   animation-duration: 4.83s; animation-delay: -2.17s; }
.hero__ai-pulse--2 { --l: 515.6px; animation-duration: 5.66s; animation-delay: -4.34s; }
.hero__ai-pulse--3 { --l: 501.5px; animation-duration: 6.49s; animation-delay: -6.51s; }
.hero__ai-pulse--4 { --l: 488.1px; animation-duration: 7.32s; animation-delay: -0.68s; }
.hero__ai-pulse--5 { --l: 448.6px; animation-duration: 4.55s; animation-delay: -2.85s; }
.hero__ai-pulse--6 { --l: 441.5px; animation-duration: 5.38s; animation-delay: -5.02s; }

/* --- contact pads: a hollow ring around a solid dot, board-style */
.hero__ai-ring {
    fill: none;
    stroke: url(#heroAiGrad);
    stroke-width: 1.1;
    opacity: .40;
}

.hero__ai-dot {
    fill: url(#heroAiGrad);
    opacity: .85;
}

.hero__ai-pad {
    /* fill-box so a pad scales about itself, not the viewBox corner */
    transform-box: fill-box;
    transform-origin: center;
    animation: heroAiPad ease-in-out infinite alternate;
}

@keyframes heroAiPad {
    from { opacity: .5; transform: scale(.9); }
    to   { opacity: 1;  transform: scale(1.08); }
}

.hero__ai-pad--1 { animation-duration: 3.6s; animation-delay: -0.5s; }
.hero__ai-pad--2 { animation-duration: 4.9s; animation-delay: -2.3s; }
.hero__ai-pad--3 { animation-duration: 3.1s; animation-delay: -1.4s; }
.hero__ai-pad--4 { animation-duration: 5.7s; animation-delay: -3.9s; }

@media (max-width: 767px) {
    /* the routing is drawn for a wide frame; a narrow one crops to a dense
       middle slice, so it steps back further still */
    .hero__ai { opacity: .28; }
}

.hero__inner {
    position: relative;
    z-index: 2;
    text-align: center;
    /* the footage is mixed-brightness (bright banquet halls), so the copy
       carries its own shadow instead of the scrim being cranked up */
    text-shadow: 0 2px 22px rgba(0, 0, 0, .6);
}

/* corner ribbon */
.hero__edition {
    position: absolute;
    z-index: 3;
    top: 104px;
    left: 0;
    padding: 9px 26px 9px 18px;
    background: linear-gradient(135deg, #00E58F 0%, #00C97C 100%);
    color: #052B1E;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
    /* notched tail, so it reads as a ribbon rather than a plain tab */
    clip-path: polygon(0 0, 100% 0, calc(100% - 12px) 50%, 100% 100%, 0 100%);
}

.hero__edition sup {
    font-size: .65em;
    text-transform: none;
}

.hero__badge {
    display: inline-block;
    margin-bottom: 26px;
    padding: 7px 18px;
    border-radius: 100px;
    border: 1px solid rgba(255, 255, 255, .24);
    background: rgba(255, 255, 255, .07);
    color: #fff;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.hero__badge sup { font-size: .7em; }

/* Official lockup. The source PNG carries a wide transparent margin
   (artwork occupies roughly the middle 65% of its height), so the margins
   around it are pulled in to compensate rather than looking gappy. */
.hero__logo {
    margin: -14px 0 -6px;
}

.hero__logo img {
    display: block;
    width: 100%;
    max-width: min(820px, 94%);
    height: auto;
    margin: 20px auto;
}

@media (max-width: 575px) {
    .hero__logo img { max-width: 100%; }
}

/* --- event theme -------------------------------------------------------- */

.hero__theme {
    margin-top: 26px;
}

.hero__theme-line {
    /* 860px is just under the lockup's 820px cap, so the theme breaks after
       "for" and stacks as two centred lines rather than running full width */
    max-width: 860px;
    margin: 0 auto;
    color: #fff;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: clamp(21px, 3.4vw, 44px);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -.01em;
    text-transform: uppercase;
    /* .hero__inner's text-shadow would paint straight through the accent's
       transparent glyphs as a dark silhouette, so depth comes from a
       drop-shadow here on the parent instead. Kept off the accent itself:
       a filter on the same element as background-clip: text breaks the clip. */
    text-shadow: none;
    filter: drop-shadow(0 2px 18px rgba(0, 0, 0, .55)) drop-shadow(0 1px 2px rgba(0, 0, 0, .4));
}

/* Entrance. Word by word rather than character by character: a heavy uppercase
   setting reads as a block, and per-character staggering on it looks like a
   fault rather than an effect. No blur in the keyframe on purpose — a filter on
   the accent would break its background-clip. */
.hero__theme-w {
    display: inline-block;
    animation: heroThemeIn .9s cubic-bezier(.22, 1, .36, 1) both;
    animation-delay: calc(var(--i) * 110ms);
}

@keyframes heroThemeIn {
    from {
        opacity: 0;
        transform: translateY(.42em) scale(.94);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* Set apart from the sans lead-in with Space Grotesk rather than a serif: the
   summit sits in a tech register, and an editorial serif read wrong against it.
   Its capitals are distinctive enough (G, R, K, the flat-topped A) to separate
   clearly from Plus Jakarta Sans while staying in the same family of forms.
   Open tracking does the rest — the lead-in above is tracked tight at -.01em.
   Bundled by the theme's font.css, so it costs no extra request. */
.hero__theme-accent {
    font-family: 'Space Grotesk', 'Plus Jakarta Sans', sans-serif;
    font-size: 1.02em;
    font-weight: 700;
    letter-spacing: .035em;
    /* trailing tracking is added after the last glyph, so the mask would leave
       a sliver of dead space without it clawed back */
    padding-right: .04em;

    /* Written on, left to right, by sliding a soft-edged mask across.
       A mask is used rather than fading letters because opacity on a child
       cannot hide a background painted by its parent — the gradient would
       stay lit. Masking the whole element hides the painted result itself.
       Base position is the FINISHED state so that cancelling the animation
       (reduced motion) leaves the phrase visible rather than blank. */
    -webkit-mask-image: linear-gradient(90deg, #000 40%, transparent 58%);
    mask-image: linear-gradient(90deg, #000 40%, transparent 58%);
    -webkit-mask-size: 250% 100%;
    mask-size: 250% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: 0 0;
    mask-position: 0 0;

    /* the wipe rides alongside the same rise the sans words get, so the phrase
       still lands with the line rather than arriving separately */
    animation:
        heroThemeWrite 1.15s cubic-bezier(.33, 1, .68, 1) both,
        heroThemeIn .9s cubic-bezier(.22, 1, .36, 1) both;
    animation-delay: calc(var(--i) * 110ms);
}

@keyframes heroThemeWrite {
    from {
        -webkit-mask-position: 100% 0;
        mask-position: 100% 0;
    }
    to {
        -webkit-mask-position: 0 0;
        mask-position: 0 0;
    }
}

/* inner span: gradient only, kept clear of the mask above it */
.hero__theme-accent-t {
    display: inline-block;
    background: linear-gradient(96deg, #7C6BFF 0%, #35D9C0 48%, #00E58F 100%);
    /* oversized so there is ramp left to travel under the sheen */
    background-size: 220% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    animation: heroThemeSheen 9s ease-in-out infinite alternate;
    animation-delay: 1.9s;
}

@keyframes heroThemeSheen {
    from { background-position: 0% 50%; }
    to   { background-position: 100% 50%; }
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 14px;
    /* the theme line above is heavy set at up to 44px, so it needs more air
       beneath it than the lighter tagline that used to sit here */
    margin-top: 36px;
}

.hero__btn {
    display: inline-block;
    padding: 13px 26px;
    border-radius: 4px;
    border: 1px solid transparent;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-decoration: none;
    transition: background .3s ease, border-color .3s ease, color .3s ease,
                transform .3s ease, box-shadow .3s ease;
}

/* primary: the same green the header CTA and the venue card already use */
.hero__btn--primary {
    background: linear-gradient(135deg, #00E58F 0%, #00C97C 100%);
    color: #052B1E;
    box-shadow: 0 10px 26px rgba(0, 229, 143, .28);
}

.hero__btn--primary:hover {
    color: #052B1E;
    transform: translateY(-2px);
    box-shadow: 0 16px 34px rgba(0, 229, 143, .42);
}

/* secondary: picks up the brand purple rather than a neutral white outline */
.hero__btn--ghost {
    background: rgba(104, 68, 237, .22);
    border-color: rgba(160, 138, 255, .70);
    color: #fff;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.hero__btn--ghost:hover {
    background: #6844ED;
    border-color: #6844ED;
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0 16px 34px rgba(104, 68, 237, .40);
}

/* date + venue card */
/* Event meta bar. The previous version led with a solid green date chip, which
   was the heaviest thing in the hero and pulled focus off the theme line. Date
   and venue now carry equal weight as two labelled items on one glass pill,
   with the green kept to the icons and labels as an accent. */
.hero__meta {
    display: inline-flex;
    align-items: center;
    gap: 26px;
    margin-top: 40px;
    padding: 13px 30px;
    border-radius: 100px;
    border: 1px solid rgba(255, 255, 255, .15);
    background: rgba(8, 10, 18, .52);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .32);
    text-align: left;
    /* the pill is its own backdrop, so the inherited copy shadow only muddies it */
    text-shadow: none;
    font-family: 'Plus Jakarta Sans', sans-serif;
}

.hero__meta-item {
    display: flex;
    align-items: center;
    gap: 13px;
}

.hero__meta-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid rgba(0, 229, 143, .34);
    background: rgba(0, 229, 143, .13);
    color: #00E58F;
}

.hero__meta-icon svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.hero__meta-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.hero__meta-label {
    color: rgba(0, 229, 143, .92);
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .2em;
    text-transform: uppercase;
}

.hero__meta-value {
    color: #fff;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.01em;
}

/* fades out at both ends rather than butting into the pill's padding */
.hero__meta-rule {
    align-self: stretch;
    width: 1px;
    background: linear-gradient(180deg, transparent, rgba(255, 255, 255, .24), transparent);
}

@media (max-width: 991px) {
    .hero { padding: 128px 0 56px; min-height: min(100vh, 720px); }
    .hero__edition { top: 92px; font-size: 11px; padding: 8px 22px 8px 15px; }
    .hero__meta { gap: 20px; padding: 12px 24px; margin-top: 34px; }
}

@media (max-width: 575px) {
    .hero { padding: 112px 0 48px; }
    .hero__badge { font-size: 10.5px; letter-spacing: .1em; margin-bottom: 20px; }
    .hero__theme { margin-top: 18px; }
    .hero__actions { gap: 10px; }
    .hero__btn { padding: 11px 18px; font-size: 12px; }

    /* the pill would overflow a phone as a row, so it stacks and squares off —
       a 100px radius on a tall block reads as a lozenge */
    .hero__meta {
        flex-direction: column;
        align-items: stretch;
        gap: 14px;
        width: 100%;
        padding: 18px 22px;
        border-radius: 18px;
    }

    /* the divider has to turn with the layout */
    .hero__meta-rule {
        align-self: auto;
        width: auto;
        height: 1px;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .24), transparent);
    }

    .hero__meta-value { font-size: 15.5px; }
}

@media (prefers-reduced-motion: reduce) {
    /* the bloom holds at full and the grain stops flickering */
    .bizo__glow,
    .bizo::after { animation: none; }
    .hero__btn { transition: none; }
    .hero__btn:hover { transform: none; }
    .abx__ph,
    .abx__ph img { transition: none; }
    .abx__ph:hover,
    .abx__ph:hover img { transform: none; }
    .hero__ai-pulse,
    .hero__ai-pad,
    /* safe to cancel: opacity:0 and the hidden mask position live only inside
       the keyframes, so the base state is the finished one */
    .hero__theme-w,
    .hero__theme-accent,
    .hero__theme-accent-t { animation: none; }
    /* without the cycle a pulse would be parked off the end of its trace */
    .hero__ai-pulse { stroke-dasharray: none; stroke-width: 1.6; opacity: .55; }
}

/* ---- past partner logo wall -------------------------------------------
   The titled roles above keep their Bootstrap columns; this is the long
   tail, so it runs as an auto-fitting grid instead — 31 logos in fixed
   columns leave ragged part-empty rows at most widths.

   Every logo gets the same box and is contained inside it, never cropped
   or stretched: the artwork ranges from square monograms to 10:1 wordmarks
   and only a uniform box makes the wall read as a grid rather than a pile.
   The cards are white because several logos ship with a white or black
   background baked in and would otherwise float on the dark band. */
.pplogos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
    margin-top: 26px;
}

.pplogos__item {
    display: grid;
    place-items: center;
    min-height: 92px;
    padding: 16px 18px;
    background: #fff;
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 8px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, .34);
    transition: transform .35s cubic-bezier(.22, 1, .36, 1),
                box-shadow .35s ease, border-color .35s ease;
}

.pplogos__item:hover {
    transform: translateY(-4px);
    border-color: rgba(201, 189, 255, .75);
    box-shadow: 0 18px 42px rgba(0, 0, 0, .45);
}

.pplogos__item img {
    max-width: 100%;
    max-height: 56px;
    width: auto;
    height: auto;
    object-fit: contain;
}

@media (max-width: 767px) {
    .pplogos {
        grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
        gap: 10px;
    }

    .pplogos__item {
        min-height: 76px;
        padding: 12px;
    }

    .pplogos__item img { max-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
    .pplogos__item { transition: none; }
    .pplogos__item:hover { transform: none; }
}

/* ---- "& many more" cell + the reaching hand ---------------------------
   The line used to sit centred on its own row under the wall. As the last
   cell of the grid it lands in the gap the logo count leaves in the final
   row rather than reading as a stray caption. It is a plain cell, no card:
   a white box here would just look like a logo that failed to load. */
.pplogos__more {
    display: grid;
    place-items: center start;
    min-height: 92px;
    padding: 10px;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: #fff;
    text-align: center;
    /* above the hand, which sits at z-index 1 behind the container */
    position: relative;
    z-index: 2;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .55);
}

/* Same asset and the same scroll-driven reach as the Business Opportunities
   band — custom.js drives --p on this section too. Behind the container, so
   it can bleed under the logo cards and only shows in the empty corner. */

/* under the wall the hand would sit on top of the logos rather than beside
   them, and the grid leaves no corner for it to reach into */
@media (max-width: 767px) {
    .pplogos__more { min-height: 76px; }
}



/* ==========================================================================
   Section headings — one size
   Overrides shortcodes.css, which set .heading-section .main-title to a flat
   42px, and the two bespoke headlines, so every section title matches.

   Colour is deliberately NOT unified: a gradient across the whole headline
   read as muddy, so each heading stays its section's plain colour and only
   the accent word carries brand colour. Those accent colours are already
   declared per section further up (#6844ED on white, #00FF97 in the awaits
   band, #C9BDFF on the partners band).
   ========================================================================== */

.heading-section .main-title,
.abx__headline,
.bizo__title,
/* Past Speakers and Our Magazines are the only section titles outside the
   .heading-section/.main-title system — style.css:529 and style.css:699 give
   each its own fixed 42px/57px block. That left them the only two headings
   that stayed at 42px on a phone while every other title clamped to 28px,
   and the only two with no accent word (see the span rule below).

   They are matched here rather than rewritten into the standard wrapper
   because they are real <h2> elements and the .main-title headings are
   <div>s — restructuring would trade away the only true section headings
   on the page. #magazines h2 is an ID selector, so its own 42px would beat
   a class rule however late it came; the ID has to be carried here to win. */
.key_speaker h2,
#magazines h2 {
    font-size: clamp(28px, 3.2vw, 42px);
    /* was a fixed 57px, which stopped tracking the size once it clamped */
    line-height: 1.22;
    letter-spacing: -.02em;
}

/* The accent word. shortcodes.css:1192 only reaches spans inside
   .heading-section .main-title, so these two need it spelled out. Both sit
   on light backgrounds, so it is the #6844ED used across the white sections
   rather than the per-band variants. No line-height here on purpose: the
   shortcodes rule pins its spans to 51px, which was sized for the old fixed
   57px heading and inflates the line box once the heading clamps down. */
.key_speaker h2 span,
#magazines h2 span {
    color: #6844ED;
    font-family: 'Playfair Display', serif;
    font-style: italic;
}

/* The two past-edition headings are full sentences, not the two-word titles
   the rest of the page uses, so they always wrap. From 768px up each carries
   its own <br> after "of", which puts the accent phrase on line two whole;
   below that the break is hidden and balance splits them evenly instead of
   filling line one and dropping a stub underneath. The max-width keeps the
   wrap off the container edge on a wide desktop — it has to clear the longer
   of the two second lines ("Past BFSI & AI Industry Partners") or that line
   would break again and defeat the <br>. */
.key_speaker h2,
#past-partners .heading-section .main-title {
    text-wrap: balance;
    max-width: 34ch;
    margin-left: auto;
    margin-right: auto;
}

/* Retires that same 51px on the headings that DO go through shortcodes.
   An inline child takes part in sizing the line box, and the tallest one
   wins, so a 51px span inside a heading whose own line-height has clamped
   to 34.16px held the line open at 51px — every accented heading was
   carrying about 17px of dead space on a phone. It went unnoticed while
   the parent was a fixed 57px, which is where the 51px came from.
   Ties shortcodes.css:1192 on specificity and wins on load order. */
.heading-section .main-title span {
    line-height: inherit;
}

/* ---- shorter sticky bar on mobile ------------------------------------
   105px is a desktop bar. Below 991px the nav collapses to the hamburger,
   so the row only holds the logo and the toggle and the rest was dead
   height eating the top of a phone screen.

   These have to move together or the header stops lining up: the inner
   row's height, the sticky bar's height, the negative margin that lets
   the hero sit under a transparent header (it must cancel the height
   exactly), and the anchor scroll offset. */
@media (max-width: 991px) {

    /* beats #header_main .header-inner { height: 105px } earlier in this file */
    #header_main .header-inner {
        height: 62px;
        padding-top: 0;
        padding-bottom: 0;
        /* .mobile-button is position:absolute and was resolving against
           #header_main, which is taller than this row (it also holds the
           off-canvas panel). Positioning the row makes the toggle centre
           against the 62px bar it actually sits in. */
        position: relative;
    }

    /* beats .header.is-fixed.is-small { height: 105px } in style.css */
    #header_main.is-fixed.is-small {
        height: 62px;
    }

    /* .header carries height:105px AND margin-bottom:-105px in style.css —
       the pair is what lets the hero sit under a transparent header. Both
       have to change, and stay equal, or the header leaves a gap below it. */
    #header_main.header {
        height: 62px;
        margin-bottom: -62px;
    }

    /* style.css pairs top:50% with a hardcoded translateY(-20px), sized
       for the old 105px bar. Centre it properly against the new height. */
    #header_main .mobile-button {
        top: 50%;
        transform: translateY(-50%);
        -webkit-transform: translateY(-50%);
    }

    #logo_header {
        width: 84px;
    }

    /* style.css sets this !important, so this has to carry it too */
    section {
        scroll-margin-top: 74px !important;
    }
}

/* "The Leaders & Experts in the Room" — shortcodes.css ships this section at
   padding-bottom: 155px, which left a large void under the role list. The only
   .style-1 instance on the site, so the override is safe to leave unscoped.
   Top padding is untouched. */
.wg-create-design.style-1 {
    padding-bottom: 60px;
}


/* ---- section appear on scroll ------------------------------------------
   .appear is added by the script, never by the markup, so every section stays
   visible if the JS never runs. The transition lives on the .is-in rule only,
   which is also why nothing animates on first paint. */
.appear {
    opacity: 0;
    transform: translateY(26px);
    will-change: opacity, transform;
}

/* sections with no inner container fade without moving */
.appear--fade {
    transform: none;
}

.appear.is-in {
    opacity: 1;
    transform: none;
    transition: opacity .75s ease, transform .75s cubic-bezier(.22, 1, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
    .appear { opacity: 1; transform: none; }
    .appear.is-in { transition: none; }
}
