/* Billanz kit — functional base (structure + visibility). Cosmetics live in skins. */
.billanz-price [hidden],
.billanz-buy[hidden] {
    display: none !important;
}

.billanz-price__row {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35em;
    flex-wrap: wrap;
}

.billanz-period-switcher {
    display: inline-flex;
    gap: 0.25rem;
    flex-wrap: wrap;
}

.billanz-buy {
    display: inline-block;
}

.billanz-buy--disabled {
    pointer-events: none;
}

/* The amount and the button must never break onto a second line. */
.billanz-price__amount,
.billanz-buy {
    white-space: nowrap;
}

/* Block-level text alignment (core has-text-align-* convention) — defined here
   too so alignment works even where block-library styles do not load. The slash
   before the cycle is real markup now (.billanz-price__slash), not a ::before. */
.billanz-price.has-text-align-left { text-align: left; }
.billanz-price.has-text-align-center { text-align: center; }
.billanz-price.has-text-align-right { text-align: right; }

/* Currency switcher — layout + a neutral button that inherits the surrounding
   text colour (works on light and dark skins); skins may override. */
.billanz-currency-switcher--horizontal { display: inline-flex; gap: 0.25rem; flex-wrap: wrap; }
.billanz-currency-switcher--vertical { display: inline-flex; flex-direction: column; gap: 0.25rem; }
.billanz-currency-switcher__btn {
    padding: 0.35em 0.8em; border: 1px solid currentColor; border-radius: 8px;
    background: transparent; color: inherit; font-weight: 600; cursor: pointer; opacity: 0.55;
}
.billanz-currency-switcher__btn.is-active { opacity: 1; }
.billanz-currency-switcher__btn:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* Tighter gap between the pricing columns (themes default to a large one). */
.billanz-price-table .wp-block-columns {
    gap: 1.25rem;
}

/* Suppress the focus ring on mouse click (it looks broken over the minimal
   buttons); keep it for keyboard users via :focus-visible for accessibility. */
.billanz-period-switcher__btn:focus:not(:focus-visible),
.billanz-buy:focus:not(:focus-visible) {
    outline: none;
    box-shadow: none;
}

/* Comparison table — a feature-by-feature grid built from stacked columns
   rows. Structure only (alignment); palette lives in the skins. */
.billanz-comparison__head,
.billanz-comparison__row {
    align-items: center;
}
.billanz-comparison__plan,
.billanz-comparison__cell {
    text-align: center;
}
.billanz-comparison__feature {
    text-align: left;
}
/* Feature-label column is wider than the plan columns so long labels
   (e.g. "Priority support") don't wrap. */
.billanz-comparison__head > .billanz-comparison__feature,
.billanz-comparison__row > .billanz-comparison__feature {
    flex-grow: 1.6;
}

/* A stacked comparison loses which plan a value belongs to, so the whole grid
   keeps its columns side-by-side and scrolls horizontally on narrow screens.
   Scoped to `.billanz-comparison` (not the inner grid wrapper) so it also fixes
   pattern instances inserted before the wrapper existed. */
.billanz-comparison {
    overflow-x: auto;
}
.billanz-comparison__head,
.billanz-comparison__row {
    min-width: 34rem;
}
@media (max-width: 781px) {
    .billanz-comparison .wp-block-columns {
        flex-wrap: nowrap !important;
    }
    /* Beat core's `.wp-block-columns:not(.is-not-stacked-on-mobile) >
       .wp-block-column { flex-basis:100% !important }` (specificity 0,3,1) with
       a 4-class selector so the columns stay in one row instead of stacking. */
    .billanz-comparison .billanz-comparison__head.wp-block-columns > .wp-block-column,
    .billanz-comparison .billanz-comparison__row.wp-block-columns > .wp-block-column {
        flex-basis: 0 !important;
        flex-grow: 1 !important;
    }
}

/* Freeze the feature-label column at the left edge while the plan columns
   scroll horizontally, so you never lose which feature a value belongs to.
   The opaque background that lets scrolled cells pass behind it is per-skin. */
.billanz-comparison__feature {
    position: sticky;
    left: 0;
    z-index: 1;
}

/* Compact the header CTA spacing so it doesn't tower over the feature rows. */
.billanz-comparison .billanz-buy-group {
    margin-top: 1rem;
}

/* Domain price table — a large per-TLD table (hundreds of rows) with a
   client-side extension filter. Structure only; palette lives in the skins. */
.billanz-tld-table__filter {
    display: block;
    box-sizing: border-box;
    width: 100%;
    max-width: 22rem;
    margin: 0 0 1rem;
    font: inherit;
}
/* The table can be wider than a phone and taller than is usable (hundreds of
   rows): scroll on both axes inside the container instead of squeezing the
   table or letting it run the whole length of the page. A max-height (set
   inline from the block's attribute) turns on vertical scroll; without it the
   container just grows to fit. */
.billanz-tld-table__scroll {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}
.billanz-tld-table__table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}
.billanz-tld-table__table th,
.billanz-tld-table__table td {
    white-space: nowrap;
}
/* Keep the header visible while the body scrolls vertically. Needs an opaque
   background so rows don't show through — the skins supply it on `thead th`. */
.billanz-tld-table__table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}
/* Amount columns read better right-aligned; the TLD column stays left. */
.billanz-tld-table__table th:not(:first-child),
.billanz-tld-table__table td:not(.billanz-tld-table__ext) {
    text-align: right;
}
.billanz-tld-table__caption {
    caption-side: top;
    text-align: left;
}
/* The filter hides non-matching rows client-side; no server round-trip. */
.billanz-tld-table__table tbody tr.is-hidden,
.billanz-tld-table__noresults[hidden] {
    display: none;
}
/* Coupon discount — struck catalog price before the discounted amount, injected
   by domain-coupon.js only when a discount applies; cosmetics live in the skins. */
.billanz-tld-table__original {
    text-decoration: line-through;
    margin-right: 0.4em;
    white-space: nowrap;
}
/* Discount loader — shown by domain-coupon.js while it applies the coupon to the
   whole table (above-the-fold rows resolve first; this covers the rest). */
.billanz-tld-table__loader {
    display: none;
    align-items: center;
    gap: 0.5em;
    margin: 0 0 1rem;
}
.billanz-tld-table__loader.is-active {
    display: flex;
}
.billanz-tld-table__spinner {
    width: 1em;
    height: 1em;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: billanz-tld-spin 0.7s linear infinite;
}
@keyframes billanz-tld-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .billanz-tld-table__spinner { animation-duration: 2s; }
}

/* "Sale" badge — present on every row, shown only once domain-coupon.js marks
   the row .is-sale. Cosmetics (colour) live in the skins. */
.billanz-tld-table__badge {
    display: none;
    margin-left: 0.5em;
    vertical-align: middle;
    font-size: 0.72em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: 4px;
    padding: 0.1em 0.45em;
}
.billanz-tld-table__table tbody tr.is-sale .billanz-tld-table__badge {
    display: inline-block;
}

/* Auth nav — show/hide by hydrated login state (JS sets the body class).
   Only ever hide; the visible variant keeps the theme's natural display so the
   core Navigation flex layout is never clobbered. Default (no class yet) shows
   the logged-out set, matching no-JS visitors. */
body:not(.billanz-logged-in) .billanz-auth--in { display: none; }
body.billanz-logged-in .billanz-auth--out { display: none; }

/* Domain search — pill form: the input grows, the TLD select + buttons hug the
   right on one no-wrap row. Register is FIRST in the DOM (so Enter = register),
   reordered after Transfer visually. Structure + size scale only; palette in the
   skins. Controls (font/padding) are em-based in the skins so the size modifier
   below scales the whole pill by setting the form font-size. */
.billanz-domain-search__form {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    font-size: 1rem;
}
.billanz-domain-search__input,
.billanz-domain-search__ext,
.billanz-domain-search__btn { font: inherit; }
.billanz-domain-search__input { flex: 1 1 auto; min-width: 0; order: 0; }
.billanz-domain-search__ext { flex: 0 0 auto; order: 1; }
.billanz-domain-search__btn { flex: 0 0 auto; white-space: nowrap; cursor: pointer; }
.billanz-domain-search__btn--transfer { order: 2; }
.billanz-domain-search__btn--register { order: 3; }

/* Size control (author-set). */
.billanz-domain-search--sm .billanz-domain-search__form { font-size: 0.9rem; }
.billanz-domain-search--lg .billanz-domain-search__form { font-size: 1.15rem; }

/* Stack cleanly on narrow screens — never overflow horizontally. */
@media (max-width: 600px) {
    .billanz-domain-search__form { flex-wrap: wrap; }
    .billanz-domain-search__input { flex: 1 1 100%; }
    .billanz-domain-search__ext,
    .billanz-domain-search .ts-wrapper,
    .billanz-domain-search__btn { flex: 1 1 auto; }
}

/* When JS enhances the TLD <select> into a Tom Select combobox, the generated
   .ts-wrapper takes the select's place in the pill row. Structure only; the
   control/dropdown palette lives in the skins. */
.billanz-domain-search .ts-wrapper {
    flex: 0 0 auto;
    order: 1;
    min-width: 7rem;
    font: inherit;
}

/* Coupon discount — the struck catalog price sits before the discounted amount.
   Injected by coupon.js only when a discount applies; cosmetics live in skins. */
.billanz-price__original {
    text-decoration: line-through;
    white-space: nowrap;
}

/* Out-of-stock badge — replaces the whole price when the catalog flags the
   product in_stock:false. Structure only; colours live in the skins. */
.billanz-price__stock {
    display: inline-block;
    white-space: nowrap;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.82em;
    border-radius: 6px;
    padding: 0.3em 0.75em;
}
