/*
 * The card view, stage by stage. js/table.js adds these classes to <html> in this order
 * and removes them in reverse:
 *
 *   is-flat     the page shrinks to the card's outline, name and address glide to their printed positions
 *   is-card     the card takes over from the page, pixel for pixel
 *   is-tilted   the card tips back onto the table
 *   is-printed  the lines only the card has are pressed in
 *
 *   is-lineup   “Let's see Paul Allen's card.”: the other cards are dealt next to yours
 */

.table {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding-inline: max(16px, env(safe-area-inset-left, 0px)) max(16px, env(safe-area-inset-right, 0px));
  perspective: 1500px;
  background: radial-gradient(ellipse 60% 55% at 50% 48%, var(--table-light), transparent 75%), var(--table);
  transition: perspective .9s var(--ease);
}

.table > .card {
  grid-area: 1 / 1;
}


/* ---------- is-flat ---------- */

.page {
  clip-path: inset(0px 0px 0px 0px round 0px);
  transition: clip-path .75s var(--ease), background-color .75s ease;
}

.page::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--card-grain);
  opacity: 0;
  transition: opacity .75s ease;
}

.is-flat .page {
  clip-path: var(--clip-to-card);
  background-color: var(--card-paper);
}

.is-flat .page::before {
  opacity: 1;
}

.site [data-morph] {
  transition: transform .75s var(--ease), color .35s ease, text-shadow .35s ease;
}

.is-flat .site [data-morph] {
  transform: var(--morph);
}

.is-flat .site {
  pointer-events: none;
}


/* ---------- is-card ---------- */

.card[data-own] {
  visibility: hidden;
}

.is-card .card[data-own] {
  visibility: visible;
}

.is-card :is(.page, .site) {
  visibility: hidden;
}


/* ---------- is-tilted ---------- */

.card[data-own] {
  transition: transform .9s var(--ease);
}

.is-tilted .card[data-own] {
  transform: rotateX(calc(34deg + var(--lean-x, 0deg))) rotateY(var(--lean-y, 0deg)) rotateZ(-7deg);
  cursor: pointer;
}

/* while following the pointer the card reacts quickly; set by js/table.js */
.card[data-own].is-following {
  transition-duration: .3s;
  transition-timing-function: ease-out;
}

/* lift the ink a hair off the paper, so the two never fight over the same depth */
.is-tilted .card__face {
  transform: translateZ(.6px);
}

/* a light that moves across the paper with the pointer */
.card[data-own] .card__paper::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(circle at var(--glint-x, 35%) var(--glint-y, 25%), rgb(255 255 255 / .5), transparent 55%);
  mix-blend-mode: soft-light;
  opacity: 0;
  transition: opacity .8s ease;
}

.is-tilted .card[data-own] .card__paper::after {
  opacity: 1;
}


/* ---------- is-printed ---------- */

/* First the blind impression appears, then the ink fills it. Lines the website travelled to are already there. */
.card[data-own] :is(.card__corner, .card__firm, .card__title, .card__town, .card__telex):not([data-morph-target]) {
  opacity: 0;
  color: transparent;
  transition: opacity .2s ease, color .2s ease;
}

.is-printed .card[data-own] :is(.card__corner, .card__firm, .card__title, .card__town, .card__telex):not([data-morph-target]) {
  opacity: 1;
  color: inherit;
  transition: opacity .25s ease var(--print-at), color .5s ease calc(var(--print-at) + 260ms);
}

.card__corner { --print-at: 0ms; }
.card__firm   { --print-at: 150ms; }
.card__title  { --print-at: 330ms; }
.card__town   { --print-at: 480ms; }
.card__telex  { --print-at: 600ms; }

.allen {
  position: fixed;
  left: 50%;
  bottom: calc(46px + env(safe-area-inset-bottom, 0px));
  translate: -50% 0;
  padding: .15rem .1rem;
  border: 0;
  border-bottom: 1px solid rgb(214 208 193 / .35);
  background: none;
  color: #d6d0c1;
  font: italic 500 1.2rem / 1.2 var(--font-italic);
  white-space: nowrap;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility 0s linear .3s, color .2s ease, border-color .2s ease;
}

.allen:hover {
  color: #fff;
  border-color: currentColor;
}

.is-printed:not(.is-lineup) .allen {
  opacity: 1;
  visibility: visible;
  transition: opacity .7s ease 1s, visibility 0s, color .2s ease, border-color .2s ease;
}


/* ---------- is-lineup ---------- */

/* a longer lens, so the cards at the ends are not distorted */
.is-lineup .table {
  perspective: 2600px;
}

.is-lineup .card[data-own] {
  transform: var(--in-slot);
}

.card:not([data-own]) {
  transform: var(--in-slot);
  translate: 0 80px;
  opacity: 0;
  visibility: hidden;
  transition: transform .35s var(--ease), translate .5s var(--ease), opacity .3s ease, visibility 0s linear .5s;
}

.is-lineup .card:not([data-own]) {
  --dealt-at: calc(100ms + var(--deal) * 150ms);
  translate: none;
  opacity: 1;
  visibility: visible;
  transition:
    transform .35s var(--ease),
    translate .8s var(--ease) var(--dealt-at),
    opacity .5s ease var(--dealt-at),
    visibility 0s linear var(--dealt-at);
}

.is-lineup a.card:is(:hover, :focus-visible) {
  transform: var(--in-slot) translateZ(28px);
  outline: none;
}


@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
}
