@layer pack {
  .hero-pack {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr);
    align-items: center;
    gap: var(--space-6);
    min-height: 34rem;
  }

  /* Once the pack is open, the pulls take the full width so all five sit in a row. */
  .hero-pack:has(.pulls) { grid-template-columns: 1fr; text-align: center; min-height: 0; }
  .hero-pack:has(.pulls) .hero-pack__intro { justify-self: center; }
  .hero-pack:has(.pulls) .lede { margin-inline: auto; }
  .hero-pack:has(.pulls) .display-title { transform: none; }

  @media (max-width: 900px) { .hero-pack { grid-template-columns: 1fr; } }

  /* Named for the view transition when the pack opens: each block glides to its new spot. */
  .hero-pack__intro { view-transition-name: pack-intro; }
  .hero-pack .pack-stage { view-transition-name: pack-stage; }
  .hero-pack ~ .section { view-transition-name: pack-scores; }
  .hero-pack ~ .insert-sheet { view-transition-name: pack-rookies; }
  body:has(.hero-pack) .site-footer { view-transition-name: pack-footer; }
  ::view-transition-group(*) { animation-duration: 0.6s; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
  /* The headline reflows from two lines to one, so hand off rather than crossfade. */
  ::view-transition-old(pack-intro) { animation: 0.2s ease-in both vt-fade-out; }
  ::view-transition-new(pack-intro) { animation: 0.35s ease-out 0.25s both vt-fade-in; }

  .pack-stage { display: grid; justify-items: center; align-content: center; gap: var(--space-4); min-height: 32rem; }
  .pack-form { display: contents; }
  .pack-hint { color: var(--ink-muted); font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.12em; }

  /* ---- The wrapper: crimped chrome foil around a printed panel ---- */
  /* The wrapper is two pieces of foil: the crimped strip above the tear line, which comes off
     when the pack is ripped, and the rest. The crimps' teeth are the pack's actual edges (a
     zig-zag mask on each piece), so the drop shadow is a filter that follows them. */
  .pack {
    --foil: linear-gradient(118deg, #b3b8c8 0%, #f7f8ff 14%, #8a8fa3 27%, #e8ebf6 41%, #6f7489 55%, #dde1ee 70%, #9ca2b6 84%, #f1f3fb 100%);
    --pack-shadow: drop-shadow(-14px 26px 22px rgb(0 0 0 / 0.55));
    position: relative;
    display: grid;
    grid-template-rows: auto 1fr;
    width: 17rem;
    height: 26rem;
    padding: 0;
    border: 0;
    cursor: pointer;
    background: none;
    color: #0a0f1f;
    transform: perspective(1000px) rotateY(-14deg) rotateX(4deg) rotateZ(2deg);
    filter: var(--pack-shadow);
    transition: transform 0.4s cubic-bezier(.2, .8, .2, 1), filter 0.4s ease;
    animation: pack-float 5s ease-in-out infinite;
  }

  .pack__top, .pack__main {
    position: relative;
    display: grid;
    overflow: hidden;
    background: var(--foil);
    background-size: 200% 200%;
    box-shadow: inset 1px 0 rgb(255 255 255 / 0.4), inset -1px 0 rgb(255 255 255 / 0.4);
  }
  .pack__top { grid-template-rows: 1.6rem 2rem; mask: conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) 50% / 14px 100%; }
  .pack__main { grid-template-rows: 1fr 1.6rem; mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / 14px 100%; }

  .pack__top::before, .pack__main::before {
    /* Holographic sheen in the foil itself. */
    content: "";
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(118deg, rgb(255 61 242 / 0.35) 0%, rgb(255 210 61 / 0.3) 6%, rgb(57 255 156 / 0.3) 12%, rgb(57 243 255 / 0.35) 18%, rgb(139 92 255 / 0.3) 24%, rgb(255 61 242 / 0.35) 30%);
    background-size: 300% 300%;
    mix-blend-mode: color-dodge;
    opacity: 0.55;
    animation: foil-drift 7s linear infinite;
    pointer-events: none;
  }

  .pack:focus-visible {
    transform: perspective(1000px) rotateY(-4deg) rotateX(2deg) rotateZ(0deg) scale(1.03);
    filter: drop-shadow(-8px 30px 26px rgb(0 0 0 / 0.6)) drop-shadow(0 0 22px rgb(57 243 255 / 0.35));
    animation: pack-wiggle 0.5s ease-in-out;
  }

  @media (hover: hover) {
    .pack:hover {
      transform: perspective(1000px) rotateY(-4deg) rotateX(2deg) rotateZ(0deg) scale(1.03);
      filter: drop-shadow(-8px 30px 26px rgb(0 0 0 / 0.6)) drop-shadow(0 0 22px rgb(57 243 255 / 0.35));
      animation: pack-wiggle 0.5s ease-in-out;
    }
  }

  .pack { -webkit-tap-highlight-color: transparent; }

  /* Crimped heat seals: ribbed strips whose teeth are cut by their piece's mask. */
  .pack__crimp {
    position: relative;
    z-index: 1;
    background: repeating-linear-gradient(90deg, rgb(0 0 0 / 0.18) 0 2px, rgb(255 255 255 / 0.4) 2px 4px), var(--foil);
  }

  .pack__tear {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-inline: 0.8rem;
    border-bottom: 2px dashed rgb(10 15 31 / 0.45);
    font: 700 0.62rem/1 var(--font-label);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgb(10 15 31 / 0.7);
  }
  .pack__tear span::after { content: " ✂"; }

  .pack__body {
    position: relative;
    z-index: 1;
    margin: 0.6rem 0.9rem;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 0.55rem;
    padding: 1rem;
    border-radius: 6px;
    background:
      repeating-linear-gradient(108deg, transparent 0 16px, rgb(57 243 255 / 0.1) 16px 17px),
      radial-gradient(circle at 50% 35%, #1d2c5c, #070b18 75%);
    box-shadow: inset 0 0 0 2px rgb(57 243 255 / 0.55), inset 0 0 30px rgb(57 243 255 / 0.2);
    color: #fff;
    text-align: center;
  }

  .pack__brand {
    font: italic 900 2.4rem/0.95 var(--font-display);
    background: linear-gradient(135deg, #d9dde8, #fff 30%, #8d93a8 55%, #f1f3fa 75%, #9aa0b5);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    transform: skewX(-8deg);
  }
  /* Letter-spacing also trails the last letter, which pulls centered type left: the matching
     padding on the left puts the letters themselves on center. */
  .pack__title, .pack__date, .pack__count { padding-left: var(--tracking); letter-spacing: var(--tracking); }
  .pack__title { --tracking: 0.24em; font: 900 1.05rem/1 var(--font-label); color: var(--neon); text-shadow: 0 0 10px var(--neon); }
  .pack__date { --tracking: 0.1em; font: 600 1rem/1 var(--font-body); text-transform: uppercase; }
  .pack__count { --tracking: 0.14em; font: 700 0.85rem/1 var(--font-body); text-transform: uppercase; color: var(--gold); }

  .pack__shine {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.65) 48%, transparent 60%);
    background-size: 250% 100%;
    background-position: 150% 0;
    pointer-events: none;
    animation: pack-shine 3.6s ease-in-out infinite;
  }

  /* ---- Ripping: the seal tears off, the wrapper drops away ---- */
  .is-ripping .pack { animation: pack-drop 0.9s cubic-bezier(.5, 0, .75, 0) forwards; }
  .is-ripping .pack__top { animation: tear-off 0.6s cubic-bezier(.2, .8, .3, 1) forwards; }

  /* ---- Peeling: a sideways drag lifts the seal from the end it starts at; past halfway it tears.
     --tear (0 to 1) is the drag's share of the wrapper, --tear-direction which way it runs. ---- */
  .pack { touch-action: pan-y; user-select: none; }
  .pack__top {
    transform-origin: calc(50% + var(--tear-direction, 1) * 50%) 100%;
    transform: translateY(calc(var(--tear, 0) * -30px)) rotate(calc(var(--tear-direction, 1) * var(--tear, 0) * -40deg));
    transition: transform 0.35s cubic-bezier(.2, .8, .2, 1);
  }
  .pack.is-peeling { animation-play-state: paused; }
  .pack.is-peeling .pack__top { transition: none; }
  .is-ripping .pack-hint { opacity: 0; transition: opacity 0.2s; }
  .is-ripping .pack-stage::after {
    content: "";
    position: absolute;
    width: 26rem;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgb(255 255 255 / 0.9), rgb(57 243 255 / 0.45) 30%, transparent 65%);
    animation: burst 0.9s ease-out forwards;
    pointer-events: none;
  }
  .pack-stage { position: relative; }
  .is-ripping .pulls { animation: pulls-out 0.5s ease-in forwards; }

  /* ---- The pulls: a face-down stack. Each card is turned over on top of it, then dealt into the
     rows below, best card last. The stack and its buttons sit in room the list keeps clear above
     the rows; once the last card is dealt, the rows move up into it. ---- */
  .pull-table { --stack-width: min(60vw, 15.5rem); --stack-height: calc(var(--stack-width) * 7 / 5); position: relative; width: 100%; }

  .pulls {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: clamp(0.75rem, 1.6vw, 1.25rem);
    width: 100%;
  }

  .pull-table.is-stacked .pulls { padding-top: calc(var(--stack-height) + 8.5rem); }

  .pull { width: clamp(9.5rem, 16vw, 13.5rem); display: grid; gap: 0.5rem; justify-items: center; align-content: start; perspective: 1200px; }

  .pull-table.is-stacked .pull:not(.is-dealt) {
    position: absolute;
    top: 0;
    left: 50%;
    width: var(--stack-width);
    translate: -50% calc(var(--pile, 4) * 5px);
    rotate: var(--lean, 3deg);
    z-index: calc(10 - var(--pile, 4));
    cursor: grab;
    touch-action: pan-y;
    user-select: none;
    transition: translate 0.3s ease, rotate 0.3s ease, transform 0.3s cubic-bezier(.2, .8, .2, 1);
    animation: deal 0.5s cubic-bezier(.2, .8, .2, 1) backwards;
    animation-delay: calc((4 - var(--pile, 4)) * 0.08s);
  }
  .pull-table.is-stacked .pull.is-dragging { cursor: grabbing; transition: none; }

  /* Counted among the cards still on the stack, so the next one squares up as the top is dealt. */
  .pull:nth-child(1 of :not(.is-dealt)) { --pile: 0; --lean: 0deg; }
  .pull:nth-child(2 of :not(.is-dealt)) { --pile: 1; --lean: -3deg; }
  .pull:nth-child(3 of :not(.is-dealt)) { --pile: 2; --lean: 2.5deg; }
  .pull:nth-child(4 of :not(.is-dealt)) { --pile: 3; --lean: -2deg; }

  /* On the stack a card is a thing to turn and throw, not yet a link. */
  .pull:not(.is-dealt) .card { pointer-events: none; }
  .pull:not(.is-dealt) .pull__rank { display: none; }

  .pull-table__controls {
    position: absolute;
    top: calc(var(--stack-height) + 2.25rem);
    inset-inline: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
  }
  .pull-table__controls[hidden] { display: none; }
  .pull-table__controls .button { margin-top: 0; }
  .pull-table__hint { flex-basis: 100%; color: var(--ink-muted); font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.12em; }

  /* A flat flip, like the profile card's: Firefox renders through preserve-3d +
     backface-visibility. The reverse is pre-mirrored and the faces swap as the card passes
     edge-on, about 13% of the way through this overshooting ease. */
  .pull__inner {
    --pull-flip-duration: 0.75s;
    position: relative;
    display: grid;
    width: 100%;
    aspect-ratio: 5 / 7;
    transform: rotateY(180deg);
    transition: transform var(--pull-flip-duration) cubic-bezier(.3, 1.3, .5, 1);
  }

  .pull.is-revealed .pull__inner { transform: rotateY(0deg); }
  .pull__face { grid-area: 1 / 1; position: relative; transition: visibility 0s linear calc(var(--pull-flip-duration) * 0.13); }
  .pull__face--back { transform: scaleX(-1); }
  .pull.is-revealed .pull__face--back, .pull:not(.is-revealed) .pull__face--front { visibility: hidden; }
  .pull__face .card { width: 100%; }

  @media (prefers-reduced-motion: reduce) {
    .pull__inner { --pull-flip-duration: 0s; }
  }

  .pull__rank { font: 700 0.7rem/1.3 var(--font-label); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); text-align: center; opacity: 0; transition: opacity 0.4s 0.5s; }
  .pull.is-revealed .pull__rank { opacity: 1; }

  .pull--hit.is-revealed .pull__inner { animation: hit-glow 1.6s ease-out 0.6s; border-radius: var(--radius-card); }

  .pulls__actions { display: flex; justify-content: center; margin-top: var(--space-5); width: 100%; }
  .pulls__actions[hidden] { display: none; }
  .pulls__actions form { display: contents; }

  @media (max-width: 640px) {
    .hero-pack, .pack-stage { min-height: 0; }
    .pack { width: 14rem; height: 21.5rem; }
  }

  @keyframes pack-float { 50% { translate: 0 -8px; } }
  @keyframes vt-fade-out { to { opacity: 0; } }
  @keyframes vt-fade-in { from { opacity: 0; } }
  @keyframes foil-drift { to { background-position: 300% 300%; } }
  @keyframes pack-shine { 0%, 55% { background-position: 150% 0; } 100% { background-position: -60% 0; } }
  @keyframes pack-wiggle { 25% { rotate: -2deg; } 75% { rotate: 2deg; } }
  @keyframes tear-off { to { transform: translate(calc(var(--tear-direction, 1) * -30px), -160px) rotate(calc(var(--tear-direction, 1) * -24deg)); opacity: 0; } }
  /* Gone by 85%, so the view transition's "before" snapshot never catches it half faded. */
  @keyframes pack-drop { 30% { transform: perspective(1000px) rotateY(0) scale(1.06); } 85%, 100% { transform: perspective(1000px) translateY(160px) rotateX(30deg) scale(0.85); opacity: 0; } }
  @keyframes burst { 0% { transform: scale(0.2); opacity: 0; } 40% { opacity: 1; } 100% { transform: scale(1.6); opacity: 0; } }
  @keyframes pulls-out { to { transform: translateY(-30px) scale(0.95); opacity: 0; } }
  @keyframes deal { from { transform: translateY(-60px) rotate(-6deg) scale(0.85); opacity: 0; } }
  @keyframes hit-glow {
    0% { box-shadow: 0 0 0 0 rgb(255 216 107 / 0.9); }
    40% { box-shadow: 0 0 50px 14px rgb(255 216 107 / 0.65); }
    100% { box-shadow: 0 0 0 0 rgb(255 216 107 / 0); }
  }
}
