/* mod_threejs_edp — shared styles for all Three.js builder elements on EDP */

/* ── Tunnel background canvas ──────────────────────────────────────────────── */
/* Fixed-position full-viewport background behind page content.
   z-index: -1 puts it BEHIND every page element including the navbar
   (the navbar's auto z-index becomes effectively 0, above us).
   pointer-events:none so it never intercepts clicks.
   Default = blue gradient if no background file is provided. */
.edp-tunnel-canvas {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: -1;
    pointer-events: none;
    transition: opacity 0.3s ease-out;
    background: linear-gradient(to bottom, #4ABFE0, #0A2A4A);
}

/* Background asset (image or video) fills the canvas */
.edp-tunnel-canvas > video,
.edp-tunnel-canvas > img {
    display:    block;
    width:      100%;
    height:     100%;
    object-fit: cover;
    /* Remove default gradient when an asset is present */
    position:   absolute;
    inset:      0;
}

/* Force tunnel sections to have transparent backgrounds so the canvas
   behind them is visible. Overrides YOOtheme's uk-section-* styles. */
.edp-tunnel-section,
.edp-tunnel-section.uk-section,
.edp-tunnel-section.uk-section-default,
.edp-tunnel-section.uk-section-primary,
.edp-tunnel-section.uk-section-secondary,
.edp-tunnel-section.uk-section-muted {
    background-color: transparent !important;
    background-image: none !important;
}
.edp-tunnel-section .uk-section-default,
.edp-tunnel-section .uk-section-primary,
.edp-tunnel-section .uk-section-secondary,
.edp-tunnel-section .uk-section-muted {
    background-color: transparent !important;
}

/* Tunnel sections break out of YOOtheme's uk-container so they reach
   viewport width when zoomed to scale 1. Without this, sections are stuck at
   ~1200px max-width regardless of zoom. The negative margin trick centers
   the section at 100vw regardless of its parent's width.
   `display: block !important` is required to override YOOtheme's `uk-flex`
   so content inside (uk-container etc.) can center via its native margin auto. */
.edp-tunnel-section {
    width:        100vw !important;
    max-width:    100vw !important;
    margin-left:  calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
    display:      block !important;
    overflow:     visible;
    position:     relative;
}

/* Stage wraps the section's content (excluding the tunnel canvas, which the
   JS auto-wrap deliberately leaves outside). JS drives transform + opacity
   per scroll frame (scroll-tied), so no CSS transition here — every value
   set by JS is the current value at that scrollY.

   v50 fix: `min-height: 100vh` (was `100%`). Percentage height needs the
   parent to have an explicit `height` (not `min-height`), so `100%` here
   resolved to 0 and the stage collapsed to its content height — fine for
   sections whose centering layout lives on an INNER div (section1,
   section2) but broken for sections like intro/intro2 whose centering
   layout is on the OUTER `.edp-tunnel-section` itself (their content
   ended up at the top of the viewport instead of mid-tunnel). With an
   explicit `100vh` the stage is always a full viewport tall and its
   `display: flex; justify-content: center` vertically centers content
   regardless of where uk-flex / uk-height-viewport classes live. */
.edp-tunnel-section .edp-tunnel-stage {
    min-height:       100vh;
    width:            100%;
    display:          flex;
    flex-direction:   column;
    justify-content:  center;
    transform-origin: 50% 50%;
    will-change:      transform, opacity;
}

/* v50 fix: zero uk-section's outer padding when it lands on
   `.edp-tunnel-section` itself (intro / intro2 / any future section that
   stacks `uk-section` on the outer wrapper). uk-section's default 80px
   top/bottom padding pushes the stage content down by 80px, so the
   "tiny dot at viewport center" pivot calc in setupSectionTunnel ends up
   80px below where content actually is. section1 / section2 have
   uk-section on an INNER div instead, so this selector doesn't match
   them — they keep their internal padding. */
.edp-tunnel-section.uk-section {
    padding-top:    0 !important;
    padding-bottom: 0 !important;
}

/* No body padding-bottom in v11 — JS now adds margin-bottom: 100vh to the
   last tunnel section instead, which provides enough scroll budget for the
   exit phase to fully complete WITHOUT leaving empty scrollable area at the
   page bottom (where the underwater scene would otherwise be visible below
   the footer). */


/* ── Compact-mode tunnel hero (transactional pages — VM product / cart) ──────
   Default `.edp-tunnel-section .edp-tunnel-stage { min-height: 100vh }` makes
   the hero always take a full viewport, which is wrong on a VM product page
   where the buy box must stay above the fold. The compact_mode toggle on
   threejs_logo_tunnel adds `.edp-hero-compact` to the parent section via a
   tiny inline script. This rule then drops the stage's 100vh enforcement so
   the section's user-set height (e.g. 30vh in YOOtheme Advanced) takes over.
   Section-zoom is also skipped JS-side via data-no-section-zoom="1". */
.edp-tunnel-section.edp-hero-compact .edp-tunnel-stage {
    min-height: 0;
}



/* ── Block wrapper (threejs_logo_tunnel) ────────────────────────────────────
   Wraps title + logo + text inside the tunnel element so they stack
   vertically and the whole group acts as a single transform target for
   setupLogoTunnel — that way the slide-in animation and the scroll-driven
   zoom don't desync the logo from the title/text.

   Perspective + preserve-3d enable the 3dlogo behavior (v34): the link
   inside the block has translate3d/rotateY transforms that need 3D depth
   to render with perspective foreshortening. perspective is set on the
   block (the children's perspective root), preserve-3d so block's
   children don't get flattened back into 2D before compositing. */
.edp-tunnel-block {
    position:         relative;     /* needed for the perspective + 3D
                                       children to compose correctly */
    width:            100%;
    display:          flex;
    flex-direction:   column;
    align-items:      center;
    justify-content:  center;
    perspective:      1500px;
    transform-style:  preserve-3d;
    will-change:      transform, opacity, filter;
    /* v48: removed `z-index: -1` — it killed clicks on the logo link
       (the link inherits the block's stacking context). Visual overlap
       with the footer on mobile is prevented by the JS pin-above-footer
       clamp in setupLogoTunnel, so this hack is no longer needed. */
}
.edp-tunnel-block > .edp-tunnel-title { margin: 0 0 0.5em; }
.edp-tunnel-block > .edp-tunnel-text  { margin: 0.5em 0 0; max-width: 40em; }
.edp-tunnel-block > .edp-logo-link    { display: block; }


/* ── Animated logo (threejs_logo_animated) ──────────────────────────────────── */

a.edp-logo-link {
    display: block;
    text-decoration: none;
}

.edp-logo-wrap {
    position: relative;
    overflow: visible;
    width: 100%;
    z-index: 1;          /* keep above section background videos/images */
    perspective: 1200px; /* enables 3D depth for the canvas's rotateY flip
                            in slide-*-flip scroll behavior (v32) */
}

.edp-logo-wrap canvas {
    display: block;
    width:  100% !important;
    height: 100% !important;
}

/* Horizontal flip — applied to the WebGL canvas inside the wrap so the JS
   transforms on .edp-logo-wrap (slide-in, hero-zoom) compose with it
   without overriding the flip. */
.edp-logo-wrap.edp-logo-flipped canvas {
    transform: scaleX(-1);
    transform-origin: 50% 50%;
}

/* Foreground overlay — element relocates to be a child of the section
   and centers over it. Same pattern as TDM. */
.edp-logo-foreground {
    position: absolute !important;
    top:       50%;
    left:      50%;
    transform: translate(-50%, -50%);
    width:     60%;
    z-index:   10;
    pointer-events: none;
}

/* ── Scroll mode "scrolling" — logo stays at its initial viewport position ── */
/* JS sets --edp-scroll-y = window.scrollY on every scroll event; CSS reads it
   into a translateY transform. Net effect: as the page scrolls, the logo's
   document position shifts to compensate, so its viewport position is locked.
   Smooth, no threshold (unlike CSS sticky). Entry animations have higher
   specificity below and override this during the slide-in transition. */
.edp-logo-wrap[data-scroll-mode="scrolling"] {
    transform:   translateY(var(--edp-scroll-y, 0px));
    will-change: transform;
}
.edp-logo-wrap.edp-logo-foreground[data-scroll-mode="scrolling"] {
    transform: translate(-50%, calc(-50% + var(--edp-scroll-y, 0px)));
}

/* ── Entry animation ───────────────────────────────────────────────────────── */
/* Initial state: off-screen via translateX. JS adds 'edp-logo-entered' on
   viewport intersection to trigger the transition. Two specificity tracks —
   one for normal flow, one for foreground overlay (which has its own
   translate(-50%, -50%) that we must preserve when entered). */

.edp-logo-wrap.edp-logo-entry-from-left,
.edp-logo-wrap.edp-logo-entry-from-right {
    transition: transform var(--edp-entry-duration, 1.5s) cubic-bezier(.2, .8, .3, 1) var(--edp-entry-delay, 0s);
    will-change: transform;
}

.edp-logo-wrap.edp-logo-entry-from-left:not(.edp-logo-entered):not(.edp-logo-foreground) {
    transform: translateX(-200%);
}
.edp-logo-wrap.edp-logo-entry-from-right:not(.edp-logo-entered):not(.edp-logo-foreground) {
    transform: translateX(200%);
}

/* Foreground variant: keep the translate-Y(-50%) for vertical centering */
.edp-logo-wrap.edp-logo-foreground.edp-logo-entry-from-left:not(.edp-logo-entered) {
    transform: translate(-200%, -50%);
}
.edp-logo-wrap.edp-logo-foreground.edp-logo-entry-from-right:not(.edp-logo-entered) {
    transform: translate(200%, -50%);
}
/* When entered, the existing .edp-logo-foreground rule applies its own
   translate(-50%, -50%) — we don't need to repeat it. */


/* ── Text Twist element (threejs_text_twist) ────────────────────────────────
   3D flip-reveal panel. Outer wrapper provides the perspective context; the
   inner panel rotates from rotateY/X(180deg) at viewport bottom to 0deg as
   the element scrolls into view (script-text-twist.js drives the transform).
   At 90° the panel is edge-on. data-fold-pending keeps the panel hidden
   until JS has set the initial transform — without this the panel would
   flash readable for 1 frame before the script kicks in. */
.edp-text-twist-outer,
.edp-tunnel-text-twist-outer {
    perspective: 900px;
}
.edp-fold-panel {
    will-change: transform;
    backface-visibility: visible;
}
.edp-fold-panel[data-fold-pending] {
    visibility: hidden;
}


/* ── Countdown element (threejs_countdown) ──────────────────────────────────
   Pure DOM countdown, no Three.js / no canvas. Element renders d/h/m/s
   columns; script-countdown.js ticks them via setInterval. Optional
   heartbeat / pulse animation driven by CSS @keyframes with a runtime
   --edp-anim-dur custom property. Cloned from RDC v5 2026-05-12 — see
   templates/yootheme_edp/builder/threejs_countdown/CHANGELOG.md. */

.edp-countdown-wrap {
    position: relative;
}

.edp-countdown {
    display: flex;
    align-items: flex-start;
    text-align: center;
}

.edp-cd-unit {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 0;
}

/* UIKit heading classes add margin-bottom — neutralise it inside the counter */
.edp-cd-number {
    line-height: 1 !important;
    margin-bottom: 0 !important;
    white-space: nowrap;
}

.edp-cd-label {
    margin-top: 0.3em;
    margin-bottom: 0 !important;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
    opacity: 0.75;
}

.edp-coming-soon {
    text-align: center;
    margin-bottom: 0.4em !important;
}

/* ── Heartbeat / pulse animations ─────────────────────────────────────────── */
@keyframes edp-heartbeat {
    0%,100% { transform: scale(1);    }
    14%     { transform: scale(1.08); }
    28%     { transform: scale(1);    }
    42%     { transform: scale(1.05); }
    56%     { transform: scale(1);    }
}

@keyframes edp-pulse {
    0%,100% { transform: scale(1);    opacity: 1;   }
    50%     { transform: scale(1.06); opacity: 0.9; }
}

.edp-anim-heartbeat { animation: edp-heartbeat var(--edp-anim-dur, 1.5s) ease-in-out infinite; }
.edp-anim-pulse     { animation: edp-pulse     var(--edp-anim-dur, 2s)   ease-in-out infinite; }


/* ── Menus Links element (threejs_menus_links) ──────────────────────────────── */

/* Outer container: JS sets height, position:relative for absolute children */
.tml-wrap {
    position: relative;
    width: 100%;
    min-height: 200px;
    overflow: visible;
}

/* Canvas for connecting lines — sits behind cards and central image */
.tml-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
    pointer-events: none;
    z-index: 0;
}

/* Central image: JS sets top and width each frame; CSS centres horizontally */
.tml-center-wrap {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    pointer-events: none;
}

.tml-center-img {
    display: block;
    width: 100%;
    height: auto;
}

/* Cards: JS sets left/top/opacity/pointer-events each frame */
.tml-card-wrap {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    z-index: 1;
    box-sizing: border-box;
}

.tml-card {
    width: 100%;
}

.tml-card-img {
    width: 100%;
    overflow: hidden;
}

.tml-card-img img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
}

/* Panel link overlay */
.tml-linked {
    position: relative;
}
.tml-card-link-overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
}
.tml-linked .uk-card-title a,
.tml-linked .tml-card-img a {
    position: relative;
    z-index: 2;
}

.tml-card-content {
    font-size: 0.78rem;
    line-height: 1.45;
}


/* ── threejs_vm_product builder element ────────────────────────────────────
   The VM `prices` sublayout renders ALL possible price-rows (basePrice,
   salesPrice, salesPriceWithDiscount, discountAmount, discountedPriceWithoutTax,
   unitPrice, etc.) and toggles their visibility via .vm-display / .vm-nodisplay
   classes based on whether each price field is meaningful for the current user
   and product. */

/* Defensive: hide every .vm-nodisplay row inside the element. VM's own CSS
   provides the same rule, but is only reliably loaded on actual VM views —
   when our element renders on a Joomla article (e.g. the tempo-page) it
   doesn't necessarily get that stylesheet, so the discount labels were
   leaking through. This scoped rule fixes it without affecting any other
   VM-rendered area of the site. */
.edp-vm-product .vm-nodisplay {
    display: none !important;
}

/* Two rows are NEVER useful on EDP — hide them unconditionally so they
   don't show up even if VM decides to .vm-display them. */
.edp-vm-product .PricesalesPriceWithDiscount,
.edp-vm-product .PriceunitPrice {
    display: none !important;
}

/* Top breathing room above the prices block. */
.edp-vm-product .product-price {
    margin-top: 1.5rem;
}

/* Price rows: label left, amount right (flex spread). Each visible price row
   has the shared `vm-price-value` class plus a per-price wrapper class. */
.edp-vm-product .vm-price-value {
    display:         flex;
    justify-content: space-between;
    align-items:     baseline;
    gap:             0.5em;
}

/* Mobile add-to-cart row: quantity input + button can stack on narrow
   viewports — Bootstrap `.row.gx-0` only kills horizontal gutter; this
   adds vertical breathing room when the cols wrap. */
.edp-vm-product .addtocart-bar .row {
    row-gap: 0.5rem;
}

/* Free-text content above the addtocart form (editor field on the element).
   Centered on mobile per Yanni's spec. */
.edp-vm-product-pre-addtocart {
    margin-top:    0.75rem;
    margin-bottom: 0.75rem;
}

/* Customfield wrapper inside the addtocart form — VM's bs5-customfields.php
   sublayout hardcodes an inline `style="background-color: #ffff99"` (a debug
   yellow). Override: transparent background, faint white border, rounded
   corners matching the Bootstrap button radius (`btn` uses 0.375rem). */
.edp-vm-product .product-field {
    background-color: transparent !important;
    border:           1px solid rgba(255, 255, 255, 0.2);
    border-radius:    0.375rem;
}

/* Breathing room between the customfields wrap and what follows it
   (pre-addtocart content or the quantity+addtocart bar). The :has() guard
   means the margin only kicks in when there's actually a customfield —
   product 1 has none, so no awkward extra gap there. */
.edp-vm-product .vm-customfields-wrap:has(.product-field) {
    margin-bottom: 1rem;
}
@media (max-width: 767px) {
    .edp-vm-product-pre-addtocart {
        text-align: center;
    }
}

/* Long-description block — top margin to separate it from the buy box above. */
.edp-vm-product .product-description {
    margin-top: 2rem;
}

/* Mobile addtocart layout: stack quantity ABOVE the add-to-cart button.
   Both rows full viewport-column width, contents centered. On desktop the
   default Bootstrap row keeps them side-by-side. */
@media (max-width: 767px) {
    .edp-vm-product .addtocart-bar .row {
        flex-direction: column;
        align-items:    stretch;
    }
    .edp-vm-product .addtocart-bar .row > .col-auto,
    .edp-vm-product .addtocart-bar .row > .vm-addtocart-button-col {
        flex:            0 0 100%;
        max-width:       100%;
        width:           100%;
        display:         flex;
        justify-content: center;
    }
    .edp-vm-product .addtocart-bar .vm-addtocart-button-col {
        margin-top: 0.5rem;
    }
    .edp-vm-product .addtocart-bar .quantity-box {
        width: fit-content;
    }
    .edp-vm-product .addtocart-bar .vm-addtocart-button-wrapper {
        width: 100%;
    }
}


/* ── Scroll-progress nav slalom (threejs_logo_tunnel option) ─────────────────
   Fixed SVG strip in the vertical middle of the viewport (40vh–60vh), right
   edge of the screen (5px gutter). Behind every section (z-index -1 puts it
   on the same plane as .edp-tunnel-canvas — emitted AFTER the canvas in DOM
   so it paints in front of the canvas gradient). The path + bubble are
   drawn in pixel-matched viewBox units by script-scroll-nav.js — the
   viewBox is set dynamically to the strip's getBoundingClientRect so 1
   viewBox-unit = 1 real px → bubble is a true circle (no aspect-ratio
   distortion). Opacity is JS-driven for the footer fade. */
.edp-scroll-nav {
    position:       fixed;
    top:            20vh;
    right:          5px;
    width:          40px;
    height:         60vh;
    z-index:        -1;
    pointer-events: none;
    transition:     opacity 0.2s ease-out;
}

/* Drag-to-scroll hit area — a floating transparent HTML element that
   tracks the bubble's viewport position. The visible bubble lives inside
   .edp-scroll-nav at z-index -1 (behind every section) and therefore
   cannot receive pointer events on its own; this overlay sits at a high
   z-index so it's always reachable. JS keeps its top/left in sync with
   the SVG bubble's screen coords. Transparent + no background = no
   visual footprint; only the cursor change reveals it's interactive. */
.edp-scroll-nav-hit {
    position:       fixed;
    width:          28px;
    height:         28px;
    transform:      translate(-50%, -50%);  /* center on (left, top) */
    border-radius:  50%;
    background:     transparent;
    cursor:         grab;
    touch-action:   none;
    z-index:        999;
    pointer-events: none;                    /* JS toggles to 'auto' when bubble is shown */
}
.edp-scroll-nav-hit:active {
    cursor: grabbing;
}

/* ── threejs_decisions ──────────────────────────────────────────────────────
   Decision-tree element. Wrapper holds the root question, a stage where the
   active level's cards render, nav controls, and a hidden canvas reserved for
   future animation modes (bubbles / card_flip).

   Stage is a CSS grid with auto-fit minmax — cards reflow on viewport changes
   without any JS resize handler.
   --------------------------------------------------------------------- */
.tjd-wrap {
    position: relative;
    width: 100%;
    /* Disable Chrome's automatic scroll-anchoring inside the element so our
       JS-driven scroll pinning isn't fighting the browser's heuristic. */
    overflow-anchor: none;
}
.tjd-stage,
.tjd-nav {
    overflow-anchor: none;
}
.tjd-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
}
.tjd-question {
    position: relative;
    z-index: 1;
    margin-bottom: var(--tjd-gap, 20px);
}
.tjd-question-text {
    margin-bottom: 4px;
}
.tjd-question-meta {
    margin: 0;
}
.tjd-stage {
    position: relative;
    z-index: 1;
    transition: opacity 200ms ease;
}
.tjd-stage.tjd-fade-out { opacity: 0; }
.tjd-stage.tjd-fade-in  { opacity: 1; }

/* UIKit grid does the columns; we only equalize card height */
.tjd-grid > * > .tjd-card-wrap { height: 100%; }

/* Root entry: center the single card and let it stay narrow */
.tjd-grid.tjd-root-entry > * {
    flex-basis: auto !important;
    max-width: min(560px, 100%);
}

.tjd-card-wrap {
    position: relative;     /* anchor for link-panel overlay */
    cursor: pointer;
    transition: transform 150ms ease, box-shadow 150ms ease;
}
.tjd-card-wrap:hover .tjd-card {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0,0,0,0.08);
}

/* Link-panel overlay — when the "Link panel" checkbox is on, the whole card
   is wrapped behind a transparent <a>. Sits ABOVE the card content so the
   browser routes clicks anywhere on the card through it. */
.tjd-card-link-overlay {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
}

/* Follow mode — trail of reduced-size cards above the active level, joined
   by a vertical line whose color is `--tjd-trail-line` (set per-element via
   inline style from the `trail_line_color` field).

   Size reduction is done via real padding + font-size overrides rather than
   `transform: scale()` — scale leaves a full-size layout box behind the
   visually-shrunk element, causing the overlap-in-background symptom. */
.tjd-wrap[data-mode="follow"] .tjd-stage {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}
.tjd-trail {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: var(--tjd-gap, 20px);
}
.tjd-trail-item {
    cursor: pointer;
    width: min(420px, 90%);
    opacity: 0.85;
    transition: opacity 150ms ease, transform 150ms ease;
}
.tjd-trail-item:hover {
    opacity: 1;
    transform: translateY(-1px);
}
.tjd-trail-item .tjd-card.uk-card-body,
.tjd-trail-item .tjd-card.uk-card-small.uk-card-body,
.tjd-trail-item .tjd-card.uk-card-large.uk-card-body,
.tjd-trail-item .tjd-card.uk-padding,
.tjd-trail-item .tjd-card.uk-padding-small,
.tjd-trail-item .tjd-card.uk-padding-large {
    padding: 6px 12px !important;
}
.tjd-trail-item .uk-card-title {
    font-size: 0.85rem !important;
    line-height: 1.25 !important;
    margin: 0 !important;
}
.tjd-trail-item .tjd-card-content,
.tjd-trail-item .tjd-card-content * {
    font-size: 0.72rem !important;
    line-height: 1.3;
}
.tjd-trail-item .tjd-card p {
    font-size: 0.68rem !important;
    line-height: 1.3;
    margin: 2px 0 0;
}
/* Hide images on trail cards — visual noise at small size. */
.tjd-trail-item .tjd-card-img { display: none; }
.tjd-trail-line {
    width: 2px;
    height: 18px;
    background: var(--tjd-trail-line, rgba(255,255,255,0.5));
    margin: 0 auto;
}
.tjd-card {
    height: 100%;
    transition: transform 150ms ease, box-shadow 150ms ease;
}
.tjd-card-img img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
}
.tjd-nav {
    display: flex;
    justify-content: center;
    gap: 12px;
    margin-top: var(--tjd-gap, 20px);
}
.tjd-nav button[hidden] { display: none; }

/* Animation: card_flip — applied via class swap before/after render.
   3D flip relies on perspective on the grid + transform on the card. */
.tjd-wrap[data-anim="card_flip"] .tjd-grid {
    perspective: 1200px;
}
.tjd-wrap[data-anim="card_flip"] .tjd-stage.tjd-fade-out .tjd-card {
    transform: rotateY(90deg);
}
.tjd-wrap[data-anim="card_flip"] .tjd-card {
    backface-visibility: hidden;
    transform: rotateY(0deg);
    transition: transform 250ms ease;
}

/* Transparent card option — mimics UIKit's `.uk-button-default` palette.
   White text + faint white border on transparent background + 3px radius +
   10px padding (xsmall). Hover lifts the border opacity and adds a subtle
   white wash. Pairs naturally with a `uk-light` ancestor. */
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-card,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-tile {
    background-color: transparent !important;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 3px;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
/* Override UIKit's card-body / tile padding with xsmall (10px) */
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-card-body,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-card-small.uk-card-body,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-card-large.uk-card-body,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-padding,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-padding-small,
.tjd-wrap[data-card-transparent="1"] .tjd-card.uk-padding-large {
    padding: 10px;
}
.tjd-wrap[data-card-transparent="1"] .tjd-card-wrap:hover .tjd-card.uk-card,
.tjd-wrap[data-card-transparent="1"] .tjd-card-wrap:hover .tjd-card.uk-tile {
    background-color: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.7);
    color: #fff;
}
.tjd-wrap[data-card-transparent="1"] .tjd-card .uk-card-title,
.tjd-wrap[data-card-transparent="1"] .tjd-card .tjd-card-content,
.tjd-wrap[data-card-transparent="1"] .tjd-card p {
    color: inherit;
}
