/**
 * CardCom OpenFields - modern Stripe-like payment card.
 * EastVisa design tokens, RTL, dark mode, mobile bottom-sheet.
 */

/* ------ Tokens (with sensible fallbacks) ------ */
.vf-of-card {
    --vf-of-primary:    var(--ev-primary, #2036A4);
    --vf-of-secondary:  var(--ev-secondary, #8C95FF);
    --vf-of-success:    var(--ev-success, #16a34a);
    --vf-of-danger:     var(--ev-danger,  #dc2626);
    /* Text on --vf-of-danger's pale background: the design system's error pair (Phase 3) */
    --vf-of-danger-text: var(--ev-danger-text, #A02533);
    /* The site's focus colour, 6.47:1 on white (Phase 3, UX 11.1) */
    --vf-of-focus:      var(--evn-focus, #1B5DB1);
    --vf-of-bg:         #ffffff;
    --vf-of-text:       #0f172a;
    --vf-of-muted:      #64748b;
    --vf-of-border:     #e5e7eb;
    --vf-of-border-strong: #cbd5e1;
    --vf-of-bg-soft:    #f8fafc;
    --vf-of-shadow-sm:  0 1px 2px rgba(15, 23, 42, 0.06);
    --vf-of-shadow-md:  0 4px 12px rgba(15, 23, 42, 0.08), 0 1px 3px rgba(15, 23, 42, 0.04);
    --vf-of-shadow-lg:  0 20px 60px rgba(15, 23, 42, 0.12), 0 6px 16px rgba(15, 23, 42, 0.06);
    --vf-of-focus-ring: 0 0 0 4px rgba(140, 149, 255, 0.22);
}

html[data-theme="dark"] .vf-of-card {
    --vf-of-bg:         #0f172a;
    --vf-of-text:       #f1f5f9;
    --vf-of-muted:      #94a3b8;
    --vf-of-border:     #1e293b;
    --vf-of-border-strong: #334155;
    --vf-of-bg-soft:    #1e293b;
    --vf-of-shadow-sm:  none;
    --vf-of-shadow-md:  0 4px 12px rgba(0, 0, 0, 0.4);
    --vf-of-shadow-lg:  0 20px 60px rgba(0, 0, 0, 0.6);
}

/* ------ Card container ------ */
.vf-of-card {
    max-width: 520px;
    margin: 24px auto;
    padding: 28px 28px 24px;
    background: var(--vf-of-bg);
    color: var(--vf-of-text);
    border: 1px solid var(--vf-of-border);
    border-radius: 16px;
    box-shadow: var(--vf-of-shadow-md);
    font-family: 'Rubik', system-ui, -apple-system, sans-serif;
    direction: rtl;
    box-sizing: border-box;
}

/* Backdrop is invisible on desktop; only shows in mobile bottom-sheet mode. */
.vf-of-backdrop {
    display: none;
    appearance: none;
    background: transparent;
    border: 0;
    cursor: pointer;
}

/* ------ Header ------ */
.vf-of-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 14px;
}

.vf-of-card-head-title {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--vf-of-text);
    letter-spacing: -0.01em;
}

.vf-of-card-head-amount {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--vf-of-primary);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

/* ------ Security + brands row ------ */
.vf-of-badges {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 22px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--vf-of-border);
}

.vf-of-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: var(--vf-of-muted);
    line-height: 1;
}

.vf-of-badge svg {
    color: var(--vf-of-success);
    flex-shrink: 0;
}

.vf-of-brands {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.vf-of-brand {
    width: 32px;
    height: 20px;
    border-radius: 3px;
    transition: transform 0.15s ease, filter 0.15s ease;
}

.vf-of-brand:hover {
    transform: translateY(-1px);
}

/* ------ Form ------ */
.vf-of-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.vf-of-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.vf-of-field label {
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--vf-of-text);
    letter-spacing: 0.01em;
}

.vf-of-field input[type="text"] {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    border: 1px solid var(--vf-of-border-strong);
    border-radius: 10px;
    background: var(--vf-of-bg);
    color: var(--vf-of-text);
    font-family: inherit;
    /* MUST be >= 16px to prevent iOS Safari auto-zoom on focus.
       Using px (not rem) because the parent's root font-size may be
       smaller than 16px, making `1rem` insufficient on some themes. */
    font-size: 16px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    box-sizing: border-box;
    box-shadow: var(--vf-of-shadow-sm);
}

.vf-of-field input[type="text"]:hover {
    border-color: #94a3b8;
}

.vf-of-field input[type="text"]:focus,
.vf-of-field input[type="text"]:focus-visible {
    outline: none;
    border-color: var(--vf-of-primary);
    box-shadow: var(--vf-of-focus-ring);
}

.vf-of-field-error {
    font-size: 0.78rem;
    color: var(--vf-of-danger);
    margin-top: 2px;
    line-height: 1.4;
}

/* Card number iframe sits where input would */
.vf-of-field--card iframe {
    width: 100%;
    height: 46px;
    border: 0;
    display: block;
    border-radius: 10px;
    overflow: hidden;
}

/* Two-column row (default — used elsewhere) */
.vf-of-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

/* Three-column row for expiration (month + year + CVV).
   Month/year inputs need less width than the CVV iframe. */
.vf-of-row--exp {
    grid-template-columns: 1fr 1fr 1.4fr;
    gap: 10px;
}

.vf-of-field--cvv iframe {
    width: 100%;
    height: 46px;
    border: 0;
    display: block;
    border-radius: 10px;
    overflow: hidden;
}

/* Center MM/YY inputs since they're short numbers in narrow columns.
   Targets only inputs inside the exp row to avoid affecting cardholder ID. */
.vf-of-row--exp .vf-of-field input[type="text"] {
    text-align: center;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.1em;
}

/* ------ Digital wallets (Apple Pay, Google Pay) ------
   The buttons live inside CardCom iframes and are styled by Apple/Google; we
   own only the slot and the "or pay by card" separator under them. Hidden until
   CardCom confirm the browser can pay, so nothing reserves space on a device
   with no wallet. */
.vf-of-wallets {
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* The sheet is a flex column inside a max-height scroll container, so on a
       short viewport the browser will happily shrink its items to fit — which
       drops the frame below the button's height floor and clips it along the
       bottom. Nothing in this row may shrink. */
    flex-shrink: 0;
}

.vf-of-wallets[hidden] {
    display: none;
}

/* One wrapper per wallet, shown independently: a browser may offer Apple Pay
   and not Google Pay, or the reverse, and neither should leave a hole. */
.vf-of-wallet {
    flex-shrink: 0;
}

.vf-of-wallet[hidden] {
    display: none;
}

/* Height comes inline from WALLET_BTN_HEIGHT; the cap here stops the button
   stretching the full sheet width on desktop, where a 520px express button
   looks off next to 46px inputs.

   background/border are forced off: the button paints its own rounded shape, so
   any backdrop on the frame shows up as a square block behind it. The embedded
   document declares no background, so an opaque box can only come from a theme
   rule like `iframe { background:#fff }` — hence !important. */
.vf-of-wallets iframe {
    display: block;
    max-width: 320px;
    margin: 0 auto;
    flex: 0 0 auto;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    outline: 0 !important;
}

/* Holds the payment buttons; the "or pay by card" separator is its sibling.
   Stacked full-width by default, turned into a side-by-side row by --compact. */
.vf-of-wallets-row {
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex-shrink: 0;
}

/* The Bit button can be narrower than the wallet frames, so the wrapper centres
   it explicitly rather than relying on the button's own `margin: 0 auto`, which
   does nothing once the button stops being full-width. */
.vf-of-wallet--bit {
    display: flex;
    justify-content: center;
}

/* ---- Compact row: Apple Pay, Google Pay and Bit side by side ----

   Applied only when Bit is in the row (it is the reason the row exists).

   `flex: 1 1 152px` — equal tiles, and the 152 is not a taste call. CardCom
   force Google's button to width:100% inside a #GooglePayDiv that carries
   overflow:hidden, so once a tile drops under the button's own minimum the
   button stops shrinking and its rounded ends are cut off instead. 152 is
   Google's published minimum, so it never reaches that point.

   The consequence is honest arithmetic: three 152px tiles plus two 4px gaps
   need 464px, which a phone does not have. So on a phone the row wraps — two
   tiles on the first line, one centred below, all still equal and none clipped.
   In the ordinary case a browser offers Apple Pay or Google Pay but not both,
   which means two tiles and a single line everywhere. */
.vf-of-wallets--compact .vf-of-wallets-row {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;
    /* 4, not 8: three tiles at Google's minimum only fit if the gaps give the
       width back. */
    gap: 4px;
}

.vf-of-wallets--compact .vf-of-wallet {
    flex: 1 1 152px;
    /* Keeps a lone tile from stretching the full sheet width, which would undo
       the point of the compact row. */
    max-width: 220px;
    height: 48px;
}

.vf-of-wallets--compact .vf-of-wallet--bit {
    width: auto;
}

/* Overrides the 320px cap from the stacked layout: here the tile decides the
   width and the frame fills it. */
.vf-of-wallets--compact iframe {
    max-width: 100%;
    width: 100% !important;
}

/* ---- Bit button ----

   Not a wallet frame — a real button that navigates, since Bit has no Open
   Fields module. It copies the wallet geometry exactly: 48px tall
   (WALLET_BTN_HEIGHT in the JS — change both together), pill radius, same cap.

   !important throughout: themes style bare `button` elements globally, often at
   higher specificity than a single class (`.entry-content button`, `#page
   button`) and sometimes with !important of their own. Without this the theme's
   primary-button look paints straight over this button. The CardCom iframes
   above carry !important for exactly the same reason. */
.vf-of-bit-btn {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 7px !important;
    width: 100% !important;
    max-width: 320px !important;
    min-width: 0 !important;
    height: 48px !important;
    min-height: 0 !important;
    margin: 0 auto !important;
    padding: 0 18px !important;
    border: 1px solid #cbd5e1 !important;
    border-radius: 24px !important;
    background: #fff !important;
    background-image: none !important;
    color: #0f172a !important;
    font-family: inherit !important;
    font-size: 0.95rem !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    text-decoration: none !important;
    box-shadow: none !important;
    cursor: pointer;
    -webkit-appearance: none !important;
    appearance: none !important;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.vf-of-bit-btn:hover {
    background: #f8fafc !important;
    background-image: none !important;
    border-color: #94a3b8 !important;
    color: #0f172a !important;
}

.vf-of-bit-btn:active {
    background: #f1f5f9 !important;
    background-image: none !important;
}

.vf-of-bit-btn:disabled { opacity: 0.6; cursor: default; }

.vf-of-bit-btn:focus-visible {
    outline: 2px solid #0f172a;
    outline-offset: 2px;
}

/* Bit's own wordmark, inlined so the sheet never depends on a CDN to draw a
   button and no img-src policy can block it. 33x33 source drawn at 26, which
   optically matches the 0.95rem label beside it. */
.vf-of-bit-btn-logo {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMC1jMDAwIDc5LjE3MWMyN2ZhYiwgMjAyMi8wOC8xNi0yMjozNTo0MSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkE1QjU1RTlFMjAyMTFFRkE3OUZDNjQxQzAwRUUxRUQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkE1QjU1RThFMjAyMTFFRkE3OUZDNjQxQzAwRUUxRUQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjMgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QzI0QzE5MTA0MzAwMTFFRDhBOEZENDExQTUwMzAyMkUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QzI0QzE5MTE0MzAwMTFFRDhBOEZENDExQTUwMzAyMkUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7o50nhAAAEeElEQVR42uxYa0xcVRD+9t7l1RV2lwWBLY/yqC2VUkPZalOUFi1iTG0VH02r8RENkdiSBk2MNK1p9IdGFKo1qVWMGKONP8REtL4paW0IrTSpxUJ5tC60rLDAAm6BZXecc70gF1AIyRJ+dJKTe8/s7Pm+PWfmzMzqiAhCdDqdxA9ZHTr4TwSgVwzG9gmFXiUgnkE8gnkEqET8JYKAh8cw444wkTGhFDtgsNlscQ6H40Ov19tHfhSxvsAReAJXxVd+uaWrq6uCFlAEnsAV+Dr1CEzMsEmSpDAskPh8vn5ZllP5tV9SnVBeSAKKD0iSaTwIJCwCuU5i8ZN44eAh3PtMIQbd7lkX2Hf4A+Q+tAMX7R0a/asVH2HLUwXoGxycE5EQHksnxzAy1ourlerON84a77BtUGwrq49p9OacuxX9sVN1//1dxhX4+plYWaOjcMUczbE7ewo592kl2tracc+mbI1+WUwM+mQDIkymWdeYkYQCzURTExOU+eWOTphCb4DRaJxmm5acpIxJlxA6HH9ieHQUWBKCts5OWCMsnK18iI2MnPtxxG95gJCyivYdqaC1O58gLE2kgNVr6ZGiYrra79Js6WP7D5AxLoW6nE5lHpq9mRAWyUd6G2F9NmFlOiE5laALoQdf3Dv34wgM4HSi1+NAUbEyX2LLhLu1DUfLS/HTuUY0VR2FOTRU+exs80W47C34vf0yosLDlV1pcv+FAVmPseFhmK1WXk8Pb3AwH1H03Hdief52/jURFLYui36sP0NjY16q+62RbtyYqzhb4WulE7Z3Fu5mXQh9O8UB1+x4nBBkpNqGs7M65owh6hnjFD/gQtn+EuRkZkCWJay7ORXvvfIyB3Ugvqg5PqlCER7kYxttCcK1guJXelk/v3vC42ES4ZHYeMsajT4rbRUQnwRHb++E7vylS1wVGBhMS0ISJDg1jXg88yNhCuPzdvXC4XJp9APua0C3AzEREcr8y5On4Kg9AZjNIitqbN1erxJmIUFB8yORmbqCi7Bh7C0/pNGXlL0N+dogXt9ViEa7Hdvyt3NJwk48NIRfW1on7OzdPbhQf5qPw4eG5mZF53QNYM9LJWDfmptjNra1ExKWK064+tEnqbj8HcrdtYdgTST9rVmU9fSzBNlAlg2b6AjflIiKp+D0TPrkux/o85pais7JIwQbFb3hjrto95sHKe6+fGW9otKyaY45Iwkh1fWnKf72HDYMILVCJpijCbHJfG8k0baC58g5NKTYPv/uYf488F87g4Xer/6GCt54i+fShH7l1oep/crVaSR0Kolw1nVM3SJRBn//83Fc+MOOwZERmNgBU6wxsKWnIdJi0djWnGnAiZO/sG/IyNucg4wVNyn6z776Gq0tLUhISMDO+7dqEgFHUCw/ev+XhL9lnMT1ombRkaB/MrBvYCGBGc+ltoQkqS+jTqezaiFJ9PT0VKk9qXeiF83Ly1vW3d39MXdibj/3om7GqRR4472oTtwZU7ryQD/7ivg7YFR05TyUrly3GP6f+FuAAQCPltSfTFVgYwAAAABJRU5ErkJggg==");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

/* ---- Artwork mode: a merchant-supplied image replaces the whole button ----
   Everything the element could contribute of its own is switched off, so what
   the customer sees is the artwork and nothing else. overflow:hidden is what
   makes the radius apply to the image too; without it a square-cornered file
   paints straight over the button's rounded edge. */
.vf-of-bit-btn--img {
    width: auto !important;
    max-width: 100% !important;
    min-width: 0 !important;
    height: auto !important;
    padding: 0 !important;
    gap: 0 !important;
    border: 0 !important;
    border-radius: 24px !important;
    background: none !important;
    background-color: transparent !important;
    background-image: none !important;
    box-shadow: none !important;
    overflow: hidden !important;
    line-height: 0 !important;
    font-size: 0 !important;
    -webkit-tap-highlight-color: transparent;
}

/* Hover/active repeat the reset: a theme's `button:hover` is its own rule and
   would otherwise reintroduce the fill the moment the pointer lands. */
.vf-of-bit-btn--img:hover,
.vf-of-bit-btn--img:active,
.vf-of-bit-btn--img:focus {
    background: none !important;
    background-color: transparent !important;
    background-image: none !important;
    border: 0 !important;
    box-shadow: none !important;
}

.vf-of-bit-btn--img:hover .vf-of-bit-btn-img { opacity: 0.9; }
.vf-of-bit-btn--img:active .vf-of-bit-btn-img { transform: scale(0.985); }

.vf-of-bit-btn-img {
    display: block !important;
    height: 48px !important;
    width: auto !important;
    max-width: 100% !important;
    border: 0 !important;
    border-radius: 24px !important;
    background: none !important;
    box-shadow: none !important;
    object-fit: contain;
    transition: opacity 0.15s ease, transform 0.1s ease;
}

/* In the compact row the artwork fills its tile and is cropped from the sides
   rather than letterboxed, so its height still matches the wallet buttons. The
   radius is 24 — half the 48px height — so all three are the same pill. */
.vf-of-wallets--compact .vf-of-bit-btn--img {
    width: 100% !important;
    height: 48px !important;
    border-radius: 24px !important;
}

.vf-of-wallets--compact .vf-of-bit-btn-img {
    width: 100% !important;
    height: 48px !important;
    border-radius: 24px !important;
    object-fit: cover;
}

/* Small print under the express row. Deliberately quiet — a footnote for the
   minority it applies to, not a warning aimed at everyone about to pay. */
.vf-of-wallets-note {
    flex-shrink: 0;
    margin: 0;
    text-align: center;
    color: #64748b;
    font-size: 0.72rem;
    line-height: 1.5;
}

.vf-of-wallets-sep {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--vf-of-muted, #64748b);
    font-size: 0.78rem;
    line-height: 1;
}

/* Rules either side of the label. Decoration only. */
.vf-of-wallets-sep::before,
.vf-of-wallets-sep::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--vf-of-border, #e5e7eb);
}

.vf-of-wallets-sep span {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* ------ Pay button ------ */
.vf-of-pay-btn {
    position: relative;
    width: 100%;
    height: 52px;
    margin-top: 8px;
    border: 0;
    border-radius: 12px;
    background: var(--vf-of-primary);
    color: #ffffff;
    font-family: inherit;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(32, 54, 164, 0.28), 0 1px 2px rgba(0, 0, 0, 0.06);
    transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease, opacity 0.15s ease;
    letter-spacing: 0.01em;
}

.vf-of-pay-btn:hover {
    background: #1a2d8a;
    transform: translateY(-1px);
    box-shadow: 0 8px 22px rgba(32, 54, 164, 0.36);
}

.vf-of-pay-btn:active {
    transform: translateY(0);
    box-shadow: 0 2px 6px rgba(32, 54, 164, 0.28);
}

.vf-of-pay-btn:disabled {
    cursor: progress;
    opacity: 0.7;
    transform: none;
}

.vf-of-pay-btn:focus-visible {
    outline: 3px solid var(--vf-of-secondary);
    outline-offset: 3px;
}

/* Spinner is hidden by default; `display: flex` only when the [hidden]
   attribute is removed (set by JS during the loading state). Without
   :not([hidden]) here `display:flex` overrode the [hidden] attribute and
   the spinner rotated permanently. */
.vf-of-pay-btn-spinner {
    display: none;
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
}

.vf-of-pay-btn-spinner:not([hidden]) {
    display: flex;
}

.vf-cardcom-spinner {
    width: 18px;
    height: 18px;
    border: 2px solid rgba(255,255,255,0.4);
    border-top-color: #ffffff;
    border-radius: 50%;
    animation: vf-of-spin 0.7s linear infinite;
}

@keyframes vf-of-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .vf-of-pay-btn, .vf-of-brand { transition: none; }
    .vf-of-pay-btn:hover, .vf-of-brand:hover { transform: none; }
    .vf-cardcom-spinner { animation-duration: 0s; border-top-color: var(--vf-of-secondary); }
}

/* Form-level error */
.vf-of-form-error {
    padding: 12px 14px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 10px;
    /* #dc2626 on #fef2f2 was 4.41:1 (axe, Phase 3 harness). The pair is 5.9:1 and up. */
    color: var(--vf-of-danger-text);
    font-size: 0.88rem;
    line-height: 1.5;
}

html[data-theme="dark"] .vf-of-form-error {
    background: rgba(220, 38, 38, 0.12);
    border-color: rgba(220, 38, 38, 0.4);
}

/* ------ Stall panel (payment fields did not load) ------
   Two visual states from one element. The soft state is amber and quiet: at
   that point nothing is known to be broken, only slow, and dressing it as an
   error would be a lie the customer can see through when the fields appear a
   second later. The hard state is red and carries the two actions.
   `!important` throughout for the same reason as the Bit button — this markup
   is built by JS, so RUCSS cannot find these selectors in the served HTML and
   a theme's own button rules would otherwise win. */
.vf-of-stall {
    margin-top: 12px !important;
    padding: 12px 14px !important;
    background: #fffbeb !important;
    border: 1px solid #fde68a !important;
    border-radius: 10px !important;
    color: #92400e !important;
    font-size: 0.88rem !important;
    line-height: 1.55 !important;
    text-align: center !important;
}

.vf-of-stall--hard {
    background: #fef2f2 !important;
    border-color: #fecaca !important;
    color: #991b1b !important;
}

.vf-of-stall-msg {
    font-weight: 600 !important;
}

.vf-of-stall-actions {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
    margin-top: 12px !important;
}

/* A real button, so it must out-declare the theme's global button styling —
   the exact failure the Bit button hit on the sibling site. */
.vf-of-stall-btn {
    display: block !important;
    width: 100% !important;
    padding: 11px 16px !important;
    background: #b91c1c !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: 10px !important;
    color: #fff !important;
    font-family: inherit !important;
    font-size: 0.92rem !important;
    font-weight: 700 !important;
    line-height: 1.2 !important;
    text-align: center !important;
    text-decoration: none !important;
    cursor: pointer !important;
    box-shadow: none !important;
    min-height: 0 !important;
}

.vf-of-stall-btn:hover { background: #991b1b !important; }

.vf-of-stall-alt {
    display: block !important;
    padding: 4px 0 !important;
    color: inherit !important;
    font-size: 0.85rem !important;
    font-weight: 600 !important;
    text-decoration: underline !important;
}

html[data-theme="dark"] .vf-of-stall {
    background: rgba(217, 119, 6, 0.12) !important;
    border-color: rgba(217, 119, 6, 0.4) !important;
    color: #fcd34d !important;
}

html[data-theme="dark"] .vf-of-stall--hard {
    background: rgba(220, 38, 38, 0.12) !important;
    border-color: rgba(220, 38, 38, 0.4) !important;
    color: #fca5a5 !important;
}

/* Success view */
.vf-of-success {
    text-align: center;
    padding: 32px 16px;
}

.vf-cardcom-success-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin: 0 auto 14px;
    background: var(--vf-of-success);
    color: #ffffff;
    border-radius: 50%;
    font-size: 1.6rem;
    font-weight: 700;
    box-shadow: 0 8px 20px rgba(22, 163, 74, 0.32);
}

.vf-of-success h3 {
    color: var(--vf-of-success);
    margin: 0 0 6px;
    font-size: 1.15rem;
}

.vf-of-success p {
    color: var(--vf-of-muted);
    font-size: 0.92rem;
    margin: 0;
}

/* Credits footer */
.vf-of-credits {
    margin-top: 18px;
    padding-top: 12px;
    border-top: 1px solid var(--vf-of-border);
}

.vf-of-credits iframe {
    width: 100%;
    height: 60px;          /* enough vertical room so CardCom's credits row
                              renders fully and doesn't get an inner scrollbar */
    min-height: 60px;
    border: 0;
    display: block;
    overflow: hidden;
}

/* ------ Mobile: bottom sheet (must match MOBILE_BREAKPOINT in JS) ------ */
@media (max-width: 768px) {
    /* Container becomes a fullscreen modal layer */
    .vf-of-mobile-mode {
        position: fixed;
        inset: 0;
        z-index: 99999;
        display: flex;
        align-items: flex-end;
    }

    .vf-of-mobile-mode .vf-of-backdrop {
        display: block;
        position: absolute;
        inset: 0;
        background: rgba(15, 23, 42, 0.55);
        backdrop-filter: blur(2px);
        animation: vf-of-fade-in 0.2s ease both;
    }

    .vf-of-mobile-mode .vf-of-card {
        position: relative;
        max-width: 100%;
        width: 100%;
        margin: 0;
        border-radius: 18px 18px 0 0;
        padding: 22px 18px 18px;
        max-height: 92vh;
        /* iOS counts the address bar in vh, which cut the bottom of the sheet (UX 11.5) */
        max-height: calc(100dvh - 16px);
        overflow-y: auto;
        box-shadow: var(--vf-of-shadow-lg);
        animation: vf-of-slide-up 0.28s cubic-bezier(0.2, 0.9, 0.3, 1) both;
        -webkit-overflow-scrolling: touch;
    }

    /* The little grab handle at the top of a bottom sheet */
    .vf-of-mobile-mode .vf-of-card::before {
        content: "";
        display: block;
        width: 44px;
        height: 4px;
        background: var(--vf-of-border-strong);
        border-radius: 999px;
        margin: -8px auto 16px;
    }

    .vf-of-mobile-mode .vf-of-card-head-amount {
        font-size: 1.3rem;
    }

    .vf-of-mobile-mode .vf-of-card-head-title {
        font-size: 0.95rem;
    }

    .vf-of-mobile-mode .vf-of-row {
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }

    .vf-of-mobile-mode .vf-of-pay-btn {
        height: 54px;
        font-size: 1.05rem;
    }

    /* Prevent the page underneath from scrolling. We restore scroll position
       via JS (vf-of-saved-scroll) so the page doesn't jump to top, which
       was the behaviour under `position: fixed; width: 100%`. */
    body.vf-of-mobile-open {
        overflow: hidden;
        touch-action: none;
    }

    @keyframes vf-of-slide-up {
        from { transform: translateY(100%); opacity: 0.8; }
        to   { transform: translateY(0);    opacity: 1; }
    }

    @keyframes vf-of-fade-in {
        from { opacity: 0; }
        to   { opacity: 1; }
    }
}

/* On desktop the badges row wraps if needed (RTL languages, smaller widths) */
@media (max-width: 480px) {
    .vf-of-badges {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* ============================================================
 * AJAX OVERLAY MODE (Phase 3.6c)
 * #vf-payment-mount becomes a fullscreen overlay the moment JS
 * injects the sheet HTML into it. On mobile: bottom sheet (slides
 * up from bottom). On desktop: centered modal (fades in). Form is
 * still in the DOM behind the dim backdrop.
 * ============================================================ */

#vf-payment-mount:not(:empty) {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    align-items: flex-end;       /* default = mobile bottom sheet */
    justify-content: center;
}

/* Backdrop always visible in overlay mode (was previously mobile-only) */
#vf-payment-mount .vf-of-backdrop {
    display: block;
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    backdrop-filter: blur(2px);
    animation: vf-of-fade-in 0.2s ease both;
}

/* Card sits above the backdrop. Reset legacy auto margins from
   the standalone card styling so flex centering wins. */
#vf-payment-mount .vf-of-card {
    position: relative;
    z-index: 1;
    margin: 0;
}

/* Mobile (≤768px): bottom sheet with grab handle */
@media (max-width: 768px) {
    #vf-payment-mount .vf-of-card {
        max-width: 100%;
        width: 100%;
        border-radius: 18px 18px 0 0;
        padding: 22px 18px 18px;
        max-height: 92vh;
        /* iOS counts the address bar in vh, which cut the bottom of the sheet (UX 11.5) */
        max-height: calc(100dvh - 16px);
        overflow-y: auto;
        box-shadow: var(--vf-of-shadow-lg);
        animation: vf-of-slide-up 0.28s cubic-bezier(0.2, 0.9, 0.3, 1) both;
        -webkit-overflow-scrolling: touch;
    }
    #vf-payment-mount .vf-of-card::before {
        content: "";
        display: block;
        width: 44px;
        height: 4px;
        background: var(--vf-of-border-strong);
        border-radius: 999px;
        margin: -8px auto 16px;
    }
}

/* Desktop (≥769px): centered modal with fade-in-up */
@media (min-width: 769px) {
    #vf-payment-mount:not(:empty) {
        align-items: center;
    }
    #vf-payment-mount .vf-of-card {
        max-width: 520px;
        width: calc(100% - 32px);
        max-height: 88vh;
        overflow-y: auto;
        box-shadow: var(--vf-of-shadow-lg);
        animation: vf-of-fade-in-up 0.25s ease both;
    }
    @keyframes vf-of-fade-in-up {
        from { opacity: 0; transform: translateY(20px); }
        to   { opacity: 1; transform: translateY(0); }
    }
}

/* Lock body scroll while sheet is open. JS adds this class on mount,
   removes on cleanup. */
body.vf-of-open {
    overflow: hidden;
    touch-action: none;
}

/* ============================================================
 * SKELETON (Phase 3.7)
 * Shown immediately on submit click while server creates the LP +
 * iframes load. Same modal frame as the real sheet so when JS swaps
 * them, only the inside content changes — no layout shift.
 * ============================================================ */
.vf-of-skeleton-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.vf-of-sk {
    background: linear-gradient(
        90deg,
        var(--vf-of-bg-soft, #f1f5f9) 0%,
        var(--vf-of-border, #e2e8f0) 50%,
        var(--vf-of-bg-soft, #f1f5f9) 100%
    );
    background-size: 200% 100%;
    border-radius: 8px;
    animation: vf-of-shimmer 1.4s linear infinite;
}

.vf-of-sk--label  { height: 12px; width: 40%; }
.vf-of-sk--input  { height: 46px; width: 100%; border-radius: 10px; }
.vf-of-sk--button { height: 52px; width: 100%; border-radius: 12px; margin-top: 8px;
                    background: linear-gradient(90deg, #c7d2fe 0%, #a5b4fc 50%, #c7d2fe 100%);
                    background-size: 200% 100%;
                    animation: vf-of-shimmer 1.4s linear infinite; }
.vf-of-sk--amount { height: 28px; width: 80px; border-radius: 6px; }

.vf-of-sk-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.vf-of-sk-col { display: flex; flex-direction: column; gap: 6px; }

.vf-of-skeleton-status {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--vf-of-border, #e2e8f0);
    color: var(--vf-of-muted, #64748b);
    font-size: 0.9rem;
}

@keyframes vf-of-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .vf-of-sk, .vf-of-sk--button { animation: none; }
}

/* Phase 2: the payment error dialog's "back to form" is a real <button>,
   styled as the link it was. (1,1,0) beats Hello Elementor's button rules. */
#vf-payment-mount .vf-of-error-back{
    min-height: 44px;
    padding: 8px 12px;
    background: none;
    border: 0;
    color: #475569;                      /* 7.6:1 on white */
    font: inherit;
    font-size: 14px;
    text-decoration: underline;
    cursor: pointer;
}
#vf-payment-mount .vf-of-error-back:hover,
#vf-payment-mount .vf-of-error-back:focus{
    background: none;
    color: #1E293B;
}

/* ------ Phase 3: the payment sheet as an accessible dialog ------

   Focus rings from the site's focus token, at 3:1 or better against the card,
   and none of them relying on the site's Additional CSS (UX 11.1). #vf-payment-mount
   in front gives (1,x,x), above Hello Elementor's button and input rules. */
#vf-payment-mount .vf-of-pay-btn:focus-visible {
    outline: 3px solid var(--vf-of-focus);
    outline-offset: 3px;
}
#vf-payment-mount .vf-of-cancel:focus-visible,
#vf-payment-mount .vf-of-stall-btn:focus-visible,
#vf-payment-mount .vf-of-stall-alt:focus-visible,
#vf-payment-mount .vf-of-bit-btn:focus-visible {
    outline: 3px solid var(--vf-of-focus);
    outline-offset: 2px;
}
/* The fields keep their border and glow, and gain a ring that passes 3:1 */
#vf-payment-mount .vf-of-field input[type="text"]:focus-visible {
    outline: 2px solid var(--vf-of-focus);
    outline-offset: 1px;
}
/* The heading row takes focus on open so a screen reader hears the title and
   the amount. It is not a control, so no ring, over the site's global ring too. */
#vf-payment-mount #vf-of-head:focus,
#vf-payment-mount #vf-of-head:focus-visible {
    outline: none !important;
    box-shadow: none !important;
}

/* "ביטול וחזרה לטופס" is a <button> now (UX 8), still drawn as the link it was,
   at 44px tall. 14px like "חזרה לטופס" of the error dialog. */
#vf-payment-mount .vf-of-cancel {
    min-height: 44px;
    padding-block: 8px;
    padding-inline: 12px;
    background: none;
    border: 0;
    border-radius: 6px;
    box-shadow: none;
    color: var(--vf-of-muted);
    font: inherit;
    font-size: 14px;
    text-decoration: underline;
    cursor: pointer;
}
#vf-payment-mount .vf-of-cancel:hover,
#vf-payment-mount .vf-of-cancel:focus {
    background: none;
    color: var(--vf-of-text);
}
#vf-payment-mount .vf-of-cancel[aria-disabled="true"] {
    cursor: default;
    opacity: 0.6;
}

/* While processing "pay" is aria-disabled, not disabled, so it keeps the focus.
   It looks as :disabled did. */
#vf-payment-mount .vf-of-pay-btn[aria-disabled="true"] {
    cursor: progress;
    opacity: 0.7;
    transform: none;
}
#vf-payment-mount .vf-of-pay-btn[aria-disabled="true"]:hover {
    background: var(--vf-of-primary);
    transform: none;
}

/* The focus guards at both ends of the card take no space */
#vf-payment-mount .vf-of-guard {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* The entrance of the card and the backdrop (UX 0.9, 11.3). The spinner and the
   skeleton have their own blocks above. */
@media (prefers-reduced-motion: reduce) {
    #vf-payment-mount .vf-of-card,
    #vf-payment-mount .vf-of-backdrop {
        animation: none !important;
    }
    .vf-of-mobile-mode .vf-of-card,
    .vf-of-mobile-mode .vf-of-backdrop {
        animation: none !important;
    }
}

/* ------ Phase 3: the no-AJAX path (render_cardcom_open_fields) ------

   Same rings and processing state, under its own wrapper #vf-of-mount. visa-form.css
   is not loaded on that page, so the visually-hidden rule comes along here too. */
#vf-of-mount .vf-visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}
#vf-of-mount .vf-of-pay-btn:focus-visible {
    outline: 3px solid var(--vf-of-focus);
    outline-offset: 3px;
}
#vf-of-mount #vf-of-cancel:focus-visible {
    outline: 3px solid var(--vf-of-focus);
    outline-offset: 2px;
}
#vf-of-mount .vf-of-field input[type="text"]:focus-visible {
    outline: 2px solid var(--vf-of-focus);
    outline-offset: 1px;
}
#vf-of-mount #vf-of-head:focus,
#vf-of-mount #vf-of-head:focus-visible {
    outline: none !important;
    box-shadow: none !important;
}
#vf-of-mount .vf-of-pay-btn[aria-disabled="true"] {
    cursor: progress;
    opacity: 0.7;
    transform: none;
}
