/* Looks for the loop systems in js/loop.js: goals, free packs, the daily ladder, the punch card,
   medals, sets and the win screen. Colours and type come from css/style.css. */

/* ---------- shared: a quiet box with a gilt hairline ---------- */
.goal, .perks .daily, .lucky, .set-chip {
  border-radius: 12px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line);
}

/* ---------- goals ---------- */
/* #goals moves between the .goals-slot of the Packs screen and the Play screen. */
.goals-slot:empty { display: none; }
.goals { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 18px; max-width: 820px; }
.goal { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 7px 12px; padding: 10px 12px; }
.goal-text { grid-column: 1; grid-row: 1; font-weight: 600; line-height: 1.15; }
.goal-bar { grid-column: 1; grid-row: 2; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .13); overflow: hidden; }
.goal-bar i { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--gilt), var(--gilt-hi)); }
.goal-count { grid-column: 2; grid-row: 2; font-size: .85rem; color: var(--muted); text-align: right; line-height: 1; min-height: .85rem; }
.goal-pay { grid-column: 2; grid-row: 1; display: flex; align-items: center; justify-content: flex-end; gap: .35em; font-weight: 800; color: var(--gilt-hi); font-variant-numeric: tabular-nums; }
.goal-pay::before, .coin {
  content: ''; width: .8em; height: .8em; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 35% 30%, #fff6c9, var(--gilt) 55%, #8f6a1c); box-shadow: inset 0 0 0 1px rgba(122, 90, 28, .6);
}
.goal-claim { grid-column: 2; grid-row: 1 / 3; padding: .5em .9em; white-space: nowrap; }
.goal.is-done { background: rgba(217, 180, 90, .16); box-shadow: inset 0 0 0 1.5px var(--gilt); }
.goal.is-done .goal-count { display: none; }
.goal.is-done .goal-claim { animation: claim-pulse 1.3s ease-in-out infinite; }
.goal.is-new { animation: goal-in .5s cubic-bezier(.2, .9, .3, 1.2) both; }
@keyframes goal-in { from { opacity: 0; transform: translateY(-16px) scale(.95); } }
/* Endless animations move and fade only (transform, opacity), so they never repaint the page. */
@keyframes claim-pulse { 50% { transform: scale(1.06); } }
/* on a phone each goal is one line with its bar along the bottom edge */
@media (max-width: 720px) {
  .goals { grid-template-columns: 1fr; gap: 6px; margin-top: 14px; }
  .goal { position: relative; overflow: hidden; grid-template-columns: minmax(0, 1fr) auto auto; gap: 0 12px; padding: 9px 12px 12px; }
  .goal-count, .goal-pay { grid-row: 1; }
  .goal-count { grid-column: 2; }
  .goal-pay { grid-column: 3; }
  .goal-bar { grid-area: auto; position: absolute; left: 0; right: 0; bottom: 0; height: 4px; border-radius: 0; }
  .goal-bar i { border-radius: 0; }
  .goal-claim { grid-column: 2 / 4; grid-row: 1; padding: .32em .8em; }
  .goal.is-done { padding: 6px 8px 10px 12px; }
}

/* coins that fly from a claimed goal to the wallet */
.coin { position: fixed; z-index: 95; width: 16px; height: 16px; pointer-events: none; box-shadow: 0 0 8px rgba(245, 223, 157, .7); }
#money { display: inline-block; }
#money.bump { animation: bump .4s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes bump { 40% { transform: scale(1.25); color: #fff; } }

/* ---------- free packs waiting to be opened ---------- */
.freebar {
  display: flex; align-items: center; gap: 14px; margin-top: 16px; max-width: 820px; padding: 10px 14px; border-radius: 8px;
  background: linear-gradient(90deg, rgba(217, 180, 90, .26), rgba(217, 180, 90, .08)); box-shadow: inset 0 0 0 1.5px var(--gilt);
}
.freebar-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; line-height: 1.2; }
.freebar-text strong { font-size: 1.15rem; color: var(--gilt-hi); }
.freebar-text span { color: var(--muted); font-size: .92rem; }
.freebar .btn { animation: claim-pulse 1.3s ease-in-out infinite; }
.pack.pack-mini { --pw: 38px; pointer-events: none; }
@media (max-width: 560px) { .freebar { padding: 8px 12px; gap: 12px; } .freebar .pack-mini { --pw: 30px; } }

/* ---------- the daily ladder and the punch card ---------- */
.perks { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; max-width: 820px; }
.perks:not(:has(> :not([hidden]))) { display: none; }
.perks .daily, .lucky { flex: 1 1 300px; min-width: 0; margin: 0; padding: 9px 12px; display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; font-size: 1rem; }
.perks .daily.is-ready { background: rgba(217, 180, 90, .16); box-shadow: inset 0 0 0 1.5px var(--gilt); }
.perks .daily .btn { padding: .45em 1em; }
@media (max-width: 560px) { .perks { gap: 6px; } .streak-dots, .lucky-pips { gap: 5px; } }
.perk-main { flex: 1; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 5px 10px; }
.perk-title { font-weight: 600; line-height: 1.15; }
.perk-sub { grid-column: 1 / -1; color: var(--muted); font-size: .88rem; line-height: 1.15; }
.streak-dots, .lucky-pips { display: flex; align-items: center; gap: 6px; height: 16px; }
.streak-dot, .lucky-pip { flex: none; width: 12px; height: 12px; border-radius: 50%; background: rgba(255, 255, 255, .16); }
.streak-dot.on, .lucky-pip.on { background: var(--gilt); box-shadow: 0 0 6px rgba(217, 180, 90, .6); }
/* a star marks luck: days 3 and 5 of the ladder and the last pip of the punch card */
.streak-dot.lucky, .lucky-pip.last {
  width: 16px; height: 16px; border-radius: 0; background: rgba(245, 223, 157, .38); box-shadow: none;
  clip-path: polygon(50% 0%, 62% 34%, 98% 35%, 69% 57%, 79% 91%, 50% 71%, 21% 91%, 31% 57%, 2% 35%, 38% 34%);
}
.streak-dot.lucky.on, .lucky-pip.last.on { background: var(--gilt-hi); }
.streak-dot.big { width: 16px; height: 16px; box-shadow: inset 0 0 0 2px rgba(245, 223, 157, .55); }
.streak-dot.big.on { box-shadow: 0 0 8px rgba(245, 223, 157, .8); background: var(--gilt-hi); }
.streak-dot.now, .lucky.is-next .lucky-pip.last { animation: dot-pulse 1.1s ease-in-out infinite; background: var(--gilt-hi); }
.lucky.is-next { background: rgba(217, 180, 90, .16); box-shadow: inset 0 0 0 1.5px var(--gilt); }
.lucky.is-next .perk-title { color: var(--gilt-hi); }
@keyframes dot-pulse { 50% { transform: scale(1.35); } }

/* the gold tag on a pack you can buy when the next pack is lucky */
.lucky-tag {
  position: absolute; z-index: 8; top: 5%; right: -7%; padding: .22em .7em; border-radius: .3em; pointer-events: none;
  font-size: 1.3em; font-weight: 800; color: var(--ink); transform: rotate(7deg);
  background: linear-gradient(180deg, var(--gilt-hi), var(--gilt) 60%, #b98f38); box-shadow: 0 .2em .6em rgba(0, 0, 0, .55), 0 0 1em rgba(245, 223, 157, .5);
}
/* It bobs only while its pack is on screen (js/card.js sets .live). */
.pack.live > .lucky-tag {
  animation: tag-bob 1.6s ease-in-out infinite; }
@keyframes tag-bob { 50% { transform: rotate(7deg) translateY(-.25em); } }

/* the odds fold away under each pack */
.odds-more { color: var(--muted); font-size: .92rem; }
.odds-more summary { cursor: pointer; list-style: none; text-align: center; text-decoration: underline; text-underline-offset: 3px; }
.odds-more summary::-webkit-details-marker { display: none; }
.odds-more[open] summary { margin-bottom: 6px; }

/* a dot on the Packs tab when something free is waiting */
.nav button.has-gift { position: relative; }
.nav button.has-gift::after {
  content: ''; position: absolute; top: 3px; right: -10px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--gilt-hi); box-shadow: 0 0 6px var(--gilt);
}

/* ---------- medals on cards ---------- */
.card-medal {
  position: absolute; z-index: 2; left: 1.25em; top: 2.9em; width: 2.5em; height: 2.5em; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--m-hi), var(--m) 55%, var(--m-lo));
  box-shadow: 0 .15em .35em rgba(0, 0, 0, .55), inset 0 0 0 .12em rgba(255, 255, 255, .45), inset 0 0 0 .26em var(--m-lo);
}
.card-medal::after {
  content: ''; position: absolute; inset: 24%; background: var(--m-lo); opacity: .8;
  clip-path: polygon(50% 0%, 62% 34%, 98% 35%, 69% 57%, 79% 91%, 50% 71%, 21% 91%, 31% 57%, 2% 35%, 38% 34%);
}
.medal-bronze { --m: #b87333; --m-hi: #eab07a; --m-lo: #6f3d14; }
.medal-silver { --m: #c3cad3; --m-hi: #ffffff; --m-lo: #6f7986; }
.medal-gold { --m: #e8b93a; --m-hi: #fff4b8; --m-lo: #8f6510; }

/* ---------- sets, at the top of the collection ---------- */
.sets { margin-top: 20px; }
.sets-head { display: flex; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; }
.sets-head strong { font-size: 1.35rem; font-weight: 600; }
.sets-head span { color: var(--muted); }
.sets-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.sets-list:empty { display: none; }
.set-chip { position: relative; overflow: hidden; display: flex; align-items: baseline; gap: .5em; padding: 6px 11px 9px; border-radius: 6px; font-size: .95rem; line-height: 1.2; }
.set-name { font-weight: 600; }
.set-count { color: var(--muted); }
.set-boost { color: var(--gilt); font-size: .88rem; }
.set-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255, 255, 255, .12); }
.set-bar i { display: block; height: 100%; background: var(--gilt); }
.set-chip.is-done { color: var(--ink); background: linear-gradient(180deg, var(--gilt-hi), var(--gilt) 60%, #b98f38); box-shadow: 0 2px 8px rgba(0, 0, 0, .4); padding-bottom: 6px; }
.set-chip.is-done .set-count, .set-chip.is-done .set-boost { color: var(--ink); }
.set-chip.is-done .set-boost { font-weight: 800; }
.set-chip.is-done .set-bar { display: none; }
.sets-more { display: inline-block; margin-top: 12px; }

/* ---------- the win screen: a gift pack or a finished set ---------- */
/* It never covers a pack being opened or the puzzle: it waits underneath until that is over. */
#reveal:not([hidden]) ~ #win, #game:not([hidden]) ~ #win { display: none; }
.win { justify-content: center; padding: 20px; z-index: 60; background: rgba(12, 4, 5, .88); }
.win-card {
  width: min(420px, 100%); display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 28px 22px 24px; text-align: center; border-radius: 14px;
  background: radial-gradient(120% 90% at 50% 0%, #5c242e, var(--wall) 70%);
  box-shadow: 0 0 0 2px var(--gilt), 0 0 0 8px rgba(217, 180, 90, .16), 0 30px 80px rgba(0, 0, 0, .7);
  animation: win-in .5s cubic-bezier(.2, .9, .3, 1.25) both;
}
@keyframes win-in { from { opacity: 0; transform: translateY(24px) scale(.85); } }
.win-kicker { font-size: 1.15rem; color: var(--gilt-hi); }
.win-title { font-size: clamp(2rem, 9vw, 2.7rem); font-weight: 800; line-height: 1.05; }
.win-line { font-size: 1.15rem; }
.win-note { color: var(--muted); }
.pack.win-pack { --pw: 112px; margin: 8px 0 12px; }
.win-art { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.win-art img { width: 46px; height: 58px; object-fit: cover; object-position: 50% 28%; border: 2px solid var(--gilt); background: var(--ink); }
.win .btn-big { margin-top: 6px; }

@media (prefers-reduced-motion: reduce) {
  .goal.is-new, .goal.is-done .goal-claim, .freebar .btn, .streak-dot.now, .lucky.is-next .lucky-pip.last, .lucky-tag, .win-card, #money.bump { animation: none; }
}

/* ---------- the gift meter: paintings found, and the next free pack ---------- */
.giftbar { margin: 16px 0 6px; }
.giftbar-line { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.giftbar-line span { color: var(--muted); }
