/**
 * CDA Plan Selector
 *
 * Every value an Elementor control can change is a custom property declared on
 * .cda-plans, so the widget's controls write ONE variable each instead of a
 * rule per element, and a theme or a page can override the same names without
 * fighting specificity.
 *
 * The selected card's appearance comes from :has(:checked) and from sibling
 * selectors on the real radio input - never from a class toggled by script.
 * That is what keeps the editor canvas correct, where widgets are re-rendered
 * without any JS init pass ever running.
 */

.cda-plans {
    --cda-plan-accent: #3fd07a;

    --cda-plan-gap: 12px;
    --cda-plan-padding: 18px 22px;
    --cda-plan-radius: 12px;
    --cda-plan-border-width: 2px;
    --cda-plan-border-color: #23262f;
    --cda-plan-border-color-selected: var(--cda-plan-accent);
    --cda-plan-bg: #12141b;
    --cda-plan-bg-selected: var(--cda-plan-bg);

    --cda-plan-radio-size: 22px;
    --cda-plan-radio-border: #3a3f4d;
    --cda-plan-radio-fill: var(--cda-plan-accent);
    --cda-plan-radio-dot: #ffffff;
    --cda-plan-radio-gap: 14px;

    --cda-plan-label-color: #ffffff;
    --cda-plan-price-color: #ffffff;
    --cda-plan-period-color: #8b92a5;
    --cda-plan-desc-color: #8b92a5;
    --cda-plan-badge-color: #06120b;
    --cda-plan-badge-bg: var(--cda-plan-accent);

    --cda-plan-btn-color: var(--cda-plan-accent);
    --cda-plan-btn-bg: rgba(63, 208, 122, 0.14);
    --cda-plan-btn-border: transparent;
    --cda-plan-btn-color-hover: #06120b;
    --cda-plan-btn-bg-hover: var(--cda-plan-accent);
    --cda-plan-btn-border-hover: transparent;
    --cda-plan-btn-padding: 12px 24px;
    --cda-plan-btn-radius: 12px;
    --cda-plan-btn-icon-size: 1.1em;

    display: flex;
    flex-direction: column;
    gap: var(--cda-plan-gap);
    margin: 0;

}

/**
 * Each card is paired with its own button in a .cda-plan-group, purely so
 * `:has()` can tell which button belongs to which radio. The group is
 * display:contents, so it draws nothing and disappears from layout entirely -
 * the cards and the buttons are flex children of .cda-plans, exactly as if the
 * grouping were not there, and the widget's gap applies between them as normal.
 *
 * `order` is what puts the buttons after every card despite being interleaved
 * in source: cards keep the default order 0, buttons take 1.
 */
.cda-plan-group {
    display: contents;
}

/**
 * Only the checked plan's button is on screen. display:none also takes the
 * others out of the accessibility tree, so a screen reader is offered one
 * Subscribe, not one per plan.
 *
 * The three rules are a deliberate ladder. A browser without :has() drops the
 * last two entirely and is left with the middle one, which shows the button the
 * server marked is-active - the pre-selected plan - so the widget still works,
 * it just cannot follow a change of selection. Where :has() does work, the
 * third rule hides the button of any plan that is NOT checked (which is what
 * retires is-active once a choice is made) and the fourth shows the one that
 * is.
 *
 * The third rule is written against the group rather than against is-active on
 * purpose, and the two must stay at equal specificity - both (0,4,0), settled
 * by source order. An earlier version hid is-active with
 * `.cda-plans:has(...) .cda-plans__submit.is-active`, which is (0,5,0) and so
 * outranked the rule meant to show the checked button: the pre-selected plan's
 * button could never appear, and selecting it made the button vanish. If you
 * touch these selectors, count the specificity - source order alone decides
 * nothing when the weights differ.
 *
 * !important on all four because this is the purchase path, not decoration: a
 * theme rule setting `display` on links would otherwise be able to leave the
 * widget with no button at all, or with one per plan. Among !important
 * declarations the cascade still runs on specificity, so the ladder's order is
 * unchanged. Nothing in the panel controls button visibility.
 */
.cda-plans__submit {
    order: 1;
    display: none !important;
}

.cda-plans__submit.is-active {
    display: flex !important;
}

.cda-plan-group:not(:has(.cda-plan__input:checked)) .cda-plans__submit {
    display: none !important;
}

.cda-plan-group:has(.cda-plan__input:checked) .cda-plans__submit {
    display: flex !important;
}

/**
 * The card is the <label>, so the whole surface is the radio's hit area and
 * its accessible name - no click handler, no aria-label to keep in sync.
 *
 * A flex column of two parts: one row holding radio, name and price, then the
 * description under it. Explicitly NOT a grid - a grid's price column has to
 * negotiate its width against the name column, and in a narrow container it
 * loses, dropping the price onto its own line and splitting the period off
 * again below that. A flex row cannot do this: the name is the only thing that
 * may shrink, so the price stays pinned to the right at every width.
 *
 * The description lines up with the name above it through a padding that is
 * computed from the radio's own size variable, so resizing the radio from the
 * panel keeps the indent correct with nothing to keep in sync by hand.
 */
.cda-plan {
    display: flex;
    flex-direction: column;
    gap: 6px;

    box-sizing: border-box;
    padding: var(--cda-plan-padding);
    background: var(--cda-plan-bg);
    border: var(--cda-plan-border-width) solid var(--cda-plan-border-color);
    border-radius: var(--cda-plan-radius);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.cda-plan:has(.cda-plan__input:checked) {
    background: var(--cda-plan-bg-selected);
    border-color: var(--cda-plan-border-color-selected);
}

/* Keyboard focus lands on the visually hidden input, so the ring has to be
   drawn on the card the user can actually see. */
.cda-plan:has(.cda-plan__input:focus-visible) {
    outline: 2px solid var(--cda-plan-accent);
    outline-offset: 2px;
}

.cda-plan--unavailable {
    cursor: not-allowed;
    opacity: 0.5;
}

/**
 * Hidden from sight, not from the accessibility tree or the keyboard: the input
 * stays focusable and stays a real radio group, which is where arrow-key
 * navigation and the "2 of 2" announcement come from.
 */
.cda-plan__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/**
 * Radio, name and price, and it never wraps.
 *
 * `flex-wrap: nowrap` is the point. Let this row wrap and the two cards in a
 * pair stop matching: a short price stays beside its name while a longer one
 * on the card below drops to a line of its own, and the pair reads as broken
 * rather than as a set. Instead the type shrinks at the breakpoints at the
 * foot of this file, so name and price scale down together and stay side by
 * side. Only past that does the name give way - min-width: 0 lets the heading
 * shrink past its longest word and the name wraps or breaks - so the price is
 * on the name's line on every card at every width.
 */
.cda-plan__row {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    column-gap: var(--cda-plan-radio-gap);
}

.cda-plan__radio {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    box-sizing: border-box;
    width: var(--cda-plan-radio-size);
    height: var(--cda-plan-radio-size);
    border: 2px solid var(--cda-plan-radio-border);
    border-radius: 50%;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* The dot is sized as a fraction of the control rather than in pixels, so
   resizing the radio from the panel keeps its proportions. */
.cda-plan__radio::after {
    content: "";
    width: 36%;
    height: 36%;
    border-radius: 50%;
    background: var(--cda-plan-radio-dot);
    transform: scale(0);
    transition: transform 0.15s ease;
}

.cda-plan:has(.cda-plan__input:checked) .cda-plan__radio {
    border-color: var(--cda-plan-radio-fill);
    background: var(--cda-plan-radio-fill);
}

.cda-plan:has(.cda-plan__input:checked) .cda-plan__radio::after {
    transform: scale(1);
}

.cda-plan__heading {
    /* The only flexible item in the row: it absorbs every spare pixel, and it
       is the only thing that gives way when there are none. min-width: 0 lets
       it shrink past its own min-content so the row never has to wrap; the
       name's overflow-wrap below is what keeps that from turning into text
       spilling over the price. */
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.cda-plan__label {
    /* min-width: 0 alongside the wrap is what makes the safety net actually
       catch. The heading may shrink past its contents, but this label is a
       flex item in turn, and without min-width: 0 its own automatic minimum
       holds it at the width of the word - so the word does not break, it
       simply overflows to the right, eats the gap and lands on top of the
       price. The two together mean the name wraps or breaks instead, and the
       gap survives at any width. */
    min-width: 0;
    overflow-wrap: break-word;
    color: var(--cda-plan-label-color);

    font-size: 1.15em;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.cda-plan__badge {
    color: var(--cda-plan-badge-color);
    background: var(--cda-plan-badge-bg);
    border-radius: 999px;
    padding: 2px 8px;
    font-size: 0.7em;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.cda-plan__price {
    /* Pushed right by auto margin rather than by space-between, so it stays
       right-aligned on the wrapped line too, where it is the only item. */
    flex: 0 0 auto;
    margin-left: auto;

    /* Flex, not inline text, so the amount and the period cannot be stacked by
       a stray `display: block` on WooCommerce's price markup from elsewhere on
       the site - inside a flex container a child's display is blockified and
       the declaration stops mattering. Baseline alignment keeps the small
       period sitting on the price's baseline rather than floating mid-height.
       The card aligns its columns to flex-start, so the price sits on the
       name's line even when the description runs to several lines. */
    display: flex;
    align-items: baseline;
    justify-content: flex-end;

    color: var(--cda-plan-price-color);

    /* em, not px, so the breakpoints at the foot of this file can scale the
       whole card from one lever. The period and the amount inside are in em
       too, so they follow this without rules of their own. */
    font-size: 1.15em;
    font-weight: 800;
    line-height: 1.2;
    white-space: nowrap;
}

/**
 * The price is the widget's own element, deliberately NOT WooCommerce's
 * .woocommerce-Price-amount markup. Those class names are a magnet for
 * site-wide CSS - a theme or an older pricing block that sets a font-size or a
 * `display: block` on every price on the site reaches into this widget and
 * overrides the panel's Price control. That fight is unwinnable from a
 * stylesheet: a rule scoped by an ID outranks any number of classes however
 * much !important is thrown at it. Not rendering the hook is the only fix that
 * actually holds. See CDA_Plan_Source::format_price().
 */
.cda-plan__amount {
    color: inherit;
    font: inherit;
}

.cda-plan__period {
    color: var(--cda-plan-period-color);
    /*font-size: 0.72em;*/
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

/**
 * The description's width is settled here and nowhere else.
 *
 * It is a row of its own, not part of the name's column, so it gets the card's
 * full width and is never squeezed by however long the price happens to be -
 * the indent is only enough to line it up with the name above. Nothing in this
 * widget caps it. When it wraps well short of the card's right edge, something
 * outside is capping it: a theme's readability cap on text elements, or an
 * `align-items` that shrinks items to fit-content instead of stretching them.
 *
 * Both are neutralised below, and the three width properties carry !important
 * because the usual culprit is a rule scoped by an ID, which no amount of
 * specificity can outrank. It blocks nothing the editor can set: no control in
 * this widget touches the description's width. The properties that ARE
 * controlled - padding, colour, size, line height - are left ordinary so the
 * panel keeps its say.
 *
 * text-wrap: pretty only affects the wrap that remains - it keeps a single
 * short word off the last line where the browser supports it, and is ignored
 * where it does not.
 */
.cda-plans .cda-plan__description.cda-plan__description {
    align-self: stretch !important;
    width: 75% !important;
    max-width: none !important;
    padding-left: calc(var(--cda-plan-radio-size) + var(--cda-plan-radio-gap));
}

/* Type kept at ordinary weight, deliberately apart from the width hardening
   above: carried at (0,3,0) it also outranked the panel's own Description
   typography, which then appeared to do nothing. */
.cda-plan__description {
    color: var(--cda-plan-desc-color);
    font-size: 0.95em;
    line-height: 1.4;
    text-wrap: pretty;
}

/**
 * This is a <button>, and themes paint buttons hard: `.woocommerce
 * button.button` is (0,2,1), and a wrapper like `#content button` is (1,0,1),
 * which no number of classes can ever outrank. Raising specificity is a race
 * that cannot be won against an unknown theme, so the paint properties are
 * marked !important, scoped to this widget's own button and nothing else.
 *
 * Crucially this does NOT override the panel - it is what makes the panel
 * work. Every colour, padding and radius below reads a custom property, and
 * those properties are what the Button controls write (onto .cda-plans). The
 * !important defends the variable's VALUE from the theme; the value itself
 * still comes from whatever the editor chose.
 *
 * font-size and the rest are deliberately left ordinary, because the Button
 * typography control sets those directly and has to stay able to.
 */
.cda-plans .cda-plans__submit.cda-plans__submit {
    /* No display here: which button is visible is decided by the :has() ladder
       above, and repeating display:flex at this weight would show all of them. */
    align-items: center;
    justify-content: center;
    gap: 10px;

    box-sizing: border-box;
    width: 100%;
    padding: var(--cda-plan-btn-padding) !important;
    border: 2px solid var(--cda-plan-btn-border) !important;
    border-radius: var(--cda-plan-btn-radius) !important;
    background: var(--cda-plan-btn-bg) !important;
    color: var(--cda-plan-btn-color) !important;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.cda-plans .cda-plans__submit.cda-plans__submit:hover,
.cda-plans .cda-plans__submit.cda-plans__submit:focus-visible {
    background: var(--cda-plan-btn-bg-hover) !important;
    color: var(--cda-plan-btn-color-hover) !important;
    border-color: var(--cda-plan-btn-border-hover) !important;
}

.cda-plans .cda-plans__submit.cda-plans__submit svg,
.cda-plans .cda-plans__submit.cda-plans__submit i {
    width: var(--cda-plan-btn-icon-size);
    height: auto;
    font-size: var(--cda-plan-btn-icon-size);
    fill: currentColor;
}

/* Editor-only message; never rendered on the front end. */
.cda-plans__notice {
    padding: 16px;
    border: 1px dashed #b0b4bd;
    border-radius: 6px;
    color: #6d7280;
    font-size: 13px;
    text-align: center;
}

@media (prefers-reduced-motion: reduce) {
    .cda-plan,
    .cda-plan__radio,
    .cda-plan__radio::after,
    .cda-plans__submit {
        transition: none;
    }
}

/**
 * Narrow screens: shrink the type rather than let the name and price row break
 * apart.
 *
 * The ladder is anchored on the 400px step and stays gentle. An earlier
 * version dropped to roughly two thirds at the narrow end, which was far more
 * than the layout needed and just looked shrunken.
 *
 * Only the name and price step down at most breakpoints. They share a row, so
 * they are the pair that runs out of room; the description has a full-width
 * row of its own and needs barely any reduction, which is why it appears in
 * the last two steps only rather than being dragged along in every one.
 *
 * Each step restates the name, the price and the description at the selector
 * their base rule already uses - NOT a single font-size on .cda-plan for
 * everything inside to inherit. That one-lever version was the obvious way to
 * write this and it silently did nothing on the live site: something there
 * sets font-size on .cda-plan at a weight this cannot reach, so every step was
 * struck out in devtools while the children kept their own sizes. Restated on
 * the children, the rules land, because those are selectors the widget is
 * already winning with. The period and the amount are em against the price, so
 * they still follow without rules of their own. The gap comes down alongside,
 * since at these widths it is worth more as room for the name than as air.
 *
 * The steps are close together, and stronger than the screen width alone would
 * suggest, on purpose. This began as one fluid container query - the type
 * sized in cqi against the WIDGET, shrinking continuously - and the
 * container-type that needed caused layout trouble on the live site. A media
 * query can only ask about the screen, and the widget is a good deal narrower
 * than that: it sits inside a popup, inside a container, each taking its own
 * padding off the width. So a phone reporting 390px can easily leave the card
 * at 270px, and factors pitched for 390px leave the name and the price
 * touching. These are pitched for the card, not the screen. The floor lands
 * near 12px on the name, which is where the fluid version clamped too.
 *
 * The first two breakpoints are Elementor's own defaults, so the panel's
 * device preview agrees with the page; the rest are common handset widths. A
 * size set in the Typography control still wins over all of this, and it is
 * per-device there too.
 *
 * Because this measures the screen rather than the widget, a cramped column on
 * a wide monitor no longer shrinks - the name wraps there instead. That is
 * what the container query bought, and it is not worth the trouble it caused.
 */
@media (max-width: 1024px) {
    .cda-plan__label,
    .cda-plan__price {
        font-size: 1.1em;
    }
}

@media (max-width: 767px) {
    .cda-plan__label,
    .cda-plan__price {
        font-size: 1.06em;
    }
}

@media (max-width: 600px) {
    .cda-plans {
        --cda-plan-radio-gap: 12px;
    }

    .cda-plan__label,
    .cda-plan__price {
        font-size: 1.02em;
    }
}

@media (max-width: 480px) {
    .cda-plan__label,
    .cda-plan__price {
        font-size: 1em;
    }
}

@media (max-width: 400px) {
    .cda-plans {
        --cda-plan-radio-gap: 10px;
    }

    .cda-plan__label,
    .cda-plan__price {
        font-size: 0.97em;
    }

    .cda-plan__description {
        font-size: 0.94em;
    }
}

@media (max-width: 360px) {
    .cda-plans {
        --cda-plan-radio-gap: 9px;
    }

    .cda-plan__label,
    .cda-plan__price {
        font-size: 0.92em;
    }

    .cda-plan__description {
        font-size: 0.9em;
    }
}
