/* Holographic passport preview (app-fx.js drives --holo-x / --holo-y between -1 and 1). */
.hub-passport-preview.is-holo {
  --holo-a: 330; --holo-b: 190; --holo-c: 55;
  --holo-blend: screen; --holo-strength: .72;
  touch-action: pan-y;
  transform: perspective(800px) rotateX(calc(var(--holo-y, 0) * -11deg)) rotateY(calc(var(--holo-x, 0) * 14deg)) scale(calc(1 + (var(--holo-active, 0) * .02)));
  box-shadow: calc(var(--holo-x, 0) * -18px) calc(20px + var(--holo-y, 0) * -12px) 50px rgba(0, 0, 0, .5), 0 0 0 1px hsla(var(--holo-a), 90%, 70%, .35), 0 0 calc(var(--holo-active, 0) * 26px) hsla(var(--holo-b), 95%, 65%, .45);
  transition: box-shadow 260ms ease;
}
.hub-passport-preview[data-passport-series="classic"],
.hub-passport-preview[data-passport-series="prestige-noir-or"] { --holo-a: 44; --holo-b: 30; --holo-c: 52; }
.hub-passport-preview[data-passport-series="red-dead-redemption-2"] { --holo-a: 28; --holo-b: 18; --holo-c: 40; --holo-blend: overlay; }
.hub-passport-preview[data-passport-series="battlefield-v"] { --holo-a: 24; --holo-b: 200; --holo-c: 44; }
.hub-passport-preview[data-passport-series="uwu"] { --holo-a: 320; --holo-b: 280; --holo-c: 190; --holo-blend: color-dodge; --holo-strength: .6; }
.hub-passport-preview[data-passport-series="cyberpunk"] { --holo-a: 180; --holo-b: 300; --holo-c: 58; }
.hub-passport-preview[data-passport-series="galaxie"] { --holo-a: 265; --holo-b: 205; --holo-c: 305; }

/* Rainbow foil band + light spot, then fine glitter that drifts with the tilt. */
.passport-holo-sheen {
  position: absolute;
  z-index: 1;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  mix-blend-mode: var(--holo-blend);
  opacity: var(--holo-strength);
  background:
    linear-gradient(112deg, transparent calc(26% + var(--holo-x, 0) * 34%), hsla(var(--holo-a), 100%, 62%, .7) calc(36% + var(--holo-x, 0) * 34%), hsla(var(--holo-b), 100%, 64%, .68) calc(45% + var(--holo-x, 0) * 34%), hsla(var(--holo-c), 100%, 62%, .62) calc(54% + var(--holo-x, 0) * 34%), transparent calc(66% + var(--holo-x, 0) * 34%)),
    radial-gradient(circle at calc(50% + var(--holo-x, 0) * 45%) calc(45% + var(--holo-y, 0) * 45%), rgba(255, 255, 255, .4), transparent 30%);
  background-size: 200% 100%, 100% 100%;
  background-position: 50% 0, 0 0;
}
.passport-holo-sheen::after {
  position: absolute;
  inset: 0;
  content: "";
  border-radius: inherit;
  opacity: .5;
  mix-blend-mode: screen;
  background:
    radial-gradient(circle at 20% 30%, #fff 0 .6px, transparent 1.4px) 0 0 / 23px 19px,
    radial-gradient(circle at 70% 60%, hsla(var(--holo-b), 100%, 80%, 1) 0 .6px, transparent 1.5px) 0 0 / 31px 27px,
    radial-gradient(circle at 40% 80%, hsla(var(--holo-a), 100%, 80%, 1) 0 .5px, transparent 1.3px) 0 0 / 17px 29px;
  transform: translate(calc(var(--holo-x, 0) * -6px), calc(var(--holo-y, 0) * -6px));
  -webkit-mask: linear-gradient(112deg, transparent calc(10% + var(--holo-x, 0) * 30%), #000 calc(40% + var(--holo-x, 0) * 30%), #000 calc(60% + var(--holo-x, 0) * 30%), transparent calc(90% + var(--holo-x, 0) * 30%));
  mask: linear-gradient(112deg, transparent calc(10% + var(--holo-x, 0) * 30%), #000 calc(40% + var(--holo-x, 0) * 30%), #000 calc(60% + var(--holo-x, 0) * 30%), transparent calc(90% + var(--holo-x, 0) * 30%));
}
.hub-passport-preview.is-holo-idle .passport-holo-sheen { animation: passport-holo-idle 5s ease-in-out infinite; }
@keyframes passport-holo-idle {
  0%, 100% { background-position: 10% 0, 0 0; }
  50% { background-position: 90% 0, 0 0; }
}

/* Reaction bursts, drawn above everything at the tapped button. */
.app-fx-burst { position: fixed; z-index: 120; width: 0; height: 0; pointer-events: none; }
.app-fx-ghost { position: absolute; left: -14px; top: -14px; width: 28px; height: 28px; border-radius: 7px; object-fit: cover; animation: app-fx-pop 620ms cubic-bezier(.2, .9, .3, 1.4) both; }
.app-fx-burst > i { position: absolute; left: -6px; top: -6px; width: 12px; height: 12px; animation: app-fx-fly 760ms cubic-bezier(.15, .8, .3, 1) var(--fx-delay, 0ms) both; }
.app-fx-keur > i { background: #ff5fa8; clip-path: path("M6 11 1.2 6.4A3 3 0 0 1 6 2.6a3 3 0 0 1 4.8 3.8z"); filter: drop-shadow(0 0 4px rgba(255, 95, 168, .7)); }
.app-fx-ouin > i { width: 8px; height: 11px; left: -4px; border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%; background: #7cc7ff; filter: drop-shadow(0 0 3px rgba(124, 199, 255, .6)); animation-name: app-fx-drop; }
.app-fx-ouin .app-fx-ghost { animation: app-fx-wobble 640ms ease-in-out both; }
@keyframes app-fx-pop {
  0% { opacity: 0; transform: scale(.6); }
  35% { opacity: 1; transform: scale(1.7) rotate(-8deg); }
  100% { opacity: 0; transform: translateY(-26px) scale(1.15); }
}
@keyframes app-fx-fly {
  0% { opacity: 0; transform: translate(0, 0) scale(.4) rotate(0); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--fx-x), var(--fx-y)) scale(1.1) rotate(var(--fx-r)); }
}
@keyframes app-fx-drop {
  0% { opacity: 0; transform: translate(0, 0) scale(.5); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(var(--fx-x) * .6), calc(var(--fx-y) + 18px)) scale(1); }
}
@keyframes app-fx-wobble {
  0% { opacity: 0; transform: scale(.7); }
  25% { opacity: 1; transform: scale(1.5) rotate(-12deg); }
  45% { transform: scale(1.5) rotate(10deg); }
  65% { opacity: 1; transform: scale(1.45) rotate(-6deg); }
  100% { opacity: 0; transform: translateY(10px) scale(1.1) rotate(0); }
}

@media (prefers-reduced-motion: reduce) {
  .hub-passport-preview.is-holo-idle .passport-holo-sheen { animation: none; }
  .app-fx-burst { display: none; }
}

/* Kafpoints gain: flying coins (positioned by app-fx.js) and a 3D spin of the balance coin. */
.app-fx-coin { position: fixed; z-index: 130; left: 0; top: 0; width: 26px; height: 26px; margin: -13px 0 0 -13px; pointer-events: none; object-fit: contain; filter: drop-shadow(0 0 6px rgba(255, 211, 46, .85)); will-change: transform, opacity; }
.kafpoints-balance.is-gaining { animation: app-fx-balance-glow 1.6s .55s ease both; }
.kafpoints-balance.is-gaining .kafpoints-coin { animation: app-fx-coin-spin 1.15s .6s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes app-fx-coin-spin { 0% { transform: perspective(200px) rotateY(0) scale(1); } 45% { transform: perspective(200px) rotateY(540deg) scale(1.3); } 100% { transform: perspective(200px) rotateY(720deg) scale(1); } }
@keyframes app-fx-balance-glow { 0%, 100% { box-shadow: none; } 30% { box-shadow: 0 0 0 3px rgba(255, 211, 46, .35), 0 0 26px rgba(255, 211, 46, .55); } }
@media (prefers-reduced-motion: reduce) { .app-fx-coin { display: none; } .kafpoints-balance.is-gaining, .kafpoints-balance.is-gaining .kafpoints-coin { animation: none; } }

/* Pull to refresh: the Immigré logo turns with the pull while a gold ring fills, then spins while refreshing. */
.app-pull-refresh .app-pull-logo { position: relative; display: grid; width: 30px; height: 30px; place-items: center; border-radius: 50%; background: conic-gradient(#ffd32e calc(var(--pull-progress, 0) * 360deg), rgba(255, 255, 255, .1) 0); font-size: 0; animation: none; }
.app-pull-refresh .app-pull-logo img { width: 24px; height: 24px; border: 2px solid var(--app-surface-2, #1b1d22); border-radius: 50%; object-fit: cover; transform: rotate(calc(var(--pull-progress, 0) * 300deg)); transition: transform 120ms linear; }
.app-pull-refresh.is-ready .app-pull-logo { box-shadow: 0 0 14px rgba(255, 211, 46, .55); }
.app-pull-refresh.is-refreshing .app-pull-logo { background: conic-gradient(#ffd32e 0 75%, rgba(255, 255, 255, .1) 0); animation: app-pull-spin 760ms linear infinite; }
.app-pull-refresh.is-refreshing .app-pull-logo img { animation: app-pull-spin 760ms linear infinite reverse; }
@keyframes app-pull-spin { to { transform: rotate(360deg); } }

/* Liquid bottom navigation. The blob replaces the per-tab highlight only once app-fx.js has placed it. */
.app-bottom-nav.has-liquid > .app-nav-blob { position: absolute; z-index: 0; top: 4px; bottom: max(4px, env(safe-area-inset-bottom)); left: 0; width: 0; border-radius: 12px; background: radial-gradient(120% 90% at 50% 100%, rgba(255, 106, 61, .3), rgba(255, 106, 61, .1) 70%); box-shadow: inset 0 -2px 0 rgba(255, 106, 61, .75), 0 0 18px rgba(255, 106, 61, .18); opacity: 0; pointer-events: none; transition: opacity 200ms ease; }
.app-bottom-nav.has-liquid > button { position: relative; z-index: 1; }
.app-bottom-nav.has-liquid > button:not(.app-compose-button).is-active { background: transparent !important; box-shadow: none !important; }
.app-nav-icon.is-drawing svg :is(path, circle):not([r=".6"]) { stroke-dasharray: 1; animation: app-nav-draw 620ms cubic-bezier(.4, 0, .2, 1) both; }
@keyframes app-nav-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* Directional screen change when a tab is tapped. */
body.app-v2-identity[data-nav-direction="forward"] .app-view.is-active { animation: app-fx-view-forward 300ms cubic-bezier(.2, .8, .25, 1) both; }
body.app-v2-identity[data-nav-direction="back"] .app-view.is-active { animation: app-fx-view-back 300ms cubic-bezier(.2, .8, .25, 1) both; }
@keyframes app-fx-view-forward { from { opacity: .35; transform: translateX(34px); } to { opacity: 1; transform: none; } }
@keyframes app-fx-view-back { from { opacity: .35; transform: translateX(-34px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .app-bottom-nav.has-liquid > .app-nav-blob { transition: none; }
  .app-nav-icon.is-drawing svg :is(path, circle) { animation: none; }
  body.app-v2-identity[data-nav-direction] .app-view.is-active { animation: none; }
}

/* Living sky on the home hero (layers added by app-fx.js between the picture and its shade). */
.hub-preview-hero-media { transform: translate3d(0, calc(var(--hero-scroll, 0) * .32px), 0); will-change: transform; }
.hub-sky { position: absolute; z-index: 0; inset: 0; overflow: hidden; pointer-events: none; transform: translate3d(0, calc(var(--hero-scroll, 0) * .18px), 0); }
.hub-sky > i { position: absolute; display: block; opacity: 0; }
.hub-sky-star { border-radius: 50%; background: #fff; box-shadow: 0 0 4px rgba(255, 255, 255, .9); }
body:is([data-home-period="night"], [data-home-period="evening"]) .hub-sky-star { opacity: .2; animation-name: hub-sky-twinkle; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
body[data-home-period="evening"] .hub-sky-star:nth-child(2n) { display: none; }
.hub-sky-shooting { top: 12%; left: 70%; width: 90px; height: 1.5px; border-radius: 2px; background: linear-gradient(90deg, rgba(255, 255, 255, .95), transparent); transform: rotate(-24deg); }
body[data-home-period="night"] .hub-sky-shooting { animation: hub-sky-shoot 11s ease-in 3s infinite; }
.hub-sky-cloud { width: 62%; height: 34%; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 255, 255, .5), transparent); filter: blur(10px); }
.hub-sky-cloud.is-one { top: 6%; left: -30%; animation: hub-sky-drift 46s linear infinite; }
.hub-sky-cloud.is-two { top: 22%; left: -40%; width: 48%; animation: hub-sky-drift 64s linear -22s infinite; }
.hub-sky-cloud.is-three { top: 2%; left: -30%; width: 40%; height: 24%; animation: hub-sky-drift 82s linear -50s infinite; }
body:is([data-home-period="morning"], [data-home-period="afternoon"]) .hub-sky-cloud { opacity: .16; }
body[data-home-period="evening"] .hub-sky-cloud { opacity: .1; background: radial-gradient(closest-side, rgba(255, 170, 120, .55), transparent); }
@keyframes hub-sky-twinkle { 0%, 100% { opacity: .15; transform: scale(.8); } 50% { opacity: .95; transform: scale(1.15); } }
@keyframes hub-sky-shoot { 0%, 90% { opacity: 0; transform: translate(0, 0) rotate(-24deg); } 92% { opacity: 1; } 100% { opacity: 0; transform: translate(-220px, 100px) rotate(-24deg); } }
@keyframes hub-sky-drift { from { transform: translateX(0); } to { transform: translateX(260%); } }
@media (prefers-reduced-motion: reduce) {
  .hub-preview-hero-media, .hub-sky { transform: none; }
  .hub-sky > i { animation: none !important; }
}

/* Shared-element flights (avatar -> profile, game tile -> game). */
.app-fx-flight { position: fixed; z-index: 140; left: 0; top: 0; object-fit: cover; pointer-events: none; box-shadow: 0 18px 50px rgba(0, 0, 0, .45); will-change: transform, width, height; }

/* Passport turns over when another series is chosen. */
.hub-passport-preview.is-flipping { animation: passport-flip 720ms cubic-bezier(.3, .7, .2, 1) both; }
.hub-passport-preview.is-flipping .passport-holo-sheen { animation: passport-flip-shine 720ms ease both; }
@keyframes passport-flip { 0% { transform: perspective(900px) rotateY(-100deg) scale(.94); filter: brightness(.6); } 60% { transform: perspective(900px) rotateY(12deg) scale(1.01); filter: brightness(1.15); } 100% { transform: perspective(900px) rotateY(0) scale(1); filter: none; } }
@keyframes passport-flip-shine { 0%, 30% { opacity: 0; } 60% { opacity: 1; background-position: 90% 0, 0 0; } 100% { opacity: var(--holo-strength); background-position: 50% 0, 0 0; } }
@media (prefers-reduced-motion: reduce) { .app-fx-flight { display: none; } .hub-passport-preview.is-flipping, .hub-passport-preview.is-flipping .passport-holo-sheen { animation: none; } }

/* Opening: the Immigré logo pops, then the screen opens in a circle from the centre. */
@property --app-intro-hole { syntax: "<length>"; inherits: false; initial-value: 0px; }
html.app-intro-play body::after { position: fixed; z-index: 2000; inset: 0; content: ""; pointer-events: none; background: url("/assets/logos/immigre-production-logo.png") center / 92px no-repeat, #08080c; -webkit-mask: radial-gradient(circle at 50% 50%, transparent var(--app-intro-hole), #000 calc(var(--app-intro-hole) + 1px)); mask: radial-gradient(circle at 50% 50%, transparent var(--app-intro-hole), #000 calc(var(--app-intro-hole) + 1px)); animation: app-intro-open 900ms cubic-bezier(.65, 0, .25, 1) both; }
@keyframes app-intro-open {
  0% { --app-intro-hole: 0px; background-size: 54px; opacity: 1; }
  32% { --app-intro-hole: 0px; background-size: 104px; }
  40% { --app-intro-hole: 0px; background-size: 96px; }
  100% { --app-intro-hole: 150vmax; background-size: 96px; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { html.app-intro-play body::after { display: none; } }

/* Player: a still halo in the cover colour behind the artwork (the artwork itself never moves). */
.hub-player-art-stage::before { position: absolute; z-index: 0; inset: 8% 12%; content: ""; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--hub-track-accent, #ff6a3d) 55%, transparent), transparent); filter: blur(28px); opacity: 0; pointer-events: none; transition: opacity 500ms ease; }
.hub-player-art { position: relative; z-index: 1; }
.hub-player-screen.is-playing .hub-player-art-stage::before { opacity: .5; }

/* Vinyl mode. */
/* Player extras row (vinyl, Kafmoments) under the title. */
.hub-player-extras { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 2px; }
.hub-player-chip { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px 0 10px; border: 1px solid rgba(255, 255, 255, .14); border-radius: 999px; background: rgba(255, 255, 255, .05); color: rgba(255, 255, 255, .86); font: inherit; font-size: .72rem; font-weight: 800; }
.hub-player-chip svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.hub-player-chip[aria-pressed="true"], .hub-player-chip[aria-expanded="true"] { border-color: color-mix(in srgb, var(--hub-track-accent, #ff6a3d) 70%, transparent); background: color-mix(in srgb, var(--hub-track-accent, #ff6a3d) 14%, transparent); color: var(--hub-track-accent, #ff6a3d); }
html .hub-player-screen.is-vinyl .hub-player-art { border-radius: 50%; background: repeating-radial-gradient(circle, #111 0 2px, #1b1b1d 2px 3px); }
.hub-player-screen.is-vinyl .hub-player-art img { clip-path: circle(31% at 50% 50%); }
.hub-player-screen.is-vinyl .hub-player-art::after { position: absolute; z-index: 2; inset: 0; content: ""; border-radius: 50%; background: radial-gradient(circle, #0c0d10 0 3.2%, transparent 3.4% 31%, rgba(255, 255, 255, .06) 31.4%, transparent 32%), conic-gradient(from 30deg, transparent 0 10%, rgba(255, 255, 255, .08) 14%, transparent 20% 60%, rgba(255, 255, 255, .06) 64%, transparent 70%); pointer-events: none; }
.hub-player-screen.is-vinyl.is-playing:not(.is-changing) .hub-player-art img { animation: hub-vinyl-spin 6s linear infinite; }
@keyframes hub-vinyl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .hub-player-screen.is-vinyl .hub-player-art img { animation: none; } }

/* Elastic sheets: their grip areas belong to the drag gesture, not to page scrolling. */
.app-sheet .app-sheet-handle, .app-sheet .app-sheet-heading, .kafpoints-panel > header, .hub-passport-save-panel > header, .hub-passport-save-panel > h2, .hub-home-customize-panel > header { touch-action: none; }

/* Profile à la MySpace: banner, overlapping avatar, featured track and Kafboutique showcase. */
.app-profile-summary.has-banner { padding-top: 0 !important; }
.app-profile-banner { position: relative; height: clamp(112px, 31vw, 190px); margin: 0 calc(-1 * max(16px, env(safe-area-inset-left))) 0; overflow: hidden; background: radial-gradient(120% 140% at 15% 0%, color-mix(in srgb, var(--profile-accent, #ffd32e) 55%, transparent), transparent 60%), radial-gradient(90% 120% at 100% 100%, rgba(255, 106, 61, .35), transparent 65%), linear-gradient(135deg, #1c1622, #0d0e12); }
.app-profile-banner::after { position: absolute; inset: 0; content: ""; background: linear-gradient(180deg, transparent 45%, color-mix(in srgb, var(--app-bg, #0b0c0f) 92%, transparent)); }
.app-profile-banner img { width: 100%; height: 100%; object-fit: cover; }
.app-profile-summary.has-banner .app-profile-identity { position: relative; z-index: 1; margin-top: -44px; align-items: start; }
.app-profile-summary.has-banner .app-profile-avatar-wrap { border-radius: 50%; box-shadow: 0 0 0 4px var(--app-bg, #0b0c0f), 0 12px 30px rgba(0, 0, 0, .45); }
.app-profile-summary.has-banner .app-profile-name { padding-top: 48px; }
@media (min-width: 601px) { .app-profile-summary.has-banner .app-profile-actions { align-self: start; margin-top: 52px; } }

.app-profile-track { display: grid; grid-template-columns: 52px minmax(0, 1fr) 38px; align-items: center; gap: 11px; width: 100%; margin-top: 12px; padding: 8px; border: 1px solid color-mix(in srgb, var(--profile-accent, #ffd32e) 40%, transparent); border-radius: 14px; background: linear-gradient(110deg, color-mix(in srgb, var(--profile-accent, #ffd32e) 14%, transparent), transparent 70%), var(--app-surface, #15171c); color: var(--app-text, #fff); text-align: left; cursor: pointer; }
.app-profile-track img { width: 52px; height: 52px; border-radius: 10px; object-fit: cover; }
.app-profile-track span { display: grid; min-width: 0; gap: 1px; }
.app-profile-track small { color: var(--profile-accent, #ffd32e); font-size: .56rem; font-weight: 900; letter-spacing: .1em; }
.app-profile-track strong { overflow: hidden; font-size: .88rem; text-overflow: ellipsis; white-space: nowrap; }
.app-profile-track em { overflow: hidden; color: var(--app-muted, #aaa); font-size: .66rem; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
.app-profile-track b { display: grid; width: 38px; height: 38px; place-items: center; border-radius: 50%; background: var(--profile-accent, #ffd32e); color: #15100a; font-size: .8rem; }

.app-profile-showcase { display: flex; gap: 8px; margin: 12px calc(-1 * max(16px, env(safe-area-inset-left))) 0; padding: 0 max(16px, env(safe-area-inset-left)) 2px; overflow-x: auto; scrollbar-width: none; }
.app-profile-showcase::-webkit-scrollbar { display: none; }
.app-profile-showcase > span { display: grid; flex: 0 0 74px; justify-items: center; gap: 4px; padding: 7px 4px 6px; border: 1px solid color-mix(in srgb, var(--item-accent) 30%, transparent); border-radius: 12px; background: color-mix(in srgb, var(--item-accent) 8%, transparent); }
.app-profile-showcase > span.is-equipped { border-color: var(--item-accent); box-shadow: 0 0 14px color-mix(in srgb, var(--item-accent) 35%, transparent); }
.app-profile-showcase img { width: 40px; height: 40px; object-fit: contain; }
.app-profile-showcase i { display: grid; width: 40px; height: 40px; place-items: center; border-radius: 50%; background: color-mix(in srgb, var(--item-accent) 22%, transparent); color: var(--item-accent); font-style: normal; font-weight: 900; }
.app-profile-showcase small { overflow: hidden; width: 100%; color: var(--app-muted, #aaa); font-size: .54rem; font-weight: 800; text-align: center; text-overflow: ellipsis; white-space: nowrap; }

.app-profile-banner-field { display: grid; gap: 6px; }
.app-profile-banner-field > span { font-size: .78rem; font-weight: 800; }
.app-profile-banner-preview { overflow: hidden; aspect-ratio: 3 / 1; border: 1px dashed var(--app-line, #333); border-radius: 12px; background: var(--app-surface, #15171c); }
.app-profile-banner-preview img { width: 100%; height: 100%; object-fit: cover; }
.app-profile-banner-preview span { display: grid; height: 100%; place-items: center; padding: 8px; color: var(--app-muted, #aaa); font-size: .68rem; text-align: center; }
.app-profile-banner-actions { display: flex; align-items: center; gap: 10px; }
#appProfileTrack { width: 100%; min-height: 42px; margin-top: 6px; padding: 0 10px; border: 1px solid var(--app-line, #333); border-radius: 10px; background: var(--app-surface, #15171c); color: var(--app-text, #fff); font: inherit; font-size: 16px; }

/* Sun and moon placed by the real time (app-fx.js), with soft halos; birds cross by day. */
.hub-sky-body { position: absolute; z-index: 2; width: 0; height: 0; opacity: 0; pointer-events: none; mix-blend-mode: screen; }
.hub-sky-body.is-sun, .hub-sky-body.is-moon { opacity: 1; transition: left 1.2s ease, top 1.2s ease; }
.hub-sky-body.is-sun { width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; background: radial-gradient(circle, #fffef6 0 38%, #fff6c8 52%, rgba(255, 244, 200, 0) 72%); box-shadow: 0 0 40px 18px rgba(255, 250, 220, .55), 0 0 140px 70px rgba(255, 248, 225, .32); }
.hub-sky-body.is-moon { width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; background: radial-gradient(circle at 34% 38%, rgba(190, 192, 210, .4) 0 9%, transparent 11%), radial-gradient(circle at 62% 58%, rgba(190, 192, 210, .32) 0 12%, transparent 14%), radial-gradient(circle at 48% 72%, rgba(195, 198, 215, .28) 0 7%, transparent 9%), radial-gradient(circle at 40% 40%, #ffffff, #f3f1ea 70%); box-shadow: 0 0 22px 6px rgba(236, 238, 255, .55), 0 0 90px 36px rgba(180, 190, 255, .22); }
.hub-sky-birds { top: 26%; left: -14%; display: flex !important; gap: 8px; color: rgba(30, 30, 45, .55); }
.hub-sky-birds svg { width: 13px; height: 6px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; animation: hub-sky-flap .7s ease-in-out infinite alternate; }
.hub-sky-birds svg:nth-child(2) { width: 10px; margin-top: 7px; animation-delay: .2s; }
.hub-sky-birds svg:nth-child(3) { width: 9px; margin-top: -4px; animation-delay: .35s; }
body:is([data-home-period="morning"], [data-home-period="afternoon"], [data-home-period="evening"]) .hub-sky-birds { animation: hub-sky-birds 26s linear 4s infinite; }
@keyframes hub-sky-birds { 0% { opacity: 0; left: -14%; top: 30%; } 4% { opacity: 1; } 60% { opacity: 1; left: 104%; top: 16%; } 62%, 100% { opacity: 0; left: 110%; top: 15%; } }
@keyframes hub-sky-flap { from { transform: scaleY(1); } to { transform: scaleY(-.6); } }
@media (prefers-reduced-motion: reduce) { .hub-sky-birds { display: none !important; } }

/* Image cropper (image-cropper.js). */
.image-cropper { position: fixed; z-index: 3000; inset: 0; display: grid; place-items: center; padding: max(16px, env(safe-area-inset-top)) 14px max(16px, env(safe-area-inset-bottom)); background: rgba(4, 5, 8, .88); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.image-cropper-panel { display: grid; gap: 14px; width: min(100%, 520px); padding: 16px; border: 1px solid rgba(255, 255, 255, .12); border-radius: 18px; background: #121418; color: #fff; }
.image-cropper-panel header { display: grid; gap: 3px; }
.image-cropper-panel header strong { font-size: 1rem; }
.image-cropper-panel header small { color: rgba(255, 255, 255, .6); font-size: .7rem; }
.image-cropper-frame { position: relative; width: 100%; max-height: 60dvh; overflow: hidden; border-radius: 12px; background: #000; touch-action: none; cursor: grab; box-shadow: 0 0 0 2px rgba(255, 211, 46, .7); }
.image-cropper-frame.is-round { width: min(100%, 60dvh); margin: 0 auto; border-radius: 50%; }
.image-cropper-frame img { position: absolute; top: 50%; left: 50%; max-width: none; user-select: none; -webkit-user-select: none; pointer-events: none; }
.image-cropper-zoom { display: flex; align-items: center; gap: 10px; color: rgba(255, 255, 255, .7); font-weight: 800; }
.image-cropper-zoom input { flex: 1; accent-color: #ffd32e; }
.image-cropper-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.image-cropper-actions button { min-height: 44px; border: 1px solid rgba(255, 255, 255, .16); border-radius: 12px; background: rgba(255, 255, 255, .06); color: #fff; font: inherit; font-weight: 800; }
.image-cropper-actions button.is-primary { border-color: #ff6a3d; background: #ff6a3d; color: #17100d; }

/* Invisible native switch used for iPhone haptics (app-fx.js). Rendered, never visible. */
.app-fx-haptic { position: fixed; left: 0; top: 0; width: 1px; height: 1px; overflow: hidden; opacity: .01; pointer-events: none; }

/* iPhone: explicit tap to allow motion for the 3D passport (app-fx.js). */
.passport-motion-button { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 40px; margin-top: 10px; border: 1px solid rgba(255, 211, 46, .45); border-radius: 12px; background: rgba(255, 211, 46, .1); color: #ffd32e; font: inherit; font-size: .74rem; font-weight: 800; }
.passport-motion-button svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
