/* Global interaction feel — user-facing app.
   ---------------------------------------------------------------------------
   Deliberately restrained. An earlier version of this file fired four effects
   on a single tap (scale + brightness + ripple + expanding ring), plus a hover
   shimmer and a vibration. Stacked effects read as a free template; one precise
   motion reads as expensive. Everything below is transform/opacity only, so it
   never touches layout and is safe on every page.

   Note: nothing here animates `transform` on <body>. A transform on an ancestor
   re-bases `position: fixed` children, which would detach the bottom nav while
   the animation ran. Page entry is opacity only for that reason. */

/* ── Substrate ───────────────────────────────────────────────────────────────
   None of this is visible on its own. Together it is most of the difference
   between an app that feels built and one that feels assembled. */
:root {
    /* Tells the browser this is a dark UI. Without it, native parts stay light:
       scrollbars, date pickers, form controls, and the autofill highlight —
       which is why autofilled fields flash bright yellow-white on a black page.
       That single detail makes a site look broken more than any layout flaw. */
    color-scheme: dark;
}

html {
    /* Over-scroll past the top or bottom exposes the page canvas. Left at the
       default it flashes white on a black app every time a customer flicks a
       list — extremely visible, and read as a rendering bug. */
    background-color: #060606;
    -webkit-text-size-adjust: 100%;   /* iOS rescales text on rotate otherwise */
}

body {
    /* Dark backgrounds make normal antialiasing look thick and slightly blurred.
       Greyscale smoothing is what makes text on this palette look sharp. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* The default blue browser selection on a gold-on-black app is jarring. */
::selection { background: rgba(229,188,52,.28); color: #fff; }

/* Chrome forces its own background on autofilled inputs and ignores background
   rules. A long inset shadow is the only thing it honours. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-text-fill-color: #fff;
    -webkit-box-shadow: 0 0 0 1000px #0a0a0a inset;
    caret-color: #e5bc34;
    transition: background-color 9999s ease-in-out 0s;
}

/* Scrollbars: default light ones on a dark page are the classic giveaway.
   Kept neutral rather than gold — the Forex screens run a blue palette, and a
   gold scrollbar there would look like a leftover from another page. */
html { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.18) transparent; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,.16);
    border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.28); }

/* Long-pressing anything on iOS pops the grey selection callout, which makes a
   card or nav item feel like a web page rather than an app control. Text that
   customers may genuinely want to copy is exempted below. */
body { -webkit-touch-callout: none; }
input, textarea, [contenteditable], .selectable,
code, pre, .wallet-address, .copyable {
    -webkit-touch-callout: default;
    -webkit-user-select: text;
    user-select: text;
}

/* ── Page entry ──────────────────────────────────────────────────────────────
   Server-rendered pages snap in. A short fade is what removes the "document"
   feel and makes navigation read as an app. CSS-only on purpose: if scripting
   fails the page is simply visible, never stuck invisible. */
@keyframes pfx-page-in { from { opacity: 0; } to { opacity: 1; } }
body { animation: pfx-page-in .22s ease-out both; }

/* ── Press feedback ──────────────────────────────────────────────────────────
   One scale, no colour shift. Down fast, back slowly — equal timing in both
   directions is what makes a press feel mechanical instead of physical. */
button,
.btn,
a.btn,
input[type="submit"],
input[type="button"],
[role="button"],
.tool-btn,
[onclick] {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

/* :where() holds this at zero specificity on purpose. This file loads after
   each page's own <style> block, so at equal specificity it would win and
   silently replace any transition that page had defined — killing, say, a
   background fade a screen was relying on. At zero specificity the page always
   wins, and this only fills in where nothing was specified. */
:where(button, .btn, a.btn, input[type="submit"], input[type="button"], [role="button"], .tool-btn, [onclick]) {
    transition: transform .28s cubic-bezier(.2,.9,.25,1.1),
                filter .18s ease,
                box-shadow .2s ease;
}

button.pfx-pressed,
.btn.pfx-pressed,
a.btn.pfx-pressed,
input[type="submit"].pfx-pressed,
input[type="button"].pfx-pressed,
[role="button"].pfx-pressed,
.tool-btn.pfx-pressed,
[onclick].pfx-pressed {
    transform: scale(.975);
    transition-duration: .07s;
    transition-timing-function: ease-out;
}

/* ── Live value change ───────────────────────────────────────────────────────
   Marked elements flash green or red when their number moves. This is the one
   piece of motion here that is genuinely informational rather than decorative:
   on a trading screen a flashing quote is how a customer knows the feed is
   live, and its absence is how they start wondering if the page has frozen.

   !important is deliberate. These elements are styled by id on their own pages
   (#stat-bid and friends), and an id selector outranks any class this file can
   write. The class is transient - it is removed again within half a second. */
[data-pfx-flash].pfx-up   { color: #0ecb81 !important; }
[data-pfx-flash].pfx-down { color: #f6465d !important; }
:where([data-pfx-flash]) { transition: color .12s linear; }

/* Desktop only. Touch devices never see hover, and on a dark UI a brightness
   lift alone is enough — no sweep, no glow. */
@media (hover: hover) and (pointer: fine) {
    button:hover:not(:disabled),
    .btn:hover:not(:disabled),
    a.btn:hover,
    input[type="submit"]:hover:not(:disabled),
    input[type="button"]:hover:not(:disabled),
    [role="button"]:hover {
        filter: brightness(1.06);
    }
}

/* ── Navigation progress ─────────────────────────────────────────────────────
   The gap between tapping something and the next page painting is dead time on
   a server-rendered site. A hairline that starts immediately fills it, so the
   tap always feels answered even when the network is slow. */
#pfx-nav-progress {
    position: fixed;
    top: 0; left: 0;
    height: 2px; width: 0;
    background: linear-gradient(90deg, rgba(229,188,52,.35), #e5bc34);
    box-shadow: 0 0 8px rgba(229,188,52,.5);
    z-index: 99999;
    opacity: 0;
    pointer-events: none;
    transition: width .25s ease, opacity .2s ease;
}
#pfx-nav-progress.on { opacity: 1; }

/* ── Loading skeletons ───────────────────────────────────────────────────────
   Applied on load to values that arrive from a later request, and removed
   automatically the first time the element's text actually changes - so no
   page has to call anything to clear them. Sized from the element's own text,
   which is why the placeholder never causes a layout shift when real data
   lands: the box was already the right shape. */
.pfx-skel {
    color: transparent !important;
    border-radius: 5px;
    background-color: rgba(255,255,255,.05);
    background-image: linear-gradient(90deg,
        rgba(255,255,255,0) 0%,
        rgba(255,255,255,.07) 50%,
        rgba(255,255,255,0) 100%);
    background-size: 200% 100%;
    background-repeat: no-repeat;
    animation: pfx-shimmer 1.25s ease-in-out infinite;
    -webkit-user-select: none;
    user-select: none;
    pointer-events: none;
}
/* Anything nested inside a skeletonised value must disappear too, or a stray
   currency symbol or arrow icon floats on top of the placeholder. */
.pfx-skel * { color: transparent !important; visibility: hidden; }
@keyframes pfx-shimmer {
    0%   { background-position: 150% 0; }
    100% { background-position: -50% 0; }
}

/* ── Async states ────────────────────────────────────────────────────────────
   Used by real request lifecycles (order execution, form submits). Text is
   hidden rather than removed so the control never changes size. */
.pfx-loading, .pfx-loading * { color: transparent !important; }
.pfx-loading {
    position: relative;
    pointer-events: none;
}
.pfx-loading::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 18px; height: 18px;
    margin: -9px 0 0 -9px;
    border: 2px solid rgba(255,255,255,.3);
    border-top-color: rgba(255,255,255,.95);
    border-radius: 50%;
    animation: pfx-spin .6s linear infinite;
}
@keyframes pfx-spin { to { transform: rotate(360deg); } }

.pfx-success { position: relative; }
.pfx-success::after {
    content: '\2713';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    font-weight: 800;
    color: #fff;
    animation: pfx-success-pop .45s cubic-bezier(.2,1.4,.35,1);
}
@keyframes pfx-success-pop {
    from { transform: scale(.6); opacity: 0; }
    60%  { transform: scale(1.08); opacity: 1; }
    to   { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    body { animation: none; }
    button, .btn, a.btn, input[type="submit"], input[type="button"], [role="button"], .tool-btn, [onclick] { transition: none; }
    button.pfx-pressed, .btn.pfx-pressed, a.btn.pfx-pressed,
    input[type="submit"].pfx-pressed, input[type="button"].pfx-pressed,
    [role="button"].pfx-pressed, .tool-btn.pfx-pressed, [onclick].pfx-pressed { transform: none; }
    #pfx-nav-progress { transition: opacity .2s ease; }
    /* The shimmer stops, but the placeholder stays - it still communicates
       "not loaded yet", which is information, not decoration. */
    .pfx-skel { animation: none; }
}
