:root {
  --page-bg: #d9d9d9;
  --banner-bg: #2a2a2e;
  --ink: #2a2a2e;
  --ink-soft: #5d5d66;
  --panel: #f3f3f4;
  --panel-line: #c2c2c7;
  --accent: #4b4b55;

  /* Card is built on the native 128 x 168 grid of the frame image. */
  --card-w: 128px;

  /* Shine timing: colour flow and how often the white flash passes. */
  --holo-cycle: 5s;
  --flash-cycle: 4.6s;

  --font-ui: "Noto Sans JP", "Yu Gothic UI", "Meiryo", system-ui, sans-serif;
  --font-lv: "Noto Sans JP", "Yu Gothic", "Meiryo", sans-serif;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html, body { margin: 0; }

body {
  background: var(--page-bg);
  color: var(--ink);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
}

/* ---------- Banner ----------
   Character on the left fading into the centre, logo in the middle and a
   close-up of the album in 3D on the right. Below the picture area the
   banner continues as a dark band (where the game picker sits) and ends in a
   grunge tear: assets/banner/tear-mask.png is opaque on top and torn at the
   bottom, so the tear also cuts through Ichigo's art. */

.banner {
  --banner-h: clamp(150px, 17vw, 260px);
  --band: 158px;   /* game picker area + the 110 px tear strip */
  position: relative;
  height: calc(var(--banner-h) + var(--band));
  overflow: hidden;
  background: var(--banner-bg);
  -webkit-mask: url("assets/banner/tear-mask.png") left bottom / 1600px auto repeat-x;
          mask: url("assets/banner/tear-mask.png") left bottom / 1600px auto repeat-x;
}

/* Owner area: no game picker, the tear starts right under the picture. */
.banner--plain { --band: 110px; }

/* Art, album and logo are placed on the whole banner, edge to edge. */
.banner__inner { height: 100%; }

/* The two sides mirror each other: a light fade at the outer edge of the
   site, full strength in the middle of each side and a long, gradual fade
   (eased, so it has no visible start) into the centre behind the logo.
   Measured from the outer edge of each side. */
.banner {
  --side-fade:
    rgba(0, 0, 0, .55) 0,
    rgba(0, 0, 0, .85) 4%,
    #000 10%,
    #000 15%,
    rgba(0, 0, 0, .84) 23%,
    rgba(0, 0, 0, .6) 32%,
    rgba(0, 0, 0, .38) 41%,
    rgba(0, 0, 0, .2) 50%,
    rgba(0, 0, 0, .08) 59%,
    rgba(0, 0, 0, .02) 67%,
    transparent 74%;
  /* Both sides go on down to the tear with a light fade above it. */
  --rise-fade: #000 calc(var(--banner-h) - 30px), rgba(0, 0, 0, .45) calc(100% - 50px);
}

/* Ichigo from the waist up in the picture area; the rest of the art goes on
   down behind the game picker until the tear, fading a little on the way.
   The image keeps its scale (tied to the banner height) and starts at the
   site's left edge. */
.banner__art {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: min(50%, calc(var(--banner-h) * 1688 / 576));
  background: url("assets/banner/ichigo.jpg") left top / calc(var(--banner-h) * 1688 / 576) auto no-repeat;
  -webkit-mask-image:
    linear-gradient(to right, var(--side-fade)),
    linear-gradient(to bottom, var(--rise-fade));
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to right, var(--side-fade)),
    linear-gradient(to bottom, var(--rise-fade));
          mask-composite: intersect;
}

/* Same width and the same fades, mirrored, on the album side: it also runs
   down to the tear. The 3D view stays centred on the picture area. */
.banner__album {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: min(50%, calc(var(--banner-h) * 1688 / 576));
  overflow: hidden;
  perspective: calc(var(--banner-h) * 2.4);
  perspective-origin: 50% calc(var(--banner-h) / 2);
  -webkit-mask-image:
    linear-gradient(to left, var(--side-fade)),
    linear-gradient(to bottom, var(--rise-fade));
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to left, var(--side-fade)),
    linear-gradient(to bottom, var(--rise-fade));
          mask-composite: intersect;
}

/* The album is one pre-rendered picture (assets/banner/album-sheet.webp:
   characters 1–36 in 6 columns × 6 rows, Lv. 200, drawn at 2× size), so the
   header loads a single image instead of separate cards. Seen from the side
   and close up; it is taller than the banner so that even the far side
   (which perspective shrinks) covers it from the top down to the tear.
   Sizes are in card units: a card is 128 × 168 with a 3 gap, so the sheet
   is 783 × 1023. */
.banner__album-sheet {
  --card-w: calc(var(--banner-h) * .82);
  --u: calc(var(--card-w) / 128);
  position: absolute;
  right: calc(var(--banner-h) * -.22);
  top: calc(var(--banner-h) / 2);
  width: calc(783 * var(--u));
  aspect-ratio: 783 / 1023;
  background: url("assets/banner/album-sheet.webp") 0 0 / 100% 100% no-repeat;
  transform: translateY(-45%) rotateY(-46deg) rotateX(6deg) rotateZ(-2deg);
  transform-origin: right center;
}

/* Shine on the static picture, only over the portraits
   (assets/banner/album-windows.png leaves out frames, icons and levels).
   Same look and timing as the cards in the album. */
.banner__album-holo,
.banner__album-flash {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.banner__album-holo {
  mix-blend-mode: screen;
  opacity: .55;
  -webkit-mask:
    url("assets/banner/album-windows.png") 0 0 / 100% 100%,
    repeating-conic-gradient(#000 0 25%, rgba(0, 0, 0, .1) 0 50%) 0 0 / calc(16 * var(--u)) calc(16 * var(--u));
  -webkit-mask-composite: source-in;
          mask:
    url("assets/banner/album-windows.png") 0 0 / 100% 100%,
    repeating-conic-gradient(#000 0 25%, rgba(0, 0, 0, .1) 0 50%) 0 0 / calc(16 * var(--u)) calc(16 * var(--u));
          mask-composite: intersect;
}

.banner__album-holo::before {
  content: "";
  position: absolute;
  left: calc(-113.137 * var(--u));
  top: calc(-113.137 * var(--u));
  width: calc(100% + 113.137 * var(--u));
  height: calc(100% + 113.137 * var(--u));
  background: repeating-linear-gradient(
    135deg,
    rgba(255, 30, 60, 1) 0,
    rgba(255, 150, 20, .35) calc(20 * var(--u)),
    rgba(120, 255, 40, 1) calc(40 * var(--u)),
    rgba(20, 230, 200, .35) calc(60 * var(--u)),
    rgba(30, 120, 255, 1) calc(80 * var(--u)),
    rgba(170, 40, 255, .35) calc(100 * var(--u)),
    rgba(255, 30, 200, 1) calc(120 * var(--u)),
    rgba(255, 60, 60, .35) calc(140 * var(--u)),
    rgba(255, 30, 60, 1) calc(160 * var(--u))
  );
  animation: sheet-holo-flow var(--holo-cycle) linear infinite;
}

/* One flash tile per card (131 × 171 = card + gap): every card flashes at
   the same moment, like in the album. */
.banner__album-flash {
  background: linear-gradient(
    135deg,
    transparent 39%,
    rgba(255, 255, 255, .28) 45%,
    rgba(255, 255, 255, .72) 50%,
    rgba(255, 255, 255, .28) 55%,
    transparent 61%
  ) 0 0 / calc(131 * var(--u)) calc(171 * var(--u));
  opacity: 0;
  -webkit-mask: url("assets/banner/album-windows.png") 0 0 / 100% 100%;
          mask: url("assets/banner/album-windows.png") 0 0 / 100% 100%;
  animation: sheet-flash var(--flash-cycle) linear infinite;
}

@keyframes sheet-holo-flow {
  from { transform: translate(0, 0); }
  to   { transform: translate(calc(113.137 * var(--u)), calc(113.137 * var(--u))); }
}

@keyframes sheet-flash {
  0%, 55% {
    opacity: 0;
    background-position: calc(-65.5 * var(--u)) calc(-85.5 * var(--u));
  }
  57% { opacity: 1; }
  66% { opacity: 1; }
  67%, 100% {
    opacity: 0;
    background-position: calc(65.5 * var(--u)) calc(85.5 * var(--u));
  }
}

/* Soft vignette so the three parts read as one image. */
.banner::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 48% calc(var(--banner-h) * 1.15) at 50% calc(var(--banner-h) / 2), rgba(0, 0, 0, .5), transparent 76%),
    linear-gradient(to bottom, rgba(0, 0, 0, .25), transparent calc(var(--banner-h) / 4));
}

/* Site logo with the game's logo, smaller, under it. */
.banner__logo {
  position: absolute;
  left: 50%;
  top: calc(var(--banner-h) / 2);
  z-index: 2;
  display: grid;
  justify-items: center;
  gap: calc(var(--banner-h) * .07);
  text-decoration: none;
  transform: translate(-50%, -50%);
}

.banner__logo img {
  display: block;
  height: auto;
  filter: drop-shadow(0 3px 14px rgba(0, 0, 0, .75));
}

/* Light grey grunge texture (stains, scratches, specks) behind the logo,
   faint enough to blend into the dark grey; its edges fade out on their own. */
.banner__logo::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: -1;
  width: calc(var(--banner-h) * 4.6);
  aspect-ratio: 1800 / 600;
  background: url("assets/banner/logo-grunge.webp") center / 100% 100% no-repeat;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.banner__logo-site {
  width: calc(var(--banner-h) * 1.78);
  max-width: 46vw;
}

.banner__logo-game {
  width: calc(var(--banner-h) * .5);
  max-width: 17vw;
}

.banner__logo:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 6px;
  border-radius: 4px;
}

/* Pulled up over the banner's dark band, so the game picker sits on it,
   just under the picture. The bottom padding clears the tear. */
.page-fade {
  position: relative;   /* above the banner; no z-index, so the picker menu can open over the toolbar */
  margin-top: calc(7px - 158px);
  padding: 0 16px 86px;
}

/* Owner area: only the text under the tear. */
.page-fade--plain {
  margin-top: -26px;
  padding: 0 16px 18px;
}

/* ---------- About page ---------- */

.about {
  max-width: 820px;
  margin: 0 auto 8px;
  padding: 26px 30px 30px;
  font-size: 15px;
  line-height: 1.7;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 12px;
}

.about h1 {
  margin: 0 0 12px;
  font-size: 26px;
  line-height: 1.25;
}

.about h2 {
  margin: 26px 0 8px;
  font-size: 18px;
  line-height: 1.3;
}

.about p { margin: 0; }

.about a { color: inherit; font-weight: 700; }

.about .about__updated {
  margin-top: 26px;
  font-size: 13px;
  color: var(--ink-soft);
}

.about ul {
  display: grid;
  gap: 8px;
  margin: 0;
  padding-left: 1.2em;
}

.about strong { font-weight: 700; }

@media (max-width: 560px) {
  .about { padding: 20px 18px 22px; font-size: 14.5px; }
  .about h1 { font-size: 22px; }
}

/* ---------- Home page ----------
   Ichigo (assets/home/ichigo.webp, 1920 × 1080 with transparency) on the
   banner's dark grey, the logo, a short pitch and the way into the album on
   the left. Ends in the same grunge tear as the banner; below it, four
   things the album does. */

.hero {
  --hero-h: clamp(560px, 90svh, 920px);
  --art-w: calc(var(--hero-h) * 16 / 9);
  --text-w: 470px;
  --pad: clamp(20px, 7vw, 140px);
  position: relative;
  display: flex;
  align-items: center;
  height: var(--hero-h);
  padding: 56px var(--pad) 130px;
  overflow: hidden;
  color: #fff;
  background:
    radial-gradient(ellipse 34% 44% at 76% 60%, rgba(255, 115, 25, .17), transparent 72%),
    radial-gradient(ellipse 26% 38% at 58% 36%, rgba(80, 140, 255, .1), transparent 72%),
    var(--banner-bg);
  /* tear-mask.png is only 590px tall: the plain layer keeps everything
     above it opaque. */
  -webkit-mask:
    url("assets/banner/tear-mask.png") left bottom / 1600px auto repeat-x,
    linear-gradient(#000 0 0) left top / 100% calc(100% - 589px) no-repeat;
          mask:
    url("assets/banner/tear-mask.png") left bottom / 1600px auto repeat-x,
    linear-gradient(#000 0 0) left top / 100% calc(100% - 589px) no-repeat;
}

/* Fills the hero's height, against the right edge; when the screen is not
   wide enough it slides right (cutting the end of the blade) rather than
   reach the text. Ichigo's arm starts at 30% of the picture. */
.hero__art {
  position: absolute;
  bottom: 0;
  left: max(calc(100% - var(--art-w)), calc(var(--pad) + var(--text-w) + 24px - var(--art-w) * .3));
  width: var(--art-w);
  height: 100%;
  pointer-events: none;
}

.hero__art img {
  display: block;
  width: 100%;
  height: 100%;
  -webkit-user-select: none;
          user-select: none;
}

/* Soft vignette, as on the banner. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 70% at 20% 45%, rgba(0, 0, 0, .28), transparent 75%),
    linear-gradient(to bottom, rgba(0, 0, 0, .25), transparent 18%);
}

.hero__content {
  position: relative;
  z-index: 1;
  width: var(--text-w);
  max-width: 100%;
}

.hero__logo {
  position: relative;
  display: grid;
  justify-items: start;
  gap: 14px;
  margin: 0;
}

.hero__logo img {
  display: block;
  height: auto;
  filter: drop-shadow(0 3px 14px rgba(0, 0, 0, .75));
}

/* The banner's grunge texture behind the logo. */
.hero__logo::before {
  content: "";
  position: absolute;
  left: 46%;
  top: 50%;
  z-index: -1;
  width: 190%;
  aspect-ratio: 1800 / 600;
  background: url("assets/banner/logo-grunge.webp") center / 100% 100% no-repeat;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.hero__logo-site { width: min(100%, 430px); }
.hero__logo-game { width: 128px; }

.hero__title {
  margin: 30px 0 12px;
  font-size: clamp(26px, 2.6vw, 36px);
  font-weight: 900;
  line-height: 1.18;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .6);
  text-wrap: balance;
  word-break: auto-phrase;   /* Japanese: break between phrases, not inside words */
}

.hero__lead {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: rgba(255, 255, 255, .78);
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 30px;
}

/* Orange like the glow around Ichigo. */
.hero__cta,
.hero__more {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 24px;
  font: 700 16px/1 var(--font-ui);
  color: #fff;
  text-decoration: none;
  border-radius: 10px;
}

.hero__cta {
  background: linear-gradient(#ff8a2a, #e9540f);
  box-shadow: 0 6px 24px rgba(255, 110, 20, .35), inset 0 1px 0 rgba(255, 255, 255, .28);
  transition: filter .15s ease, transform .15s ease;
}

.hero__cta:hover { filter: brightness(1.08); transform: translateY(-1px); }

.hero__cta svg { transition: transform .15s ease; }
.hero__cta:hover svg { transform: translateX(3px); }

.hero__more {
  font-weight: 500;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .28);
}

.hero__more:hover { background: rgba(255, 255, 255, .14); }

.hero__cta:focus-visible,
.hero__more:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* Pulled up under the tear, like the album's toolbar under the banner. */
.page.home {
  max-width: 1240px;
  margin-top: -40px;
}

.home-features {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}

.feature {
  padding: 14px 14px 18px;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 12px;
}

.feature__visual {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 92px;
  margin-bottom: 14px;
  background: var(--banner-bg);
  border-radius: 8px;
}

.feature__lv { font-size: 21px; }

/* The album's tabs (.album-tab), drawn for a dark background: the open
   one is the light one. */
.feature__tab {
  display: grid;
  place-items: center;
  min-width: 38px;
  height: 38px;
  font: 700 15px/1 var(--font-ui);
  color: rgba(255, 255, 255, .7);
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: 8px;
}

.feature__tab.is-active {
  color: var(--ink);
  background: var(--panel);
  border-color: var(--panel);
}

.feature__tab--add {
  font-weight: 500;
  font-size: 20px;
  background: none;
  border-color: rgba(255, 255, 255, .45);
  border-style: dashed;
}

.feature__title {
  margin: 0 0 6px;
  font-size: 16.5px;
  line-height: 1.3;
}

.feature__text {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.home-cta {
  margin: 26px 0 12px;
  text-align: center;
}

.home-cta__button {
  min-height: 46px;
  padding: 0 26px;
  font-size: 15px;
  text-decoration: none;
}

@media (max-width: 1100px) {
  .home-features { grid-template-columns: repeat(2, 1fr); }

  /* Not enough room beside Ichigo: the text sits over the empty left part of
     the picture, with the background darkened behind it. */
  .hero { --text-w: 420px; }
  .hero__art { left: calc(100% - var(--art-w) * .92); }
  .hero::after {
    background:
      linear-gradient(to right, rgba(42, 42, 46, .92) 0, rgba(42, 42, 46, .7) calc(var(--pad) + var(--text-w)), transparent calc(var(--pad) + var(--text-w) + 160px)),
      linear-gradient(to bottom, rgba(0, 0, 0, .25), transparent 18%);
  }
}

/* Phone, and tablet held upright: logo and text on top, Ichigo below them
   down to the tear. */
@media (max-width: 700px), (max-width: 1100px) and (orientation: portrait) {
  .hero {
    --art-w: max(122vw, min(200vw, 760px));
    display: block;
    height: auto;
    padding: 58px 18px 0;
    text-align: center;
  }

  .hero::after {
    background: linear-gradient(to bottom, rgba(0, 0, 0, .25), transparent 120px);
  }

  .hero__content { width: auto; max-width: 560px; margin: 0 auto; }
  .hero__logo { justify-items: center; gap: 10px; }
  .hero__actions { justify-content: center; margin-top: 22px; }

  /* In the flow, below the buttons: Ichigo's head in the middle of the
     screen (at 57% of the picture), the blade running off the right edge. */
  .hero__art {
    position: relative;
    left: calc(50% - var(--art-w) * .56);
    width: var(--art-w);
    height: calc(var(--art-w) * 9 / 16);
    margin-top: -12px;
  }
}

@media (max-width: 700px) {
  /* The same flatter tear as the phone banner. */
  .hero {
    -webkit-mask-position: left 0 bottom 35px, left top;
            mask-position: left 0 bottom 35px, left top;
    -webkit-mask-size: 1600px 300px, 100% calc(100% - 299px - 35px);
            mask-size: 1600px 300px, 100% calc(100% - 299px - 35px);
  }

  .hero__logo-site { width: min(78vw, 340px); }
  .hero__logo-game { width: 104px; }
  .hero__title { margin-top: 22px; font-size: 25px; }
  .hero__lead { font-size: 15px; }
  .hero__actions { flex-direction: column; gap: 10px; }
  .hero__cta, .hero__more { justify-content: center; width: min(100%, 290px); height: 48px; padding: 0 20px; font-size: 15px; }

  .page.home { margin-top: -30px; }
  .home-features { grid-template-columns: 1fr; gap: 10px; }
  .feature { display: grid; grid-template-columns: 96px 1fr; column-gap: 14px; align-items: start; }
  .feature__visual { grid-row: span 2; height: 96px; margin: 0; flex-wrap: wrap; align-content: center; gap: 4px; padding: 4px; }
  .feature__lv { font-size: 15px; }
  .feature__tab { min-width: 26px; height: 26px; font-size: 12px; border-radius: 6px; }
  .feature__tab--add { font-size: 15px; }
  .feature__visual svg { width: 76px; height: auto; }
  .feature__title { align-self: end; margin-top: 4px; }
}

/* ---------- Footer ---------- */

.site-footer {
  max-width: 1680px;
  margin: 8px auto 0;
  padding: 18px 16px 26px;
  border-top: 1px solid var(--panel-line);
  font-size: 12px;
  line-height: 1.7;
  color: var(--ink-soft);
  text-align: center;
}

.site-footer p { margin: 0; }

.site-footer a { color: inherit; }
.site-footer a:hover { color: var(--ink); }

/* ---------- Top-left nav: language + About ----------
   Outside the banner, so the language list is not clipped by the banner's
   torn edge. */

.site-nav {
  position: absolute;
  left: 14px;
  top: 12px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 6px;
}

.lang { position: relative; }

.lang__button,
.site-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  font: 500 12.5px/1 var(--font-ui);
  color: #fff;
  text-decoration: none;
  background: rgba(0, 0, 0, .45);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 8px;
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px);
          backdrop-filter: blur(4px);
}

.lang__button:hover,
.site-nav__link:hover { background: rgba(0, 0, 0, .65); }

.lang__button:focus-visible,
.site-nav__link:focus-visible,
.lang__option:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.lang__chevron { opacity: .8; transition: transform .2s ease; }
.lang__button[aria-expanded="true"] .lang__chevron { transform: rotate(180deg); }

.lang__menu {
  position: absolute;
  left: 0;
  top: calc(100% + 6px);
  display: grid;
  min-width: 190px;
  padding: 5px;
  background: #fbfbfc;
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
}

.lang__option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  font: 500 13.5px/1.2 var(--font-ui);
  color: var(--ink);
  text-align: left;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.lang__option:hover { background: #ececef; }

.lang__option::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.lang__option[aria-checked="true"] { font-weight: 700; }
.lang__option[aria-checked="true"]::before { background: var(--ink); }

/* ---------- Google account (account.js) ----------
   "Sign in" next to About; once signed in, the player's photo opens a menu
   with the save status, sign out and delete. */

.account { position: relative; }

.account__g {
  flex: none;
  padding: 2px;
  background: #fff;
  border-radius: 50%;
  box-sizing: content-box;
}

.account__button {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  overflow: visible;
  font: 700 13px/1 var(--font-ui);
  color: #fff;
  background: var(--accent);
  border: 1px solid rgba(255, 255, 255, .45);
  border-radius: 50%;
  cursor: pointer;
}

.account__avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

/* Small dot on the photo while saving (amber) or when saving failed (red). */
.account__button::after {
  content: "";
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 10px;
  height: 10px;
  border: 2px solid var(--banner-bg);
  border-radius: 50%;
  opacity: 0;
}

.account__button[data-status="loading"]::after,
.account__button[data-status="pending"]::after,
.account__button[data-status="saving"]::after { background: #ffb020; opacity: 1; }
.account__button[data-status="error"]::after { background: #ff4b4b; opacity: 1; }

.account__button:focus-visible,
.account__item:focus-visible,
.account__retry:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.account__item:focus-visible,
.account__retry:focus-visible { outline-color: var(--accent); }

.account__menu {
  position: absolute;
  left: 0;
  top: calc(100% + 6px);
  display: grid;
  gap: 8px;
  width: 260px;
  padding: 12px;
  font: 400 13px/1.45 var(--font-ui);
  color: var(--ink);
  background: #fbfbfc;
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
}

.account__who {
  display: grid;
  margin: 0;
  overflow-wrap: anywhere;
}

.account__who span { color: var(--ink-soft); font-size: 12px; }

.account__status {
  margin: 0;
  padding: 7px 9px;
  font-size: 12.5px;
  color: var(--ink-soft);
  background: #ececef;
  border-radius: 6px;
}

.account__status:empty { display: none; }

.account__retry {
  justify-self: start;
  padding: 5px 10px;
  font: 700 12.5px/1 var(--font-ui);
  color: #fff;
  background: var(--accent);
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.account__actions {
  display: grid;
  margin: 0 -6px -6px;
  padding-top: 6px;
  border-top: 1px solid #e2e2e6;
}

.account__item {
  padding: 7px 6px;
  font: 500 13.5px/1.2 var(--font-ui);
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.account__item:hover { background: #ececef; }
.account__item--danger { color: #b3261e; }

/* Which album to keep (first sign-in on a device with other marks). */
.choice {
  width: min(420px, calc(100vw - 32px));
  padding: 22px 20px 20px;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .35);
}

.choice::backdrop { background: rgba(20, 20, 24, .6); }

.choice__title {
  margin: 0 0 8px;
  font-size: 19px;
  line-height: 1.3;
}

.choice__text {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
}

.choice__options { display: grid; gap: 8px; }

.choice__option {
  display: grid;
  gap: 3px;
  padding: 11px 14px;
  font: 500 14px/1.3 var(--font-ui);
  color: var(--ink);
  text-align: left;
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  cursor: pointer;
}

.choice__option:hover { border-color: #9a9aa3; background: #fafafb; }

.choice__option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.choice__stats { font-size: 12.5px; color: var(--ink-soft); }

/* Short notices (signed out, errors) at the bottom of the screen. */
.toast {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: 60;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 11px 16px;
  font: 500 14px/1.45 var(--font-ui);
  color: #fff;
  background: rgba(32, 32, 36, .95);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .3);
  transform: translateX(-50%);
}

/* ---------- Game picker ---------- */

.game-picker {
  position: relative;
  width: fit-content;
  max-width: 1680px;
  margin: 0 auto;
}

.game-picker__button {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 5px 14px 5px 5px;
  font: 700 15px/1 var(--font-ui);
  color: #fff;
  background: rgba(0, 0, 0, .45);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 12px;
  cursor: pointer;
}

.game-picker__button:hover { background: rgba(0, 0, 0, .6); }

.game-picker__button:focus-visible,
.game-option:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.game-picker__icon {
  width: 38px;
  height: 38px;
  border-radius: 9px;
  background: #3a3a40;
  object-fit: cover;
}

.game-picker__chevron { opacity: .8; transition: transform .2s ease; }
.game-picker__button[aria-expanded="true"] .game-picker__chevron { transform: rotate(180deg); }

.game-picker__menu {
  position: absolute;
  left: 50%;
  top: calc(100% + 8px);
  z-index: 40;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px;
  background: #fbfbfc;
  border: 1px solid var(--panel-line);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .25);
  transform: translateX(-50%);
}

.game-option {
  display: grid;
  justify-items: center;
  gap: 6px;
  width: 92px;
  padding: 8px 6px;
  font: 500 11.5px/1.25 var(--font-ui);
  color: var(--ink);
  text-align: center;
  background: #fff;
  border: 1px solid #dcdce0;
  border-radius: 10px;
  cursor: pointer;
}

.game-option:hover { border-color: #a9a9b2; }

.game-option[aria-checked="true"] {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.game-option img {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  background: #3a3a40;
  object-fit: cover;
}

/* ---------- Page / toolbar ---------- */

.page {
  max-width: 1680px;
  margin: 0 auto;
  padding: 0 16px 24px;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-bottom: 12px;
}

/* Stays at the top while the album scrolls. */
.album-toolbar {
  position: sticky;
  top: 0;
  z-index: 20;
  margin-inline: -16px;
  padding: 8px 16px;
  background: rgba(217, 217, 217, .94);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

.level-box {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
}

.level-box__label {
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
}

.level-box__number {
  width: 64px;
  padding: 5px 6px;
  font: 700 16px/1.2 var(--font-ui);
  color: var(--ink);
  text-align: center;
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 6px;
}

.level-box__number:focus-visible,
.level-box__range:focus-visible,
.button:focus-visible,
.attr-filter__btn:focus-visible,
.view-toggle__btn:focus-visible,
.search__input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.level-box__range {
  width: 150px;
  accent-color: var(--accent);
}

.attr-filter {
  display: flex;
  gap: 4px;
}

.attr-filter__btn {
  display: grid;
  justify-items: center;
  gap: 1px;
  min-width: 46px;
  padding: 4px 4px 3px;
  font: 500 10.5px/1.1 var(--font-ui);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  cursor: pointer;
}

.attr-filter__btn img {
  width: 26px;
  height: 29px;
}

.attr-filter__btn:hover { border-color: #9a9aa3; }

.attr-filter__btn[aria-pressed="true"] {
  color: var(--ink);
  background: #fff;
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

/* While some attribute is chosen, the others look switched off. */
.attr-filter.is-filtering .attr-filter__btn[aria-pressed="false"] img {
  opacity: .4;
  filter: grayscale(.7);
}

.search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 240px;
  min-width: 160px;
  color: var(--ink-soft);
}

.search svg {
  position: absolute;
  left: 10px;
  pointer-events: none;
}

.search__input {
  width: 100%;
  height: 38px;
  padding: 0 10px 0 32px;
  font: 400 14px var(--font-ui);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
}

.view-toggle {
  display: flex;
  padding: 3px;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 9px;
}

.view-toggle__btn {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  font: 500 13px/1 var(--font-ui);
  color: var(--ink-soft);
  white-space: nowrap;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.view-toggle__btn:hover { color: var(--ink); }

.view-toggle__btn[aria-pressed="true"] {
  color: #fff;
  background: var(--accent);
}

.owned-count {
  margin: 0 0 0 auto;
  font-size: 14px;
  color: var(--ink-soft);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.owned-count strong { color: var(--ink); }

.button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 38px;
  padding: 0 14px;
  font: 700 14px/1 var(--font-ui);
  color: #fff;
  background: var(--accent);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}

.button:hover { background: #3a3a43; }
.button:disabled { opacity: .6; cursor: progress; }

.button--ghost {
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--panel-line);
}

.button--ghost:hover { background: #e7e7ea; }

/* ---------- Board ----------
   rows: 12 cards per row, the page scrolls.
   overview: everything inside a 16:9 frame that fits the screen. */

.board-wrap { width: 100%; }

/* ---------- Album tabs ----------
   Square tabs above the board, one per album, and a + to add one. A name
   makes its tab wider. One line: with many albums it scrolls sideways. */

.album-tabs {
  position: relative;
  margin: 0 auto 8px;
}

.album-tabs__list {
  display: flex;
  gap: 6px;
  padding: 2px;   /* room for the focus outline */
  overflow-x: auto;
  scrollbar-width: thin;
}

.album-tab,
.album-tabs__add {
  flex: none;
  min-width: 38px;
  height: 38px;
  font: 700 15px/1 var(--font-ui);
  color: var(--ink-soft);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  cursor: pointer;
}

.album-tab {
  max-width: 180px;
  padding: 0 11px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.album-tab:hover,
.album-tabs__add:hover {
  color: var(--ink);
  border-color: #9a9aa3;
}

.album-tab[aria-pressed="true"] {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

.album-tabs__add {
  display: grid;
  place-items: center;
  width: 38px;
  padding: 0;
  border-style: dashed;
}

.album-tab:focus-visible,
.album-tabs__add:focus-visible,
.tab-menu__input:focus-visible,
.tab-menu__delete:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Rename / delete the open album; below the sticky toolbar when scrolling. */
.tab-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 15;
  display: grid;
  gap: 6px;
  width: 240px;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .18);
}

.tab-menu__label {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
}

.tab-menu__input {
  height: 36px;
  padding: 0 10px;
  font: 500 14px var(--font-ui);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 7px;
}

.tab-menu__delete {
  justify-self: start;
  margin-top: 2px;
  padding: 6px 0;
  font: 500 13px var(--font-ui);
  color: #b3261e;
  background: none;
  border: 0;
  cursor: pointer;
}

.tab-menu__delete:hover { text-decoration: underline; }

/* album.js places the grid inside the board (margins in whole screen pixels). */
.board {
  --board-pad: 12px;
  margin: 0 auto;
  padding: var(--board-pad);
  border: 1px solid var(--panel-line);
  border-radius: 10px;
}

.board .album { width: max-content; }

/* album.js sets card size and gap in whole screen pixels, so every column
   and row is the same distance apart. */
.album {
  display: grid;
  grid-template-columns: repeat(var(--cols, 12), var(--card-w));
  gap: var(--gap, calc(var(--card-w) * 3 / 128));
}

.album-empty {
  margin: 24px 0;
  font-size: 14px;
  color: var(--ink-soft);
  text-align: center;
}

/* ---------- Card ----------
   Layers, bottom to top:
   background > portrait > holo > flash > frame > attribute > level */

.card {
  --u: calc(var(--card-w) / 128);
  --rx: 0deg;
  --ry: 0deg;
  position: relative;
  display: block;
  width: var(--card-w);
  height: var(--card-h, calc(var(--card-w) * 168 / 128));
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  transition: transform .35s ease, filter .2s ease;
}

.card > * {
  position: absolute;
  pointer-events: none;
  user-select: none;
}

.card__bg,
.card__portrait,
.card__holo,
.card__shine {
  left: 0;
  top: 0;
  width: 100%;
  height: calc(128 * var(--u));
}

.card__frame {
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Centred on the hexagon printed in the frame. */
.card__attr {
  left: calc(3 * var(--u));
  top: calc(94 * var(--u));
  width: calc(34 * var(--u));
  height: calc(38 * var(--u));
}

/* Not owned: whole card at 60% brightness, like the in-game album. */
.card:not(.is-owned) { filter: brightness(.6); }

.card:not(.is-owned) .card__holo,
.card:not(.is-owned) .card__shine,
.card:not(.is-owned) .card__level { display: none; }

/* Off-screen cards skip the shine, so long albums stay light. */
.album .card:not(.in-view) .card__holo,
.album .card:not(.in-view) .card__shine { display: none; }

.card:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  z-index: 2;
}

.card.is-selected { z-index: 3; }

.card.is-selected::after {
  content: "";
  position: absolute;
  inset: -2px;
  border: 2px solid #fff;
  border-radius: 6px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .35);
  pointer-events: none;
}

/* ---------- Holo shine (between portrait and frame) ----------
   Like the in-game foil: a rainbow checkerboard whose colours keep flowing,
   plus a quick white flash. The screen blend tints the dark parts of the art
   and leaves the light parts as they are, so nothing gets washed out.
   Every card uses the same timing, so they all shine together. */

/* Octagon of the portrait window, so the shine never leaks past the art. */
.card__holo,
.card__shine {
  clip-path: polygon(11% 0, 89% 0, 100% 12.5%, 100% 84.5%, 84.5% 100%, 15.5% 100%, 0 84.5%, 0 12.5%);
  overflow: hidden;
}

.card__holo {
  mix-blend-mode: screen;
  opacity: .55;
  -webkit-mask: repeating-conic-gradient(#000 0 25%, rgba(0, 0, 0, .1) 0 50%) 0 0 / calc(16 * var(--u)) calc(16 * var(--u));
          mask: repeating-conic-gradient(#000 0 25%, rgba(0, 0, 0, .1) 0 50%) 0 0 / calc(16 * var(--u)) calc(16 * var(--u));
}

/* One spectrum every 160 units along the diagonal; the layer slides one full
   spectrum per cycle (113.137 = 160 / √2 on each axis), so the loop is seamless.
   Strong and faint colours alternate, so the foil is vivid in some areas and
   almost absent in others, like in the game. */
.card__holo::before {
  content: "";
  position: absolute;
  left: calc(-113.137 * var(--u));
  top: calc(-113.137 * var(--u));
  width: calc(241.137 * var(--u));
  height: calc(241.137 * var(--u));
  background: repeating-linear-gradient(
    135deg,
    rgba(255, 30, 60, 1) 0,
    rgba(255, 150, 20, .35) calc(20 * var(--u)),
    rgba(120, 255, 40, 1) calc(40 * var(--u)),
    rgba(20, 230, 200, .35) calc(60 * var(--u)),
    rgba(30, 120, 255, 1) calc(80 * var(--u)),
    rgba(170, 40, 255, .35) calc(100 * var(--u)),
    rgba(255, 30, 200, 1) calc(120 * var(--u)),
    rgba(255, 60, 60, .35) calc(140 * var(--u)),
    rgba(255, 30, 60, 1) calc(160 * var(--u))
  );
  animation: holo-flow var(--holo-cycle) linear infinite;
}

/* Quick white flash from the top-left to the bottom-right corner. */
.card__shine::before {
  content: "";
  position: absolute;
  left: -50%;
  top: -50%;
  width: 200%;
  height: 200%;
  background: linear-gradient(
    135deg,
    transparent 39%,
    rgba(255, 255, 255, .28) 45%,
    rgba(255, 255, 255, .72) 50%,
    rgba(255, 255, 255, .28) 55%,
    transparent 61%
  );
  transform: translate(-55%, -55%);
  animation: shine-flash var(--flash-cycle) linear infinite;
}

/* Soft light that follows the pointer while the card tilts. */
.card__shine::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at var(--mx, 50%) var(--my, 50%),
    rgba(255, 255, 255, .4) 0%,
    rgba(255, 255, 255, .12) 25%,
    transparent 55%
  );
  opacity: 0;
  transition: opacity .2s ease;
}

/* The 3D tilt only exists while the pointer is over the card; at rest cards
   have no transform, so they stay on whole pixels. */
.card.is-tilting {
  z-index: 1;
  transform: perspective(calc(var(--card-w) * 4)) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .1s linear, filter .2s ease;
}

.card.is-tilting .card__shine::after { opacity: 1; }

@keyframes holo-flow {
  from { transform: translate(0, 0); }
  to   { transform: translate(46.92%, 46.92%); }
}

@keyframes shine-flash {
  0%, 56%   { transform: translate(-55%, -55%); }
  67%, 100% { transform: translate(55%, 55%); }
}

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

.lv {
  position: relative;
  display: inline-block;
  font-family: var(--font-lv);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Outline layer sits behind the gradient fill. */
.lv::before {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  color: var(--lv-stroke);
  -webkit-text-stroke: .085em var(--lv-stroke);
}

.lv__fill {
  position: relative;
  display: inline-block;
  background: linear-gradient(var(--lv-top) 20%, var(--lv-bottom) 94%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}

:root,
[data-tier="green"]  { --lv-stroke: #067a0a; --lv-top: #25ff00; --lv-bottom: #c6ff00; }
[data-tier="orange"] { --lv-stroke: #a82203; --lv-top: #f71c00; --lv-bottom: #ffc500; }
[data-tier="purple"] { --lv-stroke: #7d0590; --lv-top: #e819b6; --lv-bottom: #f8a6e5; }

/* Baseline on y=125 of the frame, starting right after the hexagon. */
.card__level {
  position: absolute;
  left: calc(39.5 * var(--u));
  top: calc(101.6 * var(--u));
  font-size: calc(25 * var(--u));
}

/* ---------- Sleeve ----------
   Translucent protector over the whole card, in the colour of the player's
   Link Slot (same scheme as the level text). Turned on in the toolbar. */

.card__sleeve { display: none; }

.sleeves-on .album .card.is-owned .card__sleeve {
  display: block;
  inset: calc(-1 * var(--u));
  border: calc(1.6 * var(--u)) solid var(--sleeve-edge);
  border-radius: calc(7 * var(--u));
  background:
    linear-gradient(118deg,
      rgba(255, 255, 255, .42) 0%,
      rgba(255, 255, 255, .1) 16%,
      rgba(255, 255, 255, 0) 28%,
      rgba(255, 255, 255, 0) 68%,
      rgba(255, 255, 255, .16) 84%,
      rgba(255, 255, 255, .05) 100%),
    var(--sleeve-tint);
  box-shadow:
    inset 0 0 calc(7 * var(--u)) var(--sleeve-glow),
    0 0 calc(3 * var(--u)) var(--sleeve-glow);
}

:root,
[data-tier="green"]  { --sleeve-tint: rgba(80, 235, 40, .17);  --sleeve-edge: rgba(70, 215, 30, .9);  --sleeve-glow: rgba(110, 255, 60, .4); }
[data-tier="orange"] { --sleeve-tint: rgba(255, 140, 0, .17);  --sleeve-edge: rgba(255, 125, 0, .9);  --sleeve-glow: rgba(255, 160, 40, .4); }
[data-tier="purple"] { --sleeve-tint: rgba(225, 45, 205, .17); --sleeve-edge: rgba(200, 35, 200, .9); --sleeve-glow: rgba(240, 90, 230, .4); }

.sleeve-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 12px;
  font-size: 13.5px;
  font-weight: 700;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
}

.sleeve-toggle input {
  width: 17px;
  height: 17px;
  margin: 0;
  accent-color: var(--accent);
}

.sleeve-toggle input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- Popover ---------- */

.popover {
  position: fixed;
  z-index: 50;
  width: 300px;
  padding: 10px;
  background: #fbfbfc;
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .22), 0 2px 6px rgba(0, 0, 0, .12);
}

.popover__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding: 0 2px 6px 4px;
}

.popover__title {
  display: block;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
}

.popover__close {
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--ink-soft);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.popover__close:hover { background: #e9e9ec; color: var(--ink); }

.popover__options {
  display: grid;
  gap: 4px;
}

.opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 42px;
  padding: 6px 10px;
  font: 500 13px/1.25 var(--font-ui);
  color: var(--ink);
  text-align: left;
  background: #fff;
  border: 1px solid #dcdce0;
  border-radius: 8px;
  cursor: pointer;
}

.opt:hover { border-color: #a9a9b2; }

.opt:focus-visible,
.popover__close:focus-visible,
.opt-res input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.opt__dot {
  flex: none;
  width: 14px;
  height: 14px;
  border: 2px solid #9a9aa3;
  border-radius: 50%;
}

.opt[aria-pressed="true"] {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.opt[aria-pressed="true"] .opt__dot {
  border-color: var(--ink);
  background: radial-gradient(circle, var(--ink) 0 45%, transparent 50%);
}

.opt__text { flex: 1; }

.opt__text small {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
}

.opt__lv {
  flex: none;
  font-size: 17px;
  padding: 1px 6px 2px;
  background: #3d3c60;
  border-radius: 4px;
}

.opt-res {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 8px 10px;
  background: #fdf3f7;
  border: 1px solid #ecc3d4;
  border-radius: 8px;
  cursor: pointer;
}

.opt-res input {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #d0558a;
}

.opt-res__text {
  display: grid;
  font-size: 13px;
  line-height: 1.3;
}

.opt-res__text small {
  font-size: 11.5px;
  color: var(--ink-soft);
}

.opt-res.is-disabled {
  cursor: not-allowed;
  opacity: .6;
}

/* ---------- Small screens ---------- */

/* ---------- Phone header ----------
   Its own layout: Ichigo on the left, the site logo on the right, and the
   language / About buttons above the logo. No album and no game logo (the
   game is shown in the picker right below). */
@media (max-width: 700px) {
  .banner__album,
  .banner__logo .banner__logo-game { display: none; }

  /* On a narrow screen the tear's ups and downs look steep, so the mask is
     squashed to half its height (a flatter line) and raised 35px to keep the
     tear where it was. The mask still covers the whole banner (308px). */
  .banner {
    -webkit-mask-position: left 0 bottom 35px;
            mask-position: left 0 bottom 35px;
    -webkit-mask-size: 1600px 300px;
            mask-size: 1600px 300px;
  }

  /* Full width but never wider than the image (shifted left), so no edge can
     show; the fade ends before the logo. */
  .banner__art {
    width: min(100%, calc(var(--banner-h) * (1688 / 576 - .3)));
    background-position: calc(var(--banner-h) * -.3) top;
    -webkit-mask-image:
      linear-gradient(to right, #000 0, #000 30%, rgba(0, 0, 0, .55) 50%, rgba(0, 0, 0, .15) 64%, transparent 74%),
      linear-gradient(to bottom, var(--rise-fade));
            mask-image:
      linear-gradient(to right, #000 0, #000 30%, rgba(0, 0, 0, .55) 50%, rgba(0, 0, 0, .15) 64%, transparent 74%),
      linear-gradient(to bottom, var(--rise-fade));
  }

  .banner__logo {
    left: auto;
    right: 14px;
    top: calc(var(--banner-h) / 2 + 10px);
    transform: translateY(-50%);
  }

  .banner__logo-site {
    width: 46vw;
    max-width: 230px;
  }

  .banner__logo::before { width: 160%; }

  .site-nav { left: auto; right: 10px; top: 8px; }
  .lang__menu, .account__menu { left: auto; right: 0; }
  .lang__button, .site-nav__link { height: 28px; padding: 0 8px; font-size: 12px; }
}

@media (max-width: 560px) {
  /* On phones the toolbar is too tall to stay pinned. */
  .album-toolbar { position: static; }
  .level-box { width: 100%; flex-wrap: wrap; }
  .level-box__range { flex: 1; min-width: 120px; width: auto; }
  .search { flex: 1 1 100%; }
  .owned-count { margin-left: 0; }

  /* Room to scroll the last row above the bottom sheet. */
  .sheet-open .page { padding-bottom: 360px; }

  .popover {
    left: 8px !important;
    right: 8px;
    top: auto !important;
    bottom: 8px;
    width: auto;
  }
}

/* ---------- Phone overview ----------
   Overview on a phone shows only the album, full screen and sideways
   (album.js asks the browser to rotate; if it can't, the hint asks the
   player to turn the phone). */

.immersive-exit,
.rotate-hint { display: none; }

.overview-immersive .site-nav,
.overview-immersive .banner,
.overview-immersive .page-fade,
.overview-immersive .album-toolbar,
.overview-immersive .album-tabs,
.overview-immersive .site-footer { display: none; }

.overview-immersive .page { padding: 6px; }

.overview-immersive .immersive-exit {
  position: fixed;
  top: 8px;
  right: 8px;
  z-index: 45;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  color: #fff;
  background: rgba(0, 0, 0, .6);
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 50%;
  cursor: pointer;
}

@media (orientation: portrait) {
  .overview-immersive .rotate-hint {
    position: fixed;
    inset: 0;
    z-index: 44;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 24px;
    color: #fff;
    text-align: center;
    background: rgba(32, 32, 36, .95);
  }

  .rotate-hint p {
    max-width: 280px;
    margin: 0;
    font-size: 16px;
    line-height: 1.5;
  }

  .rotate-hint__icon { animation: rotate-hint 2.4s ease-in-out infinite; }
}

@keyframes rotate-hint {
  0%, 25% { transform: rotate(0deg); }
  55%, 100% { transform: rotate(-90deg); }
}

@media (prefers-reduced-motion: reduce) {
  .rotate-hint__icon { animation: none; }
  .card { transition: none; }
  .card__holo::before,
  .card__shine::before,
  .banner__album-holo::before,
  .banner__album-flash { animation: none; }
}
