/* ============================================================
   PanicHost UI layer: motion, responsiveness and small fixes
   that apply to every shell (marketing, auth, portal).

   Loaded last, after the theme and the portal stylesheets, so
   anything here wins on equal specificity. Every animation is
   switched off under prefers-reduced-motion.
   ============================================================ */

/* ---------- preloader: never block the page ----------
   The theme hides its overlay on window.load, which waits for every image,
   font and third party script. On a slow connection that is seconds of a
   blank dark screen before the first word of copy. ui.js hides it as soon as
   the DOM is ready, and this animation is the belt to that brace: with no
   JS at all the overlay still fades out on its own. */
.preloader {
  transition: opacity .35s ease, visibility .35s ease;
  animation: ph-preload-out .4s ease 1.4s forwards;
}
.preloader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
@keyframes ph-preload-out { to { opacity: 0; visibility: hidden; pointer-events: none; } }

/* ---------- global motion defaults ---------- */
.btn,
.plan-cards .plan,
.gs-tier,
.gs-game,
.portal-card,
.kpi,
.ph-nav-item,
.ph-icon-btn {
  transition: transform .18s cubic-bezier(.2, .8, .3, 1), box-shadow .18s ease,
              border-color .18s ease, background-color .18s ease, color .18s ease, opacity .18s ease;
}
.btn:active:not(:disabled) { transform: translateY(1px) scale(.985); }

/* keyboard users get a visible ring, mouse users do not */
:focus-visible { outline: 2px solid #0060fe; outline-offset: 2px; border-radius: 6px; }
:focus:not(:focus-visible) { outline: none; }

/* ---------- reveal on scroll ----------
   ui.js tags sections and cards with .ph-reveal and flips .in as they enter
   the viewport. Scoped to html.ph-js so a page without JS never hides. */
html.ph-js .ph-reveal {
  opacity: 0; transform: translateY(16px);
  transition: opacity .55s cubic-bezier(.2, .8, .3, 1), transform .55s cubic-bezier(.2, .8, .3, 1);
  will-change: opacity, transform;
}
html.ph-js .ph-reveal.in { opacity: 1; transform: none; }
/* siblings stagger so a row of cards ripples in instead of popping */
html.ph-js .ph-reveal:nth-child(2) { transition-delay: .06s; }
html.ph-js .ph-reveal:nth-child(3) { transition-delay: .12s; }
html.ph-js .ph-reveal:nth-child(4) { transition-delay: .18s; }
html.ph-js .ph-reveal:nth-child(5) { transition-delay: .24s; }
html.ph-js .ph-reveal:nth-child(n+6) { transition-delay: .3s; }

/* ---------- busy submit buttons ----------
   A form that has been submitted shows it, and cannot be submitted twice. */
.btn.is-busy, button.is-busy {
  position: relative; pointer-events: none; opacity: .75; color: transparent !important;
}
.btn.is-busy::after, button.is-busy::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px;
  margin: -8px 0 0 -8px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .45); border-top-color: #fff;
  animation: ph-spin .7s linear infinite;
}
.btn-outline-dark.is-busy::after { border-color: rgba(128, 128, 128, .35); border-top-color: #0060fe; }
@keyframes ph-spin { to { transform: rotate(360deg); } }

/* ---------- flash messages ---------- */
.status.mb-2, .form-error.mb-2, .form-notice { animation: ph-drop .35s cubic-bezier(.2, .8, .3, 1); }
@keyframes ph-drop { from { opacity: 0; transform: translateY(-6px); } }

/* ============================================================
   Portal shell, small screens
   The top bar used to squeeze the title into a one-word-per-line
   column beside four buttons, and the "Create account" button
   ran off the right edge of the screen.
   ============================================================ */
@media (max-width: 760px) {
  .ph-top { gap: .5rem; padding: 10px 14px; }
  .ph-top-title h1 { font-size: 1.02rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ph-top-title p { display: none; }
  .ph-top-actions { gap: .4rem; flex: 0 0 auto; }
  .ph-icon-btn { width: 36px; height: 36px; }
  .ph-guest-btn { padding: .45rem .7rem !important; font-size: .74rem !important; white-space: nowrap; }
}
@media (max-width: 480px) {
  .ph-top-actions .ph-guest-btn.btn-outline-dark { display: none; }
  .ph-content { padding: 14px; }
  .portal-card { padding: 1.1rem 1rem; }
}

/* ============================================================
   Order wizard
   ============================================================ */

/* each step slides in as it is revealed (display none -> block restarts it) */
.ord-step { animation: ph-step-in .38s cubic-bezier(.2, .8, .3, 1); }
@keyframes ph-step-in { from { opacity: 0; transform: translateY(12px); } }

/* step markers: number -> tick once that decision is made */
.ord-step-title i { transition: background-color .2s ease, transform .2s ease; }
.ord-step.done .ord-step-title i { background: #0a7d32; }
.ord-step.done .ord-step-title i::before { content: '\2713'; }
.ord-step.done .ord-step-title i span { display: none; }

/* every choice control responds the same way */
.ord-type, .ord-line, .ord-plan, .ord-loc, .ord-term, .ord-size, .ord-ed, .ord-dmode button, .ord-dpane .cart-drow {
  transition: transform .16s cubic-bezier(.2, .8, .3, 1), border-color .16s ease,
              box-shadow .16s ease, background-color .16s ease, color .16s ease;
}
.ord-type:active, .ord-plan:active, .ord-loc:active, .ord-term:active, .ord-size:active,
.ord-ed:active, .ord-dmode button:active { transform: scale(.985); }
.ord-plan:hover, .ord-term:hover, .ord-loc:hover { transform: translateY(-1px); }
.ord-plan.on, .ord-term.on, .ord-type.on, .ord-loc.on, .ord-size.on {
  animation: ph-pick .28s cubic-bezier(.2, .8, .3, 1);
}
@keyframes ph-pick { 40% { transform: scale(1.012); } }

/* the running total ticks rather than jumping */
.ord-total b { transition: color .2s ease; }
.ord-total b.bump { animation: ph-bump .3s ease; }
@keyframes ph-bump { 40% { transform: scale(1.06); color: #0060fe; } }

/* the summary itself: fade the body when it changes */
#ord-summary-body { animation: ph-fade .25s ease; }
@keyframes ph-fade { from { opacity: .4; } }

/* a service type grid that is always two-up on a phone, not a tower */
@media (max-width: 560px) {
  .ord-types { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .55rem; }
  .ord-type { padding: .75rem .8rem; }
  .ord-type strong { font-size: .86rem; }
  .ord-step-head { flex-wrap: wrap; }
  .ord-terms { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .55rem; }
  .ord-term { padding: .8rem .75rem; }
  .ord-term-price { font-size: 1.15rem; }
  .ord-sizes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 400px) {
  .ord-terms { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- sticky mobile bar: total + CTA always in reach ----------
   On a phone the summary card sits below every step, so the price and the
   button were off screen for the whole configuration. This bar mirrors them
   and hides itself once the real summary scrolls into view. */
.ord-mobar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
  display: none; align-items: center; gap: .8rem;
  padding: .7rem 1rem calc(.7rem + env(safe-area-inset-bottom));
  background: var(--ph-side, #10111c);
  border-top: 1px solid var(--ph-border, #262842);
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .25);
  transform: translateY(0); transition: transform .25s cubic-bezier(.2, .8, .3, 1);
}
.ord-mobar[hidden] { display: none !important; }
.ord-mobar.off { transform: translateY(110%); }
.ord-mobar-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.ord-mobar-text strong { font-size: 1.15rem; font-weight: 800; color: var(--ph-text, #eaf0f7); }
.ord-mobar-text span {
  font-size: .72rem; color: var(--ph-muted, #9096a8);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ord-mobar .btn { flex: 0 0 auto; padding: .7rem 1.1rem; border-radius: 10px; font-weight: 700; font-size: .88rem; }
.ord-mobar .btn:disabled { opacity: .5; }
@media (max-width: 980px) {
  .ord-mobar { display: flex; }
  /* room for the bar so the last step is never hidden behind it */
  .ord-main { padding-bottom: 4.5rem; }
}

/* ---------- cart ---------- */
.cart-row { animation: ph-step-in .35s cubic-bezier(.2, .8, .3, 1) both; }
.cart-row:nth-child(2) { animation-delay: .05s; }
.cart-row:nth-child(3) { animation-delay: .1s; }
.cart-row:nth-child(n+4) { animation-delay: .15s; }
.cart-x { transition: border-color .15s ease, color .15s ease, transform .15s ease; }
.cart-x:hover { transform: scale(1.08); }

/* ---------- order received ---------- */
.ord-done { max-width: 620px; margin: 0 auto; text-align: center; }
.ord-done-check {
  width: 84px; height: 84px; margin: .4rem auto 1.2rem; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(46, 204, 113, .14); color: #0a7d32;
  animation: ph-pop .5s cubic-bezier(.2, .8, .3, 1);
}
.ord-done-check svg { width: 42px; height: 42px; }
.ord-done-check svg path {
  stroke-dasharray: 60; stroke-dashoffset: 60;
  animation: ph-draw .5s ease .25s forwards;
}
@keyframes ph-pop { from { transform: scale(.6); opacity: 0; } }
@keyframes ph-draw { to { stroke-dashoffset: 0; } }
.ord-done h1 { margin-bottom: .4rem; }
.ord-done-next { text-align: left; margin: 1.4rem 0 0; }
.ord-done-next li {
  display: flex; gap: .8rem; align-items: flex-start;
  padding: .8rem 0; border-top: 1px solid var(--pm-border);
}
.ord-done-next li:first-child { border-top: 0; }
.ord-done-next i {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--pm-primary); color: #fff; font-style: normal; font-size: .76rem; font-weight: 800;
}
.ord-done-next strong { display: block; color: var(--pm-text); font-size: .92rem; }
.ord-done-next span { color: var(--pm-muted); font-size: .84rem; }
.ord-done-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; margin-top: 1.4rem; }

/* ---------- auth pages ---------- */
.se-i .user-form .pass-link { transition: color .15s ease; }
.auth-sent {
  padding: 1rem 1.1rem; border-radius: 12px; margin-bottom: 1rem;
  background: rgba(46, 204, 113, .12); border: 1px solid rgba(46, 204, 113, .35);
  font-size: .9rem; line-height: 1.55;
}

/* ---------- marketing plan cards: lift on hover, bounce on the toggler ---------- */
.plan-cards .plan-toggle-btn { transition: background-color .18s ease, color .18s ease; }
.plan-cards .plan-price { animation: ph-fade .25s ease; }

/* ---------- home hero: a tighter title on phones ---------- */
@media (max-width: 767px) {
  .main-header .title-1 { font-size: 38px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  html.ph-js .ph-reveal { opacity: 1; transform: none; }
  .preloader { animation: none; opacity: 0; visibility: hidden; }
}

/* ---------- forms ---------- */
/* honeypot: off-screen, never display:none (some bots check for that) */
.ph-hp { position: absolute !important; left: -9999px !important; top: auto; width: 1px; height: 1px; overflow: hidden; opacity: 0; }
.form-notice {
  padding: .7rem .9rem; border-radius: 10px; font-size: .88rem; line-height: 1.5;
  background: rgba(0, 96, 254, .12); border: 1px solid rgba(0, 96, 254, .35); color: inherit;
}
.contact-form .contact-note { display: block; white-space: normal; line-height: 1.5; }

/* long and short labels: the phone top bar has no room for "Create account" */
.ph-short { display: none; }
@media (max-width: 560px) {
  .ph-long { display: none; }
  .ph-short { display: inline; }
  .ph-top-title h1 { font-size: .98rem; }
}

/* ============================================================
   Game detail pages (/game-servers/{game})
   ============================================================ */
.se-ii .content .card .details .name a { color: inherit; text-decoration: none; }
.se-ii .content .card .details .name a:hover { text-decoration: underline; }
.gd-hero { background-image: linear-gradient(to top, var(--darkBlue), rgba(0, 0, 0, .55)), var(--gd-poster, url(../images/pages/game-server/bg.jpg)); }
.gd-crumbs { margin: 0 0 .9rem; font-size: .84rem; color: rgba(255, 255, 255, .7); }
.gd-crumbs a { color: rgba(255, 255, 255, .85); text-decoration: none; }
.gd-crumbs span { margin: 0 .35rem; opacity: .6; }
.gd-cta { display: flex; gap: .6rem; flex-wrap: wrap; margin: 1.4rem 0 1.2rem; }
@media (max-width: 991px) { .gd-cta { justify-content: center; } }
.gd-facts { display: flex; gap: .4rem .5rem; flex-wrap: wrap; margin: 0; }
@media (max-width: 991px) { .gd-facts { justify-content: center; } }
.gd-facts li {
  font-size: .78rem; font-weight: 700; color: #fff; padding: .3rem .7rem; border-radius: 999px;
  background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .16);
}
.gd-poster { border-radius: 18px; box-shadow: 0 24px 60px rgba(0, 0, 0, .45); max-height: 420px; object-fit: cover; width: 100%; }
.gd-two { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; }
@media (max-width: 820px) { .gd-two { grid-template-columns: 1fr; } }
.gs-panel { padding: 1.4rem 1.5rem; border: 1px solid var(--pm-border); border-radius: 16px; background: var(--pm-surface); }
.gd-h { margin: 0 0 .4rem; font-size: 1.15rem; font-weight: 800; color: var(--pm-text); }
.gd-chips { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: .8rem; }
.gd-chip {
  padding: .4rem .8rem; border-radius: 999px; font-size: .82rem; font-weight: 700;
  background: var(--pm-surface-2); border: 1px solid var(--pm-border); color: var(--pm-text);
}
.gd-chip.is-default { border-color: var(--pm-primary); }
.gd-chip em { font-style: normal; font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--pm-primary); margin-left: .3rem; }
.gd-locs { margin: .8rem 0 0; display: grid; gap: .5rem; }
.gd-locs li { display: flex; align-items: center; gap: .55rem; font-weight: 700; color: var(--pm-text); font-size: .92rem; }
.gd-locs small { font-weight: 500; color: var(--pm-muted); }
.gd-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--pm-muted); flex: none; }
.gd-dot.ok { background: #22c55e; box-shadow: 0 0 0 3px rgba(34, 197, 94, .18); }
.gd-related { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .8rem; }
.gd-rel {
  display: flex; flex-direction: column; gap: .15rem; padding: .7rem; border-radius: 14px; text-decoration: none !important;
  background: var(--pm-surface); border: 1px solid var(--pm-border); color: var(--pm-text) !important;
  transition: transform .16s ease, border-color .16s ease;
}
.gd-rel:hover { transform: translateY(-2px); border-color: var(--pm-primary); }
.gd-rel img, .gd-rel-blank { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 9px; margin-bottom: .45rem; }
.gd-rel-blank { display: grid; place-items: center; font-weight: 800; font-size: 1.6rem; color: var(--pm-muted); background: var(--pm-surface-2); }
.gd-rel strong { font-size: .9rem; }
.gd-rel span { font-size: .76rem; color: var(--pm-primary); font-weight: 700; }
.gd-rel-all { justify-content: center; align-items: center; text-align: center; border-style: dashed; }

/* ---------- promo code on the cart ---------- */
.cart-coupon { margin: .8rem 0 0; }
.cart-coupon summary { cursor: pointer; font-size: .82rem; font-weight: 700; color: var(--pm-primary); list-style: none; }
.cart-coupon summary::-webkit-details-marker { display: none; }
.cart-coupon-form { display: flex; gap: .5rem; margin-top: .6rem; }
.cart-coupon-form .form-input { flex: 1; text-transform: uppercase; }
.cart-coupon-remove { margin-top: .6rem; }
.cart-coupon-line { margin-top: 0 !important; }

/* ============================================================
   Status page (/status)
   ============================================================ */
.st-page { padding: 140px 0 90px; min-height: 70vh; }
@media (max-width: 767px) { .st-page { padding: 90px 0 60px; } }
.st-hero {
  display: flex; align-items: flex-start; gap: 1rem; padding: 1.4rem 1.5rem; border-radius: 16px; margin-bottom: 2rem;
  background: var(--pm-surface); border: 1px solid var(--pm-border);
}
.st-dot { flex: none; width: 16px; height: 16px; border-radius: 50%; margin-top: .55rem; background: #22c55e; box-shadow: 0 0 0 5px rgba(34, 197, 94, .18); }
.st-incident .st-dot, .st-hero.st-incident .st-dot { background: #f59e0b; box-shadow: 0 0 0 5px rgba(245, 158, 11, .18); }
.st-hero.st-down .st-dot { background: #dc2626; box-shadow: 0 0 0 5px rgba(220, 38, 38, .18); }
.st-title { margin: 0 0 .3rem; font-size: 1.5rem; font-weight: 800; color: var(--pm-text); }
.st-sub { margin: 0; color: var(--pm-muted); font-size: .9rem; }
.st-section { margin-bottom: 2rem; }
.st-h { font-size: .78rem; font-weight: 800; letter-spacing: 1px; text-transform: uppercase; color: var(--pm-muted); margin: 0 0 .8rem; }
.st-group { font-size: .92rem; font-weight: 800; color: var(--pm-text); margin: 1rem 0 .5rem; }
.st-row { padding: .9rem 1.1rem; border-radius: 12px; background: var(--pm-surface); border: 1px solid var(--pm-border); margin-bottom: .6rem; }
.st-row-top { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; margin-bottom: .6rem; }
.st-row-top strong { color: var(--pm-text); font-size: .98rem; }
.st-uptime { margin-left: auto; font-size: .8rem; color: var(--pm-muted); }
.st-state { display: inline-flex; align-items: center; gap: .4rem; font-size: .76rem; font-weight: 700; padding: .2rem .6rem; border-radius: 999px; }
.st-state i { width: 7px; height: 7px; border-radius: 50%; display: block; }
.st-state-up { background: rgba(34, 197, 94, .14); color: #15803d; } .st-state-up i { background: #22c55e; }
.st-state-down { background: rgba(220, 38, 38, .14); color: #b91c1c; } .st-state-down i { background: #dc2626; }
.st-state-unknown { background: var(--pm-surface-2); color: var(--pm-muted); } .st-state-unknown i { background: var(--pm-muted); }
.st-strip { display: flex; gap: 2px; }
.st-day { flex: 1; height: 22px; border-radius: 3px; background: var(--pm-surface-2); }
.st-day-ok { background: #22c55e; } .st-day-partial { background: #f59e0b; } .st-day-down { background: #dc2626; }
.st-incident { padding: 1rem 1.1rem; border-radius: 12px; border: 1px solid var(--pm-border); background: var(--pm-surface); margin-bottom: .7rem; border-left: 4px solid #f59e0b; }
.st-incident-resolved { border-left-color: #22c55e; }
.st-incident-head { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.st-incident-head strong { color: var(--pm-text); }
.st-badge { font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; padding: .15rem .5rem; border-radius: 999px; background: var(--pm-surface-2); color: var(--pm-muted); }
.st-body { margin: .5rem 0 0; color: var(--pm-text); font-size: .9rem; line-height: 1.55; }
.st-meta { margin: .35rem 0 0; font-size: .78rem; color: var(--pm-muted); }
.st-foot { margin-top: 2rem; max-width: 70ch; }

/* admin: incidents and funnel */
.adm-incident { padding: .9rem 0; border-top: 1px solid var(--pm-border); }
.adm-incident:first-of-type { border-top: 0; }
.adm-incident-update { display: grid; grid-template-columns: 160px 1fr auto; gap: .5rem; margin-top: .6rem; }
@media (max-width: 640px) { .adm-incident-update { grid-template-columns: 1fr; } }
.fn-steps { display: grid; gap: .9rem; }
.fn-step-top { display: flex; justify-content: space-between; font-size: .9rem; color: var(--pm-text); margin-bottom: .3rem; }
.fn-step-top span { font-weight: 800; }
.fn-step-sub { font-size: .76rem; color: var(--pm-muted); margin-top: .25rem; }
