/* ==========================================================================
   Silver Keep MC — finishing touches (loads after site.css)
   Kept separate so site.css stays the single source of the design system.
   Uses the existing tokens (--lantern, --tint, --spring-*) with fallbacks.
   Calm by design: no particles, tilt, magnetic buttons or colour cycling.
   ========================================================================== */

/* ---------- 1. Typography details ---------- */
h1, h2, h3, .h1, .h2, .h3, .hero-title { text-wrap: balance; }
p, li, .lede { text-wrap: pretty; }
::selection { background: color-mix(in srgb, var(--lantern, #e6c27a) 34%, transparent); color: inherit; }
html { scrollbar-color: rgb(var(--tint, 255 255 255) / .22) transparent; }

/* ---------- 2. Headline word cascade (polish.js wraps the words) ---------- */
.pl-w { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .js .pl-split .pl-w { opacity: 0; }
  .is-ready .pl-split .pl-w {
    animation: pl-word .9s cubic-bezier(.2, .75, .2, 1) both;
    animation-delay: calc(var(--pl-base, 200ms) + var(--pl-i, 0) * 70ms);
  }
  .glass-lite.is-ready .pl-split .pl-w { animation-name: pl-word-lite; }
}
@keyframes pl-word {
  from { opacity: 0; transform: translateY(.32em); }
  60%  { filter: blur(0); }
  to   { opacity: 1; transform: none; filter: none; }
}
@keyframes pl-word-lite {
  from { opacity: 0; transform: translateY(.28em); }
  to   { opacity: 1; transform: none; }
}

/* ---------- 3. Copy IP: soft ring ---------- */
.pl-ring-burst {
  position: fixed; z-index: 2147483000; pointer-events: none; border-radius: 999px;
  translate: -50% -50%;
  border: 1px solid color-mix(in srgb, var(--online, #4fd48a) 48%, transparent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--online, #4fd48a) 18%, transparent);
  animation: pl-ring 1.05s cubic-bezier(.22, 1, .36, 1) forwards;
}
@keyframes pl-ring {
  from { opacity: .58; scale: .86; }
  to   { opacity: 0;  scale: 1.8; }
}

/* ---------- 4. Toast lifetime hairline (matches the 3.2 s toast in app.js) ---------- */
.pl-toast-bar {
  position: absolute; left: 14px; right: 14px; bottom: 0; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--lantern, #e6c27a) 30%, var(--lantern, #e6c27a) 70%, transparent);
  opacity: .7; transform-origin: left center; transform: scaleX(0); pointer-events: none;
}
.pl-toast-bar.is-run { animation: pl-life 3.2s linear forwards; }
@keyframes pl-life { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) { .pl-toast-bar { display: none; } }

/* ---------- 5. Back-to-top progress ring ---------- */
.pl-progress { position: absolute; inset: 0; width: 100%; height: 100%; rotate: -90deg; pointer-events: none; overflow: visible; }
/* ".to-top svg" (the arrow, 18px) also matched the ring and shrank it into a dot in the corner */
.to-top .pl-progress { width: 100%; height: 100%; }
.to-top:has(.pl-progress) { border-radius: 50%; }
.pl-progress circle {
  fill: none; stroke: var(--lantern, #e6c27a); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--scroll, 0));
  opacity: .85; transition: stroke-dashoffset .12s linear;
}

/* ---------- 6. Quick search: results cascade in when it opens ---------- */
@media (prefers-reduced-motion: no-preference) {
  .qs.qs-intro .qs-i { animation: pl-rise .42s cubic-bezier(.2, .8, .2, 1) both; animation-delay: calc(60ms + min(var(--n, 0), 10) * 22ms); }
  .qs.qs-intro .qs-g { animation: pl-fade .4s ease both; animation-delay: 40ms; }
}
@keyframes pl-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes pl-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- 7. Help articles: steps arrive in order when opened ---------- */
@media (prefers-reduced-motion: no-preference) {
  .hc-a.is-open .hc-steps > li,
  .rx.is-open .ex li { animation: pl-rise .45s cubic-bezier(.2, .8, .2, 1) both; }
  .hc-a.is-open .hc-steps > li:nth-child(1), .rx.is-open .ex li:nth-child(1) { animation-delay: 90ms; }
  .hc-a.is-open .hc-steps > li:nth-child(2), .rx.is-open .ex li:nth-child(2) { animation-delay: 135ms; }
  .hc-a.is-open .hc-steps > li:nth-child(3), .rx.is-open .ex li:nth-child(3) { animation-delay: 180ms; }
  .hc-a.is-open .hc-steps > li:nth-child(4), .rx.is-open .ex li:nth-child(4) { animation-delay: 225ms; }
  .hc-a.is-open .hc-steps > li:nth-child(5) { animation-delay: 270ms; }
  .hc-a.is-open .hc-steps > li:nth-child(n+6) { animation-delay: 310ms; }
}

/* ---------- 9. Tactile press on big tap targets ----------
   Driven by polish.js with the Web Animations API on the separate `scale`
   property, so it never overrides the transitions and transforms in site.css. */

/* ---------- 10. Footer links: a gold hairline draws in on hover ---------- */
.site-footer .sf-col a {
  background-image: linear-gradient(var(--lantern, #e6c27a), var(--lantern, #e6c27a));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 1px;
  transition: background-size .45s cubic-bezier(.2, .8, .2, 1), color .2s ease;
}
.site-footer .sf-col a:hover, .site-footer .sf-col a:focus-visible { background-size: 100% 1px; }
.site-footer .sf-status a { background-image: none; }

/* ---------- 11. Search highlights: a soft gold marker ---------- */
.qs mark, .hc-results mark, .hc-a mark {
  background: linear-gradient(transparent 58%, color-mix(in srgb, var(--lantern, #e6c27a) 38%, transparent) 58%);
  color: inherit; border-radius: 2px; padding: 0 1px;
}

/* ---------- Rendering cost: skip layout/paint of off-screen blocks ---------- */
#community, .legal { content-visibility: auto; contain-intrinsic-size: auto 720px; }
.legal { contain-intrinsic-size: auto 80px; }

/* Help articles render via JS; keep what sits below them invisible until then so nothing visibly jumps. */
html.js:not(.hc-ready) [data-page="support"] #ticket, html.js:not(.hc-ready) [data-page="support"] .legal { visibility: hidden; }

/* Server cards render via JS; hide what sits below them until then so nothing visibly jumps. */
html.js:not(.sv-ready) [data-page="index"] .howto, html.js:not(.sv-ready) [data-page="index"] #community, html.js:not(.sv-ready) [data-page="index"] .legal { visibility: hidden; }

/* Rules summary cards: very subtle hover tint (the idle float lives in polish.js). */
@media (hover: hover) and (pointer: fine) {
  .rule-big { transition: transform .6s var(--ease-out), border-color var(--t) var(--ease), box-shadow .6s var(--ease-out), background-color .5s var(--ease); }
  .rule-big:hover { background: color-mix(in srgb, var(--l1, #111318) 88%, var(--l2, #181b22)); }
}

/* ---------- "Did this help?" vote buttons ---------- */
.hc-vote .mini { position: relative; overflow: visible; transition: color .3s var(--ease), border-color .3s var(--ease), background-color .3s var(--ease), transform .5s var(--ease-spring, var(--ease-out)), opacity .3s var(--ease); }
.hc-vote .mini svg { transition: transform .5s var(--ease-spring, var(--ease-out)); transform-origin: 50% 80%; }
@media (hover: hover) and (pointer: fine) {
  .hc-vote .mini:hover { transform: translateY(-1px); }
  .hc-vote .mini[data-v="yes"]:hover svg { transform: translateY(-1px) rotate(-14deg) scale(1.12); }
  .hc-vote .mini[data-v="no"]:hover svg { transform: translateY(1px) rotate(14deg) scale(1.12); }
}
.hc-vote .mini:active { transform: scale(.94); transition-duration: .12s; }
/* once a choice is made the other one steps back */
.hc-vote[data-voted] .mini[aria-pressed="false"] { opacity: .6; }
.hc-vote .mini.is-pop { animation: vote-pop .6s cubic-bezier(.34, 1.45, .64, 1); }
.hc-vote .mini.is-pop svg { animation: vote-icon .7s cubic-bezier(.34, 1.45, .64, 1); }
.hc-vote .mini.is-pop[data-v="no"] svg { animation-name: vote-icon-no; }
.hc-vote .mini.is-pop::after { content: ""; position: absolute; inset: -1px; border-radius: inherit; border: 2px solid currentColor; opacity: 0; pointer-events: none; animation: vote-ring .7s cubic-bezier(.16, 1, .3, 1); }
@keyframes vote-pop { 0% { transform: scale(.92); } 45% { transform: scale(1.1); } 100% { transform: scale(1); } }
@keyframes vote-icon { 0% { transform: rotate(0) scale(1); } 35% { transform: translateY(-4px) rotate(-22deg) scale(1.35); } 100% { transform: none; } }
@keyframes vote-icon-no { 0% { transform: rotate(0) scale(1); } 35% { transform: translateY(4px) rotate(22deg) scale(1.35); } 100% { transform: none; } }
@keyframes vote-ring { 0% { opacity: .55; transform: scale(1); } 100% { opacity: 0; transform: scale(1.35, 1.7); } }
.vote-spark { position: absolute; left: 50%; top: 50%; width: 5px; height: 5px; margin: -2.5px; border-radius: 50%; background: currentColor; pointer-events: none; animation: vote-spark .6s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes vote-spark { from { opacity: 1; transform: rotate(var(--a)) translateX(10px) scale(1); } to { opacity: 0; transform: rotate(var(--a)) translateX(28px) scale(.2); } }
@media (prefers-reduced-motion: reduce) { .hc-vote .mini, .hc-vote .mini svg { transition: color .2s, border-color .2s, background-color .2s; } .vote-spark { display: none; } }

/* The ticket strip is animated from script; the old CSS pop-in would run on top of it. */
.hc-nohelp { animation: none; }
