/* =============================================================
   PaytreeX payment page — SKELETON LOADING
   -------------------------------------------------------------
   Painted while an offer change (plan / duration / number of
   codes) is being confirmed by the server.

   Loaded for EVERY template, always after the template's own
   stylesheets (see paytreex_payment_page_render_inline_styles),
   so a template never has to ship a skeleton of its own — and a
   template added later gets one for free.

   What it draws is the *structure* of what is loading: each card
   keeps its outline, and the text inside it becomes bars of the
   width the words had. Never one flat slab per box — that is what
   makes a placeholder look unfinished rather than designed.

   Theme structure it follows:
     - surfaces and fills come from the template's own --ptx-surface
       / --ptx-line tokens, so a dark template skeletons dark. They
       are deliberately NOT built from `currentColor`: on accent
       text that paints a coloured slab that reads as an error;
     - radii come from the *measured* element the tile stands in
       for (set inline by ui.js), falling back to --ptx-r;
     - the pending accent bar uses --ptx-accent, i.e. the offer
       colour currently applied to the page.
   ============================================================= */

.ptx-skel,
.ptx-skel-line {
    --ptx-skel-surface: var(--ptx-surface, #ffffff);
    --ptx-skel-edge: var(--ptx-line-3, #eef0f4);
    --ptx-skel-fill: var(--ptx-line, #e9eaf0);
    --ptx-skel-sheen: rgba(255, 255, 255, .55);
}

/* ---------- Block regions ---------- */
/* The region keeps its own box — only its content is swapped for
   tiles — so nothing on the page moves while it is loading. */
.ptx-skel-anchor { position: relative !important; }

.ptx-skel-host > *:not(.ptx-skel) { visibility: hidden; }

.ptx-skel {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    pointer-events: none;
    z-index: 2;
}

/* The card the content sits in: outline only, and still — it is the
   part that is not loading, it is where the loading is happening. */
.ptx-skel-surface {
    position: absolute;
    display: block;
    background: var(--ptx-skel-surface);
    border: 1px solid var(--ptx-skel-edge);
    border-radius: var(--ptx-r, 10px);
}

/* A run of text, an icon, a badge. */
.ptx-skel-tile {
    position: absolute;
    display: block;
    border-radius: 5px;
    overflow: hidden;
}

/* ---------- Text placeholders ---------- */
/* Prices, totals and recap lines keep their own metrics — the
   glyphs are made transparent rather than removed — so a long
   amount never collapses the line it sits on. */
.ptx-skel-text { color: transparent !important; text-shadow: none !important; }
.ptx-skel-text * { color: transparent !important; text-shadow: none !important; }
.ptx-skel-inline { display: inline-block; }

.ptx-skel-line {
    position: absolute;
    top: 2px;
    left: 0;
    right: 0;
    bottom: 2px;
    min-height: 10px;
    border-radius: var(--ptx-r-sm, 6px);
    pointer-events: none;
    z-index: 2;
}

/* ---------- Shimmer ---------- */
/* A light band crossing the fill: brighter than it on a light
   template, and brighter still on a dark one, so a single value
   works everywhere. ui.js staggers the tiles by writing
   animation-delay inline, so a column fills in sequence. */
.ptx-skel-tile,
.ptx-skel-line {
    background-color: var(--ptx-skel-fill);
    background-image: linear-gradient(
        100deg,
        transparent 25%,
        var(--ptx-skel-sheen) 48%,
        var(--ptx-skel-sheen) 52%,
        transparent 75%
    );
    background-repeat: no-repeat;
    background-size: 220% 100%;
    background-position: 150% 0;
    animation: ptxSkelSweep 1.4s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes ptxSkelSweep {
    from { background-position: 150% 0; }
    to   { background-position: -50% 0; }
}

/* ---------- Optimistic selection ---------- */
/* The clicked option is marked selected on the spot and carries an
   indeterminate accent bar until the server confirms it, so the
   answer to a click is immediate even when the round trip is not. */
.ptx-pending { position: relative; }
.ptx-pending::after {
    content: '';
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: 4px;
    height: 3px;
    border-radius: 3px;
    pointer-events: none;
    /* The track is drawn too, not just the segment sweeping along it: with the
       segment alone the indicator is invisible for a third of every cycle, and
       whatever frame the customer looks at has to say "working on it". It sits
       on the card's own accent tint, so the track has to be the stronger
       accent step (--ptx-ring) to read against it at all. */
    background-color: var(--ptx-ring, rgba(31, 32, 64, .18));
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        var(--ptx-accent, #B62A0F) 50%,
        transparent 100%
    );
    background-repeat: no-repeat;
    background-size: 55% 100%;
    background-position: -30% 0;
    opacity: .9;
    animation: ptxSkelTrack 1.05s ease-in-out infinite;
}

@keyframes ptxSkelTrack {
    from { background-position: -30% 0; }
    to   { background-position: 130% 0; }
}

body.ptx-loading-context .duration-option,
body.ptx-loading-context .code-quantity-option,
body.ptx-loading-context .payment-flow-option { cursor: progress; }

/* ---------- Reduced motion ---------- */
/* Sweeping bands are the part that hurts here; the placeholders
   still have to read as "busy", so they breathe instead. */
@media (prefers-reduced-motion: reduce) {
    .ptx-skel-tile,
    .ptx-skel-line {
        background-image: none;
        animation: ptxSkelPulse 1.6s ease-in-out infinite;
    }
    .ptx-pending::after {
        background-size: 100% 100%;
        background-position: 0 0;
        animation: ptxSkelPulse 1.6s ease-in-out infinite;
    }
    @keyframes ptxSkelPulse {
        0%, 100% { opacity: 1; }
        50%      { opacity: .45; }
    }
}
