/* DEEPMINE UI v4 — boot animation (splash → game reveal), the new-player guide (spotlight tour + panel tips) and the
   progressive-unlock reveals (pop-in, ceremony dialog, "new" ribbon, tree previews). */
@layer shell {
  /* ───────────── Splash ───────────── */
  #loading { gap: 10px; }
  .splash-art { position: relative; width: 168px; height: 168px; display: grid; place-items: center; margin-bottom: 2px; }
  .splash-rays {
    position: absolute;
    inset: -40px;
    border-radius: 50%;
    background: repeating-conic-gradient(from 0deg, rgb(255 222 150 / .16) 0deg 7deg, transparent 7deg 22deg);
    -webkit-mask: radial-gradient(circle, #000 18%, transparent 68%);
    mask: radial-gradient(circle, #000 18%, transparent 68%);
    animation: splash-rays 14s linear infinite, splash-fade-in 1.2s var(--ease-out) both;
  }
  .splash-logo {
    position: relative;
    width: 128px;
    height: 128px;
    background: url(/art/ui-v4/logo.svg) center / contain no-repeat;
    filter: drop-shadow(0 12px 26px rgb(0 0 0 / .65)) drop-shadow(0 0 34px rgb(245 200 105 / .35));
    animation: splash-logo-in .95s var(--ease-spring) both, splash-float 3.4s var(--ease-in-out) 1s infinite;
  }
  .splash-logo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 35%, rgb(255 255 255 / .75) 50%, transparent 65%) -160% 0 / 250% 100% no-repeat;
    -webkit-mask: url(/art/ui-v4/logo.svg) center / contain no-repeat;
    mask: url(/art/ui-v4/logo.svg) center / contain no-repeat;
    animation: splash-shine 2.6s var(--ease-in-out) .9s infinite;
  }
  .splash-motes { position: absolute; inset: 0; pointer-events: none; }
  .splash-motes i {
    position: absolute;
    bottom: 22%;
    left: calc(18% + var(--x, 0%));
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--gold-200);
    box-shadow: 0 0 8px var(--gold-300);
    opacity: 0;
    animation: splash-mote 2.8s ease-out infinite;
    animation-delay: var(--d, 0s);
  }
  .splash-motes i:nth-child(1) { --x: 4%; --d: .2s; }
  .splash-motes i:nth-child(2) { --x: 18%; --d: 1.1s; }
  .splash-motes i:nth-child(3) { --x: 34%; --d: .6s; }
  .splash-motes i:nth-child(4) { --x: 48%; --d: 1.6s; }
  .splash-motes i:nth-child(5) { --x: 60%; --d: .9s; }
  .splash-motes i:nth-child(6) { --x: 26%; --d: 2s; }
  .splash-title { display: flex; gap: .06em; font: 800 34px/1 var(--font-display); letter-spacing: .1em; }
  .splash-title span {
    display: inline-block;
    background: linear-gradient(180deg, #fff3c9 10%, #f5c869 60%, #c98a2c 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: drop-shadow(0 2px 0 var(--gold-edge)) drop-shadow(0 6px 14px rgb(0 0 0 / .7));
    animation: splash-letter .55s var(--ease-spring) both;
    animation-delay: calc(.35s + var(--i) * 55ms);
  }
  .splash-sub { margin-top: -2px; font-size: var(--fs-13); font-weight: 700; letter-spacing: .3em; color: var(--text-2); animation: splash-fade-in .8s var(--ease-out) .9s both; }
  /* v10.2 A6: the splash texts carry their Chinese source in the markup; they stay hidden until i18n/splash-boot.js (or, if it
     never ran, mobile.mjs after its catalog loaded) has written the player's language and set <html data-splash-ready>. */
  html:not([data-splash-ready]) #loading :is(.splash-sub, .splash-status) { visibility: hidden; }
  .splash-progress {
    position: relative;
    width: min(220px, 60vw);
    height: 8px;
    margin-top: 14px;
    border-radius: 999px;
    background: rgb(0 0 0 / .45);
    box-shadow: inset 0 1px 3px rgb(0 0 0 / .7), 0 0 0 1px rgb(242 205 128 / .18);
    overflow: hidden;
    animation: splash-fade-in .6s var(--ease-out) .5s both;
  }
  .splash-progress > span {
    position: absolute;
    inset: 0 auto 0 0;
    width: var(--p, 20%);
    border-radius: inherit;
    background: linear-gradient(90deg, var(--gold-500), var(--gold-200));
    box-shadow: 0 0 12px rgb(245 200 105 / .7);
    transition: width .5s var(--ease-out);
  }
  .splash-progress > span::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgb(255 255 255 / .55), transparent) -100% 0 / 50% 100% no-repeat;
    animation: splash-bar 1.4s linear infinite;
  }
  .splash-status { font-size: var(--fs-12); color: var(--text-3); letter-spacing: .04em; min-height: 1.4em; }
  .splash-actions:empty { display: none; }
  .splash-actions .primary, .splash-actions .btn { min-width: 160px; }

  /* Exit: the emblem flies forward while the splash fades. */
  #loading[hidden] .splash-art { transform: scale(1.35); opacity: 0; transition: transform .55s var(--ease-in-out), opacity .45s var(--ease-out); }
  #loading[hidden] :is(.splash-title, .splash-sub, .splash-progress, .splash-status) { transform: translateY(-10px); opacity: 0; transition: transform .45s var(--ease-out), opacity .35s var(--ease-out); }
  #loading[hidden] :is(.splash-rays, .splash-logo, .splash-motes i), #loading[hidden] .splash-logo::after, #loading[hidden] .splash-progress > span::after { animation: none; }

  /* Game reveal: bands slide into place as the splash leaves. */
  :is(.game-header, .stage-header, .map-progress, .stage, .assist-strip, .quick-market, #game-nav) {
    transition: transform .7s var(--ease-out) var(--reveal-delay, 0s), opacity .5s var(--ease-out) var(--reveal-delay, 0s);
  }
  .game-header { --reveal-delay: .05s; }
  #game-nav { --reveal-delay: .1s; }
  .stage-header { --reveal-delay: .14s; }
  .stage, .map-progress { --reveal-delay: .2s; }
  .assist-strip { --reveal-delay: .28s; }
  .quick-market { --reveal-delay: .32s; }
  #game-frame:has(> #loading:not([hidden])) .game-header { transform: translateY(-110%); opacity: 0; }
  #game-frame:has(> #loading:not([hidden])) #game-nav { transform: translateY(110%); opacity: 0; }
  #game-frame:has(> #loading:not([hidden])) :is(.stage, .map-progress) { transform: scale(.94); opacity: 0; }
  #game-frame:has(> #loading:not([hidden])) :is(.stage-header, .assist-strip, .quick-market) { transform: translateY(14px); opacity: 0; }

  @keyframes splash-logo-in { 0% { opacity: 0; transform: scale(.35) rotate(-14deg); } 70% { opacity: 1; transform: scale(1.08) rotate(3deg); } 100% { opacity: 1; transform: none; } }
  @keyframes splash-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -5px; } }
  @keyframes splash-shine { 0%, 55% { background-position: -160% 0; } 100% { background-position: 160% 0; } }
  @keyframes splash-rays { to { rotate: 360deg; } }
  @keyframes splash-fade-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes splash-letter { from { opacity: 0; transform: translateY(16px) scale(.8); } to { opacity: 1; transform: none; } }
  @keyframes splash-mote { 0% { opacity: 0; transform: translateY(0) scale(.6); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(-90px) scale(1.1); } }
  @keyframes splash-bar { to { background-position: 250% 0; } }

  /* ───────────── New-player guide ───────────── */
  #coach { position: absolute; z-index: 70; inset: 0; pointer-events: none; }
  #coach[hidden] { display: none; }
  .coach-ring {
    position: absolute;
    border-radius: 18px;
    box-shadow: 0 0 0 200vmax rgb(3 10 7 / .6), 0 0 0 2px var(--gold-200), 0 0 26px 4px rgb(245 200 105 / .45);
    transition: left .35s var(--ease-out), top .35s var(--ease-out), width .35s var(--ease-out), height .35s var(--ease-out), opacity .25s;
    pointer-events: none;
  }
  .coach-ring::after {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: 22px;
    border: 2px solid rgb(255 222 150 / .7);
    animation: coach-pulse 1.4s ease-out 6;
  }
  #coach.is-center::before { content: ''; position: absolute; inset: 0; background: rgb(3 10 7 / .7); pointer-events: auto; animation: splash-fade-in .3s var(--ease-out) both; }
  .coach-bubble {
    position: absolute;
    left: var(--gutter);
    right: var(--gutter);
    max-width: 420px;
    margin-inline: auto;
    padding: 14px 16px 12px;
    border-radius: 18px;
    background: radial-gradient(120% 90% at 0% 0%, rgb(245 200 105 / .12), transparent 60%), linear-gradient(180deg, #17402f, #0f2b20);
    border: 1px solid var(--line-gold-strong);
    box-shadow: var(--sh-3), inset 0 1px 0 rgb(255 255 255 / .1);
    color: var(--text-2);
    pointer-events: auto;
    animation: coach-in .35s var(--ease-spring) both;
  }
  #coach.is-center .coach-bubble { top: 50%; transform: translateY(-50%); text-align: center; }
  #coach.is-center .coach-actions { justify-content: center; }
  #coach:is(.is-tip, .is-loose) .coach-bubble { top: calc(var(--header-h) + var(--safe-top) + 86px); }
  /* Caret pointing at the spotlit target (x set by tutorial.mjs). */
  .coach-bubble[data-side]::before {
    content: '';
    position: absolute;
    left: clamp(22px, var(--caret-x, 50%), calc(100% - 22px));
    width: 14px;
    height: 14px;
    border: 1px solid var(--line-gold-strong);
    transform: translateX(-50%) rotate(45deg);
  }
  .coach-bubble[data-side="below"]::before { top: -8px; background: #17402f; border-right: 0; border-bottom: 0; }
  .coach-bubble[data-side="above"]::before { bottom: -8px; background: #0f2b20; border-left: 0; border-top: 0; }
  .coach-art { width: 104px; height: 104px; margin: -6px auto 2px; object-fit: contain; filter: drop-shadow(0 8px 12px rgb(0 0 0 / .55)); }
  .coach-count { display: block; margin-bottom: 2px; font: 700 11px/1.2 var(--font-display); letter-spacing: .14em; color: var(--gold-300); }
  .coach-bubble h3 { font-size: var(--fs-card-title); font-weight: 800; color: var(--gold-50); margin-bottom: 4px; }
  .coach-bubble p { font-size: var(--fs-13); line-height: 1.55; }
  .coach-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
  @keyframes coach-pulse { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.12); } }
  @keyframes coach-in { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }
  html:is(.reduce-motion, .low-quality) .splash-rays, html:is(.reduce-motion, .low-quality) .splash-motes { display: none; }

  /* ───────────── Progressive unlocks (docs/progressive-unlocks.md §6.4–§6.6) ─────────────
     The DOM shows an unlocked element at once; public/unlock-reveal.mjs adds .is-revealing for ~1 s to celebrate it
     (a nav button, a HUD chip, the quick strip). .is-hint is the objective card's "do it here" nudge on #assist-button. */
  @keyframes unlock-pop { 0% { transform: scale(.6); opacity: 0 } 60% { transform: scale(1.08); opacity: 1 } 100% { transform: scale(1) } }
  @keyframes unlock-glow { 0%, 100% { box-shadow: 0 0 0 0 rgb(242 205 128 / 0) } 40% { box-shadow: 0 0 0 6px rgb(242 205 128 / .35) } }
  @keyframes unlock-fade { from { opacity: 0 } to { opacity: 1 } }
  .is-revealing { animation: unlock-pop 600ms var(--ease-spring) both, unlock-glow 900ms ease-out 1; }
  .reduce-motion .is-revealing { animation: unlock-fade 300ms ease-out both; }
  .is-hint { animation: unlock-glow 600ms ease-out 2; }

  /* 徽章墙 ceremony: <dialog id="unlock-ceremony" class="welcome-dialog unlock-ceremony"> reuses the welcome-back
     material; its badge grid is three larger medals per row with a one-time staggered pop when the dialog opens
     (the dialog is filled once per opening, never re-rendered, so the entrance never replays). */
  .unlock-ceremony .welcome-header::before {
    background:
      radial-gradient(70% 90% at 50% 30%, rgb(245 200 105 / .28), transparent 70%),
      linear-gradient(180deg, rgb(13 36 27 / .3) 0%, rgb(15 44 33 / .82) 62%, #12382a 100%),
      var(--welcome-art, url(/art/premium/forest.jpg)) center 40% / cover no-repeat;
  }
  .unlock-ceremony .welcome-emblem:empty { display: none; }
  .unlock-ceremony .ceremony-badges { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 10px; }
  .unlock-ceremony .ceremony-badges:empty { display: none; }
  .unlock-ceremony :is(.ceremony-badge, .ceremony-badges > li) { display: grid; justify-items: center; gap: 5px; min-width: 0; }
  .unlock-ceremony .ceremony-badges .item-tile {
    width: 100%;
    max-width: 76px;
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--gold-300), 0 0 18px -4px rgb(245 200 105 / .65), inset 0 2px 0 rgb(255 255 255 / .14);
  }
  .unlock-ceremony .ceremony-badges .item-tile::after { content: none; }
  .unlock-ceremony .ceremony-badges .item-tile img { width: 86%; height: 86%; object-fit: contain; }
  .unlock-ceremony .ceremony-badges small {
    max-width: 100%;
    font-size: var(--fs-12);
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-1);
    text-align: center;
    white-space: normal;
    overflow-wrap: break-word;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .unlock-ceremony[open] .ceremony-badges > li { animation: unlock-pop 520ms var(--ease-spring) both; animation-delay: calc(180ms + var(--i, 0) * 70ms); }
  .unlock-ceremony[open] .ceremony-badges > li:nth-child(2) { --i: 1; }
  .unlock-ceremony[open] .ceremony-badges > li:nth-child(3) { --i: 2; }
  .unlock-ceremony[open] .ceremony-badges > li:nth-child(4) { --i: 3; }
  .unlock-ceremony[open] .ceremony-badges > li:nth-child(5) { --i: 4; }
  .unlock-ceremony[open] .ceremony-badges > li:nth-child(n+6) { --i: 5; }
  html:is(.reduce-motion, .low-quality) .unlock-ceremony[open] .ceremony-badges > li { animation: none; }
  @media (max-width: 359px) { .unlock-ceremony .ceremony-badges { gap: 10px 6px; } }
}

/* Page-scoped unlock states. They sit in the pages layer so the page sheets (shop.css, talents.css) cannot flatten
   them; selectors stay as narrow as the page's own. */
@layer pages {
  /* Shop: a unit card whose unlock is unseen (.is-new) wears a "新" ribbon (.shop-new-ribbon, management-panels.mjs)
     and a soft gold rim until the shop has been opened once. */
  #sheet[data-mode="shop"] .shop-card.is-new { outline: 1.5px solid rgb(245 200 105 / .55); outline-offset: -1px; }
  #sheet[data-mode="shop"] .shop-new-ribbon {
    position: absolute;
    z-index: 2;
    top: -7px;
    left: 12px;
    padding: 2px 9px 1px;
    border-radius: var(--r-pill);
    background: linear-gradient(180deg, #ff8f70, #e2452c);
    box-shadow: 0 0 0 1.5px #0f2a1f, 0 3px 8px -2px rgb(0 0 0 / .6);
    font: 800 11px/1.35 var(--font-display);
    letter-spacing: .04em;
    color: #fff8f0;
    text-shadow: 0 1px 0 rgb(0 0 0 / .3);
    white-space: nowrap;
    pointer-events: none;
  }

  /* Talent tree: a preview node (named one step ahead, not yet open) is drawn as a locked node, quieter still —
     dimmed medallion, dashed name plate, greyed cost. Transform/opacity only: the tree redraws every poll. */
  .skill-node.is-preview > .tn-med { opacity: .58; }
  .skill-node.is-preview::before { border-style: dashed; border-color: var(--line-2); }
  .skill-node.is-preview > :is(strong, small) { color: var(--text-3); }
  .skill-node.is-preview > em.tn-cost { color: var(--text-3); background: transparent; border-color: var(--line-1); }
}
