/*
  PlayStation.

  The preset that shipped before, kept as it was: SST for the type, the long grey-to-black diagonal
  the console's own panels use, the 20px corners, the 60px icon with its white bloom, and the card
  sliding in from the right edge.

  Its signature is the pulse on the right - a ring that keeps expanding out of a still centre for as
  long as the notification is up. Here that centre is the PlayStation mark itself rather than a
  plain dot, so the animation and the logo are one element instead of two.

  What it was missing and now has: the game's name, the unlock rate, and a 100% completion state.
  The rarity tiers need no translation - bronze, silver, gold and a pale platinum are already what
  this platform calls its trophies.

  Rendered by the shared preset engine (index.html); this file owns every pixel.
*/

@font-face {
  font-family: 'PS5_Font';
  src: url('SST.ttf');
  font-weight: normal;
  font-display: block;
}

@font-face {
  font-family: 'PS5_Font';
  src: url('SSTLight.ttf');
  font-weight: lighter;
  font-display: block;
}

:root {
  --ach-in: 460ms;
  --ach-out: 340ms;
  --ease-in: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.7, 0, 0.84, 0);

  --text: #eff2f5;
  --muted: rgba(239, 242, 245, 0.68);
  --accent: #ffffff;
  --accent-soft: #ffffff;
  --tint: transparent;
  --mark-opacity: 0.9;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: transparent;
}

.ach {
  position: fixed;
  left: 50%;
  top: 50%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 15px;
  width: 452px;
  /* Room on the right for the ring, exactly as the preset this comes from reserved it. */
  padding: 16px 62px 16px 20px;
  border-radius: 20px;
  background:
    linear-gradient(105deg, var(--tint), transparent 62%),
    linear-gradient(
      to right bottom,
      #414141,
      #393839,
      #313031,
      #292829,
      #222021,
      #1e1c1d,
      #1a1818,
      #161414,
      #141212,
      #131111,
      #110f0f,
      #0f0d0d
    );
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 14%, rgba(255, 255, 255, 0.06));
  color: var(--text);
  font-family: 'PS5_Font', 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  will-change: transform, opacity;
  transform: translate(-50%, -50%) scale(var(--scale, 1));
}

/* The pulse. A ring that keeps expanding out of the mark for as long as the popup is up. */
.ach::before {
  content: '';
  position: absolute;
  right: 20px;
  top: 50%;
  /*
    border-box is load-bearing: with the default content-box the 2px border sits OUTSIDE the 34px,
    so the ring's real centre lands 2px right of and 2px below the mark's - which is exactly enough
    to read as the logo sitting off-centre inside the circle.
  */
  box-sizing: border-box;
  width: 34px;
  height: 34px;
  margin-top: -17px;
  border: 2px solid var(--accent);
  border-radius: 50%;
  opacity: 0;
}

/* The mark at its centre, masked so it takes the trophy tier's colour. */
.ach::after {
  content: '';
  position: absolute;
  right: 27px;
  top: 50%;
  width: 20px;
  height: 20px;
  margin-top: -10px;
  background: var(--accent);
  -webkit-mask: url('psicon.png') center / contain no-repeat;
  mask: url('psicon.png') center / contain no-repeat;
  opacity: var(--mark-opacity);
}

/* --- icon ------------------------------------------------------------------------------------ */

.ach .icon {
  flex: 0 0 auto;
}

.ach .icon img {
  display: block;
  box-sizing: border-box;
  width: 64px;
  height: 64px;
  border-radius: 10%;
  object-fit: cover;
  background: rgba(0, 0, 0, 0.4);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 50%, transparent);
}

/* --- text ------------------------------------------------------------------------------------ */

.ach .text_wrap {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  overflow: hidden;
}

.ach .text_wrap:has(.marquee) {
  -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.35) 0, #000 10px, #000 calc(100% - 24px), transparent 100%);
  mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.35) 0, #000 10px, #000 calc(100% - 24px), transparent 100%);
}

.ach .meta {
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: 100%;
  margin-bottom: 3px;
  line-height: 1.1;
}

.ach .meta[hidden] {
  display: none;
}

.ach .game {
  min-width: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 11px;
  font-weight: normal;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ach .game[hidden] {
  display: none;
}

.ach .rarity {
  flex: 0 0 auto;
  padding: 1px 8px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent);
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.03em;
}

.ach .rarity[hidden] {
  display: none;
}

/* Normal weight, generously sized - SST carries the card, so nothing here is bolded. */
.ach .title {
  max-width: 100%;
  margin: 0;
  color: var(--text);
  font-size: 20px;
  font-weight: normal;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ach .detail {
  max-width: 100%;
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 15px;
  font-weight: lighter;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ach .title.marquee,
.ach .detail.marquee {
  display: inline-block;
  overflow: visible;
  text-overflow: clip;
  will-change: transform;
}

/* --- progress -------------------------------------------------------------------------------- */

.progress_line {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 8px;
  min-width: 0;
}

.progress_line[hidden] {
  display: none;
}

.progress_track {
  display: block;
  flex: 1 1 auto;
  min-width: 70px;
  height: 5px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.progress_meter {
  display: block;
  width: 0%;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), var(--accent-soft));
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 50%, transparent);
  transition: width 0.35s ease;
}

.progress_label {
  flex: 0 0 auto;
  color: var(--text);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* --- states ---------------------------------------------------------------------------------- */

/* Bronze, silver, gold and platinum are this platform's own trophy tiers. */
.ach.state-rare {
  --accent: #f5c542;
  --accent-soft: #fff0c0;
  --tint: rgba(245, 197, 66, 0.16);
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent),
    0 0 8px color-mix(in srgb, var(--accent) 26%, transparent);
}

.ach.state-rare.tier-silver {
  --accent: #cdd7e3;
  --accent-soft: #ffffff;
  --tint: rgba(205, 215, 227, 0.16);
}

.ach.state-rare.tier-bronze {
  --accent: #d68a4e;
  --accent-soft: #f4cba6;
  --tint: rgba(214, 138, 78, 0.16);
}

/* 100%: the platinum trophy. A cold wash across the panel and a bright rim. */
.ach.state-platinum {
  --accent: #cfeaff;
  --accent-soft: #ffffff;
  --tint: rgba(207, 234, 255, 0.22);
  --muted: rgba(207, 234, 255, 0.78);
  box-shadow:
    0 2px 9px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 8px color-mix(in srgb, var(--accent) 32%, transparent);
}

/* --- motion ---------------------------------------------------------------------------------- */

/* Slides in from the right edge, exactly as before. */
@keyframes aw_in {
  from {
    transform: translate(calc(-50% + 24px), -50%) scale(var(--scale, 1));
    opacity: 0;
  }
  to {
    transform: translate(-50%, -50%) scale(var(--scale, 1));
    opacity: 1;
  }
}

@keyframes aw_hold {
  from,
  to {
    transform: translate(-50%, -50%) scale(var(--scale, 1));
    opacity: 1;
  }
}

@keyframes aw_out {
  from {
    transform: translate(-50%, -50%) scale(var(--scale, 1));
    opacity: 1;
  }
  to {
    transform: translate(calc(-50% + 24px), -50%) scale(var(--scale, 1));
    opacity: 0;
  }
}

/* The pulse. Transform and opacity only, so it costs nothing to keep running. */
@keyframes aw_pulse {
  0% {
    transform: scale(0.45);
    opacity: 0;
  }
  45% {
    opacity: 0.9;
  }
  100% {
    transform: scale(1.55);
    opacity: 0;
  }
}

@keyframes aw_rise {
  from {
    transform: translateX(10px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes aw_mark {
  from {
    transform: scale(0.6);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: var(--mark-opacity);
  }
}

@keyframes aw_icon {
  from {
    transform: scale(0.88);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.ach.active {
  animation:
    aw_in var(--ach-in) var(--ease-in) forwards,
    aw_hold var(--ach-hold, 5200ms) forwards,
    aw_out var(--ach-out) var(--ease-out) forwards;
  animation-delay: 0s, var(--ach-in), calc(var(--ach-in) + var(--ach-hold, 5200ms));
}

.ach.active::before {
  animation: aw_pulse 1600ms ease-out 420ms infinite;
}

.ach.active::after {
  animation: aw_mark 520ms cubic-bezier(0.22, 1.2, 0.36, 1) 300ms both;
}

.ach.active .icon img {
  animation: aw_icon 480ms var(--ease-in) 110ms both;
}

/* Never .title / .detail: the engine cancels their animations when it measures the marquee. */
.ach.active .text_wrap {
  animation: aw_rise 460ms var(--ease-in) 170ms both;
}
