.pet-avatar,
.pet-gear-icon {
  --pet-fast: 160ms;
  --pet-pop: 360ms;
  --pet-loop: 3200ms;
  --pet-slow: 4200ms;
  --pet-ease-out: cubic-bezier(0, 0, 0, 1);
  --pet-ease-standard: var(--ease);
  --pet-ease-bounce: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  display: inline-block;
  overflow: visible;
  vertical-align: middle;
  touch-action: manipulation;
}

.pet-avatar.interactive {
  cursor: pointer;
  outline: none;
}

.pet-avatar.interactive:focus-visible {
  filter: drop-shadow(0 0 0.35rem rgba(255, 216, 107, 0.9));
}

.pet-ground-shadow {
  fill: #2c2225;
  opacity: 0.16;
  transform-origin: center;
}

/* Star polish: a halo behind the pet and sparkles around it, two more per tier. */
.pet-sparkle {
  stroke: #fff;
  stroke-width: 1;
  stroke-opacity: 0.7;
  transform-box: fill-box;
  transform-origin: center;
}

.pet-avatar.animated .pet-sparkle {
  animation: pet-twinkle 2.4s ease-in-out infinite;
  animation-delay: calc(var(--k) * -0.4s);
}

@keyframes pet-twinkle {
  0%, 100% { opacity: 0.7; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .pet-avatar.animated .pet-sparkle { animation: none; }
}

.pet-rig,
.pet-wings,
.pet-body,
.pet-head,
.pet-eyes,
.pet-ear-l,
.pet-ear-r,
.pet-tail,
.pet-arm-r,
.pet-heart,
.pet-sleepy-z,
.pet-mood-overlay,
.pet-cheer-sparkles,
.pet-sparkle {
  transform-box: fill-box;
  transform-origin: center;
}

.pet-rig { transform-origin: 50% 100%; }

/* Gear is placed by its SVG transform attribute, which must scale from the SVG origin. */
.pet-gear { transform-box: view-box; transform-origin: 0 0; }

/* Accessory motion. Each moving part pivots on its own box: bells and medals hang from the collar,
   the lantern from its handle, the balloon from its string, wings from the body. */
.pet-gear [class^="gear-"],
.pet-gear [class*=" gear-"],
.pet-gear-icon [class^="gear-"],
.pet-gear-icon [class*=" gear-"] { transform-box: fill-box; transform-origin: center; }
.gear-jingle, .gear-sway, .gear-lantern, .gear-billow { transform-origin: 50% 0; }
.gear-dangle { transform-origin: 67% 0; }
.gear-bob { transform-origin: 38% 100%; }
.gear-flame { transform-origin: 50% 100%; }
.gear-wing-l { transform-origin: 100% 45%; }
.gear-wing-r { transform-origin: 0 45%; }
/* The pennant's flag waves from the pole it hangs on. */
:is(.pet-gear, .pet-gear-icon) .gear-wave { transform-origin: 0 50%; }

.pet-avatar.animated .gear-twinkle { animation: gear-twinkle 2.8s ease-in-out infinite; }
.pet-avatar.animated .gear-twinkle.t2 { animation-delay: -0.9s; }
.pet-avatar.animated .gear-twinkle.t3 { animation-delay: -1.8s; }
.pet-avatar.animated .gear-jingle { animation: gear-jingle 4.6s ease-in-out infinite; }
.pet-avatar.animated .gear-sway { animation: gear-sway 3.2s ease-in-out infinite; }
.pet-avatar.animated .gear-dangle { animation: gear-sway 2.6s ease-in-out infinite; }
.pet-avatar.animated .gear-lantern { animation: gear-sway 3.6s ease-in-out infinite; }
.pet-avatar.animated .gear-glow { animation: gear-glow 2.2s ease-in-out infinite; }
.pet-avatar.animated .gear-flame { animation: gear-flame 1.3s ease-in-out infinite; }
.pet-avatar.animated .gear-bob { animation: gear-bob 3.4s ease-in-out infinite; }
.pet-avatar.animated .gear-billow { animation: gear-billow 3.2s ease-in-out infinite; }
.pet-avatar.animated .gear-wave { animation: gear-wave 2.6s ease-in-out infinite; }
.pet-avatar.animated .gear-wing-l,
.pet-avatar.animated .gear-wing-r { animation: gear-flutter 3s ease-in-out infinite; }
.pet-avatar.animated .gear-wing-r { animation-name: gear-flutter-r; }

/* Shop icons stay still in the list and come alive under the pointer. */
@media (hover: hover) {
  .gear-card:hover .pet-gear-icon .gear-twinkle { animation: gear-twinkle 2.8s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-jingle { animation: gear-jingle 1.6s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon :is(.gear-sway, .gear-dangle, .gear-lantern) { animation: gear-sway 2.4s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-glow { animation: gear-glow 2.2s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-flame { animation: gear-flame 1.3s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-bob { animation: gear-bob 3.4s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-billow { animation: gear-billow 3.2s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-wave { animation: gear-wave 1.6s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-wing-l { animation: gear-flutter 1.5s ease-in-out infinite; }
  .gear-card:hover .pet-gear-icon .gear-wing-r { animation: gear-flutter-r 1.5s ease-in-out infinite; }
}

/* A paw holding something stays put rather than waving it away. */
.pet-avatar.holding .pet-arm-r { animation: none; }

.pet-avatar.animated .pet-rig {
  animation: pet-breathe var(--pet-loop) ease-in-out infinite;
}

.pet-avatar.animated.species-bunny .pet-rig,
.pet-avatar.animated.species-fox .pet-rig {
  animation-delay: -0.5s;
}

.pet-avatar.animated.species-duck .pet-rig,
.pet-avatar.animated.species-dragon .pet-rig {
  animation-delay: -1.05s;
}

.pet-avatar.animated .pet-wings {
  transform-origin: 50% 80%;
  animation: pet-flap 2.6s ease-in-out infinite;
}

.pet-avatar.animated .pet-ground-shadow {
  animation: pet-shadow var(--pet-loop) ease-in-out infinite;
}

.pet-avatar.animated .pet-eyes {
  animation: pet-blink 4.4s ease-in-out infinite;
}

.pet-avatar.animated.species-bear .pet-eyes { animation-delay: 0.1s; }
.pet-avatar.animated.species-bunny .pet-eyes { animation-delay: 0.7s; }
.pet-avatar.animated.species-duck .pet-eyes { animation-delay: 1.2s; }
.pet-avatar.animated.species-tiger .pet-eyes { animation-delay: 1.7s; }
.pet-avatar.animated.species-dragon .pet-eyes { animation-delay: 2.2s; }
.pet-avatar.animated.species-fox .pet-eyes { animation-delay: 2.7s; }
.pet-avatar.animated.species-toad .pet-eyes { animation-delay: 3.2s; }
.pet-avatar.animated.species-scarecrow .pet-eyes { animation-delay: 3.7s; }
.pet-avatar.animated.species-red-fox .pet-eyes { animation-delay: 0.4s; }
.pet-avatar.animated.species-axolotl .pet-eyes { animation-delay: 1.5s; }
.pet-avatar.animated.species-snake .pet-eyes { animation-delay: 2.9s; }
/* Noodle's "paw" is the tail joined to its coil, so it must not wave. */
.pet-avatar.animated.species-snake .pet-arm-r { animation: none; }

.pet-avatar.animated .pet-ear-l {
  animation: pet-ear-wiggle 5.8s ease-in-out infinite;
}

.pet-avatar.animated .pet-ear-r {
  animation: pet-ear-wiggle 6.1s ease-in-out infinite reverse;
}

.pet-avatar.animated .pet-tail {
  animation: pet-tail-wag 2.4s ease-in-out infinite;
}

.pet-avatar.animated .pet-arm-r {
  animation: pet-wave 5.2s ease-in-out infinite;
}

.pet-eyes { transition: opacity 140ms ease; }

.pet-avatar.mood-happy .pet-eyes,
.pet-avatar.mood-sleepy .pet-eyes {
  opacity: 0;
}

.pet-avatar.mood-happy .pet-happy-face {
  animation: pet-happy-pop 900ms var(--pet-ease-bounce) both;
}

.pet-avatar.mood-sleepy .pet-sleepy-z {
  animation: pet-z-drift 2.8s ease-in-out infinite;
}

.pet-avatar.mood-cheer.animated .pet-rig {
  animation: pet-cheer-hop 780ms var(--pet-ease-bounce) infinite;
}

.pet-avatar.mood-cheer .pet-cheer-sparkles,
.pet-sparkle {
  animation: pet-sparkle 1.4s ease-in-out infinite;
}

.pet-poke-hearts {
  pointer-events: none;
}

.pet-heart {
  fill: #ff7aa8;
  stroke: #3a2a2e;
  stroke-width: 3px;
  opacity: 0;
}

.pet-avatar.poke-a .pet-rig,
.pet-avatar.poke-b .pet-rig {
  animation-name: pet-poke-squash, pet-breathe;
  animation-duration: 420ms, var(--pet-loop);
  animation-timing-function: var(--pet-ease-bounce), ease-in-out;
  animation-iteration-count: 1, infinite;
}

.pet-avatar.poke-a .pet-heart,
.pet-avatar.poke-b .pet-heart {
  animation: pet-heart-float 760ms var(--pet-ease-out) both;
}

.pet-avatar .heart-2 { animation-delay: 60ms; }
.pet-avatar .heart-3 { animation-delay: 110ms; }

/* A pet still to come: a solid shadow with a soft rim of light, so only its shape shows. */
.pet-avatar.locked .pet-locked-art {
  /* The shading itself is an SVG filter in PetAvatar: Safari ignores CSS filters on SVG groups. */
  opacity: 0.9;
}

.pet-avatar.locked .pet-ground-shadow {
  opacity: 0.22;
}

.pet-lock-mark {
  fill: #fff8e6;
  stroke: #3a2a2e;
  stroke-width: 3px;
  paint-order: stroke;
  font: 900 60px ui-rounded, "Nunito", system-ui, sans-serif;
}

.pet-gear-icon {
  filter: drop-shadow(0 3px 0 rgba(58, 42, 46, 0.14));
}

@keyframes pet-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.018, 0.982); }
}

@keyframes pet-flap {
  0%, 100% { transform: scaleX(1); }
  50% { transform: scaleX(1.06) translateY(-2px); }
}

@keyframes pet-shadow {
  0%, 100% { transform: scaleX(1); }
  50% { transform: scaleX(1.03); }
}

@keyframes pet-blink {
  0%, 88%, 92%, 100% { transform: scaleY(1); }
  90% { transform: scaleY(0.08); }
}

@keyframes pet-ear-wiggle {
  0%, 78%, 100% { transform: rotate(0deg); }
  82% { transform: rotate(-6deg); }
  86% { transform: rotate(5deg); }
  90% { transform: rotate(-2deg); }
}

@keyframes pet-tail-wag {
  0%, 100% { transform: rotate(-3deg); }
  50% { transform: rotate(8deg); }
}

@keyframes pet-wave {
  0%, 74%, 100% { transform: rotate(0deg); }
  80% { transform: rotate(-10deg); }
  86% { transform: rotate(9deg); }
  92% { transform: rotate(-4deg); }
}

@keyframes pet-poke-squash {
  0% { transform: scale(1); }
  32% { transform: translateY(5px) scale(1.08, 0.9); }
  68% { transform: translateY(-4px) scale(0.96, 1.06); }
  100% { transform: scale(1); }
}

@keyframes pet-heart-float {
  0% { opacity: 0; transform: translateY(12px) scale(0.7); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-34px) scale(1.08); }
}

@keyframes pet-happy-pop {
  0% { opacity: 0; transform: scale(0.96); }
  18% { opacity: 1; }
  45% { transform: scale(1.035); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes pet-z-drift {
  0% { opacity: 0; transform: translate(0, 8px) scale(0.92); }
  20%, 72% { opacity: 1; }
  100% { opacity: 0; transform: translate(6px, -18px) scale(1.05); }
}

@keyframes pet-cheer-hop {
  0%, 100% { transform: translateY(0) scale(1); }
  36% { transform: translateY(-10px) scale(0.98, 1.03); }
  68% { transform: translateY(2px) scale(1.04, 0.96); }
}

@keyframes gear-twinkle {
  0%, 55%, 100% { opacity: 0.35; transform: scale(0.55) rotate(0deg); }
  72% { opacity: 1; transform: scale(1.15) rotate(45deg); }
}

@keyframes gear-jingle {
  0%, 62%, 100% { transform: rotate(0deg); }
  68% { transform: rotate(12deg); }
  74% { transform: rotate(-10deg); }
  80% { transform: rotate(6deg); }
  86% { transform: rotate(-3deg); }
  92% { transform: rotate(1deg); }
}

@keyframes gear-sway {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(4deg); }
}

@keyframes gear-glow {
  0%, 100% { opacity: 0.16; transform: scale(0.94); }
  50% { opacity: 0.34; transform: scale(1.06); }
}

@keyframes gear-flame {
  0%, 100% { transform: scale(1, 1); }
  30% { transform: scale(0.9, 1.08); }
  60% { transform: scale(1.06, 0.94); }
}

@keyframes gear-bob {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50% { transform: translateY(-3px) rotate(4deg); }
}

@keyframes gear-billow {
  0%, 100% { transform: skewX(0deg) scale(1, 1); }
  50% { transform: skewX(-3deg) scale(1.03, 1.02); }
}

@keyframes gear-wave {
  0%, 100% { transform: skewY(0deg) scaleX(1); }
  50% { transform: skewY(5deg) scaleX(0.93); }
}

@keyframes gear-flutter {
  0%, 40%, 100% { transform: scaleX(1) rotate(0deg); }
  50%, 70% { transform: scaleX(0.78) rotate(4deg); }
  60%, 80% { transform: scaleX(1) rotate(-2deg); }
}

@keyframes gear-flutter-r {
  0%, 40%, 100% { transform: scaleX(1) rotate(0deg); }
  50%, 70% { transform: scaleX(0.78) rotate(-4deg); }
  60%, 80% { transform: scaleX(1) rotate(2deg); }
}

@keyframes pet-sparkle {
  0%, 100% { opacity: 0.72; transform: scale(0.96); }
  50% { opacity: 1; transform: scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .pet-avatar *,
  .pet-gear-icon * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------------
   Pet UI: companion cards, the pet room, roster, wardrobe, cards and win lines.
   --pet is the species color (PetArt.Palette), used as a soft tint only.
   --------------------------------------------------------------------------- */
.pet-companion { --pet: var(--accent); position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s4); align-items: center;
  padding: var(--s4); border: 1px solid var(--line); border-radius: var(--radius-lg); color: inherit; text-decoration: none;
  background: radial-gradient(120% 140% at 0% 100%, color-mix(in srgb, var(--pet) 15%, transparent), transparent 60%), var(--surface); box-shadow: var(--shadow); }
.pet-companion + * { margin-top: var(--s6); }
.pet-companion-art { position: relative; display: grid; place-items: end center; }
.pet-companion-info { display: grid; gap: var(--s1); min-width: 0; justify-items: start; }
.pet-companion-info .eyebrow { margin: 0; }
.pet-companion-name { font-size: var(--text-xl); line-height: var(--leading-title); overflow-wrap: anywhere; }
.pet-companion-link { margin-top: var(--s2); min-height: var(--s8); padding: var(--s1) var(--s4); }
.pet-companion.adopt { transition: transform var(--fast) var(--ease); }
.pet-companion.adopt:hover { transform: translateY(-2px); }
.pet-companion-eggs { display: flex; align-items: flex-end; }
.pet-companion-eggs .pet-avatar + .pet-avatar { margin-left: calc(-1 * var(--s6)); }
.pet-companion-eggs .pet-avatar:nth-child(2) { position: relative; z-index: 1; transform: translateY(-6px); }

@keyframes pet-bubble-in { from { opacity: 0; transform: translateY(6px) scale(.96); } }

.pet-xp { position: relative; width: min(100%, 16rem); height: var(--s2); border-radius: var(--pill); background: color-mix(in srgb, var(--ink) 10%, transparent); overflow: hidden; }
.pet-xp.large { width: 100%; height: .75rem; }
.pet-xp > span { position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, var(--pet), color-mix(in srgb, var(--pet) 60%, #fff));
  transform-origin: left; transform: scaleX(var(--xp)); transition: transform var(--slow) var(--ease-enter); }

/* Stage variant: the pet stands in its meadow. The scene sizes to its content, so nothing is
   cropped on phones: sky and hills on top, the pet on the grass, its card below. */
.pet-habitat { position: relative; isolation: isolate; min-height: 15rem; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); }
/* The scene bleeds a pixel past every edge: at fractional heights a flush child leaves a hairline
   of page color inside the rounded clip. The overflow hides the bleed, so nothing else moves. */
.meadow { position: absolute; inset: -1px; z-index: 0; background: #86c070; }
.meadow.scene-night { background: #274552; }
.meadow svg { position: absolute; inset: 0 0 auto 0; width: 100%; height: 15rem; }
.meadow-cloud { animation: meadow-drift 38s linear infinite alternate; }
.meadow-cloud.slow { animation-duration: 56s; animation-direction: alternate-reverse; }
.meadow-butterfly { offset-path: path("M80 190C140 150 200 200 260 170S380 150 420 180"); animation: meadow-flutter 18s ease-in-out infinite alternate; }
.meadow-stars circle { animation: meadow-twinkle 3.2s ease-in-out infinite; }
.meadow-stars circle:nth-child(2n) { animation-delay: -1.1s; }
.meadow-stars circle:nth-child(3n) { animation-delay: -2.2s; }
.meadow-fireflies circle { animation: meadow-firefly 5s ease-in-out infinite; }
.meadow-fireflies circle:nth-child(2n) { animation-delay: -1.7s; animation-duration: 6.5s; }
.meadow-fireflies circle:nth-child(3n) { animation-delay: -3.1s; }
/* Swatches are thumbnails: several on screen at once, so hold them still. */
.sky-swatch .meadow-cloud, .sky-swatch .meadow-butterfly, .sky-swatch .meadow-stars circle, .sky-swatch .meadow-fireflies circle { animation: none; }
/* Bought backgrounds: day art, then at night a navy wash over it (::after) and the moon and stars on top. */
.meadow.backdrop { background: var(--ground); }
.backdrop::after { content: ""; position: absolute; inset: 0; z-index: 1; display: var(--scene-night); background: #1d2f55; mix-blend-mode: multiply; opacity: .62; pointer-events: none; }
.backdrop .backdrop-night { z-index: 2; }
.backdrop-fall { animation: backdrop-fall 9s linear infinite; }
.backdrop-fall.slow { animation-duration: 13s; animation-delay: -5s; }
.backdrop-float { animation: backdrop-float 4.5s ease-in-out infinite alternate; }
.sky-swatch .backdrop-fall, .sky-swatch .backdrop-float { animation: none; }
@keyframes backdrop-float { to { transform: translateY(-7px); } }
@keyframes backdrop-fall { from { transform: translate(0, -40px); opacity: 0; } 15%, 85% { opacity: 1; } to { transform: translate(24px, 150px); opacity: 0; } }
@keyframes meadow-drift { to { transform: translateX(40px); } }
@keyframes meadow-flutter { from { offset-distance: 0%; } to { offset-distance: 100%; } }
@keyframes meadow-twinkle { 50% { opacity: .3; } }
@keyframes meadow-firefly { 0%, 100% { opacity: .2; transform: translate(0, 0); } 50% { opacity: 1; transform: translate(6px, -8px); } }
.pet-companion.stage { position: relative; z-index: 6; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: var(--s3); margin: 0;
  padding: calc(var(--s8) + var(--s2)) var(--s3) var(--s3); border: 0; background: none; box-shadow: none; }
.pet-companion.stage .pet-companion-art { position: relative; }
.pet-companion.stage .pet-companion-art::before { content: ""; position: absolute; left: 50%; bottom: 2%; width: 78%; height: 16%; translate: -50% 0; border-radius: 50%;
  background: radial-gradient(closest-side, rgb(255 255 255 / .35), transparent); }
.pet-companion.stage .pet-companion-info { width: 100%; justify-items: start; text-align: left; padding: var(--s3) var(--s4); border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface) 90%, transparent); backdrop-filter: blur(8px); box-shadow: 0 var(--s1) var(--s4) rgb(0 0 0 / .12); }
.pet-companion.stage .pet-companion-eggs { padding-top: var(--s2); }
/* Trading variant (game homes): your trading card, with level progress and the care link beneath. */
.pet-companion.trading { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: var(--s4); padding: 0; border: 0; background: none; box-shadow: none; }
.pet-companion.trading .trading-card { width: 100%; max-width: 20rem; }
.pet-companion-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s2) var(--s4); width: 100%; max-width: 20rem; }
.pet-companion-progress { display: grid; gap: var(--s1); flex: 1 1 10rem; min-width: 0; }
.pet-companion-progress .pet-xp { width: 100%; }


/* Starter picker. */
.starter-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: var(--s4); margin-top: var(--s6); }
.starter-card { --pet: var(--accent); display: grid; grid-template-rows: auto auto 1fr auto auto; align-items: start; gap: var(--s2); justify-items: center; text-align: center; padding: var(--s6) var(--s4) var(--s4);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: radial-gradient(90% 70% at 50% 35%, color-mix(in srgb, var(--pet) 26%, transparent), transparent 70%), var(--surface);
  box-shadow: var(--shadow); transition: transform var(--normal) var(--ease-enter), border-color var(--fast) var(--ease); }
.starter-card:hover, .starter-card.picked { transform: translateY(-4px); border-color: color-mix(in srgb, var(--pet) 60%, var(--line)); }
.starter-card h3 { margin: 0; font-size: var(--text-xl); }
.starter-card p { margin: 0; }
.starter-card button { width: 100%; margin-top: var(--s2); }
.starter-note, .starter-picker > h2 { grid-column: 1 / -1; text-align: center; }
.starter-card .pet-avatar { align-self: end; }
@media (min-width: 48rem) { .starter-picker { grid-template-columns: repeat(3, 1fr); } }
.starter-picker > .banner { grid-column: 1 / -1; }

.stat-chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s1); margin: 0; padding: 0; }
.stat-chips li { padding: 2px var(--s2); border-radius: var(--pill); font-size: var(--text-xs); font-weight: var(--weight-label);
  color: var(--stat); background: color-mix(in srgb, var(--stat) 14%, var(--surface)); }
[data-stat] { --stat: var(--accent); }
[data-stat="luck"] { --stat: #2f9e5b; }
[data-stat="wisdom"] { --stat: #6b58d6; }
[data-stat="focus"] { --stat: #d9534f; }

/* The pet room. */
.pet-stage-panel { --pet: var(--accent); padding: var(--s4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow); }
.pet-stage { position: relative; display: grid; place-items: center; min-height: 15rem; border-radius: var(--radius); }
.pet-stage-figure { position: relative; z-index: 6; display: grid; place-items: center; }
/* The try-on label sits under the pet's feet (no gear goes there) so hats and ears stay in view. */
.pet-trying { position: absolute; z-index: 7; bottom: var(--s3); left: 50%; translate: -50% 0; max-width: calc(100% - 2 * var(--s3));
  padding: var(--s1) var(--s3); border: 1px dashed var(--accent); border-radius: var(--pill); background: var(--surface);
  font-size: var(--text-xs); font-weight: var(--weight-label); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pet-stage:has(.pet-trying) .pet-stage-figure { translate: 0 calc(-1 * var(--s4)); }
.pet-stage-info, .pet-stats-panel { display: grid; gap: var(--s2); }
.pet-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2); margin-top: var(--s3); }
.pet-name { min-width: 0; font-size: var(--text-2xl); line-height: var(--leading-title); overflow-wrap: break-word; }
.pet-rename-button { position: relative; min-height: auto; padding: 2px var(--s2); border: 0; background: none; color: var(--accent); font-size: var(--text-sm); text-decoration: underline; text-underline-offset: .2em; }
.pet-rename-button .ui-icon, .pet-level-short { display: none; }
/* Renaming: a sheet with a full-width field. 16px+ text keeps iOS Safari from zooming in on focus. */
.pet-rename-pop { z-index: 400; }
.pet-rename.daily-pop-card { justify-items: stretch; }
.pet-rename h2 { font-size: var(--text-xl); overflow-wrap: anywhere; }
.pet-rename input { min-height: 3rem; font-size: max(1rem, var(--text-lg)); text-align: center; }
.pet-rename-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); }
.pet-rename-actions > * { min-height: 2.75rem; }
.pet-rename .field-error { margin: 0; font-size: var(--text-sm); }
.pet-active-note { display: flex; align-items: center; gap: var(--s2); margin: 0; color: var(--muted); font-size: var(--text-sm); }
.pet-active-note .dot { width: .5rem; height: .5rem; border-radius: 50%; background: #2f9e5b; box-shadow: 0 0 0 3px color-mix(in srgb, #2f9e5b 25%, transparent); }
.pet-stats-toggle { justify-self: start; display: inline-flex; align-items: center; gap: var(--s1); min-height: var(--s8); margin-top: var(--s2); padding: var(--s1) var(--s3);
  border-radius: var(--pill); font-size: var(--text-sm); font-weight: var(--weight-label); }
.pet-stats-toggle .ui-icon { width: 1rem; height: 1rem; transition: transform var(--fast, .15s) ease; }
.pet-stats-toggle[aria-expanded="true"] .ui-icon { transform: rotate(180deg); }
.pet-stats { list-style: none; display: grid; gap: var(--s2); margin: 0; padding: 0; }
.pet-stats.folded { display: none; }
.pet-stats li { display: grid; grid-template-columns: 5rem minmax(3rem, 1fr) minmax(3rem, auto) auto; align-items: center; column-gap: var(--s3); }
.pet-stat-info { position: relative; grid-column: 4; padding: 2px; min-width: 0; min-height: 0; border: 0; background: none; color: var(--muted); line-height: 0; border-radius: var(--pill); cursor: pointer; }
.pet-stat-info:hover, .pet-stat-info[aria-expanded="true"] { color: var(--stat); }
.pet-stat-info .ui-icon { width: 1.05rem; height: 1.05rem; }
/* Small controls keep their look but get a full-size touch target. */
.pet-stat-info::after, .pet-rename-button::after { content: ""; position: absolute; inset: 50% auto auto 50%; width: max(100%, 2.75rem); height: max(100%, 2.75rem); transform: translate(-50%, -50%); }
.pet-stat-name { font-size: var(--text-sm); font-weight: var(--weight-label); color: var(--stat); }
.pet-stat-bar { position: relative; height: var(--s2); border-radius: var(--pill); background: color-mix(in srgb, var(--stat) 12%, var(--elevated)); overflow: hidden; }
.pet-stat-bar > span { position: absolute; inset: 0; border-radius: inherit; background: var(--stat); transform-origin: left; transform: scaleX(var(--v)); transition: transform var(--normal) var(--ease-enter); }
.pet-stats strong { text-align: right; font-variant-numeric: tabular-nums; }
.pet-stat-bonus { color: var(--stat); font-size: var(--text-xs); font-weight: var(--weight-label); white-space: nowrap; }
/* What a stat does: a small bubble above its row, so nothing below it moves. */
.pet-stats li { position: relative; }
.pet-stat-effect { position: absolute; z-index: 5; bottom: calc(100% + var(--s1)); left: 0; right: 0; padding: var(--s2) var(--s3); border: 1px solid var(--line);
  border-left: 3px solid var(--stat); border-radius: var(--radius); background: var(--surface); color: var(--ink); box-shadow: 0 12px 32px -10px var(--shadow-deep), var(--shadow);
  font-size: var(--text-sm); line-height: 1.4; pointer-events: none; animation: stat-pop-in var(--motion-fast) var(--ease-enter); }
.pet-stat-effect small { display: block; color: var(--muted); font-size: var(--text-xs); }

.season-banner { width: 100%; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s2); text-align: left; margin: 0 0 var(--s4); padding: var(--s3) var(--s4); border-radius: var(--radius); background: linear-gradient(90deg, color-mix(in srgb, var(--orange) 18%, var(--surface)), var(--surface)); border: 1px solid color-mix(in srgb, var(--orange) 35%, var(--line)); color: inherit; font: inherit; }
.season-banner-go { display: inline-flex; align-items: center; gap: var(--s1); color: var(--sea); white-space: nowrap; }
.season-banner-go .ui-icon { width: 1em; height: 1em; }
.season-page > h3 { margin: 0; }
.season-page > .caption { margin: 0 0 var(--s3); }
.season-back { display: inline-flex; align-items: center; gap: var(--s1); margin-bottom: var(--s3); padding: var(--s1) var(--s3) var(--s1) var(--s2); border-radius: var(--pill); font-size: var(--text-sm); }
.season-back .ui-icon { width: 1em; height: 1em; }
.season-tag { padding: 2px var(--s2); border-radius: var(--pill); background: color-mix(in srgb, var(--orange) 18%, var(--surface)); color: var(--ink); font-size: var(--text-xs); }
.season-tag.limited { background: color-mix(in srgb, var(--orange) 34%, var(--surface)); font-weight: var(--weight-label); }

.chip-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.chip-row button { min-height: var(--s8); padding: var(--s1) var(--s3); border-radius: var(--pill); font-size: var(--text-sm); }
.chip-row button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--surface); }

/* Shelves: small square tiles, three or more to a row even on a phone. Tapping the picture tries it on;
   the pill under it is the only thing that spends coins. */
.pet-roster, .gear-grid, .backdrop-grid { list-style: none; display: grid; gap: var(--s2); margin: 0; padding: 0; }
.pet-roster { grid-template-columns: repeat(auto-fill, minmax(min(100%, 6rem), 1fr)); }
/* Gear tiles stay wide enough (two across on a phone) for full item names. */
.gear-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 9rem), 1fr)); }
.backdrop-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr)); }
@media (min-width: 768px) {
  .pet-roster { grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); gap: var(--s3); }
  .gear-grid { grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: var(--s2); }
  .backdrop-grid { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--s3); }
}

.pet-roster > li { display: flex; }
.pet-roster-card { --pet: var(--accent); position: relative; width: 100%; display: grid; justify-items: center; align-content: start; gap: 2px; padding: var(--s2) var(--s1);
  border: 1px solid var(--line); border-radius: var(--radius); color: inherit; text-align: center;
  background: radial-gradient(80% 60% at 50% 40%, color-mix(in srgb, var(--pet) 18%, transparent), transparent 70%), var(--surface);
  transition: transform var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease); }
.pet-roster-card .pet-avatar { width: 4.5rem; height: auto; }
.pet-roster-card strong { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-sm); }
.pet-roster-card .caption { font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.pet-roster-card.upcoming { border-style: dashed; background: var(--surface); cursor: default; }
.pet-roster-card.upcoming strong { letter-spacing: .12em; color: var(--muted); }
.pet-roster-card.upcoming .caption { font-size: var(--text-2xs); }
.pet-roster-card.viewing { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.pet-roster-labels { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s1);
  width: 100%; min-width: 0; min-height: calc(var(--text-2xs) * var(--leading) + var(--s1)); }
.pet-roster-labels .pet-roster-rarity { grid-column: auto; max-width: 100%; min-width: 0; margin: 0; gap: calc(var(--s1) / 2);
  padding: calc(var(--s1) / 2) calc(var(--s3) / 2); font-size: var(--text-2xs); letter-spacing: normal; text-transform: none; white-space: nowrap; }
.pet-roster-labels .pet-roster-rarity::before { display: none; }
.pet-roster-labels .pet-roster-ribbon { max-width: 100%; padding: 0; background: none; color: var(--muted); font-size: var(--text-2xs); overflow-wrap: anywhere; }

.gear-card, .backdrop-card { position: relative; display: grid; grid-template-rows: auto 1fr auto; gap: var(--s1); padding: var(--s2);
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); transition: border-color var(--motion-fast) var(--ease); }
.gear-card.wearing, .backdrop-card.wearing { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.gear-card.trying, .backdrop-card.trying { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
/* What's on the card right now reads at a glance from across the shelf. */
.try-badge { position: absolute; top: var(--s1); left: var(--s1); z-index: 1; padding: 0 var(--s2); border-radius: var(--pill); background: var(--accent); color: var(--on-accent);
  font-size: var(--text-2xs); font-weight: var(--weight-title); line-height: 1.5rem; pointer-events: none; box-shadow: 0 1px 3px var(--shadow-deep); }
/* The art fills its tile: icons are drawn small inside a square, so the square takes the tile's full height. */
.gear-try { container-type: size; display: grid; place-items: center; width: 100%; aspect-ratio: 4 / 3; min-height: 0; padding: var(--s1); border: 0; border-radius: var(--radius-sm); background: var(--elevated); box-shadow: none; }
.gear-try .pet-gear-icon { width: min(100cqw, 100cqh); height: auto; transition: transform var(--motion-fast) var(--ease); }
.gear-text { display: grid; align-content: start; gap: 2px; min-width: 0; }
/* Names and kinds wrap (three and two lines at most) rather than cut off, so every item can be read on any tile. */
.gear-text strong { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;
  font-size: var(--text-sm); line-height: 1.25; overflow-wrap: break-word; }
.gear-text > .caption { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: var(--text-xs); line-height: 1.3; }
.gear-text .season-tag { justify-self: start; font-size: var(--text-2xs); }
.gear-text .stat-chips li { padding: 0 var(--s1); font-size: var(--text-2xs); }
/* Every pill and badge sits at the foot of its tile, so prices line up across a row. */
.gear-action { width: 100%; min-height: 2.25rem; padding: var(--s1) var(--s2); border-radius: var(--pill); font-size: var(--text-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }
span.gear-action, a.gear-action { display: block; min-height: 0; padding: 0; white-space: normal; text-align: center; font-size: var(--text-xs); line-height: 1.3; }
a.gear-action { min-height: 24px; padding-block: 4px; }
.gear-action s, .primary s { opacity: .65; margin-right: .3em; font-weight: normal; }
.gear-action.coupon { border-color: var(--accent); }
/* Too dear for now: the price stays legible, just quieter. */
button.short .coin { filter: grayscale(1); opacity: .6; }
button.short:not(.primary) { color: var(--muted); }
/* A primary you can't pay for yet drops to a plain button, so it never shouts louder than what you can buy. */
button.primary.short { border-color: var(--line); background: var(--elevated); color: var(--muted); box-shadow: none; }
.shop-balance { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s1); margin: 0; font-variant-numeric: tabular-nums; }
.shop-balance .link-button { min-height: 0; padding: 0; font-size: inherit; }
.shop-short { color: var(--error); white-space: normal !important; }
.backdrop-try { display: block; width: 100%; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; overflow: hidden; cursor: pointer; box-shadow: none; }
.backdrop-try .sky-swatch.pet-habitat { height: 5.5rem; margin: 0; }
@media (hover: hover) {
  .pet-roster-card:not(.upcoming):hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
  .gear-try:hover .pet-gear-icon { transform: scale(1.08); }
  .gear-card:hover, .backdrop-card:hover { border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
}
@media (prefers-reduced-motion: reduce) {
  .pet-roster-card, .gear-try .pet-gear-icon { transition: none; }
  .pet-roster-card:hover { transform: none !important; }
}

/* Shelf signs. Your things sit on plain shelves; the shop sits under a striped awning so it never blends in. */
.shelf { display: grid; gap: var(--s3); min-width: 0; }
.shelf + .shelf { margin-top: var(--s4); }
.shelf-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s3); }
.shelf-head h3 { margin: 0; font-size: var(--text-lg); }
.shelf-hint, .shelf-empty { margin: 0; }
.shop-shelf { padding: 0 var(--s3) var(--s3); border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line)); border-radius: var(--radius-lg);
  background: linear-gradient(color-mix(in srgb, var(--accent) 9%, var(--surface)), var(--background) 12rem); overflow: hidden; }
.shop-sign { position: relative; padding-top: calc(var(--s6) + var(--s1)); }
.shop-awning { position: absolute; inset: 0 calc(-1 * var(--s3)) auto; height: var(--s6);
  background: repeating-linear-gradient(90deg, var(--accent) 0 var(--s6), color-mix(in srgb, var(--accent) 22%, var(--surface)) var(--s6) var(--s12));
  -webkit-mask: radial-gradient(circle at 50% 100%, transparent .55rem, #000 .6rem) 0 0 / var(--s6) 100%;
  mask: radial-gradient(circle at 50% 100%, transparent .55rem, #000 .6rem) 0 0 / var(--s6) 100%; }
.shop-sign h3 { font-size: var(--text-xl); letter-spacing: var(--tracking-title); }
.shop-shelf .pet-roster-card, .shop-shelf .gear-card, .shop-shelf .backdrop-card { background-color: var(--surface); }

/* Tabs and search pin below the card strip; shelves scroll underneath. */
.shop { --dock-h: 0px; --tools-h: 0px; display: grid; gap: var(--s4); align-items: start; }
/* The phone strip resizes as it pins; Chrome's scroll anchoring would pull the page back up and unpin it again. */
html:has(.shopping) { overflow-anchor: none; }
.shop-floor { display: grid; gap: var(--s3); min-width: 0; }
/* Keep shelves out of the pinned toolbar's gaps. */
.shop-tools { display: grid; gap: inherit; position: sticky; top: calc(var(--dock-h) + var(--s2)); z-index: 15; background: var(--background);
  box-shadow: 0 calc(-1 * var(--s2)) 0 var(--background), 0 6px 16px -12px var(--shadow-deep); }
/* Until the first buy: it is half price, said once above the shelves. */
.roster-deal { color: var(--accent); font-weight: 600; }
.first-buy-note { margin: 0; padding: var(--s2) var(--s3); border-radius: var(--radius); font-size: var(--text-sm);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface)); border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line)); }
.shop-floor .chip-row { margin: 0; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.shop-floor .chip-row button { min-height: 2.75rem; }
.shop-floor .chip-row::-webkit-scrollbar { display: none; }
.shop-floor .chip-row button { flex: none; }
.shop-floor > .banner { margin: 0; }
/* 16px text, so iOS never zooms in on focus. */
.shop-search input { min-height: 2.5rem; padding-block: var(--s1); font-size: 1rem; border-radius: var(--pill); }
.shop-floor :is(li, .shelf, .chip-row, .shop-results) { scroll-margin-top: calc(var(--tools-h) + var(--s4)); }
.shop-results { display: grid; gap: var(--s3); }
.shop-results .group-title { margin: 0; }
.shop-floor .season-banner { margin: 0; }

/* The dock: your card, always in view. Beside the shelves on tablets and up, scrolling on its own if the screen is short.
   A column of fixed-size blocks, so a long dock scrolls instead of squeezing the card's rows into each other. */
.shop-dock.player-card-panel { display: flex; flex-direction: column; gap: var(--s3); min-width: 0; }
.shop-dock.player-card-panel > *, .dock-side > * { flex: none; }
.dock-side { display: contents; }
.pet-stat-glyph, .pet-outfit, .pet-stat-pop { display: none; }
.shop-dock .pet-card-stage .trading-card { max-width: clamp(8rem, (100dvh - 28rem) * .6, 17rem); }
@media (min-width: 720px) {
  .shop { grid-template-columns: minmax(14rem, 17rem) minmax(0, 1fr); column-gap: var(--s4); }
  .shop-dock.player-card-panel { position: sticky; top: var(--s4); max-height: calc(100dvh - 2 * var(--s4)); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  .shop-tools { top: var(--s2); }
}
@media (min-width: 960px) { .shop { grid-template-columns: minmax(16rem, 21rem) minmax(0, 1fr); column-gap: var(--s6); } }
@media (min-width: 1200px) { .shop { grid-template-columns: 23rem minmax(0, 1fr); column-gap: var(--s8); } }
/* Short screens (landscape phones): the full card keeps its portrait but drops its trophy shelf. */
@media (max-height: 600px) { .shop-dock .tc-shelf, .shop-dock .tc-foot { display: none; } }

/* Sharing always draws the whole card at full size, from this copy kept off screen. */
.card-export-copy { position: fixed; top: 0; left: -200vw; width: 20rem; pointer-events: none; }

/* Phones: the page is a fitting room. Your card at the top; once you scroll, just your pet in its scene, pinned and short,
   with one slim row of tabs under it and a dense grid of things to try. What you're trying waits in the checkout bar
   along the bottom, so the pinned strip never grows. */
@media (max-width: 719px) {
  /* The heading steps back to one line: the title and your coins. */
  .collection-heading.has-pet { flex-wrap: nowrap; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }
  .collection-heading.has-pet > .stack { min-width: 0; }
  .collection-heading.has-pet .eyebrow { display: none; }
  /* Any name fits: long ones wrap (balanced) and step down a size rather than being cut off. */
  .collection-heading.has-pet h1 { font-size: var(--text-xl); line-height: 1.15; overflow-wrap: anywhere; text-wrap: balance; }
  .collection-heading.has-pet h1.long-name { font-size: var(--text-lg); }
  .collection-heading.has-pet .purse { flex: none; }
  /* Tucked: no heading row at all. The title stays for screen readers; the coins live in the masthead chip, and the
     purse drops down from the top of the page when that chip is tapped. */
  .collection-heading.tucked { z-index: 25; display: block; height: 0; margin: 0; }
  .collection-heading.tucked > .stack, .collection-heading.tucked .purse > summary { position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .collection-heading.tucked .purse-body { top: 0; }

  .shop { gap: var(--s3); }
  .shop-dock.player-card-panel { --card-w: clamp(8rem, min(42vw, (100dvh - 24rem) * .6), 13.25rem); --room: min(32vw, 8rem); position: sticky; top: 0; z-index: 20; display: grid;
    grid-template-columns: var(--card-w) minmax(0, 1fr); grid-template-areas: "card side"; align-items: start; gap: var(--s3);
    margin-inline: calc(-1 * var(--s4)); padding: var(--s2) var(--s4); border-width: 0 0 1px; border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
  .shop-dock .pet-card-stage { grid-area: card; width: var(--card-w); padding-top: 0; }
  .shop-dock .pet-card-stage .trading-card { width: 100%; max-width: none; }
  .shop-dock .pet-stage-info { grid-area: info; align-content: start; gap: 2px var(--s2); }
  .shop-dock .pet-stats-panel { grid-area: stats; display: grid; gap: var(--s1); }
  .shop-dock .pet-card-preview-note { grid-area: note; margin: 0; }
  .shop-dock .pet-card-preview-note[data-testid] { display: none; }

  /* Trophies: the card at full size on its own, and sharing it. */

  /* Shopping: everything beside the card is one column that scrolls on its own, never taller than the card. */
  .shopping .shop-dock .pet-card-share-wrap { display: none; }
  .shopping .dock-side { grid-area: side; display: flex; flex-direction: column; gap: var(--s2); align-self: stretch; min-width: 0; min-height: 0;
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; container-type: size; }
  .shopping:not(.dock-stuck) .dock-side { overflow: visible; container-type: inline-size; }
  .shopping .dock-side > .pet-stage-info { order: 1; }
  .shopping .dock-side > .pet-outfit { order: 2; flex: 1 1 auto; min-height: 6rem; }
  .shopping .dock-side > .pet-stats-panel { order: 3; }
  .shopping .dock-side > .pet-card-preview-note { order: 4; }
  /* Scrolled: the pet in its scene, short, so the shop gets the screen. */
  /* Keep the strip stable and its toolbar pinned even with a short or empty search result. */
  .shopping.dock-stuck .shop-floor { min-height: calc(100lvh + 4rem - var(--dock-h)); align-content: start; }
  .shopping.dock-stuck .shop-dock.player-card-panel { grid-template-columns: var(--room) minmax(0, 1fr); padding-block: var(--s2); }
  .shopping.dock-stuck .shop-dock :is(.pet-card-stage, .pet-xp-note, .pet-stage-info > .banner) { display: none; }
  /* Name, level and the XP bar on one line; the stats; then the outfit as one row of small slots. */
  .shopping.dock-stuck .shop-dock .pet-stage-info { grid-template-columns: minmax(0, max-content) minmax(2.5rem, 1fr); }
  .shopping.dock-stuck .shop-dock .pet-stage-info > .pet-title { grid-column: 1; flex-wrap: wrap; }
  .shopping.dock-stuck .shop-dock .pet-stage-info > .pet-xp { grid-column: 2; }
  .shopping.dock-stuck .dock-side > .pet-outfit { order: 4; flex: none; min-height: 0; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: auto; }
  .shopping.dock-stuck .shop-dock .outfit-slot { height: auto; aspect-ratio: 1; padding: 0; }
  .shopping.dock-stuck .shop-dock .outfit-label { display: none; }
  /* An empty slot names itself rather than showing a bare plus. */
  .shopping.dock-stuck .shop-dock .outfit-slot.empty .ui-icon { display: none; }
  .shopping.dock-stuck .shop-dock .outfit-slot.empty .outfit-label { display: block; font-size: .5625rem; letter-spacing: 0; }
  /* Previewing a pet you don't own: its name and Adopt stay; the blurb waits for the full card. */
  .shopping.dock-stuck .shop-dock .pet-stage-info > :is(.muted, p.caption:not(.shop-balance)) { display: none; }
  .shopping.dock-stuck .dock-side { gap: var(--s1); }
  .shopping.dock-stuck .shop-dock ul.pet-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .shopping.dock-stuck .shop-dock .pet-stats li { justify-content: center; column-gap: 2px; padding: 0; }
  .shopping.dock-stuck .shop-dock .pet-stats li { column-gap: 1px; min-height: 1.5rem; }
  .shopping.dock-stuck .shop-dock .pet-stat-glyph .ui-icon { width: .75rem; height: .75rem; }
  .shopping.dock-stuck .shop-dock .outfit-slot .pet-gear-icon { width: 72cqw; }
  .shopping.dock-stuck .fitting-room { grid-area: card; position: relative; display: block; width: var(--room); height: var(--room);
    border-radius: var(--radius); overflow: hidden; box-shadow: inset 0 0 0 1px var(--line), var(--shadow); }
  .fitting-room .meadow { background: linear-gradient(var(--sky, #9fd8ef) 70%, var(--ground, #86c070) 70%); }
  .fitting-room .meadow svg { inset: auto -40% 0; width: 180%; height: auto; aspect-ratio: 2 / 1; }
  .fitting-room .stamp-figure { top: auto; bottom: 6%; width: 86%; translate: -50% 0; }

  /* Name, a pencil to rename, level and the XP bar on one line; the bar drops under a name too long to share it. */
  .shopping .shop-dock .pet-stage-info { display: flex; flex-wrap: wrap; align-items: center; gap: 2px var(--s1); }
  .shopping .shop-dock .pet-stage-info > * { flex: 1 1 100%; }
  .shopping .shop-dock .pet-stage-info > .pet-title { display: contents; }
  .shopping .shop-dock .pet-title > :is(.pet-name, .pet-rename-button, .pet-level) { flex: none; }
  .shopping .shop-dock .pet-stage-info > .pet-xp { flex: 1 1 2rem; height: .5rem; }
  .shopping .shop-dock .pet-stage-info > .pet-xp-note { display: none; }
  .shopping .shop-dock :is(.pet-xp-next, .pet-kind, .pet-level-word) { display: none; }
  .shopping .shop-dock .pet-level-short { display: inline; }
  .shopping .shop-dock .pet-level { white-space: nowrap; }
  .shop-dock .pet-title { margin-top: 0; column-gap: var(--s1); row-gap: 0; }
  .shop-dock .pet-name { font-size: var(--text-lg); }
  .shopping .shop-dock .pet-name { font-size: clamp(.8125rem, 150cqi / var(--name-len, 8), var(--text-md)); line-height: 1.2; white-space: nowrap; }
  .shopping .shop-dock .pet-title .caption, .shopping .shop-dock .pet-stage-info > .caption { flex-basis: auto; font-size: var(--text-xs); }
  .shopping .shop-dock .pet-rename-button { display: inline-grid; place-items: center; min-width: 1.5rem; min-height: 1.5rem; padding: 0 2px; color: var(--muted); }
  .shopping .shop-dock .pet-rename-button .ui-icon { display: block; width: .875rem; height: .875rem; }
  .shopping .shop-dock .pet-rename-text { display: none; }
  .shop-dock .pet-stage-info > .muted { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; margin: 0; font-size: var(--text-sm); }
  .shop-dock .pet-stage-info > .banner { margin: 0; padding: var(--s1) var(--s2); font-size: var(--text-xs); }
  .shop-dock .pet-stage-info > .primary { justify-self: start; min-height: 2.25rem; padding-inline: var(--s3); font-size: var(--text-sm); }

  /* The outfit: a tile per slot plus the scene, each showing what's on; tap one to shop that slot. */
  /* The slots take whatever height the card leaves: big enough to read what's on at a glance. */
  .shopping .shop-dock .pet-outfit { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: minmax(2.75rem, 1fr); gap: var(--s1); }
  @container (max-width: 9rem) { .shopping .shop-dock .pet-outfit { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .shop-dock .outfit-cell { position: relative; display: grid; min-width: 0; }
  .shop-dock .outfit-slot { position: relative; display: grid; place-items: center; align-content: center; gap: 2px; min-width: 0; min-height: 0; height: 100%;
    padding: 2px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--ink) 4%, transparent); color: var(--muted); box-shadow: none; }
  .shop-dock .outfit-slot { container-type: size; }
  .shop-dock .outfit-slot .pet-gear-icon { width: clamp(1.25rem, min(62cqw, 100cqh - 1.5rem), 3.5rem); height: auto; aspect-ratio: 1; }
  .shop-dock .outfit-slot.empty { border-style: dashed; background: none; }
  .shop-dock .outfit-slot.empty .ui-icon { opacity: .7; }
  .shop-dock .outfit-slot.trying { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
  .shop-dock .outfit-slot[aria-pressed="true"] { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--ink); }
  .shop-dock .outfit-label { font-size: var(--text-xs); line-height: 1; letter-spacing: .02em; }
  .shop-dock .outfit-scene { padding: 0; overflow: hidden; }
  .shop-dock .outfit-scene .sky-swatch.pet-habitat { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; border-radius: 0; }
  .shop-dock .outfit-scene .sky-swatch .meadow svg { width: 100%; height: 100%; aspect-ratio: auto; }
  .shop-dock .outfit-scene .outfit-label { position: absolute; inset: auto 0 0; padding: 1px 0; background: #070c18aa; color: #fff; }
  .shop-dock .outfit-slot.empty .ui-icon { width: 1.125rem; }

  /* Stats: a row of icon chips; tap one to see what it is. */
  .shopping .shop-dock .pet-stats-toggle { display: none; }
  .shop-dock .pet-stats-toggle { margin-top: 0; min-height: 2.75rem; padding: 0 var(--s2); font-size: var(--text-sm); }
  .shop-dock .pet-stats { display: flex; flex-wrap: wrap; gap: var(--s1); }
  .shop-dock .pet-stats.folded { display: none; }
  .shop-dock .pet-stats li { position: relative; flex: 1 0 auto; display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s2); min-height: 1.75rem;
    padding: 0 var(--s2); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--ink) 5%, transparent); }
  .shop-dock .pet-stat-name { flex: 1 0 auto; font-size: var(--text-xs); white-space: nowrap; }
  .shop-dock .pet-stats strong { font-size: var(--text-sm); white-space: nowrap; }
  .shop-dock .pet-stat-bar { display: none; }
  .shop-dock .pet-stat-info { position: absolute; inset: 0; width: auto; height: auto; min-height: 0; padding: 0; border: 0; border-radius: inherit; background: none; }
  .shop-dock .pet-stat-info .ui-icon { display: none; }
  .shop-dock .pet-stats li:has(.pet-stat-effect) { box-shadow: inset 0 0 0 1.5px var(--stat); }
  .shop-dock .pet-stat-effect { min-width: 14rem; }
  /* Even chips: icon and value. A gear boost tints the value; tap for the exact bonus. */
  .shopping .shop-dock .pet-stats, .shopping .shop-dock .pet-stats.folded { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; }
  .shopping .shop-dock .pet-stats li .pet-stat-bonus { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .shopping .shop-dock .pet-stats li:has(.pet-stat-bonus) strong { color: var(--stat); }
  .shopping .shop-dock .pet-stats li { justify-content: center; flex-wrap: nowrap; column-gap: 2px; min-width: 0; padding: 0 2px; }
  .shopping .shop-dock .pet-stat-glyph { display: inline-flex; color: var(--stat); }
  .shopping .shop-dock .pet-stat-glyph .ui-icon { width: .9375rem; height: .9375rem; stroke-width: 2.25; }
  .shopping .shop-dock .pet-stat-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .shopping .shop-dock .pet-stats strong { font-size: var(--text-xs); }
  .shopping:not(.dock-stuck) .shop-dock .pet-stats li { min-height: 2.75rem; }
  /* Tapping a chip rings it and pops what it does over the shop; the chips themselves never move. */
  .shopping .shop-dock .pet-stat-effect { display: none; }
  .shopping .shop-dock .pet-stats li:has(.pet-stat-effect) { box-shadow: inset 0 0 0 1.5px var(--stat); }
  .shopping .shop-dock .pet-stat-pop { position: absolute; z-index: 25; top: calc(100% + var(--s1)); left: var(--s4); right: var(--s4); display: block;
    padding: var(--s2) var(--s3); border: 1px solid var(--line); border-left: 3px solid var(--stat); border-radius: var(--radius); background: var(--surface);
    box-shadow: 0 12px 32px -10px var(--shadow-deep), var(--shadow); font-size: var(--text-sm); line-height: 1.4; cursor: pointer;
    animation: stat-pop-in var(--motion-fast) var(--ease-enter); }
  .shopping .shop-dock .pet-stat-pop strong { color: var(--stat); }
  .shopping .shop-dock .pet-stat-pop small { display: block; color: var(--muted); font-size: var(--text-xs); }

  /* Tabs and search stay pinned under the strip. */
  .shop-floor { gap: var(--s2); }
  .shop-tools { top: var(--dock-h); }
  .shop-tools > .tab-bar { padding: 3px; }
  /* Shelf jumps clear the card and the whole search toolbar. */
  .shop-floor :is(li, .shelf, .chip-row, .shop-results) { scroll-margin-top: calc(var(--dock-h) + var(--tools-h) + var(--s2)); }
  .shop-tools > .tab-bar [role="tab"] { flex-direction: row; gap: var(--s1); min-height: 2.25rem; padding-inline: var(--s2); }
  .shop-tools > .tab-bar [role="tab"] .caption { display: none; }
  .shop-floor .chip-row { gap: var(--s1); }
  .shop-floor .chip-row button { min-height: 2.25rem; padding-inline: var(--s3); font-size: var(--text-sm); }
  .shelf { gap: var(--s2); }
  .shelf + .shelf { margin-top: var(--s2); }
  .shelf-head { column-gap: var(--s2); }
  .shelf-head h3, .shop-sign h3 { font-size: var(--text-md); }
  .shelf-head .caption { font-size: var(--text-xs); }

  /* The shop: small tiles, as many to a row as fit. Tap the picture to try it on; the price buys it. */
  .gear-grid { grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); gap: var(--s2) var(--s1); }
  .backdrop-grid { grid-template-columns: repeat(auto-fill, minmax(6.25rem, 1fr)); gap: var(--s2) var(--s1); }
  .gear-card, .backdrop-card { gap: 2px; padding: 3px 3px var(--s1); border-radius: var(--radius); }
  .gear-try { aspect-ratio: 1; padding: 6px; }
  .backdrop-try .sky-swatch.pet-habitat { height: auto; aspect-ratio: 4 / 3; }
  .gear-text { gap: 0; padding-inline: 2px; }
  .gear-text strong { display: block; -webkit-line-clamp: unset; line-clamp: unset; overflow: visible; font-size: var(--text-2xs); line-height: 1.3; white-space: normal; overflow-wrap: anywhere; hyphens: auto; }
  .gear-text > .caption, .gear-text .stat-chips { display: none; }
  /* Limited time: a clock badge on the picture's corner (the words stay for screen readers). */
  .gear-text .season-tag.limited { position: absolute; top: 6px; right: 6px; width: 1.125rem; height: 1.125rem; padding: 0; overflow: hidden; border-radius: 50%; font-size: 0;
    background: #e8743b url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.75' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Cpath d='M12 8v4l2.5 2'/%3E%3C/svg%3E") center / 80% no-repeat; }
  .gear-text .shop-short { font-size: var(--text-2xs); line-height: 1.25; }
  .gear-action { min-height: 2rem; padding: 0 2px; font-size: var(--text-xs); }
  .gear-action .coin { width: .8em; height: .8em; }
  /* A deal shows two prices: the struck one shrinks and the coin steps aside so both fit a narrow card. */
  .gear-action.coupon .coin { display: none; }
  .gear-action s { margin-right: .2em; font-size: .9em; }
  span.gear-action, a.gear-action { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: var(--text-2xs); }
  .try-badge { display: none; }
  .gear-card.trying, .backdrop-card.trying { box-shadow: 0 0 0 2px var(--accent); }
  .gear-card.trying::after, .backdrop-card.trying::after { content: ""; position: absolute; top: 5px; left: 5px; width: .875rem; height: .875rem; border-radius: 50%;
    background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5 9-10'/%3E%3C/svg%3E") center / 70% no-repeat; }
}

/* Player card: the pet is the portrait. */
.player-card-pet { position: relative; display: block; line-height: 0; }
.player-card-pet .pet-avatar { filter: drop-shadow(0 2px 4px #0002); }
.player-card-pet-level { position: absolute; right: -2px; bottom: 2px; min-width: 1.4rem; padding: 2px 5px; border-radius: var(--pill); background: var(--ink); color: var(--surface);
  font-size: var(--text-xs); font-weight: var(--weight-title); line-height: 1.2; text-align: center; font-variant-numeric: tabular-nums; }
.player-card-petname { color: var(--ink); font-size: var(--text-sm); font-weight: var(--weight-label); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-card:has(.player-card-pet) { background: radial-gradient(60% 120% at 0% 0%, color-mix(in srgb, var(--pet) 18%, transparent), transparent 70%),
  linear-gradient(100deg, color-mix(in srgb, var(--scene-accent) 12%, var(--surface)), var(--surface) 60%); }

/* Trading card: the full player card, made to show off. Rank sets the metal and how much the foil shines;
   the card tilts toward the pointer (app.js sets --rx/--ry/--mx/--my). */
.player-card.trading-card { --tier: #8e99ab; --tier-hi: #e6ebf2; --tier-lo: #4b5566; --holo: 0; --rx: 0deg; --ry: 0deg; --mx: 50%; --my: 30%;
  position: relative; container-type: inline-size; display: flex; flex-direction: column; gap: var(--s2); width: 100%; max-width: 20rem; margin-inline: auto;
  padding: clamp(var(--s1), 3%, var(--s2)); border: 0; border-radius: var(--radius-lg); isolation: isolate; overflow: hidden;
  background: linear-gradient(145deg, var(--tier-hi) 0%, var(--tier) 30%, var(--tier-lo) 62%, var(--tier) 82%, var(--tier-hi) 100%);
  box-shadow: inset 0 1px 0 #fff9, inset 0 0 0 1px var(--tier-lo), 0 18px 32px -18px var(--tier-lo), var(--shadow);
  transform: perspective(800px) rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--lift, 1)); transition: transform var(--motion-slow) var(--ease-pop), --mx var(--motion-slow) var(--ease), --my var(--motion-slow) var(--ease);
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-user-drag: none;
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
.trading-card.tilting { transition: none; }
.trading-card:has(.tc-rank-menu) { touch-action: pan-y; }
/* Touch: the card lifts under your finger and springs back (with a little overshoot) on release. */
.trading-card.pressed { --lift: 1.03; transition: transform var(--motion-fast) var(--ease); }
.trading-card.tilting .tc-foil, .trading-card.tilting .tc-holo { animation: none; }
.trading-card.tier-bronze { --tier: #b5763f; --tier-hi: #f3cfa5; --tier-lo: #6d3f1c; --holo: .12; }
.trading-card.tier-silver { --tier: #a9b5c6; --tier-hi: #f7faff; --tier-lo: #5d6a7d; --holo: .22; }
.trading-card.tier-gold { --tier: #e0ad2e; --tier-hi: #fff1b8; --tier-lo: #8a5d07; --holo: .4; }
.trading-card.tier-platinum { --tier: #4fbfbb; --tier-hi: #dafffc; --tier-lo: #1d6a73; --holo: .55; }
.trading-card.tier-diamond { --tier: #8b78f0; --tier-hi: #f0e9ff; --tier-lo: #3e2a9c; --holo: .75; }
/* Foil: a rainbow sheen and a glare that follow the pointer. */
.tc-foil { position: absolute; inset: 0; z-index: 9; pointer-events: none; border-radius: inherit; mix-blend-mode: soft-light; opacity: calc(.25 + var(--holo));
  background: radial-gradient(circle at var(--mx) var(--my), #ffffffb0 0%, transparent 42%),
    linear-gradient(115deg, transparent 20%, #ff7ac6 32%, #ffd36b 40%, #7dffb0 48%, #74c8ff 56%, #c48bff 64%, transparent 76%) var(--mx) var(--my) / 250% 250% no-repeat; }
.tier-unranked .tc-foil { background: radial-gradient(circle at var(--mx) var(--my), #fff6 0%, transparent 38%); }

.tc-art.pet-habitat { aspect-ratio: 4 / 5; min-height: 0; border-radius: calc(var(--radius-lg) - var(--s1)); box-shadow: 0 0 0 2px var(--tier-lo), inset 0 0 0 1px #fff5; }
/* Portrait cards show nearly the whole scene, side props included, instead of cropping its sides away:
   the scene's ground meets the pet's feet, its sky colour fills above and its ground colour below. */
.tc-art .meadow { background: linear-gradient(var(--sky, #9fd8ef) 50%, var(--ground, #86c070) 50%); }
.tc-art .meadow svg { inset: auto -15% 12%; width: 130%; height: auto; aspect-ratio: 2 / 1; }
.tc-art::after { content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: linear-gradient(#0b1220a6, transparent 24%, transparent 70%, #0b1220d9); }
.tc-halo { position: absolute; left: 50%; bottom: 10%; z-index: 4; width: 78%; aspect-ratio: 1; translate: -50% 0; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--pet, var(--tier)) 55%, #fff) 0%, transparent 65%); opacity: .55; }
.tc-pet { position: absolute; inset: auto 0 13% 0; z-index: 6; display: grid; justify-items: center; line-height: 0; }
.tc-pet .pet-avatar { width: min(270px, 93cqi); height: auto; filter: drop-shadow(0 6px 6px #0004); }
.tc-top { position: absolute; inset: var(--s2) var(--s2) auto; z-index: 7; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s2); color: #fff; }
.tc-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-top: var(--s1);
  font-size: var(--text-lg); font-weight: var(--weight-title); letter-spacing: var(--tracking-title); text-shadow: 0 1px 2px #0009; }
.tc-name a { color: inherit; text-decoration: none; }
.tc-name a:hover { text-decoration: underline; }
/* The rank crest: a shield in the tier's metal. */
.tc-crest { flex: none; display: grid; justify-items: center; align-content: start; gap: 1px; min-width: 3.4rem; padding: 6px var(--s3) 15px;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 11px), 50% 100%, 0 calc(100% - 11px)); color: #1b1408;
  background: linear-gradient(160deg, var(--tier-hi), var(--tier) 55%, var(--tier-lo)); filter: drop-shadow(0 2px 3px #0006); }
.tc-crest-tier { font-size: var(--text-2xs); font-weight: var(--weight-title); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.tc-crest strong { font-size: var(--text-lg); line-height: 1; font-variant-numeric: tabular-nums; }
.tc-crest .ui-icon { width: 1.1em; height: 1.1em; }
.tier-platinum .tc-crest, .tier-diamond .tc-crest { color: #fff; }
/* The game the crest's rank is from (players pick it on their card). */
.tc-crest-game { display: inline-flex; align-items: center; gap: 2px; max-width: 5.6rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--text-2xs); font-weight: var(--weight-title); line-height: 1.2; }
.tc-crest-game img { flex: none; border-radius: 3px; }
/* A rated crest is small: the rating with the game's logo under it. */
.tc-crest:has(> [data-testid="card-arena-game"]) { display: grid; justify-items: center; gap: 2px; min-width: 0; padding: 4px 6px 11px; }
.tc-crest:has(> [data-testid="card-arena-game"]) strong { order: -1; font-size: var(--text-sm); }
.tc-crest:has(> [data-testid="card-arena-game"]) .tc-crest-game { max-width: none; }
.tc-crest:has(> [data-testid="card-arena-game"]) .tc-crest-game img { width: 14px; height: 14px; }
.tc-crest-game img { display: block; }
/* On your own card the crest is a button: tap it to pick which rank shows, or hide it. */
.tc-crest-pick { border: 0; font: inherit; cursor: pointer; transition: transform .15s var(--ease), filter .15s var(--ease); }
.tc-crest-pick:hover { filter: drop-shadow(0 3px 6px #0008) brightness(1.06); }
.tc-crest-pick:active { transform: scale(.96); }
.tc-crest-pick:focus-visible { outline: none; filter: drop-shadow(0 0 0 #fff) drop-shadow(0 0 3px #fff); }
.tc-crest-hidden { --tier-hi: #ffffff59; --tier: #ffffff33; --tier-lo: #ffffff1f; color: #fff; text-shadow: 0 1px 2px #0008; backdrop-filter: blur(6px); }
/* The open menu lifts the crest row over the name, pet and caption. */
.tc-top:has(.tc-rank-menu) { z-index: 12; }
.tc-rank-menu { position: absolute; top: calc(100% + var(--s1)); right: 0; z-index: 9; display: grid; min-width: 12rem; max-width: calc(100cqi - 2 * var(--s2)); padding: var(--s1);
  max-height: 15.5rem; overflow-y: auto; overscroll-behavior: contain;
  border-radius: var(--radius); background: var(--surface); color: var(--ink); box-shadow: 0 10px 28px #0007; text-shadow: none;
  transform-origin: top right; animation: tc-menu-in .16s var(--ease); }
.tc-rank-menu button { display: flex; align-items: center; justify-content: flex-start; gap: var(--s2); min-height: 2.25rem; padding: 0 var(--s2); border: 0; border-radius: calc(var(--radius) - 4px);
  background: none; color: inherit; font: inherit; font-size: var(--text-sm); text-align: left; cursor: pointer; }
.tc-rank-menu button:hover, .tc-rank-menu button:focus-visible { background: color-mix(in srgb, var(--ink) 8%, transparent); outline: none; }
.tc-rank-menu button[aria-checked="true"] { font-weight: var(--weight-title); }
.tc-rank-menu button[aria-checked="true"]::after { content: "✓"; margin-left: auto; color: var(--accent); }
.tc-rank-menu small { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.tc-rank-menu button[aria-checked="true"] small { margin-left: var(--s2); }
.tc-rank-menu img { flex: none; border-radius: 4px; }
.tc-rank-group .ui-icon { flex: none; width: 14px; height: 14px; margin-left: var(--s1); transition: rotate .15s var(--ease); }
.tc-rank-group small { margin-left: auto; }
.tc-rank-group[aria-expanded="true"] .ui-icon { rotate: 180deg; }
.tc-rank-group[data-chosen] { font-weight: var(--weight-title); }
.tc-rank-menu .tc-rank-sub { padding-left: calc(var(--s2) * 2 + 16px); min-height: 2rem; }
.tc-rank-menu .ui-icon { width: 16px; height: 16px; }
@keyframes tc-menu-in { from { opacity: 0; transform: scale(.94) translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .tc-rank-menu { animation: none; } }
.tc-caption { position: absolute; inset: auto var(--s3) var(--s2); z-index: 7; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: var(--s2); color: #fff; text-shadow: 0 1px 2px #0009; }
.tc-petname { grid-column: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: clamp(var(--text-sm), 150cqi / var(--name-len, 6), var(--text-xl)); line-height: var(--leading-title); letter-spacing: var(--tracking-title); }
.tc-species { grid-column: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-sm); font-weight: var(--weight-title); font-variant-numeric: tabular-nums; opacity: .9; }
.tc-streak { grid-column: 2; grid-row: 1 / span 2; align-self: end; display: inline-flex; align-items: center; gap: 3px; padding: 2px var(--s2); border-radius: var(--pill);
  background: linear-gradient(135deg, #ffb347, #ff6a3d); color: #fff; font-size: var(--text-sm); font-weight: var(--weight-title); font-variant-numeric: tabular-nums; text-shadow: none; box-shadow: 0 2px 6px #0005; }
.tc-streak .ui-icon { width: 1em; height: 1em; }
/* The trophy shelf: three sockets, pinned medals first. */
.tc-shelf { list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s1); margin: 0; padding: var(--s1) var(--s2);
  border-radius: calc(var(--radius-lg) - var(--s1)); background: linear-gradient(#0b1220e6, #0b1220bf); box-shadow: inset 0 1px 3px #000a, 0 1px 0 #fff4; }
.tc-shelf li { display: grid; justify-items: center; align-content: start; gap: var(--s1); min-width: 0; }
.tc-shelf .trophy-badge { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--tier-hi) 50%, transparent)); }
.tc-medal-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #e8edf6; font-size: var(--text-2xs); font-weight: var(--weight-label); }
.tc-socket span { display: block; width: 28px; height: 28px; border-radius: 50%; border: 1px dashed #ffffff8c; background: #ffffff1a; }
.tc-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--s2); margin: 0; padding: 0 var(--s2);
  color: color-mix(in srgb, var(--tier-lo) 65%, #000); font-size: var(--text-2xs); font-weight: var(--weight-title); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.tier-gold .tc-foot, .tier-bronze .tc-foot { color: #3a2506; }
.tc-foot span:last-child { display: inline-flex; align-items: center; gap: 3px; font-variant-numeric: tabular-nums; }
.tc-foot .ui-icon { width: 1em; height: 1em; }
@media (prefers-reduced-motion: reduce) {
  .player-card.trading-card { transition: none; }
  .tc-foil { animation: none !important; }
}

/* Holographic cards (PlayerCard adds .holo to every trading card, and a rarity-* class when there is a pet).
   Two axes that read apart: the frame is Arena rank (each rank keeps the one below's effect), and the foil
   over the art is card rarity (CardRarity: pet, gear, stats). The top stat tints the foil (--stat via
   data-stat) and the stat total sets how hard the halo glows (--glow). Level never changes rarity; it adds
   stars, a gold nameplate at max and a stronger foil and halo (--lvl, 0 at level 1 to 1 at max). Reflections only follow the
   tilt's --mx/--my (hover, or press on touch); they never sweep on their own. */
@property --aurora { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
/* Registered so the light glides back to rest when the pointer leaves; app.js sets them as percentages on tilt. */
@property --mx { syntax: "<percentage>"; inherits: true; initial-value: 50%; }
@property --my { syntax: "<percentage>"; inherits: true; initial-value: 30%; }
.trading-card.holo { --foil: 0; --rim: 0px; --glow: 0; --lvl: 0; }
.trading-card.holo:not([data-stat]) { --stat: #ffffff; }
.trading-card.holo.rarity-unique { --foil: .32; }
.trading-card.holo.rarity-rare { --foil: .5; }
.trading-card.holo.rarity-epic { --foil: .62; }
.trading-card.holo.rarity-legendary { --foil: .74; }
.trading-card.holo.rarity-mythic { --foil: .84; }

/* Frame: brushed metal from Bronze up. */
.trading-card.holo:not(.tier-unranked) { background-image: repeating-linear-gradient(90deg, #ffffff38 0 1px, transparent 1px 3px, #0000001f 3px 4px),
  linear-gradient(145deg, var(--tier-hi) 0%, var(--tier) 30%, var(--tier-lo) 62%, var(--tier) 82%, var(--tier-hi) 100%); }
/* The rim: a ring just inside the card edge (masked to --rim wide). Silver: a glint that runs along it as you tilt. */
.tc-frame { position: absolute; inset: 0; z-index: 8; pointer-events: none; border-radius: inherit; padding: var(--rim);
  -webkit-mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
.holo.tier-silver { --rim: 3px; }
.holo.tier-gold { --rim: 4px; }
.holo.tier-platinum, .holo.tier-diamond { --rim: 5px; }
.holo.champion { --rim: 6px; }
.holo:is(.tier-silver, .tier-gold) .tc-frame { background: linear-gradient(115deg, transparent 30%, #fff 50%, transparent 70%) var(--mx) var(--my) / 300% 300% no-repeat,
  linear-gradient(160deg, var(--tier-hi), var(--tier) 50%, var(--tier-lo)); filter: drop-shadow(0 0 3px var(--tier-hi)); }
.trading-card.holo:is(.tier-gold, .tier-platinum, .tier-diamond) { box-shadow: inset 0 1px 0 #fff9, 0 0 18px -2px var(--tier), 0 18px 32px -18px var(--tier-lo), var(--shadow); }
/* Gold: the crest shimmers with the tilt and the corners sparkle. */
.holo:is(.tier-gold, .tier-platinum, .tier-diamond) .tc-crest { background: linear-gradient(110deg, var(--tier-lo), var(--tier) 30%, var(--tier-hi) 45%, var(--tier) 60%, var(--tier-lo)) calc(100% - var(--mx)) 0 / 250% 100%; }
.holo:is(.tier-gold, .tier-platinum, .tier-diamond) .tc-frame::before, .holo:is(.tier-gold, .tier-platinum, .tier-diamond) .tc-frame::after {
  content: ""; position: absolute; width: 22px; aspect-ratio: 1; background: #fff; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  filter: drop-shadow(0 0 5px var(--tier-hi)) drop-shadow(0 0 2px #fff); animation: tc-twinkle 2.2s var(--ease) infinite; }
.holo .tc-frame::before { top: 1px; left: 1px; }
.holo .tc-frame::after { right: 1px; bottom: 1px; animation-delay: 1.3s !important; }
@keyframes tc-twinkle { 0%, 100% { opacity: .3; scale: .45; rotate: 0deg; } 50% { opacity: 1; scale: 1.1; rotate: 45deg; } }
/* Platinum: a rainbow rim that turns with the tilt. */
.holo.tier-platinum .tc-frame, .holo.tier-diamond .tc-frame {
  background: conic-gradient(from calc(var(--ry) * 12 + var(--rx) * 6), #ff3fa8, #ffcc33, #39f58a, #33b4ff, #a95cff, #ff3fa8); filter: drop-shadow(0 0 4px #fff8); }
/* Diamond: cracked-ice facets on the metal, and the crest is cut like a gem. */
.trading-card.holo.tier-diamond { background-image:
  linear-gradient(60deg, #ffffff59 25%, transparent 25% 50%, #ffffff33 50% 75%, transparent 75%),
  linear-gradient(-60deg, #ffffff4d 25%, transparent 25% 50%, #00000033 50% 75%, transparent 75%),
  linear-gradient(145deg, var(--tier-hi) 0%, var(--tier) 30%, var(--tier-lo) 62%, var(--tier) 82%, var(--tier-hi) 100%);
  background-size: 22px 38px, 22px 38px, auto; background-position: var(--mx) var(--my), calc(100% - var(--mx)) var(--my), 0 0; }
.holo.tier-diamond .tc-crest { clip-path: polygon(14% 0, 86% 0, 100% 14px, 100% calc(100% - 11px), 50% 100%, 0 calc(100% - 11px), 0 14px); }
/* Champion (top 10): an aurora that flows round the rim. */
.holo.champion .tc-frame { background: conic-gradient(from var(--aurora), #3cf0c5, #5b8cff, #c46bff, #ff6bb5, #ffd36b, #3cf0c5);
  animation: tc-aurora 4s linear infinite; filter: drop-shadow(0 0 6px #c46bff) drop-shadow(0 0 2px #fff); }
.trading-card.holo.champion { box-shadow: inset 0 1px 0 #fff9, 0 0 30px 0 #8f6bffaa, 0 0 12px #3cf0c580, 0 18px 32px -18px var(--tier-lo), var(--shadow); }
@keyframes tc-aurora { to { --aurora: 360deg; } }

/* Foil by rarity, tinted by the top stat: a reverse holo in the art window, behind the pet so it stays crisp,
   leaving the frame to show the rank. A lighter sheen (.tc-foil) still crosses the whole card. */
.tc-holo { position: absolute; inset: 0; z-index: 5; pointer-events: none; border-radius: inherit; }
.trading-card.holo .tc-foil { opacity: calc(.18 + var(--foil) * .35); animation: none; }
.trading-card.holo.rarity-common .tc-foil { opacity: .18; }
.trading-card.holo .tc-holo { opacity: calc(.3 + var(--foil) + var(--lvl) * .16); animation: none;
  background: radial-gradient(circle at var(--mx) var(--my), #ffffffd0 0%, transparent 45%); }
.trading-card.holo.rarity-unique .tc-holo { background: radial-gradient(circle at var(--mx) var(--my), #ffffffb0 0%, transparent 40%),
  linear-gradient(115deg, transparent 25%, color-mix(in srgb, var(--stat) 70%, #fff) 50%, transparent 75%) var(--mx) var(--my) / 250% 250% no-repeat; }
/* Rare and up: bands of rainbow holo that slide with the light, on a wash of the top stat's color. */
.trading-card.holo:is(.rarity-rare, .rarity-epic, .rarity-legendary, .rarity-mythic) .tc-holo { mix-blend-mode: overlay; background:
  radial-gradient(circle at var(--mx) var(--my), #ffffffe0 0%, #ffffff40 25%, transparent 50%),
  repeating-linear-gradient(115deg, #ff3fa8 0%, #ffcc33 5%, #39f58a 10%, #33b4ff 15%, #a95cff 20%, #ff3fa8 25%) var(--mx) var(--my) / 300% 300%,
  linear-gradient(color-mix(in srgb, var(--stat) 55%, transparent), color-mix(in srgb, var(--stat) 55%, transparent)); }
/* Epic: glitter specks that shift as the light moves. */
.trading-card.holo:is(.rarity-epic, .rarity-legendary, .rarity-mythic) .tc-holo::before { content: ""; position: absolute; inset: 0; border-radius: inherit; mix-blend-mode: color-dodge;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 11 -6.4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") var(--mx) var(--my) / 140px 140px;
  -webkit-mask: radial-gradient(circle at var(--mx) var(--my), #000 0%, #000a 55%, #0004 100%); mask: radial-gradient(circle at var(--mx) var(--my), #000 0%, #000a 55%, #0004 100%); }
/* Legendary: a galaxy of stars behind the sheen, and depth: the pet and its scene part as you tilt. */
.trading-card.holo:is(.rarity-legendary, .rarity-mythic) .tc-holo::after { content: ""; position: absolute; inset: 0; border-radius: inherit; mix-blend-mode: screen; opacity: 1;
  background: radial-gradient(2.5px 2.5px at 20% 30%, #fff, transparent), radial-gradient(1.5px 1.5px at 70% 20%, #fff, transparent),
    radial-gradient(2.5px 2.5px at 40% 70%, #fff, transparent), radial-gradient(1.5px 1.5px at 85% 60%, #fff, transparent),
    radial-gradient(2px 2px at 10% 85%, #fff, transparent), radial-gradient(2.5px 2.5px at 60% 45%, #fff, transparent),
    radial-gradient(60% 40% at 30% 40%, #7b5cffa0, transparent), radial-gradient(50% 40% at 75% 70%, #ff5cc8a0, transparent);
  background-size: 90px 110px, 90px 110px, 90px 110px, 90px 110px, 90px 110px, 90px 110px, 100% 100%, 100% 100%;
  background-position: calc(var(--mx) * .3) calc(var(--my) * .3); }
.holo:is(.rarity-legendary, .rarity-mythic) .tc-pet { translate: calc((var(--mx) - 50%) * .24) calc((var(--my) - 50%) * .12); }
.holo:is(.rarity-legendary, .rarity-mythic) .tc-art .meadow { scale: 1.1; translate: calc((50% - var(--mx)) * .08) calc((50% - var(--my)) * .06); }
/* Mythic: the foil's hue turns with the tilt, and sparkles drift up off the pet. */
.trading-card.holo.rarity-mythic .tc-holo { filter: hue-rotate(calc(var(--ry) * 20)); transition: filter var(--motion-slow) var(--ease); }
.trading-card.holo.rarity-mythic.tilting .tc-holo { transition: none; }
.tc-sparkles { position: absolute; inset: 10% 15% 18%; z-index: 7; pointer-events: none; }
.tc-sparkles i { position: absolute; bottom: var(--b); width: 15px; aspect-ratio: 1;
  background: color-mix(in srgb, var(--stat) 30%, #fff); clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  filter: drop-shadow(0 0 4px var(--stat)) drop-shadow(0 0 2px #fff); opacity: 0; animation: tc-rise 3s var(--ease) infinite; animation-delay: calc(var(--i) * -.27s); }
@keyframes tc-rise { 0% { opacity: 0; translate: 0 0; scale: .4; } 30% { opacity: 1; scale: 1; } 100% { opacity: 0; translate: 0 -80px; scale: .6; } }

/* Halo: tinted by the top stat, brighter the higher the stats. */
.holo .tc-halo { background: radial-gradient(circle, color-mix(in srgb, var(--stat, var(--pet)) 60%, #fff) 0%, transparent 65%); opacity: calc(.45 + var(--glow) * .35 + var(--lvl) * .3); scale: calc(.95 + var(--lvl) * .25); }
/* Rare gear glints on its own (the selectors are written per card, see PlayerCard; Reduce Motion holds a steady glow). */
@keyframes tc-gear-glint { 0%, 70%, 100% { filter: none; } 82% { filter: brightness(1.8) drop-shadow(0 0 6px #fff) drop-shadow(0 0 2px #fff); } }

/* Rarity tag, level stars, and a gold nameplate at level 30. */
.holo .tc-caption { grid-template-rows: auto auto auto; }
.holo .tc-streak { grid-row: 1 / span 3; }
.tc-rarity { grid-column: 1; justify-self: start; display: inline-flex; align-items: center; gap: 4px; margin-bottom: 2px; padding: 1px var(--s2) 1px 5px; border-radius: var(--pill);
  background: #0b1220b3; color: var(--rarity, #e8edf6); font-size: var(--text-2xs); font-weight: var(--weight-title); letter-spacing: var(--tracking-label); text-transform: uppercase; text-shadow: none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rarity, #fff) 55%, transparent); }
.tc-rarity::before { content: ""; width: 9px; aspect-ratio: 1; background: var(--rarity, #e8edf6); clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.rarity-common { --rarity: #c9d1dc; }
.rarity-unique { --rarity: #6ee7a0; }
.rarity-rare { --rarity: #6fb7ff; }
.rarity-epic { --rarity: #c79bff; }
.rarity-legendary { --rarity: #ffb547; }
.rarity-mythic { --rarity: #ff7ad1; }
.rarity-mythic .tc-rarity { color: #fff; background: linear-gradient(100deg, #ff7ac6, #ffd36b, #7dffb0, #74c8ff, #c48bff); }
.rarity-mythic .tc-rarity::before { background: #fff; }
.tc-stars { margin-right: 4px; color: #ffd36b; letter-spacing: 1px; }
.tc-level { display: inline-block; min-width: 1.5em; padding: 0 .4em; border-radius: var(--pill); background: #ffffff2e; box-shadow: inset 0 0 0 1px #ffffff40; text-align: center; line-height: 1.35; }
.holo.maxed .tc-petname { background: linear-gradient(180deg, #fff6c9, #ffd36b 55%, #e09a1a); -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: none; filter: drop-shadow(0 1px 1px #0009); }
@container (max-width: 12rem) {
  .tc-top { inset: var(--s3) var(--s2) auto; align-items: center; gap: var(--s1); }
  .tc-name { padding-top: 0; font-size: var(--text-xs); }
  .trading-card .tc-top .tc-crest { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--s1);
    min-width: var(--control); min-height: var(--s6); padding: var(--s1) var(--s2); border-radius: var(--pill); clip-path: none; filter: none; font-size: var(--text-xs); }
  /* The small badge keeps a full-size touch target without making the header taller. */
  .tc-crest-pick::after { content: ""; position: absolute; inset: calc((var(--control) - var(--s6)) / -2) 0; }
  .trading-card .tc-crest-pick:focus-visible { outline: 2px solid var(--tier-hi); outline-offset: 2px; }
  .tc-crest-tier { font-size: var(--text-2xs); letter-spacing: normal; text-transform: none; }
  .tc-crest-hidden .tc-crest-tier { display: none; }
  .trading-card .tc-crest strong { order: 0; font-size: var(--text-xs); }
  .trading-card .tc-crest .tc-crest-game img, .trading-card .tc-crest .ui-icon { width: var(--s3); height: var(--s3); }
  .tc-rank-menu { min-width: 0; width: 100%; max-width: none; max-height: calc(125cqi - var(--s12)); }
  .tc-rank-menu button { min-width: 0; min-height: var(--control); flex-wrap: wrap; gap: var(--s1); padding: var(--s1); font-size: var(--text-xs); overflow-wrap: anywhere; }
  .tc-rank-menu small { font-size: var(--text-2xs); }
  .tc-rank-menu .tc-rank-sub { min-height: var(--control); padding-left: var(--s2); }
  .tc-pet .pet-avatar { width: calc(100cqi - var(--s6)); }
  .holo .tc-caption { inset: auto var(--s2) var(--s2); grid-template-rows: auto; align-items: center; }
  .tc-petname { grid-row: 1; font-size: var(--text-sm); }
  .tc-species, .tc-medal-name, .tc-foot { display: none; }
  .holo .tc-streak { grid-row: 1; align-self: center; font-size: var(--text-2xs); padding: 2px var(--s1); }
  .tc-shelf { padding: var(--s1); gap: var(--s1); }
  .tc-shelf .trophy-badge { filter: none; }
  .trading-card.holo .tc-frame { padding: 1px; filter: none; }
  .tc-rarity { gap: 3px; padding: 0 5px 0 4px; font-size: .5625rem; }
  .tc-rarity::before { width: 7px; }
  .holo .tc-frame::before, .holo .tc-frame::after { width: var(--s2); }
}
/* "Shiny player cards" turned off in Settings: the rainbow holo, foil and sparkles go, the rank metal and
   rarity colors stay, so a card still reads as rare without moving. */
[data-card-shine="off"] :is(.tc-holo, .tc-foil, .tc-sparkles) { display: none; }
[data-card-shine="off"] :is(.holo .tc-frame, .holo .tc-crest) { animation: none !important; }
[data-card-shine="off"] .holo .tc-frame::before, [data-card-shine="off"] .holo .tc-frame::after { animation: none !important; opacity: .8; }

@media (prefers-reduced-motion: reduce) {
  .holo .tc-frame, .holo .tc-frame::before, .holo .tc-frame::after, .holo .tc-crest, .tc-sparkles i, .trading-card.holo .tc-foil, .tc-holo { animation: none !important; }
  .holo .tc-frame::before, .holo .tc-frame::after { opacity: .8; }
  .tc-sparkles i { opacity: .7; }
}

/* Before a live match: your card and your rival's, face to face. */
.versus-cards { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: var(--s2); width: 100%; }
.versus-cards > div { min-width: 0; }
.versus-cards .trading-card { max-width: 18rem; }
.versus-cards .versus-mark { font-size: var(--text-md); }
.tc-unknown { display: grid; place-items: center; aspect-ratio: 5 / 7; max-width: 17rem; margin: 0 auto; border: 2px dashed var(--line); border-radius: var(--radius-lg);
  color: var(--muted); font-weight: var(--weight-title); overflow-wrap: anywhere; text-align: center; padding: var(--s2); }
.versus-cards .rival { animation: rival-deal var(--motion-slow) var(--ease-pop) both; }
@keyframes rival-deal { from { opacity: 0; transform: translateY(var(--s4)) rotate(4deg) scale(.94); } }
@media (max-height: 520px) and (orientation: landscape) {
  .versus-cards .trading-card { max-width: 12.5rem; }
  .versus-cards .tc-art.pet-habitat { aspect-ratio: 16 / 9; }
  .versus-cards .tc-art .meadow svg { inset: 0; width: 100%; height: 100%; aspect-ratio: auto; }
  .versus-cards .tc-shelf, .versus-cards .tc-foot { display: none; }
  .versus-cards .tc-pet .pet-avatar { width: min(110px, 34cqi); }
}
@media (prefers-reduced-motion: reduce) { .versus-cards .rival { animation: none; } }

/* Win cards. */
.win-pet { display: flex; align-items: center; gap: var(--s3); margin: var(--s2) 0; padding: var(--s2) var(--s3); border-radius: var(--radius); background: color-mix(in srgb, var(--accent) 10%, transparent);
  animation: pet-bubble-in var(--slow) var(--ease-enter) both; animation-delay: 400ms; }
.win-pet p { margin: 0; text-align: left; }
.win-pet-find { color: var(--accent); font-weight: var(--weight-label); }

@media (max-width: 40rem) {
  .pet-companion { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .pet-companion-info { justify-items: center; }
  .pet-companion.stage { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .pet-companion.stage .pet-companion-info { justify-items: start; }
  .pet-stats li { grid-template-columns: 4.5rem minmax(0, 1fr) 2.5rem auto; }
}

/* Pet tabs: a pill switcher (not a <nav>, which becomes the fixed bottom bar on phones). */
/* Tabs size to their labels and share any spare room; when they can't all fit, the bar scrolls sideways. */
.tab-bar { display: flex; gap: var(--s1); min-width: 0; padding: var(--s1); border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface);
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.tab-bar::-webkit-scrollbar { display: none; }
.tab-bar [role="tab"] { flex: 1 0 auto; white-space: nowrap; padding-inline: var(--s2); display: flex; align-items: center; justify-content: center; gap: var(--s1); min-height: var(--control);
  border: 0; border-radius: var(--pill); background: transparent; color: var(--muted); font-weight: var(--weight-label); box-shadow: none; }
.tab-bar [role="tab"][aria-selected="true"] { background: var(--accent); color: var(--on-accent); }
.tab-bar [role="tab"][aria-selected="true"] .caption { color: inherit; opacity: .7; }
@media (max-width: 959px) {
  .tab-bar [role="tab"] { padding-inline: var(--s1); flex-direction: column; gap: 0; min-height: 2.75rem; line-height: 1.2; font-size: var(--text-sm); }
  .tab-bar [role="tab"] .caption { font-size: var(--text-xs); }
}

/* Guests: pets and the shop need an account. */
.pet-gate { display: grid; justify-items: center; gap: var(--s3); margin-top: var(--s6); padding: var(--s8) var(--s4); text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow); }
.pet-gate h2 { margin: 0; }
.pet-gate p { margin: 0; max-width: 34rem; }
.pet-gate-pets { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); }
/* A guest's pet, beside the ask to keep it; on phones the pet sits beside its name so the ask stays in view. */
.collection-heading .guest-pet-note { margin: 0; }
.guest-pet { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: var(--s4); margin-top: var(--s6); }
.guest-pet-card, .guest-pet-keep { display: grid; align-content: center; justify-items: center; gap: var(--s2); padding: var(--s6) var(--s4); text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow); }
.guest-pet-card { background: radial-gradient(90% 70% at 50% 35%, color-mix(in srgb, var(--pet) 26%, transparent), transparent 70%), var(--surface); }
.guest-pet h2 { margin: 0; overflow-wrap: anywhere; }
.guest-pet-name .caption { white-space: nowrap; }
.guest-pet-keep { border-color: color-mix(in srgb, var(--pet) 45%, var(--line)); }
.guest-pet-keep p { margin: 0; max-width: 30rem; }
.guest-pet-keep .button.primary { width: min(100%, 20rem); margin-top: var(--s2); }
.guest-pet-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 var(--s4); }
.guest-pet-actions .link-button { color: var(--accent); }
.guest-pet-rename { display: grid; gap: var(--s2); width: min(100%, 20rem); }
.guest-pet-rename input { width: 100%; min-height: 3rem; font-size: max(1rem, var(--text-lg)); text-align: center; }
.guest-pet-rename .field-error { margin: 0; }
@media (max-width: 719px) {
  .guest-pet { gap: var(--s3); margin-top: var(--s3); }
  .guest-pet-card { grid-template-columns: auto minmax(0, 1fr); justify-items: start; column-gap: var(--s3); padding: var(--s3) var(--s4); text-align: start; }
  .guest-pet-card > .pet-avatar { grid-row: span 2; width: 7.5rem; height: 7.5rem; }
  .guest-pet-card > .guest-pet-rename { grid-row: span 2; }
  .guest-pet-actions { justify-content: start; }
  .guest-pet-keep { padding: var(--s4); }
}

.tc-rarity.rarity-mythic { color: #fff; background: linear-gradient(100deg, #ff7ac6, #ffd36b, #7dffb0, #74c8ff, #c48bff); }
.tc-rarity.rarity-mythic::before { background: #fff; }

/* The checkout bar: pinned along the bottom of the shelves while you try things on, so trying never pushes the card or the shop around.
   What's on, as chips you can take off one by one; the one price for the lot; Reset back to the saved look. */
.try-tray { --tray-gap: var(--s3); position: sticky; z-index: 16; bottom: calc(var(--tray-gap) + env(safe-area-inset-bottom)); justify-self: center; width: min(100%, 40rem);
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "items buy head" "note note note"; align-items: center; gap: var(--s1) var(--s2);
  margin: 0; padding: var(--s2); border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line)); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface)); box-shadow: 0 12px 32px -10px var(--shadow-deep), var(--shadow);
  animation: try-tray-in var(--motion-normal) var(--ease-enter); }
@keyframes try-tray-in { from { opacity: 0; translate: 0 1rem; } }
@media (prefers-reduced-motion: reduce) { .try-tray { animation: none; } }
.try-head { grid-area: head; display: flex; align-items: center; min-width: 0; }
.try-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.try-tray .try-reset { display: grid; place-items: center; width: 2.5rem; min-height: 2.5rem; padding: 0; border-radius: 50%; font-size: 0; }
.try-tray .try-reset .ui-icon { width: 1.125rem; height: 1.125rem; }
.try-tray:has(li:only-child) .try-head { display: none; }
.try-tray ul { grid-area: items; display: flex; align-items: center; gap: var(--s1); min-width: 0; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.try-tray ul::-webkit-scrollbar { display: none; }
.try-tray:not(:has(.try-all)) ul { grid-column: 1 / 3; }
.try-tray li { flex: none; display: flex; align-items: center; gap: var(--s1); min-width: 0; }
.try-tray li > .pet-gear-icon { flex: none; width: 2rem; height: 2rem; }
.try-scene { flex: none; display: block; width: 2rem; height: 2rem; border-radius: var(--radius-sm); }
.try-tray .try-scene.sky-swatch.pet-habitat { width: 2rem; height: 2rem; min-height: 0; margin: 0; }
.try-tray .try-name { overflow: hidden; font-size: var(--text-sm); font-weight: var(--weight-label); line-height: 1.2; text-overflow: ellipsis; white-space: nowrap; }
.try-label { display: grid; gap: 1px; min-width: 0; }
/* What the item adds to your pet's stats, so trying it on shows the numbers too. */
.try-stats { display: flex; flex-wrap: wrap; gap: 2px var(--s1); }
.try-stats > span { display: inline-flex; align-items: center; gap: 1px; color: var(--stat); font-size: var(--text-2xs); font-weight: var(--weight-title); line-height: 1.2; font-variant-numeric: tabular-nums; }
.try-stats .ui-icon { width: .75rem; height: .75rem; stroke-width: 2.5; }
.try-tray li > .caption:not(.shop-short) { font-size: var(--text-xs); white-space: nowrap; }
.try-tray li button.primary, .try-tray .try-all { min-height: 2.5rem; padding: 0 var(--s3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.try-tray .try-off { flex: none; display: grid; place-items: center; width: 2rem; min-height: 2rem; padding: 0; border-radius: 50%; color: var(--muted); }
.try-tray .try-off .ui-icon { width: .875rem; height: .875rem; }
.try-tray .try-gift { flex: none; display: grid; place-items: center; width: 2.5rem; min-height: 2.5rem; padding: 0; border-radius: 50%; color: var(--accent); }
.try-tray .try-gift .ui-icon { width: 1.125rem; height: 1.125rem; }
.try-tray li:not(:only-child) .try-gift { display: none; }
.try-tray li .shop-short { display: none; }
/* One thing on: its picture and name fill the bar, then the way to keep it and its ×. */
.try-tray li:only-child { flex: 1 1 auto; }
.try-tray li:only-child .try-label { flex: 1 1 auto; }
/* Several: a chip each (picture, any note on how to get it, ×), and Buy all is the one price. */
.try-tray li:not(:only-child) { position: relative; padding: 3px; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.try-tray li:not(:only-child) > .pet-gear-icon, .try-tray li:not(:only-child) > .try-scene { width: 2rem; height: 2rem; }
.try-tray li:not(:only-child) > .caption:not(.shop-short) { display: none; }
/* Its × is a badge on the corner, and the whole chip is its target. */
.try-tray li:not(:only-child) .try-off { position: absolute; top: -2px; right: -2px; width: 1rem; min-height: 1rem; border: 1px solid var(--line); background: var(--surface); box-shadow: var(--shadow); }
.try-tray li:not(:only-child) .try-off::after { content: ""; position: absolute; top: -2px; right: -2px; width: 2.5rem; height: 2.5rem; }
.try-tray li:not(:only-child) .try-off .ui-icon { width: .625rem; height: .625rem; stroke-width: 3; }
.try-tray ul { padding: 2px; }
/* Phones: above the app's tab bar. */
@media (max-width: 767px) and (not ((orientation: landscape) and (max-height: 520px))) { .try-tray { --tray-gap: 5.5rem; } }
@media (max-width: 479px) {
  .try-tray { column-gap: var(--s1); }
  .try-tray .try-all { padding: 0 var(--s2); }
  .try-tray .try-all-n { display: none; }
}
.try-tray li:not(:only-child) .try-name { position: absolute; width: 1px; height: 1px; clip-path: inset(50%); }
.try-tray:has(.try-all) li > button.primary[aria-label^="Buy"] { display: none; }
.try-tray li:not(:only-child) > button.primary { min-height: 1.75rem; padding: 0 var(--s2); font-size: var(--text-xs); }
.try-tray .try-all { grid-area: buy; }
.try-tray > .shop-balance { grid-area: note; justify-content: center; font-size: var(--text-xs); }
.try-tray .shop-balance-lead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.try-tray > .caption { grid-area: note; margin: 0; font-size: var(--text-xs); text-align: center; }
.try-tray > .try-note-owner { display: none; }
.try-tray > .shop-balance + .caption { grid-row: 3; }
/* The Pets stage is your player card: pet, look and backdrop live on it; name, XP and stats sit below. */
.player-card-panel { position: relative; container-type: inline-size; display: grid; gap: var(--s3); }
.pet-card-stage { display: grid; justify-items: center; gap: var(--s2); }
.fitting-room { display: none; }
/* Sits in the panel corner, beside the card; narrow panels drop the card below it so it never covers the crest. */
.pet-card-share-wrap { position: absolute; top: var(--s3); right: var(--s3); z-index: 14; }
.pet-share-scrim { position: fixed; inset: 0; z-index: -1; }
.pet-share-menu { max-width: none; white-space: nowrap; }
.pet-share-menu .ui-icon { width: 1.05rem; height: 1.05rem; flex: none; }
.pet-share-menu button:disabled { opacity: .5; cursor: progress; }
.pet-card-share { position: relative; display: grid; place-items: center; width: 2.5rem; height: 2.5rem; min-height: 0; padding: 0; border-radius: 50%; }
.pet-card-share .ui-icon { width: 1.15rem; height: 1.15rem; }
@container (max-width: 24rem) { .player-card-panel:has(.pet-card-share) .pet-card-stage { padding-top: 2.5rem; } }
.pet-card-preview-note { margin: 0; text-align: center; }
.tc-recent-games { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.tc-recent-games:empty::after { content: "No recent games"; }
.tc-recent-games img { width: 18px; height: 18px; border-radius: 4px; box-shadow: 0 1px 2px #0004; }
.trophy-sheet { display: grid; gap: var(--s4); max-width: min(92vw, 24rem); }
.trophy-sheet-head { display: flex; align-items: center; gap: var(--s3); }
.trophy-sheet-head h2 { margin: 0; }
.trophy-sheet-head .eyebrow { margin: 0; }

/* Which Arena's rank the card shows. */

@keyframes stat-pop-in { from { opacity: 0; translate: 0 -4px; } }
@media (prefers-reduced-motion: reduce) { .pet-stat-pop, .pet-stat-effect { animation: none !important; } }

/* Star polish: three stars, lit per tier, and the button for the next one. */
.pet-polish { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s2); }
.pet-polish-stars { letter-spacing: .05em; color: var(--line, #ccc); font-size: var(--text-md, 1rem); line-height: 1; }
.pet-polish-stars .on { color: #e8b021; text-shadow: 0 0 4px rgba(255, 215, 106, .8); }
.pet-polish-buy { display: inline-flex; justify-content: center; align-items: center; gap: 4px; flex: 1 1 auto; min-width: 0;
  padding: 4px var(--s2); font-size: var(--text-sm); white-space: nowrap; }
.pet-polish-buy.short { opacity: .7; }
.pet-polish-try { flex: none; min-height: 0; padding: 4px 6px; border-radius: 999px; background: none; border: 1px dashed var(--line, #ccc); box-shadow: none; }
.pet-polish-try[aria-pressed="true"] { border: 1px solid #e8b021; background: rgba(255, 215, 106, .18); }
.pet-polish-stars .trying { animation: polish-try 1.2s ease-in-out infinite alternate; }
@keyframes polish-try { from { opacity: .55; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pet-polish-stars .trying { animation: none; } }
.pet-polish-help { margin: 0; }
@media (max-width: 719px) {
  .shopping .shop-dock.player-card-panel .pet-card-stage { padding-top: 0; }
  .shopping .shop-dock .pet-polish { flex-wrap: nowrap; }
  .shopping .shop-dock .pet-polish-stars { flex: none; font-size: var(--text-xs); }
  .shopping .shop-dock .pet-polish-buy { max-width: 100%; padding-inline: var(--s1); font-size: var(--text-xs); }
  .shopping .shop-dock .pet-polish { gap: var(--s1); }
  .shopping .shop-dock .pet-polish-try { padding: 1px 2px; letter-spacing: 0; }
  /* The phone dock has no room for the explainer; it shows once the stars are tapped. */
  .shopping .shop-dock .pet-polish-help { display: none; font-size: var(--text-xs); line-height: 1.25; }
  .shopping .shop-dock .pet-polish:has(.pet-polish-try[aria-pressed="true"]) + .pet-polish-help { display: block; }
  .shopping.dock-stuck .shop-dock .pet-polish, .shopping.dock-stuck .shop-dock .pet-polish-help { display: none; }
  /* A slot too short for both shows just its name. */
  @container (max-height: 2.75rem) { .shop-dock .outfit-slot.empty .ui-icon { display: none; } }
}
