/* ===========================================================================
   HOME PAGE

   The welcome title card, the front-page hero (full-bleed artwork, big title,
   fade) and the poster grid underneath it. Nothing here appears on any other
   page.

   Loaded by: index.html
   =========================================================================== */

#fancy-scroll-container {
    flex-direction: column;
}

/* ===========================================================================
   WELCOME TITLE CARD

   Markup is at the top of <body> in index.html. It plays once, on arriving at
   the site, and is skipped when the title-bar logo brings you back here.

   The logo is a black hole, so the card is built as one: a starfield falling
   inward, a bloom where the hole sits, and light thrown out along the disc.

   The shape of it: stars fade up and start their fall; a departure-board
   roller flicks through the creations and lands on "Welcome to"; the mark
   irises open out of a sliver and throws a flare down its own axis, then two
   light echoes; "PogoInc" drops in letter by letter and a highlight runs
   across it; then the sky closes back down to a thin horizontal line — the
   same shape as the disc, everything falling in — and goes.

   Timings are written out as plain seconds rather than shared variables, so
   the running order can be read straight down the file:

       0.00s   stars fade up and begin falling inward, bloom starts opening
       0.10s   roller starts flicking through the creations
       2.01s   roller settles on "Welcome to"
       2.05s   logo mark irises open, flare whips out along the disc
       2.12s   light echoes go out
       2.18s   "PogoInc" lands, letter by letter
       2.62s   highlight runs across the wordmark
       3.20s   the stage lifts away
       3.30s   the sky closes to a slit
       3.76s   gone

   Two beats, and the split between them is the whole point: the roller names
   the creations, and only once it has landed on "Welcome to" does anything
   else move. The mark used to start opening under "Creative Experiments",
   which saved about half a second and cost the sense that the words are what
   summon the logo. Everything after 2.01s reads as the consequence of that
   line arriving.

   That makes the roller set the length of the card. Each creation has to sit
   still long enough to be read — a shade under half a second — and with
   three of them plus the move between each, two seconds are gone before the
   lock-up is allowed to begin.

   Nothing here loops. The card is on screen for under four seconds, so an
   infinite animation would just be burning a compositor thread behind a
   hidden element for the rest of the visit.
   =========================================================================== */

#welcome_screen {
    position: fixed;
    inset: 0;
    z-index: 1000;
    overflow: hidden;
    /* Clicks reach the page underneath the whole time, so nothing is blocked
       while it plays. */
    pointer-events: none;
    animation: welcome-dismiss 3.76s linear forwards;
}

/* ?from=true — the title-bar logo. Straight to the page. */
#welcome_screen.welcome-skip {
    display: none;
}

@keyframes welcome-dismiss {
    0%, 99% { visibility: visible; }
    100%    { visibility: hidden; }
}

/* ---- The sky ----
   Two halves rather than one sheet, so the exit can close them onto the
   centre line.

   Painting order within a half, back to front:
       the panel itself   flat deep space, so a seam can never show the page
       ::before           the sky: bloom at the hole, falling off to deep
       .welcome-stars     the starfield

   The sky layer is sized to the whole card and pinned to its half's OUTER
   edge, so both halves lay down the same gradient over the same rectangle
   and meet invisibly. Anchoring each one to the shared inner edge instead
   looks equivalent and is not: the halves overlap, so their inner edges are
   1% apart, and the two ellipses land ~8px out of step. That reads as a line
   straight across the bloom. */

#welcome_screen {
    /* Each half runs a shade past 50% so the two always overlap — a flat
       50/50 can leave a hairline of the page showing between them on
       fractional device pixels. The sky layer inside is scaled back up by
       the same factor (100 / 50.5) to cover the card exactly. */
    --welcome-half: 50.5%;
    --welcome-sky-height: 198.0198%;
}

.welcome-panel {
    position: absolute;
    left: 0;
    width: 100%;
    height: var(--welcome-half);
    overflow: hidden;
    background-color: var(--color-welcome-deep);
    animation: welcome-close 0.42s cubic-bezier(0.76, 0, 0.24, 1) 3.30s forwards;
}

.welcome-panel--top    { top: 0;    transform-origin: 50% 100%; }
.welcome-panel--bottom { bottom: 0; transform-origin: 50% 0; }

/* Fully opaque, all three stops — bloom, sky, deep space at the edges. No
   alpha anywhere in it, so there is no transparent-black to interpolate
   through and nothing to grey the falloff. Fading it in against the flat
   deep-space panel underneath is what makes the bloom open. */
.welcome-panel::before {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: var(--welcome-sky-height);
    /* Radii are pulled out so the shape can be reset per breakpoint below
       without restating the whole gradient. */
    --welcome-bloom-w: 68%;
    --welcome-bloom-h: 34%;
    background-image: radial-gradient(
        ellipse var(--welcome-bloom-w) var(--welcome-bloom-h) at 50% 50%,
        var(--color-welcome-glow) 0%,
        var(--color-welcome-sky) 45%,
        var(--color-welcome-deep) 100%
    );
    /* Its own centre is the centre of the card, which is where the hole is. */
    transform-origin: 50% 50%;
    animation: welcome-glow 3.76s ease-out both;
}

.welcome-panel--top::before    { top: 0; }
.welcome-panel--bottom::before { bottom: 0; }

/* A phone is far taller than it is wide, so radii in percent come out
   standing on end — a column of light rather than a disc. Reshape it to lie
   along the mark's axis, the way the glow round a black hole does. */
@media (max-width: 700px) {
    .welcome-panel::before {
        --welcome-bloom-w: 105%;
        --welcome-bloom-h: 22%;
    }
}

/* Never below scale 1. The layer is exactly card-sized, so shrinking it pulls
   its own edge inside the card — and because the gradient only reaches deep
   space at the far end of its ellipse, that edge is still mid-falloff along
   the sides and shows up as a rectangle sitting on the flat panel behind.
   Growing from 1 gives the same opening bloom with nothing to give away. */
@keyframes welcome-glow {
    from { opacity: 0.45; transform: scale(1); }
    to   { opacity: 1;    transform: scale(1.22); }
}

/* Stars. A 2px dot wearing one very long box-shadow — every star in the sky
   is a copy of this element, offset and resized by its own shadow. The list
   is written by the script in index.html, along with the transform origin;
   see the note there for why they are not tiled gradients.

   Positions are in card coordinates, so this is pinned to the top of the
   whole card in both halves rather than to the half it lives in. The bottom
   half therefore has to reach back up past its own top edge, which is the
   sky layer's height less the one panel it is already offset by. */
.welcome-stars {
    position: absolute;
    left: 0;
    width: 2px;
    height: 2px;
    border-radius: 50%;
    animation: welcome-swirl 3.76s ease-out both;
}

.welcome-panel--top .welcome-stars    { top: 0; }
.welcome-panel--bottom .welcome-stars { top: calc(100% - var(--welcome-sky-height)); }

/* Scaling down about the middle of the card walks every star toward the hole,
   and the couple of degrees of rotation gives the fall a bit of spin. Because
   the shadows are scaled along with the element, the stars shrink slightly as
   they go, which sells the distance. */
@keyframes welcome-swirl {
    0%   { opacity: 0; transform: scale(1.16) rotate(-2deg); }
    12%  { opacity: 1; }
    100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

@keyframes welcome-close {
    to { transform: scaleY(0); }
}

/* ---- The lock-up ----
   Roller, mark and wordmark all hold their space from the first frame even
   though two of them are invisible, so nothing reflows as they arrive. */

.welcome-stage {
    position: absolute;
    inset: 0;
    box-sizing: border-box;
    padding: 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(10px, 2.2vh, 20px);
    color: #ffffff;
    text-align: center;
    animation: welcome-lift 0.3s ease-in 3.20s forwards;
}

@keyframes welcome-lift {
    to { opacity: 0; transform: translateY(-4vh) scale(0.97); }
}

/* ---- Roller ---- */

.welcome-roller {
    height: 1.6em;
    overflow: hidden;
    font-family: 'Circular Spotify', sans-serif;
    font-weight: 600;
    font-size: clamp(0.72rem, 3vw, 1.1rem);
    /* Was 0.28em, which looked the part but is genuinely slower to read —
       tracking that wide stops the words holding together as shapes. */
    letter-spacing: 0.22em;
    /* Letter spacing is added after the last letter too, which drags the line
       half a space to the left of centre. This puts it back. */
    text-indent: 0.22em;
    text-transform: uppercase;
    /* Kept tight: the box is clipped to one line, so a wide shadow would be
       sheared off along the top and bottom edges. 1.6em of line height leaves
       about 0.3em of leading either side to put it in. */
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
    opacity: 0.9;
}

.welcome-roller-track {
    animation: welcome-roll 1.91s cubic-bezier(0.16, 1, 0.3, 1) 0.10s both;
}

.welcome-roller-track span {
    display: block;
    height: 1.6em;
    line-height: 1.6em;
    white-space: nowrap;
}

/* Four names, so each step is a quarter of the track.

   The percentages are ugly because the timings behind them are not: over the
   1.91s this runs for, every move takes 0.13s and every name then sits dead
   still for 0.46s. The stillness is the part that matters. Nothing can be
   read while it is sliding, so the hold IS the reading time — an earlier cut
   of this moved every 0.14s with only 0.12s of rest between, which flicked
   over far too fast to take in three multi-word titles. */
@keyframes welcome-roll {
    0%     { transform: translateY(28%); opacity: 0; }
    7.3%   { transform: translateY(0); opacity: 1; }
    31.4%  { transform: translateY(0); }
    38.2%  { transform: translateY(-25%); }
    62.3%  { transform: translateY(-25%); }
    69.1%  { transform: translateY(-50%); }
    93.2%  { transform: translateY(-50%); }
    100%   { transform: translateY(-75%); }
}

/* ---- Logo mark ---- */

.welcome-mark {
    position: relative;
    width: clamp(120px, 34vw, 260px);
    aspect-ratio: 512 / 204;
}

/* The logo art is white already, so unlike the title bar's copy it is left
   alone — the light-mode inversion there would turn it dark against blue. */
.welcome-mark img {
    display: block;
    position: relative;
    width: 100%;
    height: auto;
    animation: welcome-iris 0.50s cubic-bezier(0.16, 1, 0.3, 1) 2.05s both;
}

/* The mark is a disc through a ring, so it opens the way a disc would:
   outward from a sliver at the centre, rather than fading or scaling in. */
@keyframes welcome-iris {
    from {
        clip-path: inset(0 49% 0 49%);
        opacity: 0;
        filter: drop-shadow(0 0 0 rgba(169, 214, 255, 0.5));
    }
    60% { opacity: 1; }
    to {
        clip-path: inset(0 0 0 0);
        opacity: 1;
        filter: drop-shadow(0 0 20px rgba(169, 214, 255, 0.5));
    }
}

/* The accretion streak: light thrown out along the disc's own axis as it
   opens, whipping past the edges of the screen and settling to a thin line
   through the middle of the mark. Anamorphic, so horizontal only. */
.welcome-flare {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 320%;
    height: 3px;
    background-image: linear-gradient(
        90deg,
        rgba(169, 214, 255, 0) 0%,
        var(--color-welcome-glow) 18%,
        var(--color-welcome-flare) 38%,
        #ffffff 50%,
        var(--color-welcome-flare) 62%,
        var(--color-welcome-glow) 82%,
        rgba(169, 214, 255, 0) 100%
    );
    filter: blur(1.5px);
    animation: welcome-flare 0.95s cubic-bezier(0.16, 1, 0.3, 1) 2.05s both;
}

@keyframes welcome-flare {
    0%   { opacity: 0;    transform: translate(-50%, -50%) scaleX(0.02) scaleY(0.4); }
    18%  { opacity: 1; }
    100% { opacity: 0.42; transform: translate(-50%, -50%) scaleX(1) scaleY(1); }
}

/* Two light echoes going out as it lands. Very flat — they follow the disc,
   not the circle. */
.welcome-pulse {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 100%;
    height: 62%;
    border: 2px solid var(--color-welcome-flare);
    border-radius: 50%;
    animation: welcome-ring 0.85s ease-out 2.12s both;
}

.welcome-pulse--late {
    animation-delay: 2.28s;
}

@keyframes welcome-ring {
    0%   { transform: translate(-50%, -50%) scale(0.15); opacity: 0; }
    15%  { opacity: 0.75; }
    100% { transform: translate(-50%, -50%) scale(1.9); opacity: 0; }
}

/* ---- Wordmark ----
   Hanson, the same display face as the "Home" title the card hands over to.

   Deliberately not clipped. The obvious way to sweep a highlight across a
   word is the glint rectangle the posters use, but that has to be held inside
   an overflow: hidden box, and the same box then crops the text shadow these
   letters need to stay readable against the paler light-mode blue. Running
   the highlight letter by letter instead gets the light travelling through
   the word with nothing to clip. */

.welcome-wordmark {
    display: flex;
    margin: 0;
    font-family: 'Hanson', 'Circular Spotify', sans-serif;
    font-weight: 200;
    font-size: clamp(2.4rem, 13vw, 6.5rem);
    line-height: 1;
    letter-spacing: 0.02em;
}

/* --i is set per letter in the markup. */
.welcome-wordmark span {
    display: block;
    text-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
    animation:
        welcome-letter 0.45s cubic-bezier(0.16, 1, 0.3, 1)
            calc(2.18s + var(--i) * 0.04s) both,
        welcome-sheen 0.40s ease-in-out
            calc(2.62s + var(--i) * 0.04s) both;
}

@keyframes welcome-letter {
    from { opacity: 0; transform: translateY(0.4em); filter: blur(6px); }
    to   { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes welcome-sheen {
    0%, 100% { text-shadow: 0 4px 24px rgba(0, 0, 0, 0.35); }
    50% {
        text-shadow:
            0 4px 24px rgba(0, 0, 0, 0.35),
            0 0 26px rgba(255, 255, 255, 0.85);
    }
}

/* ---- Reduced motion ----
   The card still plays, it just does not move: the finished lock-up is there
   from the start, holds, and cross-fades out.

   The keyframes stay out here, at the top level. Inside the @media block they
   are only registered while it matches, and an animation-name pointing at a
   keyframes set that does not exist is silently dropped — which takes the
   fade-out with it and leaves the card stuck on screen. */

@keyframes welcome-quiet-exit {
    to { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
    #welcome_screen {
        animation: welcome-quiet-exit 0.5s ease-in 1.1s forwards;
    }

    .welcome-panel,
    .welcome-panel::before,
    .welcome-stars,
    .welcome-stage,
    .welcome-roller-track,
    .welcome-mark img,
    .welcome-wordmark span {
        animation: none;
    }

    .welcome-roller-track {
        transform: translateY(-75%);
    }

    /* Straight to its settled state. It needs the centring transform written
       back in, because that only exists inside its keyframes. */
    .welcome-flare {
        animation: none;
        opacity: 0.42;
        transform: translate(-50%, -50%);
    }

    /* The stars stay — they are scenery, not movement. Only the fall stops. */
    .welcome-pulse {
        display: none;
    }
}

/* ---- Hero ----

   The artwork and the title drift as the page is scrolled, at different rates
   and in the same direction, so the hero has depth rather than sliding off as
   one flat picture.

   --hero-scroll is written by js_main.js on each scroll frame: 0 at the top,
   1 once the hero has been scrolled clear. Everything below is derived from
   it, so the whole effect is one number and there is nothing for the script to
   keep in step.

   The rates are chosen so the artwork always loses to the page — at 0.12 of
   the scroll distance it still moves up, just slowly, which is what reads as
   distance. Anything approaching parity looks like the image is stuck to the
   window, and going the other way looks like a bug. */

#home-header-container {
    position: relative;
    width: 100%;
    overflow: hidden;
    height: 65vh;
    display: block;
}

#home-header {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 50vh;
    width: 100%;
    color: white;
    font-family: 'Circular Spotify', sans-serif;
    font-weight: 800;
    font-size: 64px;
    text-shadow: 0 0 16px #000000bf;
    z-index: 50;
    margin: 0;
    margin-top: 64px;
    position: absolute;
    overflow: hidden;

    /* The title is nearer than the artwork, so it travels further, and it fades
       as it goes rather than sliding under the copy below. */
    transform: translate3d(0, calc(var(--hero-scroll, 0) * -22%), 0);
    opacity: calc(1 - var(--hero-scroll, 0) * 1.15);
    will-change: transform;
}

#home-header h1 {
    margin: 0;
    padding: 0;
    text-align: center;
}

/* Scaled up a touch so there is artwork to spare at both ends of the drift;
   at 1:1 the parallax would pull the bottom edge up off the fade. */
#home-header-container #frontpage_design {
    margin: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: translate3d(0, calc(var(--hero-scroll, 0) * 12%), 0) scale(1.08);
    will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
    #home-header,
    #home-header-container #frontpage_design {
        transform: none;
        opacity: 1;
        will-change: auto;
    }
}

#fade-effect {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, var(--color-fade) 100%);
}

/* ---- Intro copy ---- */

#home-text-content {
    padding: 16px;
    justify-content: center;
    align-items: center;
    display: flex;
    flex-direction: column;
}

#home-text-content p {
    max-width: 1250px;
    text-align: center;
}

/* ---- Poster grid ----
   Two posters side by side with the Creative Experiments banner spanning
   the full width beneath them. The glint sweep on hover reuses the
   @keyframes glint-sweep defined in style_main.css. */

.front-page-section {
    display: grid;
    grid-template-columns: auto auto;
    gap: clamp(8px, 3vw, 16px);
    justify-content: center;
    margin-bottom: clamp(32px, 6vw, 64px);
}

.front-page-graphic {
    position: relative;
    display: inline-block;
    width: clamp(100px, 40vw, 256px);
    aspect-ratio: 297 / 420; /* A3 */
    border-radius: 8px;
    overflow: hidden;

    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    transition: transform var(--dur-panel) var(--ease-out),
                box-shadow var(--dur-panel) var(--ease-out);
}

.front-page-graphic img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;

    /* Improve downscale sharpness */
    image-rendering: -webkit-optimize-contrast;
    image-rendering: smooth;

    backface-visibility: hidden;
    transform: translateZ(0);
}

/* The poster art itself pushes in slightly behind the frame on hover, so the
   card reads as a window onto the artwork rather than a picture being nudged
   around the page. */
.front-page-graphic img {
    transition: transform var(--dur-panel) var(--ease-out);
}

@media (hover: hover) {
    .front-page-graphic:hover {
        transform: translateY(-6px);
        box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45);
    }

    .front-page-graphic:hover img {
        transform: scale(1.04);
    }
}

.front-page-graphic:active {
    transform: translateY(-2px) scale(0.985);
    transition-duration: var(--dur-press);
}

.front-page-graphic::after {
    content: "";
    position: absolute;
    top: -50%;
    left: -75%;
    width: 50%;
    height: 200%;
    background: linear-gradient(
        120deg,
        transparent 0%,
        rgba(255, 255, 255, 0.25) 50%,
        transparent 100%
    );
    transform: rotate(25deg);
    opacity: 0;
    pointer-events: none;
}

@media (hover: hover) {
    .front-page-graphic:hover::after {
        animation: glint-sweep 0.8s ease forwards;
    }
}

.front-page-graphic-wide {
    grid-column: 1 / -1;
    width: 100%;
    height: clamp(80px, 11vw, 120px);
}

.front-page-graphic-div {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
    align-items: center;
    flex-wrap: wrap;
    gap: 32px;
}

@media (max-width: 640px) {
    .front-page-section {
        margin-bottom: 100px;
    }
}
