/* twin-orbit — layout, sizes, motion only (colours live in the template) */

.twin-orbit {
    --to-outer: 30rem;
    --to-inner: 18rem;
    --to-bottom: 3.5rem;
    --to-b-outer: 3rem;
    --to-b-inner: 2.25rem;
    --to-spread: 0.85;
    padding-bottom: 14rem !important;
}

.twin-orbit__glow {
    width: 64rem;
    height: 40rem;
    transform: translate(-50%, -30%);
    filter: blur(90px);
}

.twin-orbit__eyebrow {
    font-size: 0.875rem;
    letter-spacing: 0.2em;
}

.twin-orbit__title {
    letter-spacing: -0.03em;
    text-wrap: balance;
}

/* --- concentric rings, both anchored to the section bottom --- */
.twin-orbit__ring {
    left: 50%;
    top: auto !important;
    box-sizing: border-box;
    z-index: 0;
}

/* only the ring line fades out towards the top; bubbles stay unmasked */
.twin-orbit__line {
    box-sizing: border-box;
    -webkit-mask-image: linear-gradient(to bottom, transparent 10%, black 45%);
    mask-image: linear-gradient(to bottom, transparent 10%, black 45%);
}

.twin-orbit__line--dashed {
    border-style: dashed !important;
}

.twin-orbit__ring--outer {
    --to-d: var(--to-outer);
    --to-size: var(--to-b-outer);
    width: var(--to-outer);
    height: var(--to-outer);
    margin-left: calc(var(--to-outer) / -2);
    bottom: var(--to-bottom) !important;
    animation: twin-orbit-sway-cw 14s ease-in-out infinite alternate;
}

.twin-orbit__ring--inner {
    --to-d: var(--to-inner);
    --to-size: var(--to-b-inner);
    width: var(--to-inner);
    height: var(--to-inner);
    margin-left: calc(var(--to-inner) / -2);
    bottom: calc(var(--to-bottom) + (var(--to-outer) - var(--to-inner)) / 2) !important;
    animation: twin-orbit-sway-ccw 11s ease-in-out infinite alternate;
}

/* bubble sits on the ring: rotate to its angle, push out by the radius, rotate back upright */
.twin-orbit__bubble {
    --to-a: 90deg;
    width: var(--to-size);
    height: var(--to-size);
    margin-top: calc(var(--to-size) / -2);
    margin-left: calc(var(--to-size) / -2);
    transform:
        rotate(calc(90deg + (var(--to-a) - 90deg) * var(--to-spread)))
        translateX(calc(var(--to-d) / 2))
        rotate(calc(-90deg - (var(--to-a) - 90deg) * var(--to-spread)));
}

.twin-orbit__bubble--n6-1 { --to-a: 20deg; }
.twin-orbit__bubble--n6-2 { --to-a: 48deg; }
.twin-orbit__bubble--n6-3 { --to-a: 76deg; }
.twin-orbit__bubble--n6-4 { --to-a: 104deg; }
.twin-orbit__bubble--n6-5 { --to-a: 132deg; }
.twin-orbit__bubble--n6-6 { --to-a: 160deg; }
.twin-orbit__bubble--n7-1 { --to-a: 18deg; }
.twin-orbit__bubble--n7-2 { --to-a: 42deg; }
.twin-orbit__bubble--n7-3 { --to-a: 66deg; }
.twin-orbit__bubble--n7-4 { --to-a: 90deg; }
.twin-orbit__bubble--n7-5 { --to-a: 114deg; }
.twin-orbit__bubble--n7-6 { --to-a: 138deg; }
.twin-orbit__bubble--n7-7 { --to-a: 162deg; }
.twin-orbit__bubble--n8-1 { --to-a: 16deg; }
.twin-orbit__bubble--n8-2 { --to-a: 37deg; }
.twin-orbit__bubble--n8-3 { --to-a: 58deg; }
.twin-orbit__bubble--n8-4 { --to-a: 79deg; }
.twin-orbit__bubble--n8-5 { --to-a: 101deg; }
.twin-orbit__bubble--n8-6 { --to-a: 122deg; }
.twin-orbit__bubble--n8-7 { --to-a: 143deg; }
.twin-orbit__bubble--n8-8 { --to-a: 164deg; }
.twin-orbit__bubble--m4-1 { --to-a: 26deg; }
.twin-orbit__bubble--m4-2 { --to-a: 62deg; }
.twin-orbit__bubble--m4-3 { --to-a: 118deg; }
.twin-orbit__bubble--m4-4 { --to-a: 154deg; }
.twin-orbit__bubble--m5-1 { --to-a: 22deg; }
.twin-orbit__bubble--m5-2 { --to-a: 56deg; }
.twin-orbit__bubble--m5-3 { --to-a: 90deg; }
.twin-orbit__bubble--m5-4 { --to-a: 124deg; }
.twin-orbit__bubble--m5-5 { --to-a: 158deg; }
.twin-orbit__bubble--m6-1 { --to-a: 20deg; }
.twin-orbit__bubble--m6-2 { --to-a: 47deg; }
.twin-orbit__bubble--m6-3 { --to-a: 74deg; }
.twin-orbit__bubble--m6-4 { --to-a: 106deg; }
.twin-orbit__bubble--m6-5 { --to-a: 133deg; }
.twin-orbit__bubble--m6-6 { --to-a: 160deg; }

/* icons counter-rotate so glyphs stay upright while the ring sways */
.twin-orbit__face {
    line-height: 1;
}

.twin-orbit__face--outer {
    animation: twin-orbit-sway-ccw 14s ease-in-out infinite alternate;
}

.twin-orbit__face--inner {
    animation: twin-orbit-sway-cw 11s ease-in-out infinite alternate;
}

@keyframes twin-orbit-sway-cw {
    from { transform: rotate(-5deg); }
    to   { transform: rotate(5deg); }
}

@keyframes twin-orbit-sway-ccw {
    from { transform: rotate(5deg); }
    to   { transform: rotate(-5deg); }
}

/* axis dot + pulse */
.twin-orbit__dot {
    width: 0.75rem;
    height: 0.75rem;
}

.twin-orbit__pulse {
    animation: twin-orbit-pulse 2.4s ease-out infinite;
}

@keyframes twin-orbit-pulse {
    0%   { transform: scale(1); opacity: 0.6; }
    100% { transform: scale(3.5); opacity: 0; }
}

/* mobile: drop the outermost bubbles that would fall off-screen */
@media (max-width: 767.98px) {
    .twin-orbit__bubble--edge {
        display: none !important;
    }
}

@media (min-width: 768px) {
    .twin-orbit {
        --to-outer: 58rem;
        --to-inner: 44rem;
        --to-bottom: 5rem;
        --to-b-outer: 5rem;
        --to-b-inner: 3.5rem;
        --to-spread: 0.92;
        padding-bottom: 18rem !important;
    }
}

@media (min-width: 1024px) {
    .twin-orbit {
        --to-outer: 90rem;
        --to-inner: 70rem;
        --to-bottom: 6.5rem;
        --to-b-outer: 6.5rem;
        --to-b-inner: 4.5rem;
        --to-spread: 1;
        padding-bottom: 21rem !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    .twin-orbit__ring,
    .twin-orbit__face,
    .twin-orbit__pulse {
        animation: none !important;
    }
}

.float-jitter-grid__portrait {
    width: 7rem;
    height: 7rem;
}

@media (min-width: 768px) {
    .float-jitter-grid__portrait {
        width: 8rem;
        height: 8rem;
    }
}

.float-jitter-grid__beacon {
    width: 1.5rem;
    height: 1.5rem;
}

.float-jitter-grid__tile:nth-child(4n+2) {
    transform: translateY(1rem) translateX(0.5rem);
}

.float-jitter-grid__tile:nth-child(4n+3) {
    transform: translateY(2rem) translateX(-0.5rem);
}

.float-jitter-grid__tile:nth-child(4n+4) {
    transform: translateY(1rem) translateX(1rem);
}

/* quote v14 — nebula bento grid (BS fallback: CSS Grid row-span has no Bootstrap analog) */
.quote-nebula__bento {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.quote-nebula__bento-item--feature {
    grid-column: span 2 / span 2;
    grid-row: span 2 / span 2;
}

.quote-nebula__bento-item--wide {
    grid-column: span 2 / span 2;
}

.quote-nebula__bento-item--small {
    grid-column: span 1 / span 1;
}

@media (max-width: 767px) {
    .quote-nebula__bento {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .quote-nebula__bento-item--feature {
        grid-row: span 1 / span 1;
    }
}

/* grunge torn-edge clip via jagged polygon (no BS/clip-path analog) */
.quote-nebula__torn {
    clip-path: polygon(
        0% 2%, 4% 0%, 12% 1.5%, 22% 0%, 33% 1.2%, 45% 0%, 58% 1.5%, 70% 0%, 82% 1%, 92% 0%, 100% 2%,
        100% 96%, 96% 100%, 88% 98%, 76% 100%, 64% 98.5%, 52% 100%, 40% 98%, 28% 100%, 16% 98.5%, 6% 100%, 0% 97%
    );
}

/* blurred background glow behind the featured quote, sharp content stays on top (no BS backdrop-filter analog) */
.quote-nebula__glow {
    filter: blur(48px);
}

/* fixed decorative arrow-icon sizing (no BS w/h utility for arbitrary rem sizes) */
.quote-nebula__arrow {
    display: inline-flex;
    width: 1.25rem;
    height: 1.25rem;
}

/* terminal-style annotation block */
.quote-nebula__terminal {
    white-space: pre-wrap;
    word-break: break-word;
}

/* scroll-triggered slide-in reveal — root background stays a still, non-animated texture on purpose */
.quote-nebula__reveal {
    transition: transform 700ms ease, opacity 700ms ease;
}

.quote-nebula__reveal--left {
    transform: translateX(-2.5rem);
    opacity: 0;
}

.quote-nebula__reveal--right {
    transform: translateX(2.5rem);
    opacity: 0;
}

.quote-nebula__reveal.is-visible {
    transform: translateX(0);
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .quote-nebula__reveal {
        transition: opacity 200ms ease;
        transform: none;
    }

    .quote-nebula__reveal--left,
    .quote-nebula__reveal--right {
        transform: none;
    }
}
/* hover + focus affordances (layout/outline via theme token) */
@media (hover: hover) {
    .quote-nebula-root [role="listitem"]:hover,
    .quote-nebula-root article:hover,
    .quote-nebula-root [class*="quote-nebula__card"]:hover,
    .quote-nebula-root .quote-nebula__book:hover,
    .quote-nebula-root .quote-nebula__step:hover,
    .quote-nebula-root .quote-nebula__index-card:hover,
    .quote-nebula-root .quote-nebula__pill:hover,
    .quote-nebula-root .quote-nebula__item:hover {
        transform: translateY(-0.125rem);
    }
}

.quote-nebula-root [role="listitem"],
.quote-nebula-root article,
.quote-nebula-root [class*="quote-nebula__card"],
.quote-nebula-root .quote-nebula__book,
.quote-nebula-root .quote-nebula__step,
.quote-nebula-root .quote-nebula__index-card,
.quote-nebula-root .quote-nebula__pill {
    transition: transform 200ms ease;
}

.quote-nebula-root a:focus-visible,
.quote-nebula-root button:focus-visible,
.quote-nebula-root [tabindex="0"]:focus-visible,
.quote-nebula-root input:focus-visible,
.quote-nebula-root summary:focus-visible,
.quote-nebula-root [role="slider"]:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

@media (hover: hover) {
    .quote-nebula-root button:hover,
    .quote-nebula-root a:hover,
    .quote-nebula-root summary:hover {
        opacity: 0.92;
    }
}


.callout-signup__section {
    padding-top: 6rem;
    padding-bottom: 6rem;
}

.callout-signup__jump--rise:hover { transform: scale(1.05); transition: transform .2s ease; }

