/* Autodrain feature styles. Reuses site tokens where available. */
.okd-hidden { display: none !important; }

.okd-trigger {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--accent, #e056a0); color: #1a0a12;
    border: none; border-radius: 30px; padding: 8px 16px;
    font-size: 13px; font-weight: 700; cursor: pointer; font-family: inherit;
    box-shadow: 0 4px 18px rgba(224, 86, 160, 0.35);
    transition: transform 0.12s ease, box-shadow 0.2s ease, filter 0.2s ease;
}
.okd-trigger:hover { transform: translateY(-1px); filter: brightness(1.05); box-shadow: 0 6px 24px rgba(224, 86, 160, 0.5); }
.okd-trigger:active { transform: scale(0.97); }

@media (prefers-reduced-motion: reduce) {
    .okd-trigger { transition: none; }
}

/* ---- Particle bursts (particles.js) ---------------------------------- */
/* Two nodes per particle: the outer span flies along the path, the inner
   span pops, tumbles, sways and fades. Splitting them lets each motion keep
   its own easing so the flight reads as "shoot out, hang, sink". */
.okd-particles {
    position: absolute; inset: 0;
    pointer-events: none; overflow: visible; z-index: 3;
    contain: layout style;
}
.okd-particle {
    position: absolute; left: 0; top: 0;
    will-change: transform;
    pointer-events: none; user-select: none;
    animation: okd-fly var(--dur, 1.4s) var(--delay, 0ms) both;
}
.okd-particle__glyph {
    display: block;
    line-height: 1;
    will-change: transform, opacity;
    transform-origin: 50% 55%;
    animation: okd-pop var(--dur, 1.4s) var(--delay, 0ms) both;
}
/* Mid tiers get a soft pink glow, rainbow tier cycles hue and glows harder. */
.okd-particle--glow .okd-particle__glyph {
    filter: drop-shadow(0 0 6px rgba(255, 120, 190, 0.55));
}
.okd-particle--rainbow .okd-particle__glyph {
    filter: drop-shadow(0 0 8px rgba(255, 150, 220, 0.75));
    animation: okd-pop var(--dur, 1.4s) var(--delay, 0ms) both,
               okd-hue 1.2s linear var(--delay, 0ms) infinite;
}

/* Flight path. Fast out (ease-out), then a slow gravity sink (ease-in). The
   timing function inside a keyframe applies to the segment that starts there. */
@keyframes okd-fly {
    0% {
        transform: translate(-50%, -50%);
        animation-timing-function: cubic-bezier(0.12, 0.85, 0.28, 1);
    }
    62% {
        transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy)));
        animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.6);
    }
    100% {
        transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy) + var(--fall)));
    }
}
/* Pop in with a little overshoot, tumble, sway once, fade at the end. */
@keyframes okd-pop {
    0%   { transform: translateX(0) scale(0.2) rotate(0deg); opacity: 0; }
    10%  { transform: translateX(calc(var(--sway) * 0.3)) scale(1.28) rotate(calc(var(--rot) * 0.15)); opacity: 1; }
    22%  { transform: translateX(calc(var(--sway) * 0.7)) scale(1) rotate(calc(var(--rot) * 0.3)); opacity: 1; }
    62%  { transform: translateX(var(--sway)) scale(1.02) rotate(calc(var(--rot) * 0.75)); opacity: 1; }
    100% { transform: translateX(calc(var(--sway) * 0.4)) scale(0.72) rotate(var(--rot)); opacity: 0; }
}
@keyframes okd-hue {
    from { filter: hue-rotate(0deg) drop-shadow(0 0 8px rgba(255, 150, 220, 0.75)); }
    to   { filter: hue-rotate(360deg) drop-shadow(0 0 8px rgba(255, 150, 220, 0.75)); }
}

/* Reduced motion: no overshoot, no tumble, no sway, no hue cycling. Just a
   short soft drift and fade. particles.js also shrinks counts and travel. */
@media (prefers-reduced-motion: reduce) {
    .okd-particle { animation-name: okd-fly-calm; }
    .okd-particle__glyph,
    .okd-particle--rainbow .okd-particle__glyph { animation: okd-pop-calm var(--dur, 0.7s) ease-out var(--delay, 0ms) both; filter: none; }
    .okd-particle--glow .okd-particle__glyph { filter: none; }
}
@keyframes okd-fly-calm {
    0%   { transform: translate(-50%, -50%); }
    100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy) + var(--fall))); }
}
@keyframes okd-pop-calm {
    0%   { transform: scale(0.8); opacity: 0; }
    30%  { transform: scale(1); opacity: 1; }
    100% { transform: scale(1); opacity: 0; }
}

/* ---- Escalating counter (counter.js) -------------------------------- */
/* Three separate elements carry the three motions so they never fight:
   the stage pulses (tier 3 and rainbow), the num pops on each send, and the
   value holds the color or the rainbow gradient. The glow is a blurred twin
   of the text sitting behind the number rather than a text-shadow, because a
   text-shadow paints over a background-clip: text gradient and would smear
   the rainbow pink. counter.js drives --okd-glow (0..1) every frame of a roll
   so the bloom grows with the digits. */
/* Centering: the wrap, the stage and the number are all flex-centered rather
   than inline-block inside text-align: center. An inline-block wider than its
   line box overflows to the right only, so the old layout drifted the number
   off center once it outgrew the column. A flex item wider than its container
   under justify-content: center overflows both sides equally, so the number
   stays visually centered no matter how many digits it grows. On top of that
   counter.js measures the number whenever its digit count changes and sets
   --okd-fit below 1 if it would still not fit, so inside the popup card it
   never has to overflow at all. */
.okd-counter {
    --okd-glow: 0;
    --okd-glow-hue: hsl(330 100% 72%);
    --okd-fit: 1;
    position: relative; text-align: center; padding: 10px 0 14px;
    display: flex; flex-direction: column; align-items: center;
    width: 100%; min-width: 0;
}
.okd-counter-label {
    font-size: 13px; letter-spacing: 1px; text-transform: lowercase;
    color: var(--muted, #9a8aa0); margin-bottom: 6px;
    transition: color 0.6s ease, letter-spacing 0.6s ease;
}
.okd-counter[data-tier="3"] .okd-counter-label { letter-spacing: 2px; }
.okd-counter.okd-rainbow .okd-counter-label { color: #f0e8f0; letter-spacing: 3px; }

.okd-counter-stage {
    display: flex; justify-content: center; align-items: center;
    width: 100%; min-width: 0;
}
.okd-counter-num {
    position: relative; display: block; flex: none;
    padding: 0 0.12em;
    white-space: nowrap;
    /* Sized so "$1,234.00" sits on one line inside a ~360px card; --okd-fit
       shrinks it further if a longer number ever needs it. */
    font-size: calc(clamp(34px, 11vw, 56px) * var(--okd-fit, 1));
    font-weight: 900; line-height: 1;
    font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
    will-change: transform;
}
.okd-counter-value {
    position: relative; z-index: 1;
    color: var(--accent, #e056a0);
}

/* Glow twin: two blurred copies of the number, a tight hot core and a wide
   soft bloom. Both scale their blur and opacity with --okd-glow. */
.okd-counter-glow {
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none; user-select: none;
    color: var(--okd-glow-hue);
}
.okd-counter-glow::before,
.okd-counter-glow::after {
    content: attr(data-text);
    position: absolute; left: 0; right: 0; top: 0;
    white-space: nowrap;
}
.okd-counter-glow::before {
    filter: blur(calc(2px + 6px * var(--okd-glow)));
    opacity: calc(0.15 + 0.55 * var(--okd-glow));
}
.okd-counter-glow::after {
    filter: blur(calc(10px + 30px * var(--okd-glow)));
    opacity: calc(0.05 + 0.8 * var(--okd-glow));
}

/* Impact pop. Peak scale comes from --okd-pop so a $10 send nudges and a
   $120 send thumps, with a small undershoot on the way back so it settles
   like something with weight. */
.okd-counter-num.okd-pop {
    animation: okd-bump var(--okd-pop-ms, 380ms) cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes okd-bump {
    0%   { transform: scale(1); }
    32%  { transform: scale(var(--okd-pop, 1.12)); }
    64%  { transform: scale(calc(1 - (var(--okd-pop, 1.12) - 1) * 0.22)); }
    100% { transform: scale(1); }
}

/* Heartbeat pulse once the total gets serious. Quicker and a touch bigger at
   rainbow. Lives on the stage so a pop never interrupts it. */
.okd-counter[data-tier="3"] .okd-counter-stage { animation: okd-pulse 1.6s ease-in-out infinite; }
.okd-counter.okd-rainbow .okd-counter-stage { animation: okd-pulse-big 1.25s ease-in-out infinite; }
@keyframes okd-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.03); } }
@keyframes okd-pulse-big { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }

/* Tier-up ripple: a ring the size of the number that blooms out and fades. */
.okd-counter-halo {
    --okd-halo: #ff7ac8;
    position: absolute; border-radius: 999px; pointer-events: none;
    opacity: 0; z-index: 2;
    box-shadow: 0 0 0 2px var(--okd-halo), 0 0 28px var(--okd-halo), inset 0 0 28px var(--okd-halo);
}
.okd-counter-halo.okd-halo-go { animation: okd-halo 0.8s cubic-bezier(0.16, 0.8, 0.3, 1) both; }
@keyframes okd-halo {
    0%   { transform: scale(0.75); opacity: 0; }
    14%  { opacity: 0.9; }
    100% { transform: scale(1.9); opacity: 0; }
}

/* Floating "+$10.00" chips. Rise distance and size are set inline by amount. */
.okd-counter-delta {
    --rise: 70px;
    position: absolute; z-index: 4;
    transform: translate(-50%, -50%);
    font-weight: 800; white-space: nowrap; pointer-events: none; user-select: none;
    font-variant-numeric: tabular-nums;
    color: var(--accent, #e056a0);
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
    animation: okd-delta 1.05s cubic-bezier(0.18, 0.7, 0.2, 1) both;
}
@keyframes okd-delta {
    0%   { transform: translate(-50%, -30%) scale(0.6); opacity: 0; }
    16%  { transform: translate(-50%, -60%) scale(1.12); opacity: 1; }
    30%  { transform: translate(-50%, -70%) scale(1); opacity: 1; }
    100% { transform: translate(-50%, calc(-50% - var(--rise))) scale(0.94); opacity: 0; }
}

/* Rainbow tier. The value and both glow twins carry the same sliding
   gradient, started together so they stay in step. The glow color is a warm
   white so the bloom reads as light, not as more pink. */
.okd-counter.okd-rainbow { --okd-glow-hue: #fff0fa; }
.okd-counter.okd-rainbow .okd-counter-value,
.okd-counter.okd-rainbow .okd-counter-glow::before,
.okd-counter.okd-rainbow .okd-counter-glow::after,
.okd-counter-delta--rainbow {
    color: transparent !important;
    background: linear-gradient(100deg,
        #ff5f6d 0%, #ffb457 16%, #f9f871 30%, #7dffb0 46%,
        #6fd6ff 60%, #b58bff 76%, #ff6fd8 90%, #ff5f6d 100%);
    background-size: 400% 100%;
    -webkit-background-clip: text; background-clip: text;
    animation: okd-rainbow 5s linear infinite;
}
.okd-counter-delta--rainbow { text-shadow: none; animation: okd-delta 1.05s cubic-bezier(0.18, 0.7, 0.2, 1) both, okd-rainbow 5s linear infinite; }
@keyframes okd-rainbow { to { background-position: 400% 0; } }

/* Reduced motion: no pop, no pulse, no ripple, no sliding rainbow. The
   number and color still change (with a soft color fade), the glow still
   sits at its tier level, and the chip just fades in place. counter.js also
   sets the number instantly instead of rolling it. */
@media (prefers-reduced-motion: reduce) {
    .okd-counter-num.okd-pop,
    .okd-counter[data-tier="3"] .okd-counter-stage,
    .okd-counter.okd-rainbow .okd-counter-stage,
    .okd-counter-halo.okd-halo-go,
    .okd-counter.okd-rainbow .okd-counter-value,
    .okd-counter.okd-rainbow .okd-counter-glow::before,
    .okd-counter.okd-rainbow .okd-counter-glow::after { animation: none !important; }
    .okd-counter-value { transition: color 0.5s ease; }
    .okd-counter-delta,
    .okd-counter-delta--rainbow { animation: okd-delta-calm 0.9s ease both; }
}
@keyframes okd-delta-calm {
    0%   { transform: translate(-50%, -80%); opacity: 0; }
    25%  { opacity: 1; }
    100% { transform: translate(-50%, -80%); opacity: 0; }
}

/* Slideshow columns */
.okd-slide-col { position: relative; width: 100%; height: 100%; overflow: hidden; background: #0b0810; }
.okd-slide-layer {
    position: absolute; inset: 0; background-size: cover; background-position: center;
    opacity: 0; transition: opacity 1.1s ease;
}
.okd-slide-layer.okd-show { opacity: 1; }
/* Beta protection: upscale the tiny censored data-URL into crisp mosaic blocks. */
.okd-slide-layer.okd-pixelated { image-rendering: pixelated; image-rendering: crisp-edges; }
.okd-beta-hint { display: block; margin-top: 3px; font-size: 11px; line-height: 1.35; opacity: 0.6; }
@media (prefers-reduced-motion: reduce) { .okd-slide-layer { transition: opacity 0.3s ease; } }

/* ---- Trigger entrance (ui.js) --------------------------------------- */
/* The heart beats slowly at rest and quickens on hover so the button reads
   as alive before anyone clicks it. */
.okd-trigger-heart { display: inline-block; line-height: 1; transform-origin: 50% 55%; animation: okd-heartbeat 2.4s ease-in-out infinite; }
.okd-trigger:hover .okd-trigger-heart { animation-duration: 0.9s; }
@keyframes okd-heartbeat {
    0%, 100% { transform: scale(1); }
    14% { transform: scale(1.18); }
    28% { transform: scale(1); }
    42% { transform: scale(1.12); }
    56% { transform: scale(1); }
}
/* When main.js unhides it, it slides in from the right edge of the topbar. */
.okd-trigger:not(.okd-hidden) { animation: okd-trigger-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) backwards; }
@keyframes okd-trigger-in {
    from { opacity: 0; transform: translateX(10px) scale(0.94); }
    to   { opacity: 1; transform: none; }
}

/* ---- Setup modal (ui.js) -------------------------------------------- */
/* z-index 300: above the wishlist checkout modal (200), and far below a
   Stripe 3D Secure challenge, which renders at the very top of the stack. */
.okd-modal-overlay {
    position: fixed; inset: 0; z-index: 300;
    display: flex; align-items: center; justify-content: center; padding: 20px;
    background: rgba(5, 5, 8, 0.75); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
    animation: okd-fade-in 0.2s ease both;
}
.okd-modal {
    position: relative;
    background: var(--panel, #1a1420); border: 1px solid var(--border, #3a2c40);
    border-radius: 14px; padding: 22px; width: 100%; max-width: 440px;
    max-height: 88vh; overflow-y: auto;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(224, 86, 160, 0.08);
    animation: okd-slideup 0.28s cubic-bezier(0.22, 1, 0.36, 1) both;
}
/* Soft accent glow along the top edge, so the card feels lit rather than flat. */
.okd-modal::before {
    content: ""; position: absolute; left: 10%; right: 10%; top: -1px; height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent, #e056a0), transparent);
    opacity: 0.7; pointer-events: none;
}
@keyframes okd-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes okd-slideup {
    from { opacity: 0; transform: translateY(18px) scale(0.97); }
    to   { opacity: 1; transform: none; }
}
/* Exit: the overlay fades and the card drops back down a touch. */
.okd-modal-overlay.okd-out { animation: okd-fade-out 0.22s ease both; pointer-events: none; }
.okd-modal-overlay.okd-out .okd-modal { animation: okd-slidedown 0.22s ease-in both; }
@keyframes okd-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes okd-slidedown { to { opacity: 0; transform: translateY(10px) scale(0.98); } }

/* Fields settle in one after another (--okd-i is set by ui.js). */
.okd-modal .okd-cardline, .okd-modal .okd-field, .okd-modal .okd-check, .okd-modal .okd-row,
.okd-modal .okd-note, .okd-modal .okd-start, .okd-modal .okd-x2, .okd-modal .okd-hint {
    animation: okd-rise 0.36s cubic-bezier(0.22, 1, 0.36, 1) backwards;
    animation-delay: calc(60ms + var(--okd-i, 0) * 45ms);
}
.okd-modal .okd-row .okd-field { animation: none; }
/* Transform only on purpose: if the animation never runs or never finishes
   (reduced motion, a throttled tab, an odd browser) opacity is not touched, so
   the text can never be left invisible. */
@keyframes okd-rise { from { transform: translateY(8px); } to { transform: none; } }

.okd-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.okd-modal-head h3 { margin: 0; font-size: 16px; color: var(--text, #f0e8f0); }
.okd-x, .okd-x2 {
    background: var(--panel2, #241a2c); border: 1px solid var(--border, #3a2c40);
    color: var(--muted, #9a8aa0); border-radius: 8px; cursor: pointer; font-family: inherit;
    transition: color 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
}
.okd-x { width: 28px; height: 28px; font-size: 15px; line-height: 1; display: grid; place-items: center; }
.okd-x:hover { color: #ff5f6d; border-color: #ff5f6d; transform: rotate(90deg); }

.okd-cardline {
    display: flex; align-items: center; gap: 8px;
    font-size: 12px; color: var(--muted, #9a8aa0); margin-bottom: 14px;
    padding: 8px 10px; border-radius: 8px;
    background: rgba(224, 86, 160, 0.06); border: 1px dashed rgba(224, 86, 160, 0.3);
}
.okd-cardline-dot {
    width: 7px; height: 7px; border-radius: 50%; background: var(--accent, #e056a0);
    box-shadow: 0 0 0 0 rgba(224, 86, 160, 0.5); animation: okd-dot-ping 2s ease-out infinite;
}
@keyframes okd-dot-ping { 0% { box-shadow: 0 0 0 0 rgba(224, 86, 160, 0.5); } 100% { box-shadow: 0 0 0 8px rgba(224, 86, 160, 0); } }

.okd-field { display: block; font-size: 12px; color: var(--muted, #9a8aa0); margin-bottom: 12px; transition: opacity 0.2s ease; }
.okd-field--dim { opacity: 0.45; }
.okd-select, .okd-input {
    width: 100%; margin-top: 5px; box-sizing: border-box;
    background: var(--panel2, #241a2c); border: 1px solid var(--border, #3a2c40);
    border-radius: 8px; color: var(--text, #f0e8f0); padding: 9px 12px;
    font-family: inherit; font-size: 13px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.okd-select:focus, .okd-input:focus { outline: none; border-color: var(--accent, #e056a0); box-shadow: 0 0 0 3px rgba(224, 86, 160, 0.18); }
.okd-select:disabled { cursor: not-allowed; }
.okd-row { display: flex; gap: 10px; }
.okd-half { flex: 1; min-width: 0; }
.okd-check {
    display: flex; gap: 8px; align-items: flex-start; font-size: 12px;
    color: var(--text, #f0e8f0); margin-bottom: 12px; cursor: pointer;
}
.okd-check input { accent-color: var(--accent, #e056a0); margin: 1px 0 0; flex: none; }
.okd-ack {
    background: var(--panel2, #241a2c); border: 1px solid var(--border, #3a2c40);
    border-radius: 8px; padding: 10px; line-height: 1.4;
    transition: border-color 0.2s ease, background 0.2s ease;
}
.okd-ack:hover { border-color: var(--accent-dim, #a03870); }
.okd-ack:has(input:checked) { border-color: var(--accent, #e056a0); background: rgba(224, 86, 160, 0.08); }
.okd-note { color: var(--muted, #9a8aa0); font-size: 13px; line-height: 1.5; margin: 0 0 14px; }
.okd-hint { color: var(--muted, #9a8aa0); font-size: 11px; text-align: center; margin: 10px 0 0; opacity: 0.8; }
.okd-pool-hint { color: var(--accent, #e056a0); font-size: 10px; text-align: center; margin: 6px 0 0; opacity: 0.85; min-height: 14px; word-break: break-word; }
.okd-start, .okd-x2 {
    width: 100%; padding: 13px; border-radius: 8px; border: none;
    background: var(--accent, #e056a0); color: #1a0a12; font-weight: 800; font-size: 15px;
    cursor: pointer; font-family: inherit; margin-top: 4px;
    transition: opacity 0.2s ease, transform 0.12s ease, box-shadow 0.25s ease, filter 0.2s ease;
}
.okd-start:hover, .okd-x2:hover { filter: brightness(1.06); }
.okd-start:active, .okd-x2:active { transform: scale(0.98); }
.okd-start:disabled { opacity: 0.45; cursor: not-allowed; transform: none; filter: none; }
/* Once everything is ticked the button glows so the next step is obvious. */
.okd-modal .okd-start.okd-start--ready {
    box-shadow: 0 6px 24px rgba(224, 86, 160, 0.45);
    animation: okd-rise 0.36s cubic-bezier(0.22, 1, 0.36, 1) backwards, okd-ready 1.8s ease-in-out infinite;
    animation-delay: calc(60ms + var(--okd-i, 0) * 45ms), 0ms;
}
@keyframes okd-ready {
    0%, 100% { box-shadow: 0 6px 22px rgba(224, 86, 160, 0.35); }
    50%      { box-shadow: 0 8px 32px rgba(224, 86, 160, 0.6); }
}

/* Exceptions panel — shown when "surprise me" is checked */
.okd-except-wrap {
    margin-bottom: 12px; margin-left: 24px;
    background: rgba(224, 86, 160, 0.05);
    border: 1px solid rgba(224, 86, 160, 0.2);
    border-radius: 8px; padding: 10px 12px;
    animation: okd-rise 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.okd-except-header {
    font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px;
    color: var(--muted, #9a8aa0); font-weight: 700; margin-bottom: 8px;
}
.okd-except-list {
    display: flex; flex-direction: column; gap: 4px;
    max-height: 150px; overflow-y: auto;
}
.okd-except-list::-webkit-scrollbar { width: 4px; }
.okd-except-list::-webkit-scrollbar-track { background: transparent; }
.okd-except-list::-webkit-scrollbar-thumb { background: var(--border, #3a2c40); border-radius: 4px; }
.okd-except-item {
    display: flex; align-items: center; gap: 8px;
    font-size: 12px; color: var(--text, #f0e8f0); cursor: pointer;
    padding: 4px 6px; border-radius: 6px;
    transition: background 0.12s ease;
}
.okd-except-item:hover { background: rgba(224, 86, 160, 0.1); }
.okd-except-item input[type="checkbox"] { accent-color: var(--accent, #e056a0); flex: none; cursor: pointer; }
.okd-except-price {
    color: var(--muted, #9a8aa0); font-size: 11px; margin-left: 5px;
}
.okd-except-err {
    color: #ff5f6d; font-size: 11px; margin: 6px 0 0; padding: 0;
}

/* Inline add-card form (signed in, no card yet). Stripe renders its own
   iframe inside #okdCardMount, so the container just gets the same box look
   as .okd-select and lets the field fill it. */
#okdCardMount {
    box-sizing: border-box; min-height: 44px; margin: 0 0 12px;
    background: var(--panel2, #241a2c); border: 1px solid var(--border, #3a2c40);
    border-radius: 8px; padding: 12px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
#okdCardMount:focus-within { border-color: var(--accent, #e056a0); box-shadow: 0 0 0 3px rgba(224, 86, 160, 0.18); }
.okd-carderr, #okdCardErr {
    color: #ff5f6d; font-size: 12px; line-height: 1.4; margin: 0 0 10px; min-height: 0;
}
.okd-carderr:empty, #okdCardErr:empty { display: none; }
/* Quiet secondary button under "save card". */
.okd-modal .okd-x2.okd-cancel {
    background: transparent; border: 1px solid var(--border, #3a2c40);
    color: var(--muted, #9a8aa0); font-weight: 600; font-size: 13px; padding: 10px; margin-top: 8px;
}
.okd-modal .okd-x2.okd-cancel:hover { color: var(--text, #f0e8f0); border-color: var(--accent-dim, #a03870); filter: none; }

/* ---- Immersive stage (ui.js) ---------------------------------------- */
/* z-index 250: above the page and the checkout modal, below the setup modal
   (300) and far below a Stripe 3D Secure challenge. Never raise it above a
   Stripe popup. The popup card is a child of this layer (its own z-index is
   only relative to the backdrop), so it can never climb above one either. */
.okd-immersive {
    position: fixed; inset: 0; z-index: 250;
    background: #06040a; color: var(--text, #f0e8f0);
    opacity: 0; transition: opacity 0.45s ease;
}
.okd-immersive.okd-in { opacity: 1; }
.okd-immersive.okd-out { opacity: 0; transition: opacity 0.4s ease; pointer-events: none; }

/* Backdrop: two slideshow columns splitting the viewport. They are meant to
   be looked at, so the only darkening is the light scrim below and a very
   soft feather where the two columns meet. */
.okd-backdrop {
    position: absolute; inset: 0; z-index: 1;
    display: grid; grid-template-columns: 1fr 1fr;
}
.okd-col {
    height: 100vh; height: 100dvh; overflow: hidden; position: relative; min-width: 0;
    opacity: 0; transition: opacity 0.7s ease 0.1s, transform 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.1s;
}
.okd-col-left  { transform: translateX(-4%); }
.okd-col-right { transform: translateX(4%); }
.okd-immersive.okd-in .okd-col { opacity: 1; transform: none; }
.okd-col::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
}
.okd-col-left::after  { background: linear-gradient(90deg, transparent 82%, rgba(6, 4, 10, 0.35) 100%); }
.okd-col-right::after { background: linear-gradient(270deg, transparent 82%, rgba(6, 4, 10, 0.35) 100%); }

/* Light scrim: enough for the card and its glow to read, not enough to hide
   the art. A touch darker right behind the card so the text has contrast. */
.okd-scrim {
    position: absolute; inset: 0; pointer-events: none; z-index: 2;
    background:
        radial-gradient(ellipse 34% 46% at 50% 50%, rgba(6, 4, 10, 0.34), transparent 100%),
        rgba(6, 4, 10, 0.18);
}

/* The popup card, centered in the viewport. */
.okd-popup-wrap {
    position: absolute; inset: 0; z-index: 3;
    display: flex; align-items: center; justify-content: center;
    padding: 20px; pointer-events: none;
}
.okd-popup {
    pointer-events: auto;
    position: relative;
    width: 100%; max-width: 360px; box-sizing: border-box;
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    padding: 18px 20px 16px; text-align: center;
    background: color-mix(in srgb, var(--panel, #1a1420) 84%, transparent);
    border: 1px solid var(--border, #3a2c40); border-radius: 16px;
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(224, 86, 160, 0.1), 0 0 48px rgba(224, 86, 160, 0.12);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    overflow: visible; /* particles and the tier halo are allowed to spill out */
    opacity: 0; transform: translateY(14px) scale(0.97);
    transition: opacity 0.5s ease 0.2s, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.2s;
}
@supports not (background: color-mix(in srgb, #000 50%, transparent)) {
    .okd-popup { background: rgba(26, 20, 32, 0.86); }
}
/* Same lit top edge as the setup modal so the two feel like one family. */
.okd-popup::before {
    content: ""; position: absolute; left: 12%; right: 12%; top: -1px; height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent, #e056a0), transparent);
    opacity: 0.7; pointer-events: none;
}
.okd-immersive.okd-in .okd-popup { opacity: 1; transform: none; }
.okd-center-mount { width: 100%; min-width: 0; }
.okd-status { color: var(--muted, #9a8aa0); font-size: 13px; letter-spacing: 0.5px; min-height: 18px; }
.okd-message {
    color: var(--text, #f0e8f0); font-size: 13px; min-height: 18px; max-width: 34ch;
    line-height: 1.4; opacity: 0.88;
}
.okd-message--swap { animation: okd-msg-swap 0.4s ease both; }
@keyframes okd-msg-swap {
    from { opacity: 0; transform: translateY(5px); }
    to   { opacity: 0.88; transform: none; }
}
.okd-tally {
    font-size: 12px; color: var(--muted, #9a8aa0); letter-spacing: 0.4px;
    font-variant-numeric: tabular-nums;
}

/* Next-send bar. The fill width is driven inline by ui.js so it always
   matches the real delay; CSS only owns the look and the sending shimmer. */
.okd-next { width: 100%; }
.okd-next-label {
    font-size: 11px; color: var(--muted, #9a8aa0); letter-spacing: 0.6px;
    text-transform: lowercase; margin-bottom: 5px; min-height: 13px;
    transition: color 0.3s ease;
}
.okd-next--sending .okd-next-label { color: var(--accent, #e056a0); }
.okd-next-track {
    position: relative; height: 4px; border-radius: 4px; overflow: hidden;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.05);
}
.okd-next-fill {
    position: absolute; left: 0; top: 0; bottom: 0; width: 0;
    border-radius: 4px;
    background: linear-gradient(90deg, var(--accent-dim, #a03870), var(--accent, #e056a0));
    box-shadow: 0 0 10px rgba(224, 86, 160, 0.45);
    transition: opacity 0.2s ease;
}
/* Sending: the fill fades back and a soft band sweeps the track. */
.okd-next--sending .okd-next-fill { opacity: 0.35; }
.okd-next--idle .okd-next-fill { opacity: 0; }
.okd-next-track::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%;
    border-radius: 4px; opacity: 0; pointer-events: none;
    background: linear-gradient(90deg, transparent, rgba(255, 190, 230, 0.75), transparent);
}
.okd-next--sending .okd-next-track::after { opacity: 1; animation: okd-next-sweep 1.1s ease-in-out infinite; }
@keyframes okd-next-sweep {
    from { transform: translateX(-100%); }
    to   { transform: translateX(250%); }
}

/* Stop is always visible. Outline red with a slow breathing dot so it never
   disappears into the scene, and it fills in on hover. */
.okd-stop {
    display: inline-flex; align-items: center; gap: 9px;
    margin-top: 4px; background: rgba(6, 4, 10, 0.55); color: #ff9db0;
    border: 1px solid #ff5f6d; border-radius: 30px; padding: 9px 24px;
    font-weight: 700; font-size: 14px; cursor: pointer; font-family: inherit;
    transition: background 0.15s ease, color 0.15s ease, transform 0.12s ease, box-shadow 0.2s ease;
}
.okd-stop:hover { background: rgba(255, 95, 109, 0.18); color: #ffd3da; box-shadow: 0 0 22px rgba(255, 95, 109, 0.3); transform: translateY(-1px); }
.okd-stop:active { transform: scale(0.97); }
.okd-stop:focus-visible { outline: 2px solid #ff9db0; outline-offset: 3px; }
.okd-stop-dot {
    width: 8px; height: 8px; border-radius: 50%; background: #ff5f6d;
    animation: okd-stop-breathe 2.2s ease-in-out infinite;
}
@keyframes okd-stop-breathe { 0%, 100% { opacity: 0.55; transform: scale(0.9); } 50% { opacity: 1; transform: scale(1.1); } }
.okd-esc-hint { font-size: 11px; color: var(--muted, #9a8aa0); opacity: 0.6; margin-top: -4px; }

/* Narrow screens: one column fills the whole backdrop, card hugs the edges. */
@media (max-width: 820px) {
    .okd-backdrop { grid-template-columns: 1fr; }
    .okd-col-right { display: none; }
    .okd-popup-wrap { padding: 14px; }
    .okd-popup { padding: 16px 14px 14px; }
}
@media (hover: none) {
    .okd-esc-hint { display: none; }
}

/* ── Wheel of fortune ─────────────────────────────────────────────────── */
.okd-wheel-mount { padding: 2px 0 0; }
.okd-wheel-wrap {
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    position: relative;
}
.okd-wheel-ptr {
    width: 0; height: 0;
    border-left: 9px solid transparent;
    border-right: 9px solid transparent;
    border-top: 15px solid #fff;
    filter: drop-shadow(0 2px 5px rgba(224,86,160,0.7));
}
.okd-wheel-canvas {
    display: block; border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 0 22px rgba(224,86,160,0.35), 0 6px 18px rgba(0,0,0,0.55);
    transition: box-shadow 0.2s ease;
}
.okd-wheel-canvas:hover {
    box-shadow: 0 0 32px rgba(224,86,160,0.55), 0 6px 18px rgba(0,0,0,0.55);
}
.okd-wheel-tagline {
    font-size: 11px; color: var(--accent, #e056a0);
    text-align: center; letter-spacing: 0.2px; opacity: 0.9;
    font-style: italic; margin-bottom: 3px;
}
.okd-wheel-hint {
    font-size: 10px; color: var(--muted, #9a8aa0);
    text-align: center; min-height: 14px; letter-spacing: 0.3px;
}

/* ── Wheel win toast ─────────────────────────────────────────────────── */
.okd-wheel-win {
    position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -60%) scale(0.88);
    background: linear-gradient(140deg, #2e1020 0%, #1a0a14 100%);
    border: 1px solid rgba(224,86,160,0.55);
    border-radius: 20px; padding: 22px 32px;
    text-align: center; z-index: 8;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.32s ease, transform 0.38s cubic-bezier(0.34, 1.56, 0.64, 1);
    box-shadow: 0 12px 40px rgba(224,86,160,0.28), 0 2px 10px rgba(0,0,0,0.7);
    min-width: 220px;
}
.okd-wheel-win--in {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}
.okd-wheel-win-title {
    font-size: 17px; font-weight: 700; color: #fff;
    margin-bottom: 8px; letter-spacing: 0.2px;
}
.okd-wheel-win-body {
    font-size: 13px; color: var(--muted, #9a8aa0); line-height: 1.6;
}
.okd-wheel-win-body strong { color: var(--accent, #e056a0); }

/* Setup modal: wheel-of-fortune checkbox is slightly indented + dimmed label */
.okd-check.okd-wheel-check { margin-bottom: 2px; }

/* Make popup card scrollable on short viewports */
.okd-popup { max-height: calc(100dvh - 40px); overflow-y: auto; }

/* Reduced motion: instant show and hide, no stagger, no slide, no glow
   pulse, no heartbeat, no sending shimmer. The next-send fill still moves
   because it is the countdown itself, not decoration. Colors and layout are
   untouched. */
@media (prefers-reduced-motion: reduce) {
    .okd-trigger:not(.okd-hidden), .okd-trigger-heart,
    .okd-modal-overlay, .okd-modal, .okd-modal-overlay.okd-out, .okd-modal-overlay.okd-out .okd-modal,
    .okd-modal .okd-cardline, .okd-modal .okd-field, .okd-modal .okd-check, .okd-modal .okd-row,
    .okd-modal .okd-note, .okd-modal .okd-start, .okd-modal .okd-x2, .okd-modal .okd-hint, .okd-modal .okd-pool-hint,
    .okd-cardline-dot, .okd-modal .okd-start.okd-start--ready, .okd-message--swap, .okd-stop-dot,
    .okd-next--sending .okd-next-track::after { animation: none !important; }
    .okd-next--sending .okd-next-track::after { opacity: 0; }
    .okd-next--sending .okd-next-fill { opacity: 1; }
    .okd-immersive, .okd-col, .okd-popup, .okd-x, .okd-stop, .okd-next-label,
    .okd-wheel-win { transition: none !important; }
    .okd-col-left, .okd-col-right { transform: none; opacity: 1; }
    .okd-popup { opacity: 1; transform: none; }
    .okd-x:hover { transform: none; }
}
