/* ═══════════════════════════════════════════
   Memory Wall — graduation-glow
   A worn photo album, not a slideshow: photos
   arrive one at a time as the recipient scrolls
   at their own pace, each placed with a slight
   settle rather than dropped as a grid.
   ═══════════════════════════════════════════ */

.memory-wall-container {
    position: relative;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* ───── Sparkle field — sparser than welcome, drifts behind the photos ───── */
.memory-wall-sparkles {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

/* Second sparkle tone. On a light ground a second COLOUR cannot work: any
   tint saturated enough to read is darker than the parchment, which is what
   made these render as dark specks. Vary the glint's size instead, and let
   the shared .sparkle-layer--light variant own the colour. */
.sparkle-layer--light .sparkle.memory-wall-sparkle-sage {
    width: 9px;
    height: 9px;
}

/* ───── The scrollable album itself ───── */
.memory-wall-scroll {
    position: relative;
    z-index: 1;
    width: 100%;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
    scrollbar-width: none;
    /* Cards fade out at the bottom instead of being sliced by a hard line. */
    /* Soft at both edges. The bottom fade alone left scrolled cards sliced
       by a hard line under the title band. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 1.5rem, #000 calc(100% - 3rem), transparent);
    mask-image: linear-gradient(to bottom, transparent 0, #000 1.5rem, #000 calc(100% - 3rem), transparent);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.25rem;
    padding: 4.5rem 1.5rem 2.5rem;
}

.memory-wall-scroll::-webkit-scrollbar {
    display: none;
}

/* ───── Title — the album's title page, first thing in the scroll flow ───── */
.memory-wall-title {
    flex-shrink: 0;
    width: 100%;
    max-width: 420px;
    margin: 0 auto;
    /* Was flush with the top edge (y=0): a web-app viewport, not an album. */
    padding: clamp(1.25rem, 5vh, 2.25rem) 1.25rem 0.75rem;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.5rem, 5.5vw, 2.15rem);
    line-height: 1.25;
    color: var(--text-primary);
    text-align: center;
    opacity: 0;
    transform: translateY(20px);
    animation: memory-wall-titleIn 900ms var(--ease-expo-out) forwards;
    animation-delay: 150ms;
}

/* ───── Each photo — placed, not loaded ───── */
.memory-wall-photo {
    width: 100%;
    max-width: 420px;
    opacity: 0;
    transform: translateY(52px) scale(0.97);
    transition: opacity 900ms var(--ease-expo-out), transform 900ms var(--ease-expo-out);
}

.memory-wall-photo.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* The card is the tap target: a plain button reset to inherit the frame's
   visual language, with the closed face and open frame layered inside it. */
.memory-wall-card {
    position: relative;
    display: block;
    width: 100%;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.memory-wall-card:focus-visible {
    outline: 2px solid var(--accent-warm-deep);
    outline-offset: 5px;
    border-radius: 12px;
}

.memory-wall-photo-frame {
    position: relative;
    display: block;
    background: var(--glass);
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    padding: 0.65rem 0.65rem 1.1rem;
    box-shadow: 0 22px 46px rgba(42, 40, 32, 0.16);
    opacity: 0;
    transition: opacity 500ms var(--ease-expo-out);
}

.memory-wall-card.is-open .memory-wall-photo-frame {
    opacity: 1;
}

.memory-wall-photo:nth-child(odd) .memory-wall-photo-frame {
    transform: rotate(-1.1deg);
}

.memory-wall-photo:nth-child(even) .memory-wall-photo-frame {
    transform: rotate(0.9deg);
}

/* ───── The closed face — a quiet, wordless tap affordance sized to match
   the frame it covers, so nothing shifts when the card opens ───── */
.memory-wall-card-face {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--glass);
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    box-shadow: 0 22px 46px rgba(42, 40, 32, 0.16);
    opacity: 1;
    transition: opacity 500ms var(--ease-expo-out);
}

.memory-wall-card.is-open .memory-wall-card-face {
    opacity: 0;
    pointer-events: none;
}

.memory-wall-photo:nth-child(odd) .memory-wall-card-face {
    transform: rotate(-1.1deg);
}

.memory-wall-photo:nth-child(even) .memory-wall-card-face {
    transform: rotate(0.9deg);
}

/* The closed face shows the memory it hides -- softly. It used to be an
   identical blank '+' on every card, so the recipient chose a position, not
   a memory, and nearly everyone tapped the top card: the finale's claim
   about their choice was true of the layout, not of them. */
.memory-wall-card-peek {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 10px;
    filter: blur(14px) saturate(0.85);
    opacity: 0.55;
    transform: scale(1.08);
}

/* Its own ground, because the photo behind it is the buyer's. Dark text on
   a 55% blur of a hall full of black gowns measured 2.93:1; the fixtures'
   flat light placeholders read 6.6:1, which is why every gate passed. A
   near-opaque pill of --void holds AA over any photo (~11:1 over black). */
.memory-wall-card-hint {
    position: absolute;
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    padding: 0.45rem 0.8rem;
    border-radius: 10px;
    background: color-mix(in srgb, var(--void) 88%, transparent);
    font-family: var(--font-display);
    font-style: italic;
    font-size: 1.05rem;
    line-height: 1.35;
    color: var(--text-primary);
    text-align: center;
}

.memory-wall-card-face {
    overflow: hidden;
}

/* Now that the face shows a blurred photo, the '+' needs its own ground: on
   the photo it measured 2.86:1, under the 3:1 a large glyph needs. */
.memory-wall-card-mark {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: var(--void);
    box-shadow: 0 6px 16px rgba(42, 40, 32, 0.12);
    font-family: var(--font-body);
    font-weight: 300;
    font-size: 1.9rem;
    line-height: 1;
    color: var(--accent-warm-deep);
    opacity: 0.9;
    transition: transform 300ms var(--ease-back-out), opacity 300ms var(--ease-silk);
}

.memory-wall-card:hover .memory-wall-card-mark,
.memory-wall-card:focus-visible .memory-wall-card-mark {
    transform: scale(1.15);
    opacity: 0.9;
}

.memory-wall-image {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 6px;
    background: var(--bg-elevated);
}

.memory-wall-caption {
    display: block;
    margin: 0.7rem 0 0;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.82rem;
    line-height: 1.5;
    letter-spacing: 0.01em;
    color: var(--text-secondary);
    text-align: center;
}

/* ───── Closing line — appears once every card has been opened ───── */
.memory-wall-closing {
    flex-shrink: 0;
    width: 100%;
    max-width: 420px;
    margin: 0.5rem auto 0;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 1rem;
    line-height: 1.6;
    letter-spacing: 0.01em;
    color: var(--text-secondary);
    text-align: center;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 800ms var(--ease-expo-out), transform 800ms var(--ease-expo-out);
}

.memory-wall-closing.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ───── Scroll prompt — pulses until the first scroll gesture ───── */
.memory-wall-scroll-prompt {
    position: absolute;
    left: 50%;
    bottom: 1.75rem;
    z-index: 2;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    pointer-events: none;
    transition: opacity 500ms var(--ease-silk);
}

.memory-wall-scroll-prompt.is-hidden {
    opacity: 0;
}

.memory-wall-scroll-arrow {
    font-size: 1.4rem;
    line-height: 1;
    color: var(--accent-warm-deep);
    animation: memory-wall-arrowBounce 1.8s var(--ease-breath) infinite;
}

.memory-wall-scroll-label {
    font-family: var(--font-body);
    font-size: 0.78rem;
    font-weight: 400;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

/* The arrow bows out after the first scroll; the count stays until every
   memory is open, so a recipient who skipped one is told why the way
   forward has not appeared -- it used to be an empty dead end. */
.memory-wall-scroll-prompt.is-scrolled .memory-wall-scroll-arrow {
    display: none;
}

/* ───── Footer — the reach-forward cue after the last photo. Normal flow,
   sized to content: it is the last row in the container's flex column, so
   it always lands at the bottom of the viewport without needing to be
   pulled out of flow. ───── */
.memory-wall-footer {
    position: relative;
    z-index: 3;
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    padding: 1.1rem 1.25rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, var(--bg-primary) 45%, transparent);
    opacity: 0;
    transform: translateY(18px);
    pointer-events: none;
    transition: opacity 800ms var(--ease-expo-out), transform 800ms var(--ease-expo-out);
}

.memory-wall-footer.is-visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.memory-wall-footer-btn {
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 0.92rem;
    color: var(--void);
    background: var(--accent-warm);
    border: none;
    border-radius: 999px;
    padding: 0.85rem 1.6rem;
    cursor: pointer;
    box-shadow: 0 14px 30px var(--accent-warm-glow-soft);
    transition: transform 300ms var(--ease-back-out), box-shadow 300ms var(--ease-silk);
}

.memory-wall-footer-btn:hover,
.memory-wall-footer-btn:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 18px 36px var(--accent-warm-glow);
}

/* ───── Keyframes ───── */
@keyframes memory-wall-arrowBounce {
    0%, 100% { transform: translateY(0); opacity: 0.9; }
    50% { transform: translateY(9px); opacity: 0.4; }
}

@keyframes memory-wall-titleIn {
    to { opacity: 1; transform: translateY(0); }
}

/* ───── Mobile ───── */
@media (max-width: 480px) {
    .memory-wall-scroll {
        padding: 3.5rem 1.1rem 2rem;
        gap: 2.5rem;
    }

    .memory-wall-photo {
        max-width: 100%;
    }

    .memory-wall-title,
    .memory-wall-closing {
        max-width: 100%;
    }
}
