/* ─────────────────────────────────────────────────────────────
   footer.css — shared upgraded site footer (.page-footer)
   Used on the landing page and all public content pages.
   Depends on landing.css design tokens (--accent-*, --text-*).
   Provides fallbacks for --font-heading / --border-color, which
   live in styles.css and aren't linked on every page.
   ───────────────────────────────────────────────────────────── */

.page-footer {
    position: relative;
    overflow: hidden;
    border-top: 1px solid var(--border-color, rgba(255, 255, 255, 0.08));
    background: linear-gradient(180deg, rgba(167, 119, 227, 0.04), rgba(12, 10, 18, 0.6));
    padding: 72px 6% 32px;
    /* The footer is the last thing in the document scroll, so on an edge-to-edge
       phone it is what ends up underneath the navigation bar / gesture pill. Content
       passing under the bar mid-scroll is fine and expected; content that STOPS
       there is not, because the final row of links can never be scrolled clear of
       it. The inset is added to the footer rather than to body so the footer's own
       gradient extends behind the bar instead of exposing the page background.
       --safe-bottom is 0 in a browser, so the web footer is unchanged. */
    padding-bottom: calc(32px + var(--safe-bottom));
    margin-top: 40px;
}

.footer-glow {
    position: absolute;
    top: -160px;
    left: 50%;
    transform: translateX(-50%);
    width: 620px;
    height: 320px;
    background: radial-gradient(ellipse at center, rgba(110, 142, 251, 0.22), transparent 70%);
    filter: blur(20px);
    pointer-events: none;
    animation: footerGlowPulse 7s ease-in-out infinite;
}

@keyframes footerGlowPulse {
    0%, 100% { opacity: .55; transform: translateX(-50%) scale(1); }
    50%      { opacity: 1;   transform: translateX(-50%) scale(1.08); }
}

/* Woven "loom" threads that fill the empty side gutters */
.footer-threads {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 300px;
    pointer-events: none;
    background-image: repeating-linear-gradient(
        115deg,
        rgba(167, 119, 227, 0.11) 0px,
        rgba(167, 119, 227, 0.11) 1px,
        transparent 1px,
        transparent 22px
    );
    -webkit-mask-image: radial-gradient(ellipse 70% 90% at center, #000 0%, transparent 75%);
    mask-image: radial-gradient(ellipse 70% 90% at center, #000 0%, transparent 75%);
    opacity: .8;
    animation: threadDrift 12s ease-in-out infinite;
}

.footer-threads-left {
    left: 0;
}

.footer-threads-right {
    right: 0;
    transform: scaleX(-1);
    animation-delay: -6s;
}

.footer-threads::after {
    content: "";
    position: absolute;
    top: 40%;
    left: 45%;
    width: 90px;
    height: 90px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, rgba(110, 142, 251, 0.35), rgba(167, 119, 227, 0.08) 60%, transparent 72%);
    filter: blur(4px);
    animation: orbFloat 9s ease-in-out infinite;
}

@keyframes threadDrift {
    0%, 100% { background-position: 0 0; opacity: .55; }
    50%      { background-position: 0 -22px; opacity: .9; }
}

@keyframes orbFloat {
    0%, 100% { transform: translateY(0) scale(1); opacity: .7; }
    50%      { transform: translateY(-16px) scale(1.12); opacity: 1; }
}

@media (max-width: 1100px) {
    .footer-threads { display: none; }
}

.footer-inner {
    position: relative;
    max-width: 920px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 40px 72px;
    padding-bottom: 40px;
}

.footer-brand {
    flex: 1 1 300px;
    max-width: 380px;
}

.footer-brand .footer-logo {
    font-family: var(--font-heading, var(--font-display));
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--text-primary);
    margin-bottom: 14px;
}

.footer-tagline {
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.65;
    margin-bottom: 20px;
}

.footer-socials {
    display: flex;
    gap: 12px;
}

.social-btn {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    color: var(--text-secondary);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    transition: transform .25s ease, color .25s ease, border-color .25s ease, background .25s ease;
}

.social-btn:hover {
    transform: translateY(-3px);
    color: #fff;
    background: var(--accent-gradient);
    border-color: transparent;
    box-shadow: 0 8px 20px -6px rgba(167, 119, 227, 0.6);
}

.footer-cols {
    display: flex;
    flex-wrap: wrap;
    gap: 64px;
}

.footer-col {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.footer-col h4 {
    font-family: var(--font-heading, var(--font-display));
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-faint, var(--text-secondary));
    margin-bottom: 4px;
}

.footer-col a {
    position: relative;
    color: var(--text-secondary);
    font-size: 0.92rem;
    width: fit-content;
    padding-left: 0;
    transition: color .25s ease, transform .25s ease;
}

.footer-col a::before {
    content: "";
    position: absolute;
    left: -14px;
    top: 50%;
    width: 8px;
    height: 1.5px;
    border-radius: 2px;
    background: var(--accent-gradient);
    transform: translateY(-50%) scaleX(0);
    transform-origin: left center;
    opacity: 0;
    transition: transform .25s ease, opacity .25s ease;
}

.footer-col a:hover {
    color: var(--text-primary);
    transform: translateX(14px);
}

.footer-col a:hover::before {
    transform: translateY(-50%) scaleX(1);
    opacity: 1;
}

.footer-col a.is-current {
    color: var(--accent-soft, var(--accent-color));
}

.footer-bottom {
    position: relative;
    max-width: 920px;
    margin: 0 auto;
    padding-top: 24px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.footer-madeby {
    color: var(--text-faint, var(--text-secondary));
    font-size: 0.85rem;
}

.footer-madeby i {
    color: var(--accent-color);
    margin-left: 4px;
}

@media (max-width: 640px) {
    .footer-inner { gap: 36px; }
    .footer-cols { gap: 32px; }
    .footer-bottom { justify-content: center; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
    .footer-glow,
    .footer-threads,
    .footer-threads::after { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   TOUCH INPUT — shared footer
   Third sibling of the TOUCH INPUT blocks at the end of landing.css and
   styles.css; see the landing.css header for why this is keyed on pointer
   capability rather than a width breakpoint, and why both `hover: none` and
   `pointer: coarse` are listed. Keep all three in step.

   This file had no such block, which mattered more here than elsewhere: the
   footer is on all 19 pages, so its two defects showed up everywhere.
   ═══════════════════════════════════════════════════════════════════ */

@media (hover: none), (pointer: coarse) {

    /* A tap leaves :hover applied until the next tap lands somewhere else, so
       the link that was just tapped stayed shifted 14px right with its accent
       dash showing -- and since tapping a footer link navigates, that frozen
       state was the last thing on screen before the page changed. The dash is
       reset with the shift because the two are one effect; leaving it lit
       beside an un-shifted label looks like a rendering fault. */
    .footer-col a:hover,
    .social-btn:hover {
        transform: none;
    }

    .footer-col a:hover::before {
        transform: translateY(-50%) scaleX(0);
        opacity: 0;
    }

    /* Tap targets. The links measured 24px tall -- WCAG 2.5.8's floor exactly,
       and nothing above it -- inside a 12px-gap column, and the social button
       was 40px against --tap-min: 44px.

       Trading the 12px gap for 2px is what keeps this from adding 160px to the
       footer: 44px bands at a 46px pitch land close to the 36px pitch they
       replace, so the column grows ~50px rather than doubling. Adjacent
       targets end up nearly touching, which is the normal shape of a mobile
       list row -- a mis-tap hits the neighbouring link instead of dead space,
       and that is the accepted trade for every row being reachable at all.

       `display: flex` is needed for min-height to have anything to centre
       against. `width: auto` drops the base rule's `width: fit-content`, which
       sized each target to its own label and left "Blog" 31px wide against a
       44px target -- restoring the flex default stretches every link to the
       column instead, so the whole row is tappable and the narrowest column
       (65px) still clears the minimum in both axes. The label does not move:
       it is left-aligned in a box that only grew rightwards. */
    .footer-col {
        gap: 2px;
    }

    .footer-col a {
        display: flex;
        align-items: center;
        width: auto;
        min-height: var(--tap-min, 44px);
    }

    .social-btn {
        width: var(--tap-min, 44px);
        height: var(--tap-min, 44px);
    }
}
