/*
 * Virgo CMS - Animated Number module styles.
 *
 * Shared across every variant (cards / dark / overlay / minimal / percentage).
 * The core layout (responsive grid sized by the columns setting, counter cell,
 * value, label) and every animation structure (odometer / rolling / typewriter
 * strips) live here; a per-variant .animated-number--{variant} modifier swaps
 * the visual theme (background, card surface, colors). Runtime values are driven
 * by the renderer: the grid column count via .animated-number--cols-{n}, the
 * border-radius + gap via the --an-radius / --an-gap custom properties, and the
 * hover effect via data-hover-effect — so no other inline styles are needed.
 */

/* ============================================
   CORE LAYOUT
   ============================================ */

[data-module-type^="animated_number"] {
    box-sizing: border-box;
    --an-gap: 1.5rem;
    /* The renderer emits --an-radius (px) from the appearance setting; map it
       onto the surface radius token so the per-variant preset default still
       applies when the module has not overridden it. */
    --an-cell-radius: var(--an-radius, 0);
    /* Value size is pure rem so it scales with the site font-size setting
       (--base-font-size on <html>), not the viewport. The min keeps digits
       legible on small screens; the max stops hero counters from dominating. */
    --an-value-size: clamp(2rem, 2.6rem, 3rem);
    --an-value-weight: 700;
    --an-label-size: 1.1rem;
    --an-label-weight: 500;
    --an-surface-bg: transparent;
    --an-surface-border: transparent;
    --an-value-color: inherit;
    --an-label-color: inherit;
    --an-cell-padding: 1rem;
    width: 100%;
}

[data-module-type^="animated_number"] *,
[data-module-type^="animated_number"] *::before,
[data-module-type^="animated_number"] *::after {
    box-sizing: border-box;
}

/* ============================================
   LIGHT/DARK COLOR OVERRIDE REBIND LAYER (per counter)
   ============================================
   The renderer emits --an-{field}-color-light and --an-{field}-color-dark on
   each .an-counter ONLY for the modes the admin overrode. These rules rebind
   the element-facing --an-{field}-color to the ACTIVE mode's override; when
   that override var is ABSENT (admin left "use theme default" checked for that
   mode), the var() falls back to --an-{field}-color as the preset established
   it on the ancestor (e.g. #ffffff for transparent horizontal_cards,
   var(--text-ink) for opaque, var(--text-muted) for labels) — which is already
   dark/palette-aware because the preset rules use tokens that rebind under
   [data-bs-theme="dark"]. So an empty mode renders its correct token default
   instead of inheriting the other mode's hex, and the dark override never
   leaks into light mode (or vice-versa). The rebind sits on .an-counter (where
   the properties are consumed), winning over the ancestor preset value by
   proximity; the dark rule adds the [data-bs-theme="dark"] ancestor for its
   specificity edge. Prefix/suffix keep the same inner fallback as their element
   rule (var(--an-value-color)) so they track the (possibly overridden) value
   color when no dedicated prefix/suffix override exists. */
[data-module-type^="animated_number"] .an-counter {
    --an-prefix-color: var(--an-prefix-color-light, var(--an-prefix-color, var(--an-value-color)));
    --an-value-color:  var(--an-value-color-light,  var(--an-value-color));
    --an-suffix-color: var(--an-suffix-color-light, var(--an-suffix-color, var(--an-value-color)));
    --an-label-color:  var(--an-label-color-light,  var(--an-label-color));
    --an-counter-description-color: var(--an-counter-description-color-light, var(--an-counter-description-color, var(--text-muted, #5a6b66)));
}

[data-bs-theme="dark"] [data-module-type^="animated_number"] .an-counter {
    --an-prefix-color: var(--an-prefix-color-dark, var(--an-prefix-color, var(--an-value-color)));
    --an-value-color:  var(--an-value-color-dark,  var(--an-value-color));
    --an-suffix-color: var(--an-suffix-color-dark, var(--an-suffix-color, var(--an-value-color)));
    --an-label-color:  var(--an-label-color-dark,  var(--an-label-color));
    --an-counter-description-color: var(--an-counter-description-color-dark, var(--an-counter-description-color, var(--text-muted, #5a6b66)));
}

/* LIGHT/DARK COLOR OVERRIDE REBIND LAYER (main card header — horizontal_cards /
   vertical_cards). The renderer emits --an-title-color-light/dark and
   --an-description-color-light/dark on the preset root. Here the rebind uses NO
   inner fallback: when the override var is absent, var() with no fallback makes
   the declaration invalid at computed-value time, so --an-title-color stays
   unset and the descendant rules below (.an-module-title { color:
   var(--an-title-color, #ffffff | var(--text-ink)) }) apply their OWN mode-aware
   fallback — preserving the transparent (#ffffff) vs opaque (var(--text-ink))
   behaviour. A present override wins and is applied in its mode. */
.animated-number--horizontal_cards,
.animated-number--vertical_cards {
    --an-title-color:       var(--an-title-color-light);
    --an-description-color: var(--an-description-color-light);
}

[data-bs-theme="dark"] .animated-number--horizontal_cards,
[data-bs-theme="dark"] .animated-number--vertical_cards {
    --an-title-color:       var(--an-title-color-dark);
    --an-description-color: var(--an-description-color-dark);
}

/* Responsive grid driven by the columns modifier class. */
.animated-number {
    display: grid;
    gap: var(--an-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}

.animated-number--cols-1 { grid-template-columns: 1fr; }
.animated-number--cols-2 { grid-template-columns: repeat(2, 1fr); }
.animated-number--cols-3 { grid-template-columns: repeat(3, 1fr); }
.animated-number--cols-4 { grid-template-columns: repeat(4, 1fr); }
.animated-number--cols-5 { grid-template-columns: repeat(5, 1fr); }
.animated-number--cols-6 { grid-template-columns: repeat(6, 1fr); }
.animated-number--cols-7 { grid-template-columns: repeat(7, 1fr); }
.animated-number--cols-8 { grid-template-columns: repeat(8, 1fr); }

@media (max-width: 767.98px) {
    /* On small screens collapse every grid to at most 2 columns so counters stay readable. */
    .animated-number--cols-3,
    .animated-number--cols-4,
    .animated-number--cols-5,
    .animated-number--cols-6,
    .animated-number--cols-7,
    .animated-number--cols-8 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 575.98px) {
    .animated-number--cols-2,
    .animated-number--cols-3,
    .animated-number--cols-4,
    .animated-number--cols-5,
    .animated-number--cols-6,
    .animated-number--cols-7,
    .animated-number--cols-8 {
        grid-template-columns: 1fr;
    }
}

/* ============================================
   COUNTER CELL
   ============================================ */

.an-counter {
    text-align: center;
    padding: var(--an-cell-padding);
    background: var(--an-surface-bg);
    border: 1px solid var(--an-surface-border);
    border-radius: var(--an-cell-radius);
    transition: box-shadow 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
}

.an-value {
    display: flex;
    align-items: baseline;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.1em;
    font-size: var(--an-value-size);
    font-weight: var(--an-value-weight);
    line-height: 1.1;
    color: var(--an-value-color);
}

.an-prefix,
.an-suffix {
    font-size: 0.55em;
    font-weight: var(--an-value-weight);
    opacity: 0.95;
}

/* Per-counter prefix/suffix text color. When the admin sets a dedicated
   prefix/suffix color, the renderer emits --an-prefix-color / --an-suffix-color
   on the .an-counter cell and these rules pick it up; otherwise they fall back
   to the value color so the prefix/suffix read as part of the number (the
   default behaviour). Generic (not preset-scoped) because every variant that
   carries per-counter colors (horizontal_cards / vertical_cards / minimal) uses
   the same token; variants without color columns never emit the property so the
   var() fallback applies. */
.an-prefix {
    color: var(--an-prefix-color, var(--an-value-color));
}
.an-suffix {
    color: var(--an-suffix-color, var(--an-value-color));
}

.an-label {
    margin-top: 0.5rem;
    font-size: var(--an-label-size);
    font-weight: var(--an-label-weight);
    color: var(--an-label-color);
    line-height: 1.4;
}

/* ============================================
   ANIMATION STRUCTURES
   ============================================ */

/* The number wraps (.an-digits) and every engine-built animation span inherit
   the large --an-value-size from .an-value instead of collapsing to the
   template's body-size "span" reset (p, span, label, a { font-size: var(--fs-body) }).
   Without this, that global rule pins every descendant number span to 1rem
   while prefix/suffix (which set their own size) stay large — inverting the
   intended hierarchy so the number reads small and the prefix/suffix read big.
   Descendant-scoped on .an-value and excludes .an-prefix/.an-suffix (which keep
   their smaller 0.55em size) so it overrides the global span rule and covers
   every nested odometer/rolling/typewriter cell at once. */
.an-value span:not(.an-prefix):not(.an-suffix),
.an-number-text {
    font-size: inherit;
}

/* Count up / none: a plain text span updated each frame. */
.an-number-text {
    display: inline;
}

/* Odometer: inline-flex of per-digit cells, each with a 1em viewport masking a
   vertical strip of 0..9+0 (11 entries). translateY shifts the strip in em. */
.an-odo {
    display: inline-flex;
    align-items: baseline;
}

.an-odo-digit {
    display: inline-block;
    overflow: hidden;
    height: 1em;
    line-height: 1;
    vertical-align: baseline;
}

.an-odo-viewport {
    display: block;
    height: 1em;
    overflow: hidden;
}

.an-odo-strip {
    display: block;
}

.an-odo-strip > span {
    display: block;
    height: 1em;
    line-height: 1;
}

.an-odo-sep {
    display: inline-block;
}

/* Rolling: inline-flex of per-digit viewports, each masking a 0..9 column.
   translateY shifts the column in % (one digit = 10% of the column height). */
.an-roll {
    display: inline-flex;
    align-items: baseline;
}

.an-roll-digit {
    display: inline-block;
    overflow: hidden;
    height: 1em;
    line-height: 1;
    vertical-align: baseline;
}

.an-roll-viewport {
    display: block;
    height: 1em;
    overflow: hidden;
}

.an-roll-col {
    display: block;
}

.an-roll-col > span {
    display: block;
    height: 1em;
    line-height: 1;
}

.an-roll-sep {
    display: inline-block;
}

/* Typewriter: chars are plain text nodes inserted before the cursor, so they
   inherit the number's styling directly (no per-char span needed). The cursor is
   a thin inline block that blinks behind the growing number, em-based so it
   scales with the number font-size. */
.an-tw-cursor {
    display: inline-block;
    width: 0.06em;
    height: 1em;
    background-color: currentColor;
    margin-left: 0.1em;
    vertical-align: baseline;
    animation: an-tw-blink 0.7s step-end infinite;
}

@keyframes an-tw-blink {
    from, to { opacity: 1; }
    50% { opacity: 0; }
}

/* ============================================
   PRESET: horizontal_cards (corporate horizontal card grid with background)
   ============================================ */

/* White text over a module-level background image. The background is a real
   image element (class an-bg-img, with srcset + sizes, so the browser picks the
   resolution by viewport width) rather than a CSS background-image, which could
   only branch on DPR and pixelated on 1x desktops. A gradient overlay is painted
   by the ::before layer. Counter cells are transparent so the backdrop shows
   through; depth is not needed since the whole module reads as one image-backed
   panel. The root panel's own corner radius is driven by --an-main-card-radius
   (renderer, 0-24px); frameless (default on) drops the border so the panel reads
   as a seamless full-bleed backdrop, otherwise a subtle border frames it as a
   card. overflow: hidden clips the background image + overlay to the radius. */
.animated-number--horizontal_cards {
    --an-surface-bg: transparent;
    --an-surface-border: rgba(255, 255, 255, 0.18);
    --an-cell-padding: 1.75rem 1rem;
    --an-value-color: #ffffff;
    --an-label-color: #ffffff;
    --an-value-size: clamp(2.25rem, 2.85rem, 3.25rem);
    position: relative;
    padding: clamp(2rem, 6vw, 5rem) clamp(1rem, 4vw, 3rem);
    color: #ffffff;
    overflow: hidden;
    border-radius: var(--an-main-card-radius, 0);
}

/* Main card panel border: shown only when the frameless toggle is OFF. When
   frameless is ON (default) the panel has no border and reads as a seamless
   full-bleed backdrop; turning it off frames the panel as a distinct card. The
   border is a translucent white so it stays visible over the background image +
   dark overlay (mirrors the counter cell's --an-surface-border, not the page's
   grey --border-color which would vanish on the dark backdrop). */
.animated-number--horizontal_cards:not(.an-main-card-frameless) {
    border: 1px solid var(--an-surface-border, rgba(255, 255, 255, 0.18));
}

/* Header text legibility shadow over the background image (horizontal_cards
   only). Driven by the --an-text-shadow-strength custom property (1-10, emitted
   by the renderer only when the admin slider is > 0). A layered black drop
   shadow whose offset, blur and opacity scale together with the strength, so the
   readout matches perceived depth. Applies to the module title, description and
   a TEXT-style main card link (which sits transparent over the image like the
   header text) — the button-style link is excluded because it carries its own
   solid primary surface, and the counter cards carry their own shadow (see
   below). At strength 0 the custom property is absent and every var() fallback
   (0) collapses the calcs to a fully transparent, zero-offset shadow
   (effectively none). */
.animated-number--horizontal_cards .an-module-title,
.animated-number--horizontal_cards .an-module-description,
.animated-number--horizontal_cards .an-card-link--text {
    text-shadow:
        0 calc(var(--an-text-shadow-strength, 0) * 0.2px)
          calc(var(--an-text-shadow-strength, 0) * 0.8px)
          rgba(0, 0, 0, calc(var(--an-text-shadow-strength, 0) * 0.09)),
        0 calc(var(--an-text-shadow-strength, 0) * 0.1px)
          calc(var(--an-text-shadow-strength, 0) * 0.3px)
          rgba(0, 0, 0, calc(var(--an-text-shadow-strength, 0) * 0.09));
}

/* Counter-card text legibility shadow. Driven by the
   --an-card-text-shadow-strength custom property (1-10, emitted by every
   variant's renderer when the admin slider is > 0). Same layered black drop
   shadow shape as the header shadow, scoped to the counter cards' own text
   (value, label, description) so each card reads on its own surface — the dark
   and overlay presets render white text on dark fills, the minimal/cards
   presets can opt in for depth. At strength 0 the custom property is absent and
   every var() fallback (0) collapses the calcs to a no-op shadow. Generic
   (not preset-scoped) because card_text_shadow is a shared Number Cards knob. */
[data-module-type^="animated_number"] .an-value,
[data-module-type^="animated_number"] .an-label,
[data-module-type^="animated_number"] .an-counter-description {
    text-shadow:
        0 calc(var(--an-card-text-shadow-strength, 0) * 0.2px)
          calc(var(--an-card-text-shadow-strength, 0) * 0.6px)
          rgba(0, 0, 0, calc(var(--an-card-text-shadow-strength, 0) * 0.09)),
        0 calc(var(--an-card-text-shadow-strength, 0) * 0.1px)
          calc(var(--an-card-text-shadow-strength, 0) * 0.3px)
          rgba(0, 0, 0, calc(var(--an-card-text-shadow-strength, 0) * 0.09));
}

/* Decorative background image filling the root behind the overlay and content.
   Stacked below ::before (z-index 1) and the content (z-index 2); object-fit:
   cover mirrors the previous background-size: cover behavior. */
.animated-number--horizontal_cards .an-bg-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
    pointer-events: none;
    user-select: none;
}

/* Uniform darkening overlay painted behind the content via ::before. The
   strength is driven by the --an-overlay custom property (0.00–0.80, set by the
   renderer from the admin range slider), so a single rule covers every value
   instead of a fixed enum. It covers the ENTIRE background (a solid translucent
   black fill), not just the bottom — previously a bottom-only gradient left the
   top of the image unobscured and the text illegible there. The .an-bg-overlay
   modifier is emitted only when the strength is positive, so 0 disables the
   layer entirely. Stacked above the background image but below the content
   (z-index: 1 vs the content's auto/0). */
.animated-number--horizontal_cards.an-bg-overlay::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, var(--an-overlay, 0.3));
    z-index: 1;
    pointer-events: none;
}

/* Lift every direct child above the ::before overlay so text stays legible. */
.animated-number--horizontal_cards > * {
    position: relative;
    z-index: 2;
}

/* Module header row: title column + description column side by side, baseline
   aligned to the bottom (reference t_pb_row_24 align-items: flex-end). On small
   screens the columns stack vertically. */
.an-header {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 1.5rem 2rem;
    margin-bottom: clamp(1.5rem, 4vw, 3rem);
}

.an-title-col {
    flex: 1 1 320px;
    min-width: 0;
}

.an-desc-col {
    flex: 1 1 320px;
    min-width: 0;
}

.an-module-title {
    margin: 0;
    font-size: var(--fs-display, clamp(2rem, 5vw, 3.25rem));
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: var(--an-title-color, #ffffff);
}

.an-module-description {
    margin: 0;
    font-size: var(--fs-body, 1rem);
    line-height: 1.6;
    color: var(--an-description-color, #ffffff);
}

/* Per-language main card link (Ana Kart). Two display modes mirror the listing
   read-more button/text toggle: a solid primary pill (.an-card-link--button,
   default) or a bare text link (.an-card-link--text). Both are mode-aware via
   theme tokens so they adapt to the 5 palettes + dark mode automatically. */
.an-card-link {
    display: inline-flex;
    align-items: center;
    margin-top: 16px;
    font-size: var(--fs-lead, 1rem);
    font-weight: 600;
    line-height: 1.4;
    text-decoration: none;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

.an-card-link--button {
    padding: 8px 18px;
    border-radius: 999px;
    color: var(--on-primary, #ffffff);
    background-color: var(--primary-color, #1d6b5e);
    border: 1px solid transparent;
}

.an-card-link--button:hover,
.an-card-link--button:focus-visible {
    /* color is re-declared so the site-wide a:hover rule does not repaint the
       button text onto the hover background (which would make it unreadable). */
    color: var(--on-primary, #ffffff);
    background-color: var(--primary-deep, #155449);
}

.an-card-link--text {
    padding: 0;
    /* The admin override is emitted by the renderer as --an-link-color-light on
       the module root; when absent (no override) the fallback resolves to the
       theme's --primary-color. The dark-mode variant below handles
       --an-link-color-dark. The base color is captured in --an-link-current so
       the hover rule can darken IT (not currentColor, which would be circular
       once :hover repaints color). */
    --an-link-current: var(--an-link-color-light, var(--primary-color, #1d6b5e));
    color: var(--an-link-current);
    background-color: transparent;
    border: 0;
    border-radius: 0;
}

[data-bs-theme="dark"] .an-card-link--text {
    --an-link-current: var(--an-link-color-dark, var(--an-link-color-light, var(--primary-color, #1d6b5e)));
}

.an-card-link--text:hover,
.an-card-link--text:focus-visible {
    /* Darken the link's own color (override or theme primary) on hover. Mixing
       the captured --an-link-current with black avoids the circular currentColor
       issue. Falls back to --primary-deep on browsers without color-mix. */
    color: color-mix(in srgb, var(--an-link-current) 80%, #000);
}

/* The counter grid keeps the shared .an-counter cell, but adds a muted
   description paragraph under each label (reference et_pb_text_34). The cell
   surface is translucent so the background shows through subtly. The horizontal
   cards root is a background panel (not the grid itself), so the responsive
   column grid lives on the inner .an-grid wrapper. */
.an-grid {
    display: grid;
    gap: var(--an-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* The horizontal_cards root is a background panel (not a grid), so the column
   count modifier classes target the inner .an-grid instead of the root. Mirrors
   the responsive collapse behaviour of the shared .animated-number--cols rules. */
.animated-number--horizontal_cards .an-grid.an-grid--cols-1 { grid-template-columns: 1fr; }
.animated-number--horizontal_cards .an-grid.an-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-6 { grid-template-columns: repeat(6, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-7 { grid-template-columns: repeat(7, 1fr); }
.animated-number--horizontal_cards .an-grid.an-grid--cols-8 { grid-template-columns: repeat(8, 1fr); }

@media (max-width: 767.98px) {
    .animated-number--horizontal_cards .an-grid.an-grid--cols-3,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-4,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-5,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-6,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-7,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-8 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 575.98px) {
    .animated-number--horizontal_cards .an-grid.an-grid--cols-2,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-3,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-4,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-5,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-6,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-7,
    .animated-number--horizontal_cards .an-grid.an-grid--cols-8 {
        grid-template-columns: 1fr;
    }
}

/* Counter surface is driven by the transparent_background toggle, NOT by whether
   a background image is present. The .an-counter core rule reads its fill from
   the --an-surface-bg token, so both modes override the TOKEN (not background
   directly) to win cleanly over the preset default.
   - transparent_background OFF (default, :not(.an-transparent)): the counter
     takes the page card surface (--bg-color) with a subtle border + shadow,
     mirroring the team module's card. The value/label read with the page's text
     tokens. This is the card-grid look — the counters read as real cards on top
     of any backdrop (background image included, which sits behind them).
   - transparent_background ON (.an-transparent): a translucent dark wash so the
     backdrop reads through the counter while white text stays legible over the
     image.
   The tokens drive 5 palettes + dark mode automatically. */
.animated-number--horizontal_cards:not(.an-transparent) {
    --an-surface-bg: var(--bg-color, #fff);
    --an-value-color: var(--text-ink, #1a2421);
    --an-label-color: var(--text-muted, #5a6b66);
    --an-surface-border: var(--border-color, #e3e8e5);
    color: var(--text-color, #1a2421);
}

.animated-number--horizontal_cards:not(.an-transparent) .an-counter {
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0.04);
}

.animated-number--horizontal_cards:not(.an-transparent) .an-module-title {
    color: var(--an-title-color, var(--text-ink, #1a2421));
}

.animated-number--horizontal_cards:not(.an-transparent) .an-module-description {
    color: var(--an-description-color, var(--text-color, #1a2421));
}

.animated-number--horizontal_cards:not(.an-transparent) .an-counter-description {
    color: var(--an-counter-description-color, var(--text-muted, #5a6b66));
}

/* Transparent mode: a translucent dark wash so the counters stay legible over
   the background image (the backdrop reads through the counter) with white text.
   The horizontal_cards preset intentionally overrides the shared core "transparent
   clears the fill" behaviour (.animated-number.an-transparent[.an-frameless]
   .an-counter { background: transparent }), which would otherwise fully clear
   the counter for every variant. Specificity is raised to (0,5,0) — root + preset
   + transparent + frameless + cell — so it wins regardless of whether frameless
   is also on (the common case over a background image). */
.animated-number--horizontal_cards.an-transparent {
    --an-surface-bg: rgba(0, 0, 0, 0.15);
}

.animated-number.animated-number--horizontal_cards.an-transparent.an-frameless .an-counter,
.animated-number.animated-number--horizontal_cards.an-transparent:not(.an-frameless) .an-counter {
    background: rgba(0, 0, 0, 0.15);
}

.animated-number--horizontal_cards.an-transparent .an-counter-description {
    color: var(--an-counter-description-color, rgba(255, 255, 255, 0.78));
}

/* Counter description: spacing/size shared. Color resolves from (1) a dedicated
   --an-counter-description-color custom property emitted by the renderer when the
   admin sets a per-counter description color, falling back to (2) the inherited
   muted text token so the description reads as secondary copy. The
   horizontal_cards / vertical_cards preset overrides below raise specificity for
   their surface modes (opaque page text token / translucent white over an
   image), so this generic rule only governs variants without a preset override
   (minimal). */
.an-counter-description {
    margin: 0.5rem 0 0;
    font-size: var(--fs-body, 1rem);
    line-height: 1.6;
    color: var(--an-counter-description-color, var(--text-muted, #5a6b66));
}

/* Centered-text toggle (horizontal_cards / vertical_cards only). Centered is
   the default, so the modifier is added only when the admin opts into
   start-aligned text. text-align: start is a CSS logical property — it resolves
   to left in LTR and right in RTL automatically, so a single rule covers both
   text directions. The .an-value flex row pairs with justify-content: flex-start
   (flexbox respects the inherited direction, so flex-start lands on the
   inline-start edge in RTL as well). Scoped to .animated-number so it applies
   to both presets without a per-preset selector. */
.animated-number.an-text-start .an-counter {
    text-align: start;
}

.animated-number.an-text-start .an-value {
    justify-content: flex-start;
}

@media (max-width: 767.98px) {
    /* On small screens the title + description stack and shrink so the header
       does not dominate above the counters. */
    .an-header {
        align-items: flex-start;
    }
}

/* ============================================
   PRESET: vertical_cards (split panel: title/description left, counters right)
   ============================================ */
/* Same image-backed panel pattern as horizontal_cards (transparent surface,
   white text, background image behind a darkening overlay, root corner radius
   driven by --an-main-card-radius, frameless border toggle). The layout differs:
   the root is a two-column grid — a LEFT column (~40%) holding the main card
   title above its description, and a RIGHT column (~60%) holding the counter
   column grid. overflow: hidden clips the background image + overlay to the
   radius. */
.animated-number--vertical_cards {
    --an-surface-bg: transparent;
    --an-surface-border: rgba(255, 255, 255, 0.18);
    --an-cell-padding: 1.75rem 1rem;
    --an-value-color: #ffffff;
    --an-label-color: #ffffff;
    --an-value-size: clamp(2.25rem, 2.85rem, 3.25rem);
    position: relative;
    padding: clamp(2rem, 6vw, 5rem) clamp(1rem, 4vw, 3rem);
    color: #ffffff;
    overflow: hidden;
    border-radius: var(--an-main-card-radius, 0);
    /* The vertical split: ~40% left (title + description), ~60% right (counters). */
    display: grid;
    grid-template-columns: 40% 1fr;
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: center;
}

/* Main card panel border: shown only when the frameless toggle is OFF (mirrors
   horizontal_cards). Translucent white so it stays visible over the background
   image + dark overlay. */
.animated-number--vertical_cards:not(.an-main-card-frameless) {
    border: 1px solid var(--an-surface-border, rgba(255, 255, 255, 0.18));
}

/* Main card text vertical position (vertical_cards only). The base rule above
   defaults the root grid to align-items: center; these modifiers re-pin the
   LEFT column (.an-main-col — title + description) to the top or bottom edge so
   the admin can shift the header within the split panel. No modifier = center. */
.animated-number--vertical_cards.an-main-text-top {
    align-items: flex-start;
}

.animated-number--vertical_cards.an-main-text-bottom {
    align-items: flex-end;
}

/* Header text legibility shadow over the background image. Same layered black
   drop shadow as horizontal_cards, scoped to the vertical preset's title,
   description and a TEXT-style main card link (transparent over the image). The
   button-style link is excluded (it carries its own solid primary surface). At
   strength 0 the custom property is absent and every var() fallback (0)
   collapses the calcs to a no-op shadow. */
.animated-number--vertical_cards .an-module-title,
.animated-number--vertical_cards .an-module-description,
.animated-number--vertical_cards .an-card-link--text {
    text-shadow:
        0 calc(var(--an-text-shadow-strength, 0) * 0.2px)
          calc(var(--an-text-shadow-strength, 0) * 0.8px)
          rgba(0, 0, 0, calc(var(--an-text-shadow-strength, 0) * 0.09)),
        0 calc(var(--an-text-shadow-strength, 0) * 0.1px)
          calc(var(--an-text-shadow-strength, 0) * 0.3px)
          rgba(0, 0, 0, calc(var(--an-text-shadow-strength, 0) * 0.09));
}

/* Decorative background image filling the root behind the overlay and content
   (mirrors horizontal_cards). Stacked below the ::before overlay (z-index 1) and
   the content (z-index 2). */
.animated-number--vertical_cards .an-bg-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
    pointer-events: none;
    user-select: none;
}

/* Uniform darkening overlay painted behind the content via ::before (mirrors
   horizontal_cards). Driven by the --an-overlay custom property (0.00–0.80). */
.animated-number--vertical_cards.an-bg-overlay::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, var(--an-overlay, 0.3));
    z-index: 1;
    pointer-events: none;
}

/* Lift every direct child above the ::before overlay so text stays legible. */
.animated-number--vertical_cards > * {
    position: relative;
    z-index: 2;
}

/* LEFT column: main card title + description stacked vertically (the vertical
   split vs horizontal_cards, which lays them out as a flex row above the grid). */
.animated-number--vertical_cards .an-main-col {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

/* Override the generic .an-title-col / .an-desc-col flex sizing so they stack
   naturally inside the left column instead of sitting side by side. */
.animated-number--vertical_cards .an-main-col .an-title-col,
.animated-number--vertical_cards .an-main-col .an-desc-col {
    flex: none;
    min-width: 0;
}

/* RIGHT column: holds the counter grid. */
.animated-number--vertical_cards .an-counters-col {
    min-width: 0;
}

/* Counter grid column modifiers — vertical_cards supports 1-3 columns (clamped
   server-side; default 1). Mirrors horizontal_cards' inner .an-grid rule. */
.animated-number--vertical_cards .an-grid.an-grid--cols-1 { grid-template-columns: 1fr; }
.animated-number--vertical_cards .an-grid.an-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.animated-number--vertical_cards .an-grid.an-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }

/* Counter surface is driven by the transparent_background toggle (same behaviour
   as horizontal_cards). Opaque mode: the counter takes the page card surface
   (--bg-color) with white-override text tokens replaced by the page text tokens,
   so the counters read as real cards on top of any backdrop.
   transparent_background OFF (default, :not(.an-transparent)): page card surface. */
.animated-number--vertical_cards:not(.an-transparent) {
    --an-surface-bg: var(--bg-color, #fff);
    --an-value-color: var(--text-ink, #1a2421);
    --an-label-color: var(--text-muted, #5a6b66);
    --an-surface-border: var(--border-color, #e3e8e5);
    color: var(--text-color, #1a2421);
}

.animated-number--vertical_cards:not(.an-transparent) .an-counter {
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0.04);
}

.animated-number--vertical_cards:not(.an-transparent) .an-module-title {
    color: var(--an-title-color, var(--text-ink, #1a2421));
}

.animated-number--vertical_cards:not(.an-transparent) .an-module-description {
    color: var(--an-description-color, var(--text-color, #1a2421));
}

.animated-number--vertical_cards:not(.an-transparent) .an-counter-description {
    color: var(--an-counter-description-color, var(--text-muted, #5a6b66));
}

/* Transparent mode: a translucent dark wash so the counters stay legible over
   the background image (mirrors horizontal_cards). */
.animated-number--vertical_cards.an-transparent {
    --an-surface-bg: rgba(0, 0, 0, 0.15);
}

.animated-number.animated-number--vertical_cards.an-transparent.an-frameless .an-counter,
.animated-number.animated-number--vertical_cards.an-transparent:not(.an-frameless) .an-counter {
    background: rgba(0, 0, 0, 0.15);
}

.animated-number--vertical_cards.an-transparent .an-counter-description {
    color: var(--an-counter-description-color, rgba(255, 255, 255, 0.78));
}

/* Responsive: on tablet the two columns stack (title/description on top, counters
   below); on phone the counter grid narrows to fewer columns. */
@media (max-width: 991.98px) {
    .animated-number--vertical_cards {
        grid-template-columns: 1fr;
        align-items: stretch;
    }
}

@media (max-width: 767.98px) {
    .animated-number--vertical_cards .an-grid.an-grid--cols-3 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 575.98px) {
    .animated-number--vertical_cards .an-grid.an-grid--cols-2,
    .animated-number--vertical_cards .an-grid.an-grid--cols-3 {
        grid-template-columns: 1fr;
    }
}

/* ============================================
   PRESET: minimal (typography-led card grid)
   ============================================ */
/* Counter surface is driven by the transparent_background toggle (same behaviour
   as horizontal_cards). The default (transparent_background OFF) is an opaque
   page card surface (--bg-color, one step above the content wrapper's --card-bg
   so the counter cards read as a real hierarchy) with a subtle border + shadow.
   Turning transparent_background ON drops the fill so the counters float
   directly on the page background. The tokens drive 5 palettes + dark mode
   automatically. */

.animated-number--minimal {
    --an-surface-bg: var(--bg-color, #fff);
    --an-surface-border: var(--border-color, #e3e8e5);
    --an-cell-padding: 1rem 0.5rem;
    --an-value-color: var(--text-ink, #1a2421);
    --an-label-color: var(--text-muted, #5a6b66);
    --an-value-size: clamp(2.5rem, 3.25rem, 4rem);
    --an-value-weight: 800;
    color: var(--text-color, #1a2421);
}

.animated-number--minimal .an-counter {
    position: relative;
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0.04);
}

/* A short, low-opacity accent centered above the number — a quiet typographic
   cue rather than a heavy full-width rule. Kept narrow and translucent so it
   reads as part of the minimal, typography-led preset instead of a loud bar. */
.animated-number--minimal .an-counter::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 2rem;
    height: 2px;
    background: var(--primary-color, #1d6b5e);
    opacity: 0.35;
    border-radius: 4px;
}

/* Transparent mode: clears the counter fill so the counters float directly on
   the page background (the shared .an-transparent rule at the bottom of this
   file sets background: transparent; here we only reset the surface token so
   the core .an-counter rule stays consistent). */
.animated-number--minimal.an-transparent {
    --an-surface-bg: transparent;
}

/* ============================================
   APPEARANCE VARIANTS (transparent / frameless)
   ============================================ */
/* Both toggles drop the card surface so the counters float directly on the
   page background. transparent removes the background fill (keeps the border
   unless frameless is also on); frameless removes the border + shadow. Applied
   on the root so they compose with any preset. */

.animated-number.an-transparent .an-counter {
    background: transparent;
    box-shadow: none;
}

.animated-number.an-frameless .an-counter {
    border-color: transparent;
    box-shadow: none;
}

.animated-number.an-transparent.an-frameless .an-counter {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
}

/* ============================================
   HOVER-EFFECT VARIANTS (data-hover-effect)
   ============================================ */
/* Card hover is opt-in: the chosen effect is read from the root container's
   data-hover-effect attribute and applies to every .an-counter cell. Mirrors the
   pages-magazine family. Default "none" keeps the counters inert. Selectors are
   scoped to [data-module-type^="animated_number"] so the variants never leak
   into other modules. animated number has no photo, so zoom is adapted to the
   number itself (a subtle scale) instead of an image. */

[data-module-type^="animated_number"][data-hover-effect="none"] .an-counter {
    transition: none;
}

/* HOVER: lift (the counter rises with a deeper shadow) */
[data-module-type^="animated_number"][data-hover-effect="lift"] .an-counter:hover {
    transform: translateY(-4px);
    border-color: var(--border-strong, #b9c2bd);
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0.06),
                0 8px 16px rgba(26, 36, 33, 0.12);
}

/* HOVER: overlay (a tonal wash slides over the counter body) */
[data-module-type^="animated_number"][data-hover-effect="overlay"] .an-counter {
    position: relative;
    overflow: hidden;
}

[data-module-type^="animated_number"][data-hover-effect="overlay"] .an-counter::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--primary-tint, rgba(29, 107, 94, 0.08));
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    z-index: 0;
}

[data-module-type^="animated_number"][data-hover-effect="overlay"] .an-counter > * {
    position: relative;
    z-index: 1;
}

[data-module-type^="animated_number"][data-hover-effect="overlay"] .an-counter:hover::after {
    opacity: 1;
}

[data-module-type^="animated_number"][data-hover-effect="overlay"] .an-counter:hover {
    border-color: var(--primary-color, #1d6b5e);
}

/* HOVER: zoom (no photo — the number itself scales up slightly) */
[data-module-type^="animated_number"][data-hover-effect="zoom"] .an-counter:hover .an-value {
    transform: scale(1.06);
}

.an-value {
    transition: transform 0.3s ease;
}

[data-module-type^="animated_number"][data-hover-effect="zoom"] .an-counter:hover {
    border-color: var(--border-strong, #b9c2bd);
}

/* HOVER: glow (a primary halo via an inset ring + tight outer glow). The ring
   is painted by an ::after layer stacked above the cell content (z-index: 2) so
   the number is not covered. */
[data-module-type^="animated_number"][data-hover-effect="glow"] .an-counter {
    position: relative;
    overflow: hidden;
}

[data-module-type^="animated_number"][data-hover-effect="glow"] .an-counter::after {
    content: "";
    position: absolute;
    inset: 0;
    box-shadow: inset 0 0 0 2px var(--primary-color, #1d6b5e);
    background: var(--primary-tint, rgba(29, 107, 94, 0.08));
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    z-index: 2;
}

[data-module-type^="animated_number"][data-hover-effect="glow"] .an-counter:hover::after {
    opacity: 1;
}

[data-module-type^="animated_number"][data-hover-effect="glow"] .an-counter:hover {
    border-color: var(--primary-color, #1d6b5e);
    box-shadow: 0 4px 12px rgba(29, 107, 94, 0.28);
}

/* Dark mode — shadow-bearing effects read deeper against dark cards. */
[data-bs-theme="dark"] [data-module-type^="animated_number"][data-hover-effect="lift"] .an-counter:hover {
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.5);
}

[data-bs-theme="dark"] [data-module-type^="animated_number"][data-hover-effect="glow"] .an-counter:hover {
    box-shadow: 0 4px 12px rgba(29, 107, 94, 0.4);
}

/* ============================================
   REDUCED MOTION
   ============================================ */

@media (prefers-reduced-motion: reduce) {
    .an-counter,
    .an-value {
        transition: none;
    }

    .an-counter:hover {
        box-shadow: none;
        transform: none;
    }

    .an-counter:hover .an-value {
        transform: none;
    }
}
