/* ==========================================================================
   LAYOUT: nav, main, footer, hero, site chrome
   ========================================================================== */

/* Skip-to-content link (injected first in <body> by layout.js) */
.skip-link {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 2000;
    padding: 10px 18px;
    background: var(--ios-blue);
    color: #fff;
    border-radius: 99px;
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
    /* -220%, not -150%: the resting spot must also clear the 14px shadow
       blur, which at -150% still bled a few pixels into the viewport. */
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
    transform: translateY(-220%);
    transition: transform 0.2s ease;
}
.skip-link:focus {
    transform: translateY(0);
    outline: none;
}

nav {
    display: flex;
    align-items: center;
    background: var(--nav-bg);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    width: fit-content;
    max-width: calc(100% - 32px);
    margin: 20px auto 10px;
    /* 6px + 44px links + 6px = the same 56px pill height as the mobile bar */
    padding: 6px 1.5rem;
    border-radius: 100px;
    border: 1px solid rgba(0,0,0,0.08);
    box-shadow: 0 8px 30px rgba(0,0,0,0.12);
    position: sticky;
    top: 20px;
    z-index: 1000;
    text-align: center;
    /* Safety valve for the narrow-desktop band just above the mobile
       breakpoint, where all seven links only just fit. */
    overflow-x: auto;
    scrollbar-width: none;
}
nav::-webkit-scrollbar { display: none; }

/* Desktop: the links behave as if they were direct children of <nav>
   (display: contents removes the wrapper's box), and the mobile menu
   button doesn't exist. responsive.css flips both for small screens. */
.nav-links { display: contents; }
.nav-menu-btn { display: none; }

/* No opacity fade on resting links: at 0.8 they fell below WCAG AA contrast
   on the light background. Hover/active recolor instead. */
nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    text-decoration: none;
    color: var(--text-color);
    font-weight: 500;
    font-size: 0.9rem;
    margin: 0 12px;
    transition: color 0.2s ease;
    white-space: nowrap;
}

nav a:hover, nav a.active {
    color: var(--link-blue);
}

/* Hamburger-to-X icon for the mobile menu button: two bars that fold into
   a cross when the nav carries .is-open. Pure transform, no reflow. */
.nav-menu-icon {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 16px;
}
.nav-menu-icon span {
    display: block;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
nav.is-open .nav-menu-icon span:first-child { transform: translateY(3.5px) rotate(45deg); }
nav.is-open .nav-menu-icon span:last-child { transform: translateY(-3.5px) rotate(-45deg); }

/* Page scroll is locked while the mobile menu sheet is open */
body.nav-open { overflow: hidden; }

main {
    flex: 1;
    /* 1200px, up from 1000: at 1000 the content only used ~69% of a 1440
       display and read as a narrow centered strip. Text-heavy layouts
       (blog articles) keep their own tighter caps for line length. */
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
    width: 100%;
    box-sizing: border-box;
}

footer {
    background-color: var(--bg-color);
    border-top: 1px solid rgba(0,0,0,0.1);
    padding: 60px 20px;
    text-align: center;
    font-size: 0.85rem;
    color: var(--text-muted);
}

footer a { color: var(--text-muted); text-decoration: none; margin: 0 12px; transition: color 0.2s;}
footer a:hover { color: var(--link-blue); text-decoration: none; }

/* Flex, not text-align: the generated footer HTML has no whitespace between
   links, so as inline content the row is one unbreakable line that forced
   horizontal overflow on phones. flex-wrap gives it real break points. */
.footer-links {
    margin-top: 15px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}

/* Second footer row: the app-facing utility pages (Apps, Support, Privacy).
   Tighter spacing so it reads as a subordinate row of the links above. */
.footer-links--apps { margin-top: 8px; }

.sep { opacity: 0.3; margin: 0 5px; }

/* Footer social icons */
.footer-socials {
    display: flex;
    justify-content: center;
    gap: 22px;
    margin-bottom: 20px;
}

.footer-socials a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    color: var(--text-muted);
    transition: color 0.2s ease, transform 0.2s ease;
}

.footer-socials a:hover {
    color: var(--link-blue);
    transform: translateY(-2px);
}

.page-hero {
    text-align: center;
    padding: 40px 0 60px;
}

/* 404 page */
.error-code {
    font-size: clamp(5rem, 18vw, 9rem);
    line-height: 1;
    margin: 0;
    background: linear-gradient(135deg, var(--ios-blue), #af52de);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    letter-spacing: -0.03em;
}
.error-text {
    max-width: 460px;
    margin: 16px auto 0;
    color: var(--text-muted);
    line-height: 1.6;
}

.hero-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 48px 40px;
    max-width: 100%;
    margin: 20px auto 0;
    position: relative;
    border-radius: 24px;
    /* The children rest on real z-planes (see --rest-z below) and home.js
       tilts the whole card toward the pointer; preserve-3d is what lets
       those planes shear apart in the projection. The glass skin lives on
       ::before because backdrop-filter directly on this element would
       force transform-style back to flat and kill the depth. */
    transform-style: preserve-3d;
    transition: transform 0.18s ease-out;
}

.hero-section::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 24px;
    background: var(--card-bg);
    backdrop-filter: blur(25px) saturate(180%);
    -webkit-backdrop-filter: blur(25px) saturate(180%);
    border: 1px solid var(--card-border);
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.02), 0 12px 24px -4px rgba(0, 0, 0, 0.06);
    /* Sit just behind the z=0 content plane so the 3D painting order
       always keeps the skin at the back. */
    transform: translateZ(-1px);
}

/* A quiet bit of pride: hover my name and it blooms into a rainbow.
   Pure CSS, no trigger to find. The shimmer lives in the entrance's
   no-preference block below, composed WITH hero-rise: if the hover rule
   declared `animation: pride-shimmer` alone it would knock hero-rise out
   of the animation list, and un-hovering would re-add it, replaying the
   entrance (the name visibly bounced). Under reduced motion only this
   rule applies, so hovering shows the gradient statically. */
.hero-section h1 {
    cursor: default;
    background-image: linear-gradient(90deg,
        #ff3b30, #ff9500, #ffcc00, #34c759, #007aff, #af52de, #ff3b30);
    background-size: 200% 100%;
    background-position: 0 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: currentColor;
    transition: -webkit-text-fill-color 0.4s ease;
}
.hero-section h1:hover {
    -webkit-text-fill-color: transparent;
}
@keyframes pride-shimmer {
    to { background-position: 200% 0; }
}

.hero-photo {
    width: 220px;
    height: 220px;
    background-color: #f0f0f5;
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 20px 40px rgba(0,0,0,0.15);
    margin-bottom: 24px;
    /* No transition on transform here: home.js drives a per-frame parallax
       transform on scroll, and a transition would make it rubber-band. */
}

/* Deliberate vertical rhythm: 24 / 10 / 24. The h1 margin reset matters
   most; the browser's default 0.67em top margin (~38px at this size) was
   what made the photo look like it had extra padding under it. */
.hero-section h1 { margin: 0; }
.hero-section .tagline { margin-top: 10px; margin-bottom: 0; }
.hero-section .hero-socials { margin-top: 24px; }

/* Hero depth. Two custom properties per layer feed one shared keyframe:
   --rise-z is where the entrance starts (photo deepest, top to bottom far
   to close) and --rest-z is where the layer permanently LIVES. The resting
   depths are what make the pointer tilt read as 3D: when home.js rotates
   the card, planes at different z shear apart in the projection. Anything
   else that writes transform on a layer (the scroll parallax in home.js)
   must therefore include the layer's translateZ(var(--rest-z)).
   `backwards` (not `both`) fill matters: once the entrance ends the
   keyframe must release `transform` back to the resting rule / parallax. */
.hero-section { perspective: 1000px; }
@media (prefers-reduced-motion: no-preference) {
    .hero-photo,
    .hero-section h1,
    .hero-section .tagline,
    .hero-section .hero-socials {
        transform: translateZ(var(--rest-z));
        animation: hero-rise 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
    }
    /* Every resting depth must stay in FRONT of the glass skin's -1px
       plane: anything behind it renders through the ::before's
       backdrop-filter and blurs (the photo did, at an earlier -40px). So
       the far layer (photo) sits on the surface and the near layers rise
       toward the viewer. */
    .hero-photo { --rise-z: -350px; --rest-z: 0px; }
    .hero-section h1 { --rise-z: -240px; --rest-z: 40px; animation-delay: 0.1s; }
    .hero-section .tagline { --rise-z: -140px; --rest-z: 75px; animation-delay: 0.2s; }
    .hero-section .hero-socials { --rise-z: -60px; --rest-z: 110px; animation-delay: 0.3s; }
    /* Pride shimmer on hover, composed with (never replacing) hero-rise;
       hero-rise's timing here must stay identical to the rule above or
       the browser treats it as a new animation and restarts it. */
    .hero-section h1:hover {
        animation:
            hero-rise 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 0.1s backwards,
            pride-shimmer 6s linear infinite;
    }
}
@keyframes hero-rise {
    from { opacity: 0; transform: translateY(14px) translateZ(var(--rise-z, -140px)); }
    to { opacity: 1; transform: translateY(0) translateZ(var(--rest-z, 0px)); }
}

.hero-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hero-socials {
    display: flex;
    gap: 20px;
    justify-content: center;
    margin-top: 16px;
}

.cta-section {
    text-align: center;
    padding: 60px 0 20px;
}

.card-icon-wrap {
    width: 50px;
    height: 50px;
    background: rgba(120, 120, 128, 0.12);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
}

/* Theme toggle button in nav */
.theme-toggle-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: 2px 4px;
    margin: 0 4px;
    display: inline-flex;
    align-items: center;
    color: var(--text-color);
    opacity: 0.8;
    transition: color 0.2s ease, opacity 0.2s ease;
    vertical-align: middle;
    line-height: 1;
}

.theme-toggle-btn:hover { color: var(--link-blue); opacity: 1; }

/* Back-to-top button (injected on every page by layout.js) */
#back-to-top {
    position: fixed;
    bottom: 32px;
    right: 32px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--card-bg);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border: 1px solid var(--card-border);
    box-shadow: 0 4px 16px var(--shadow-medium);
    color: var(--text-color);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.3s ease, transform 0.3s ease, color 0.2s ease, box-shadow 0.2s ease;
    pointer-events: none;
    z-index: 999;
}

#back-to-top.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

#back-to-top:hover {
    color: var(--link-blue);
    box-shadow: 0 8px 24px var(--shadow-medium);
}
