/* ============================================================
   CARDS — surfaces, tarot cards, reveal animation
   ============================================================ */

/* --- Generic surface --------------------------------------- */

.surface {
    background: var(--surface-celestial);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm), var(--ring-gold);
}

/* --- Interactive panel -------------------------------------- */

.panel {
    position: relative;
    /* Keeps the sparkle layers from being painted over by sibling cards. */
    isolation: isolate;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    background: var(--surface-celestial);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm), var(--ring-gold);
    text-decoration: none;
    color: inherit;
    transition: transform var(--duration-base) var(--ease-out),
                box-shadow var(--duration-base) var(--ease-out),
                border-color var(--duration-base) var(--ease-out);
}

a.panel:hover,
a.panel:focus-visible {
    color: inherit;
    transform: translateY(-3px);
    border-color: var(--border-accent);
    /* La linea de oro de arriba es una sombra interior, no un
       pseudoelemento: `::before` y `::after` ya llevan las chispas, y un
       tercero pedia un nodo mas en la plantilla para un adorno. */
    box-shadow:
        inset 0 3px 0 0 var(--gold),
        var(--shadow-lg),
        var(--glow-moon),
        var(--ring-gold-strong);
}

/* ------------------------------------------------------------
   SPARKLES ON HOVER
   Two mask layers, each carrying several stars at different
   sizes and positions. Masked rather than drawn, so the colour
   comes from `background-color` and follows the theme. The two
   layers twinkle out of phase, which reads as scattered.
   ------------------------------------------------------------ */

.panel::before,
.panel::after,
.spread-card::before,
.spread-card::after,
.sign-card::before,
.sign-card::after,
.card-slot::before,
.card-slot::after {
    content: "";
    position: absolute;
    /* Spills slightly past the card so sparkles ring the edge. */
    inset: -10px;
    z-index: 1;
    pointer-events: none;
    opacity: 0;
    background-color: var(--gold-bright);
    mask-image: var(--sparkle-star), var(--sparkle-star), var(--sparkle-star);
    -webkit-mask-image: var(--sparkle-star), var(--sparkle-star), var(--sparkle-star);
    mask-repeat: no-repeat;
    -webkit-mask-repeat: no-repeat;
    transition: opacity var(--duration-base) var(--ease-out);
}

.panel::before,
.spread-card::before,
.sign-card::before,
.card-slot::before {
    mask-position: 1% 8%, 97% 24%, 8% 94%;
    -webkit-mask-position: 1% 8%, 97% 24%, 8% 94%;
    mask-size: 16px, 10px, 12px;
    -webkit-mask-size: 16px, 10px, 12px;
}

.panel::after,
.spread-card::after,
.sign-card::after,
.card-slot::after {
    mask-position: 95% 90%, 52% 1%, 0% 52%;
    -webkit-mask-position: 95% 90%, 52% 1%, 0% 52%;
    mask-size: 11px, 13px, 9px;
    -webkit-mask-size: 11px, 13px, 9px;
}

/* Only where hovering is a real input: on touch the state would stick. */
@media (hover: hover) {
    a.panel:hover::before,
    a.panel:focus-visible::before,
    a.spread-card:hover::before,
    a.spread-card:focus-visible::before,
    a.sign-card:hover::before,
    a.sign-card:focus-visible::before,
    .card-slot:hover::before {
        opacity: 1;
        animation: sparkle-twinkle 1.6s var(--ease-in-out) infinite;
    }

    a.panel:hover::after,
    a.panel:focus-visible::after,
    a.spread-card:hover::after,
    a.spread-card:focus-visible::after,
    a.sign-card:hover::after,
    a.sign-card:focus-visible::after,
    .card-slot:hover::after {
        opacity: 1;
        animation: sparkle-twinkle 1.6s var(--ease-in-out) 0.4s infinite;
    }
}

@keyframes sparkle-twinkle {
    0%, 100% { opacity: 0.35; transform: scale(0.82) rotate(-8deg); }
    50%      { opacity: 1;    transform: scale(1.08) rotate(8deg); }
}

/* Reduced motion: the sparkles still appear, they just hold still. */
@media (prefers-reduced-motion: reduce) {
    a.panel:hover::before,
    a.panel:hover::after,
    a.spread-card:hover::before,
    a.spread-card:hover::after,
    a.sign-card:hover::before,
    a.sign-card:hover::after,
    .card-slot:hover::before,
    .card-slot:hover::after {
        animation: none;
        opacity: 0.8;
    }
}

.panel__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    /* Indigo/violet, not gold on cream: the gold tile read as parchment
       rather than as Yuna. Gold is kept to the hairline ring. */
    color: var(--secondary-contrast);
    background: linear-gradient(
        140deg,
        var(--accent-soft),
        var(--secondary-soft)
    );
    box-shadow: var(--ring-gold-strong);
    border-radius: var(--radius-md);
    transition: transform var(--duration-base) var(--ease-out),
                box-shadow var(--duration-base) var(--ease-out);
}

/* Al pasar por encima el icono se adelanta y se queda quieto: el panel ya
   tiene la atencion, asi que el balanceo continuo sobra. */
a.panel:hover .panel__icon,
a.panel:focus-visible .panel__icon {
    animation: none;
    transform: translateY(-4px) scale(1.08);
    color: var(--text-on-accent);
    background: linear-gradient(140deg, var(--accent), var(--secondary));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 55%, transparent),
                0 0 22px color-mix(in srgb, var(--gold) 45%, transparent);
}

.panel__title {
    font-size: var(--text-lg);
    margin: 0;
}

.panel__text {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin: 0;
}

.panel__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: auto;
    padding-top: var(--space-2);
}

/* ============================================================
   TAROT CARD
   ============================================================ */

.tarot-card {
    /* Rider-Waite proportions. */
    aspect-ratio: 300 / 512;
    width: 100%;
    perspective: 1200px;
    background: none;
    border: none;
    padding: 0;
}

.tarot-card__inner {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform var(--duration-reveal) var(--ease-in-out);
}

/* The flip lifts and tilts as it turns, so the card feels handled rather
   than switched. `scale` peaks mid-turn, which sells the depth. */
.tarot-card.is-revealed .tarot-card__inner {
    animation: card-flip var(--duration-reveal) var(--ease-in-out) forwards;
}

@keyframes card-flip {
    0% {
        transform: rotateY(0) rotateZ(0) scale(1) translateY(0);
    }
    45% {
        transform: rotateY(90deg) rotateZ(-3deg) scale(1.1) translateY(-10px);
    }
    100% {
        transform: rotateY(180deg) rotateZ(0) scale(1) translateY(0);
    }
}

/* A burst of moonlight at the moment the face lands. */
.tarot-card.is-revealed .tarot-card__face--front {
    animation: card-flare var(--duration-reveal) var(--ease-out) forwards;
}

@keyframes card-flare {
    0%, 50% {
        box-shadow: var(--shadow-md);
    }
    70% {
        box-shadow:
            0 0 0 2px var(--gold-bright),
            0 0 46px 10px color-mix(in srgb, var(--gold) 55%, transparent),
            var(--shadow-lg);
    }
    100% {
        box-shadow: var(--glow-card);
    }
}

@media (prefers-reduced-motion: reduce) {
    .tarot-card.is-revealed .tarot-card__inner {
        animation: none;
        transform: rotateY(180deg);
    }

    .tarot-card.is-revealed .tarot-card__face--front {
        animation: none;
    }
}

.tarot-card__face {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: var(--radius-md);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    box-shadow: var(--shadow-md);
}

/* `contain`, not `cover`: a tarot card's border and its title are part of
   the artwork, and cropping them is never right. It also lets the deck hold
   mixed proportions while it is being redrawn, with the indigo behind reading
   as a mat rather than as a gap. */
.tarot-card__face img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: var(--yuna-indigo-900);
}

.tarot-card__face--back {
    background: var(--yuna-indigo-900);
}

.tarot-card__face--front {
    transform: rotateY(180deg);
    background: var(--bg-surface-sunken);
}

/* Reversed cards are shown upside down, as they are drawn. */
.tarot-card__face--front.is-reversed img {
    transform: rotate(180deg);
}

/* Hover lift, only where hovering is a real input. */
@media (hover: hover) {
    .tarot-card:hover .tarot-card__face {
        box-shadow: var(--glow-card);
    }

    .tarot-card--interactive:hover {
        transform: translateY(-4px);
    }
}

.tarot-card--interactive {
    cursor: pointer;
    transition: transform var(--duration-base) var(--ease-out);
}

/* Face-down cards waiting on the table breathe gently, each offset from the
   next, so the spread looks alive before anything is drawn. */
.tarot-card--waiting {
    animation: card-float 5.5s var(--ease-in-out) infinite;
    animation-delay: calc(var(--reveal-index, 0) * 700ms);
}

@keyframes card-float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50%      { transform: translateY(-9px) rotate(0.6deg); }
}

/* A slow sheen crossing the card back. */
.tarot-card--waiting .tarot-card__face--back::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        115deg,
        transparent 38%,
        color-mix(in srgb, var(--gold-bright) 32%, transparent) 50%,
        transparent 62%
    );
    background-size: 280% 100%;
    animation: card-sheen 6s var(--ease-in-out) infinite;
    animation-delay: calc(var(--reveal-index, 0) * 700ms);
    pointer-events: none;
}

@keyframes card-sheen {
    0%, 65%, 100% { background-position: 170% 0; }
    85%           { background-position: -70% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .tarot-card--waiting,
    .tarot-card--waiting .tarot-card__face--back::after {
        animation: none;
    }
}

/* --- Card slot (position + card together) -------------------- */

.card-slot {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: center;
    text-align: center;
}

.card-slot__position {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--accent-ink);
}

/* The name, orientation and meaning sit on their own panel: loose under the
   artwork they read as stray paragraphs rather than as part of the card. The
   type is a step smaller here, so the picture keeps the weight. */
/* Exactly as wide as the artwork above it. Left to fill the grid cell it
   spilled past the card on both sides and the column lost its symmetry. */
.card-slot__panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
    width: var(--card-max, 11rem);
    max-width: 100%;
    padding: var(--space-3) var(--space-2);
    background: var(--surface-celestial);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    /* A definite line. At --border-accent (42% violet) the edge measured 1.65
       against the panel and the box simply did not read as a box. */
    border: var(--border-width) solid color-mix(in srgb, var(--secondary) 80%, transparent);
    border-radius: var(--radius-lg);
    box-shadow: var(--ring-gold-strong), var(--shadow-md);
}

.card-slot__name {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
}

.card-slot__meaning {
    margin-top: var(--space-1);
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--text-secondary);
    text-wrap: pretty;
}

/* ------------------------------------------------------------
   THE DEAL
   Each card flies in from where the deck sat — above the row,
   in the middle — and lands in its own place, one after
   another. The horizontal distance is the slot's offset from
   the centre of the row, which is why the template passes
   `--slot-count` alongside the existing `--reveal-index`.

   `backwards`, not `both`: the fill has to hold the start
   state through the delay, but must NOT hold the end state
   afterwards, or the finished animation would outrank the
   pointer tilt below and the cards would never lean.
   ------------------------------------------------------------ */

.card-slot {
    /* A fraction of a slot width, not a whole one: the cards have to leave
       from roughly one place — the deck — and the spread is stacked into a
       narrow column beside the reading as often as it is laid out in a row.
       At a full slot width the outer two flew in from off the page. */
    --deal-shift: calc(
        (((var(--slot-count, 1) - 1) / 2) - var(--reveal-index, 0)) * 40%
    );
    animation: card-deal 620ms var(--ease-out) backwards;
    animation-delay: calc(var(--reveal-index, 0) * 130ms);
}

@keyframes card-deal {
    from {
        opacity: 0;
        transform: translate3d(var(--deal-shift), -22vh, 0)
                   rotate(-13deg) scale(0.74);
    }
    55% {
        opacity: 1;
    }
    to {
        opacity: 1;
        transform: translate3d(0, 0, 0) rotate(0) scale(1);
    }
}

/* ------------------------------------------------------------
   TILT AND SHINE
   The slot leans towards the pointer and a highlight follows
   it across the face. `flourish.js` writes the four custom
   properties; every transform stays here with the card.

   `perspective()` is a transform function rather than the
   `perspective` property because the element being rotated is
   the one carrying it, and the property only applies to an
   element's children.
   ------------------------------------------------------------ */

.card-slot.is-tilting {
    transform: perspective(900px)
               rotateX(var(--tilt-x, 0deg))
               rotateY(var(--tilt-y, 0deg));
}

/* The lean glides back when the pointer leaves, but follows it without any
   transition at all: interpolating towards a target that moves every frame
   is what made the card trail half a second behind the cursor. */
.card-slot {
    transition: transform var(--duration-base) var(--ease-out);
}

.card-slot.is-tilting {
    transition: none;
}

.tarot-card__face--front::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(
        circle at var(--shine-x, 50%) var(--shine-y, 50%),
        color-mix(in srgb, var(--gold-bright) 40%, transparent),
        transparent 58%
    );
    opacity: 0;
    transition: opacity var(--duration-base) var(--ease-out);
    pointer-events: none;
}

.card-slot.is-tilting .tarot-card__face--front::after {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .card-slot {
        animation: none;
        transition: none;
    }

    .card-slot.is-tilting {
        transform: none;
    }
}

/* ============================================================
   CATALOGUE LIST
   ============================================================ */

.card-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow-y: auto;
    padding-right: var(--space-1);
}

.card-list__item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: var(--radius-md);
    border-left: 3px solid transparent;
    transition: all var(--duration-fast) var(--ease-out);
}

.card-list__item:hover {
    color: var(--text-primary);
    background: var(--bg-surface-hover);
}

.card-list__item.is-active {
    color: var(--text-primary);
    font-weight: var(--weight-semibold);
    background: var(--accent-soft);
    border-left-color: var(--accent-ink);
}

/* ============================================================
   CARD ZOOM
   The cards are thumbnails, so tapping one has to show the
   artwork at a size worth looking at.
   ============================================================ */

.card-zoom {
    width: min(26rem, calc(100vw - 2 * var(--space-4)));
    max-height: calc(100dvh - 2 * var(--space-4));
    padding: 0;
    color: var(--text-primary);
    background: var(--surface-celestial-strong);
    border: var(--border-width) solid var(--border-accent);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg), var(--glow-moon);
    overflow: auto;
}

.card-zoom::backdrop {
    background: var(--overlay);
    backdrop-filter: blur(4px);
}

.card-zoom__inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-5);
    text-align: center;
}

.card-zoom__close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--text-secondary);
    background: var(--bg-surface);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-pill);
    transition: color var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
}

.card-zoom__close:hover {
    color: var(--text-primary);
    background: var(--bg-surface-hover);
}

/* Sized to the viewport height, so the whole card is visible without
   scrolling on a phone held upright. */
.card-zoom__image {
    width: auto;
    max-width: 100%;
    max-height: min(58dvh, 24rem);
    object-fit: contain;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md), var(--ring-gold-strong);
}

/* Turned, exactly as it lies on the table. */
.card-zoom__image.is-reversed {
    transform: rotate(180deg);
}

.card-zoom__body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
}

.card-zoom__position {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--accent-ink);
}

.card-zoom__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--text-xl);
}

.card-zoom__meaning {
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--text-secondary);
    text-wrap: pretty;
}

/* The card is a button now, so the browser's control styling has to go. */
button.tarot-card {
    appearance: none;
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    color: inherit;
    cursor: zoom-in;
}

/* ============================================================
   EL PANEL EN MOVIMIENTO

   El icono flota despacio. Es el unico movimiento continuo de la
   seccion, asi que es donde cae la vista al llegar; cada panel
   arranca en un punto distinto del ciclo para que no latan los
   tres a la vez, que pareceria un error.
   ============================================================ */

.panel__icon {
    animation: panel-icon-float 4.5s var(--ease-in-out) infinite;
}

.grid > :nth-child(2) .panel__icon { animation-delay: -1.5s; }
.grid > :nth-child(3) .panel__icon { animation-delay: -3s; }

@keyframes panel-icon-float {
    0%, 100% {
        transform: translateY(0);
        box-shadow: 0 0 0 0 transparent;
    }
    50% {
        transform: translateY(-4px);
        box-shadow: 0 0 18px 0 color-mix(in srgb, var(--gold) 35%, transparent);
    }
}

/* La flecha del pie sale a recibir. */
a.panel:hover .panel__footer .material-symbols-rounded,
a.panel:focus-visible .panel__footer .material-symbols-rounded {
    transform: translateX(5px);
    color: var(--accent-ink);
}

.panel__footer .material-symbols-rounded {
    transition: transform var(--duration-base) var(--ease-out),
                color var(--duration-base) var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
    .panel__icon,
    a.panel:hover .panel__icon,
    a.panel:focus-visible .panel__icon {
        animation: none;
        transform: none;
    }

    a.panel:hover .panel__footer .material-symbols-rounded,
    a.panel:focus-visible .panel__footer .material-symbols-rounded {
        transform: none;
    }
}
