/* ---------- Card 1: TLD list — floating tiles ---------- */

/* Phương án F: outer panel containing 2×2 grid of TLD cells.
   Cells share the panel surface (no individual borders) and are
   separated only by thin inner dividers — feels like ONE quadrant
   grid rather than 4 floating cards.                                  */
.v3-public-sections .v3-tld-card {
    background: var(--v3-glass-bg-strong) !important;
    border: 1px solid var(--v3-glass-border-hi) !important;
    border-radius: var(--v3-radius-lg, 16px) !important;
    box-shadow: var(--v3-depth-2, 0 10px 30px rgba(0,0,0,0.35)) !important;
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    padding: 0 !important;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    overflow: hidden;          /* clip dividers to rounded corners */
}

.v3-public-sections .v3-tld-item {
    /* Phương án F cell: flat row, no own border/bg, dividers via
       border-right/bottom on nth-child below.  Layout = inline flex
       row so name / badge / action sit on ONE line.                  */
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 14px !important;
    padding: 18px 22px !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    backdrop-filter: none !important;
    box-shadow: none !important;
    text-align: left;
    cursor: pointer;
    transition: background 180ms ease;
    position: relative;
    min-height: 64px;
    font-family: var(--v3-display);
    color: var(--v3-ink);
}

/* Inner dividers — clean 2×2 grid feel without individual borders.
   nth-child(1,3) = left col → border-right
   nth-child(1,2) = top row  → border-bottom                            */
.v3-public-sections .v3-tld-card .v3-tld-item:nth-child(2n+1) {
    border-right: 1px solid rgba(255, 255, 255, 0.06) !important;
}
.v3-public-sections .v3-tld-card .v3-tld-item:nth-child(-n+2) {
    border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
}

/* Status accent via subtle GLASS TINT — no hard stripe.  A soft
   radial wash from the left edge fades into transparent, giving
   each cell a glass-like coloured glow that signals status without
   breaking the unified panel feel.                                      */
.v3-tld-item[data-status="available"] {
    background: radial-gradient(
        ellipse 80% 100% at 0% 50%,
        rgba(95, 227, 168, 0.10) 0%,
        rgba(95, 227, 168, 0.04) 35%,
        transparent 75%
    ) !important;
}
.v3-tld-item[data-status="registered"] {
    background: radial-gradient(
        ellipse 80% 100% at 0% 50%,
        rgba(217, 107, 107, 0.09) 0%,
        rgba(217, 107, 107, 0.035) 35%,
        transparent 75%
    ) !important;
}

/* Hover — intensify the tint slightly */
.v3-tld-item:hover {
    background: rgba(255, 255, 255, 0.025) !important;
}
.v3-tld-item[data-status="available"]:hover {
    background: radial-gradient(
        ellipse 90% 110% at 0% 50%,
        rgba(95, 227, 168, 0.16) 0%,
        rgba(95, 227, 168, 0.06) 40%,
        transparent 80%
    ) !important;
}
.v3-tld-item[data-status="registered"]:hover {
    background: radial-gradient(
        ellipse 90% 110% at 0% 50%,
        rgba(217, 107, 107, 0.14) 0%,
        rgba(217, 107, 107, 0.05) 40%,
        transparent 80%
    ) !important;
}

/* Selected — strongest wash + soft inset cyan ring */
.v3-tld-item.is-selected {
    background: rgba(37, 170, 225, 0.05) !important;
    box-shadow: inset 0 0 0 1px rgba(37, 170, 225, 0.20) !important;
}
.v3-tld-item.is-selected[data-status="available"] {
    background: radial-gradient(
        ellipse 100% 120% at 0% 50%,
        rgba(95, 227, 168, 0.20) 0%,
        rgba(95, 227, 168, 0.07) 45%,
        transparent 85%
    ) !important;
    box-shadow: inset 0 0 0 1px rgba(95, 227, 168, 0.28) !important;
}
.v3-tld-item.is-selected[data-status="registered"] {
    background: radial-gradient(
        ellipse 100% 120% at 0% 50%,
        rgba(217, 107, 107, 0.18) 0%,
        rgba(217, 107, 107, 0.06) 45%,
        transparent 85%
    ) !important;
    box-shadow: inset 0 0 0 1px rgba(217, 107, 107, 0.24) !important;
}

.v3-tld-name {
    /* flex row: grow to take remaining space, truncate if too long */
    flex: 1 1 auto;
    min-width: 0;
    grid-column: unset;
    grid-row: unset;
    align-self: center;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--v3-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.v3-tld-badge {
    flex: 0 0 auto;
    grid-column: unset;
    grid-row: unset;
    align-self: center;
    justify-self: end;
    font-family: var(--v3-mono);
    font-size: 9.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    padding: 4px 11px;
    border-radius: 999px;
    border: 1px solid currentColor;
    color: var(--v3-muted);
    line-height: 1.2;
}

.v3-tld-item[data-status="available"]  .v3-tld-badge { color: var(--v3-green); }
.v3-tld-item[data-status="registered"] .v3-tld-badge { color: var(--v3-red); opacity: 0.85; }
.v3-tld-item[data-status="checking"]   .v3-tld-badge {
    color: var(--v3-muted);
    opacity: 0.65;
    border-color: transparent;
    background: rgba(255,255,255,.03);
}

.v3-tld-badge .fa-spinner { font-size: 10px; color: var(--v3-accent); }

/* P1 layout — Available row hides the redundant 'Available' badge.
   Price pill + Register CTA + green radial bg already signal "free
   to register"; the text badge just competed with the price for
   visual weight.  Registered keeps its red badge because that row
   has no price pill — it needs an explicit status word.            */
.v3-tld-item[data-status="available"]  .v3-tld-badge { display: none; }
.v3-tld-item[data-status="checking"]   .v3-tld-badge { display: inline-flex; }   /* spinner still wanted */

/* Inline price badge — shows V3Pricing.getFinalPriceXRP() next to
   status when the TLD is available.  SNS-style (eth.sol → 310.5 SOL).
   Module: /js/v3-pricing.js · render: js/search.js syncTldList().    */
.v3-tld-price {
    flex: 0 0 auto;
    align-self: center;
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    margin-left: 4px;
    padding: 4px 11px;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    line-height: 1;
    white-space: nowrap;
    color: var(--v3-ink, #e8eaf0);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    min-height: 22px;
}
.v3-tld-price:empty { display: none; }
.v3-tld-price .v3-tld-price-num {
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.v3-tld-price .v3-tld-price-cur {
    font-size: 9.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption, 0.08em);
    color: var(--v3-accent, #25aae1);
    opacity: 0.92;
}
.v3-tld-price .fa-spinner {
    font-size: 10px;
    color: var(--v3-muted, #8993a1);
}
/* Available state — subtle green tint matches the (now-hidden) badge */
.v3-tld-item[data-status="available"] .v3-tld-price {
    background: rgba(95, 227, 168, 0.07);
    border-color: rgba(95, 227, 168, 0.18);
    transition: background-color 0.18s var(--v3-ease, ease),
                border-color 0.18s var(--v3-ease, ease);
}
.v3-tld-item[data-status="available"] .v3-tld-price-cur {
    color: var(--v3-green, #5fe3a8);
}
/* Hover polish — brighten the price pill in sync with the Register
   CTA glow so the whole right side reads as "actionable".          */
.v3-tld-item[data-status="available"]:hover .v3-tld-price {
    background: rgba(95, 227, 168, 0.14);
    border-color: rgba(95, 227, 168, 0.32);
}
/* Registered state — JS already clears textContent, but belt-and-braces
   in case some path renders content before status flips.              */
.v3-tld-item[data-status="registered"] .v3-tld-price { display: none; }

/* Mobile: tighten padding so price + badge + CTA all fit one row.    */
@media (max-width: 640px) {
    .v3-tld-price { padding: 3px 8px; margin-left: 2px; }
    .v3-tld-price .v3-tld-price-num { font-size: 12.5px; }

    /* H2 fix — stack 4 TLDs vertically so each row matches the search
       input width above (full container width), and CTA + price never
       get clipped at the right edge.                                   */
    .v3-public-sections .v3-tld-card {
        grid-template-columns: 1fr !important;
    }
    .v3-public-sections .v3-tld-card .v3-tld-item:nth-child(2n+1) {
        border-right: 0 !important;
    }
    .v3-public-sections .v3-tld-card .v3-tld-item:nth-child(-n+3) {
        border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
    }
    .v3-public-sections .v3-tld-card .v3-tld-item {
        padding: 16px 18px !important;
        min-height: 56px;
        gap: 10px !important;
        flex-wrap: wrap !important;          /* H3: wrap when name too long */
    }
    /* H3 — when domain name overflows, allow it to take its own row
       and push price + CTA to a second row below.  Prevents the CTA
       from being clipped off-screen on long names like
       "helloagainxrpfiwweffsfrfdfffd.rlusd".                          */
    .v3-public-sections .v3-tld-card .v3-tld-item .v3-tld-name {
        flex: 1 1 100%;
        word-break: break-all;
        overflow-wrap: anywhere;
        min-width: 0;
    }
    .v3-public-sections .v3-tld-card .v3-tld-item .v3-tld-badge,
    .v3-public-sections .v3-tld-card .v3-tld-item .v3-tld-price {
        flex: 0 0 auto;
    }
    /* Push the action button to the right end of the secondary row.   */
    .v3-public-sections .v3-tld-card .v3-tld-item .v3-tld-action {
        margin-left: auto;
    }

    /* H2 fix — replace the text "Register →" button with a compact
       circular arrow chip on mobile.  JS injects `.v3-tld-cta` inside
       the wrapper, so we target the inner button directly (not the
       outer span).  Keeps the affordance obvious without eating row
       width.                                                          */
    .v3-tld-item[data-status="available"] .v3-tld-cta {
        font-size: 0 !important;     /* hide "Register" text node */
        width: 36px !important;
        height: 36px !important;
        min-width: 36px !important;
        padding: 0 !important;
        border-radius: 999px !important;
        background: linear-gradient(135deg, var(--v3-accent, #25aae1), var(--v3-accent-soft, #5dc8f0)) !important;
        color: #050608 !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        gap: 0 !important;
        flex: 0 0 auto !important;
        box-shadow: 0 4px 12px -2px rgba(37, 170, 225, 0.4);
    }
    .v3-tld-item[data-status="available"] .v3-tld-cta i,
    .v3-tld-item[data-status="available"] .v3-tld-cta .fa-arrow-right {
        font-size: 14px !important;
        color: #050608 !important;
        margin: 0 !important;
    }
    /* Registered status — keep the "View" text, just compact it. */
    .v3-tld-item[data-status="registered"] .v3-tld-action,
    .v3-tld-item[data-status="registered"] .v3-tld-cta {
        font-size: 11px;
    }
}

.v3-tld-action {
    /* flex row: sit at far right after badge */
    flex: 0 0 auto;
    grid-column: unset;
    grid-row: unset;
    margin: 0;
    font-family: var(--v3-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-accent);
    opacity: 1;
    min-height: 0;
}

.v3-tld-action .v3-view-arrow {
    display: inline-block;
    transition: transform .2s var(--v3-ease);
}

.v3-tld-item:hover .v3-tld-action .v3-view-arrow {
    transform: translate(2px, -2px);
}

/* ---------- Card 2: Register hero ---------- */

/* ============================================================
   Currency selector pill (compact, single row).
   Rate (USD/XRP) is rendered INSIDE the RLUSD pill title via
   #v3-currency-rlusd-rate to avoid an extra row.  No separate
   USD preview block.
   Module: /js/v3-currency-wire.js · wireRegister() in checkBuy().
   ============================================================ */
.v3-currency-block {
    display: flex;
    justify-content: center;
    margin: 4px 0 -2px;
}
.v3-currency-selector {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background: rgba(255, 255, 255, 0.035);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 999px;
}
.v3-currency-pill {
    appearance: none;
    background: transparent;
    border: 0;
    color: var(--v3-mute, #8993a1);
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 5px 13px;
    border-radius: 999px;
    cursor: pointer;
    line-height: 1.1;
    transition: background-color 0.18s var(--v3-ease, ease),
                color 0.18s var(--v3-ease, ease);
}
.v3-currency-pill:hover:not(.is-disabled):not(.is-active) {
    background: rgba(255, 255, 255, 0.04);
    color: var(--v3-ink, #e8eaf0);
}
.v3-currency-pill.is-active {
    background: linear-gradient(135deg, var(--v3-accent, #25aae1), var(--v3-accent-soft, #b08cff));
    color: var(--v3-bg, #0e111a);
    box-shadow: 0 0 14px rgba(37, 170, 225, 0.22);
    transition: filter 0.18s var(--v3-ease, ease), box-shadow 0.18s var(--v3-ease, ease);
}
/* Audit UI/UX §1.2 — give the active pill a hover lift so it feels
   responsive instead of inert.                                      */
.v3-currency-pill.is-active:hover {
    filter: brightness(1.08);
    box-shadow: 0 0 22px rgba(37, 170, 225, 0.32);
}
.v3-currency-pill.is-disabled {
    cursor: not-allowed;
    opacity: 0.55;
}
.v3-currency-pill.is-disabled:hover {
    background: transparent;
}
.v3-currency-pill .v3-currency-rate {
    font-weight: 500;
    opacity: 0.85;
    margin-left: 2px;
    letter-spacing: 0;
}
/* P4 — Live indicator dot on RLUSD pill to signal "rate is fetched live",
   visually differentiating from static suffixes like " · native".  Pulses
   when rate is present; static when loading/n/a (see :empty sibling rule). */
.v3-currency-live-dot {
    display: inline-block;
    width: 5px;
    height: 5px;
    border-radius: 999px;
    background: var(--v3-green, #5fe3a8);
    margin: 0 4px 0 2px;
    vertical-align: middle;
    animation: v3-pulse-dot 1.8s ease-in-out infinite;
    box-shadow: 0 0 4px rgba(95, 227, 168, 0.5);
}
.v3-currency-pill.is-disabled .v3-currency-live-dot {
    background: var(--v3-mute, #8993a1);
    box-shadow: none;
    animation: none;
    opacity: 0.55;
}
.v3-currency-pill.is-warn .v3-currency-live-dot {
    background: #ffc864;
    box-shadow: 0 0 4px rgba(255, 200, 100, 0.5);
}
@keyframes v3-pulse-dot {
    0%, 100% { opacity: 1;   transform: scale(1); }
    50%      { opacity: 0.45; transform: scale(0.82); }
}
@media (prefers-reduced-motion: reduce) {
    .v3-currency-live-dot { animation: none; opacity: 0.8; }
}

/* ============================================================
   Audit UI/UX §1.1 — CSS-based tooltip on hover.  Replaces the
   slow + ugly native `title` attribute.  Reads from `data-tooltip`
   (set alongside the title in JS so screen readers + browsers
   with disabled CSS still see the native tooltip).
   §2.2 — hidden on touch devices (pointer:coarse) since hover
   doesn't fire there; mobile UX gets explicit hint instead (below).
   ============================================================ */
@media (hover: hover) and (pointer: fine) {
    .v3-currency-pill[data-tooltip] { position: relative; }
    .v3-currency-pill[data-tooltip]::after {
        content: attr(data-tooltip);
        position: absolute;
        bottom: calc(100% + 8px);
        left: 50%;
        transform: translateX(-50%) translateY(2px);
        background: rgba(14, 17, 26, 0.97);
        color: var(--v3-ink, #e8eaf0);
        font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
        font-size: 10.5px;
        font-weight: 500;
        letter-spacing: 0.02em;
        white-space: nowrap;
        padding: 5px 9px;
        border-radius: 6px;
        border: 1px solid rgba(255, 255, 255, 0.08);
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.12s var(--v3-ease, ease),
                    transform 0.12s var(--v3-ease, ease);
        z-index: 10;
    }
    .v3-currency-pill[data-tooltip]:hover::after,
    .v3-currency-pill[data-tooltip]:focus-visible::after {
        opacity: 1;
        transform: translateX(-50%) translateY(0);
    }
}

/* Audit UI/UX §2.2 — mobile-only hint badge below RLUSD pill when
   it's in warn state (trust line missing).  Hover-tooltip pattern
   doesn't work on touch, so we surface a tiny inline label.        */
@media (hover: none), (pointer: coarse) {
    .v3-currency-block {
        position: relative;
    }
    .v3-currency-pill.is-warn::before {
        content: 'tap to set up';
        position: absolute;
        bottom: -16px;
        left: 50%;
        transform: translateX(-50%);
        font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
        font-size: 9px;
        font-weight: 500;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: #ffc864;
        opacity: 0.85;
        white-space: nowrap;
        pointer-events: none;
    }
    .v3-currency-pill { position: relative; }
}

/* ============================================================
   Compact 2-row price block — replaces .v3-result-price-grid.
   Row 1 (tagline, small): "was 10 XRP · save 5 XRP"
   Row 2 (hero, large):    "You pay  5 XRP"
   Tagline auto-hidden when discount=0 (data-no-discount=1).
   ============================================================ */
.v3-result-price-compact {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 12px 18px 16px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 14px;
    margin: 6px 0;
}
.v3-price-tagline {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 11.5px;
    color: var(--v3-mute, #8993a1);
    line-height: 1;
}
.v3-price-was {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    opacity: 0.75;
}
.v3-price-strike {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(255, 255, 255, 0.4);
    /* A11y P4 — bump opacity 0.72 → 0.85 for safer contrast margin. */
    opacity: 0.85;
}
.v3-price-tagline-sep {
    opacity: 0.4;
}
.v3-price-save {
    color: var(--v3-green, #5fe3a8);
    font-weight: 600;
}
.v3-price-tagline-unit {
    font-weight: 500;
    opacity: 0.85;
    margin-left: 1px;
}
.v3-price-hero {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    line-height: 1;
}
.v3-price-hero-label {
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--v3-muted, #8993a1);
    opacity: 0.9;
}
.v3-price-hero-value {
    font-family: var(--v3-display);
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--v3-accent, #25aae1);
    /* Design-critique P3 — smooth fade across currency switch. */
    transition: opacity 0.16s var(--v3-ease, ease);
}
.v3-price-hero-unit,
.v3-price-tagline {
    transition: opacity 0.16s var(--v3-ease, ease);
}
.v3-price-hero.is-switching .v3-price-hero-value,
.v3-price-hero.is-switching .v3-price-hero-unit,
.v3-result-price-compact.is-switching .v3-price-tagline {
    opacity: 0.25;
}
@media (prefers-reduced-motion: reduce) {
    .v3-price-hero-value,
    .v3-price-hero-unit,
    .v3-price-tagline { transition: none; }
}
.v3-price-hero-unit {
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--v3-muted, #8993a1);
}
/* No-discount state — drop the strike-through tagline row entirely. */
.v3-register-card[data-no-discount="1"] .v3-price-tagline { display: none; }

/* ============================================================
   RLUSD trust line setup panel + pill warn state.
   Module: /js/v3-rlusd-trustline.js · UI wire: v3-currency-wire.js
   ============================================================ */

/* Warn state on the RLUSD pill — connected wallet, no trust line yet.
   Distinguish from `is-disabled` (no wallet) by a soft amber tint that
   reads as "actionable but needs setup".                              */
.v3-currency-pill.is-warn {
    color: #ffc864;
    opacity: 0.85;
}
.v3-currency-pill.is-warn:hover { opacity: 1; }

/* Inline trust-line setup panel — Design-critique P2 overlay mode.
   Sits ABOVE the price block without pushing content down, so the
   Register button stays at the same screen position when panel opens.
   Backdrop dims content underneath so user focus moves to the action. */
.v3-currency-block { position: relative; }
.v3-trustline-panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 8px;
    z-index: 4;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 14px;
    background: linear-gradient(135deg, rgba(255, 200, 100, 0.14), rgba(255, 200, 100, 0.06)),
                rgba(20, 23, 32, 0.97);
    border: 1px solid rgba(255, 200, 100, 0.32);
    border-radius: 12px;
    text-align: left;
    box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.6),
                0 0 24px rgba(255, 200, 100, 0.10);
    animation: v3-trustline-slide-in 0.22s var(--v3-ease, ease) both;
    backdrop-filter: blur(8px) saturate(120%);
}
.v3-trustline-panel[hidden] { display: none; }
@keyframes v3-trustline-slide-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.v3-trustline-panel-icon {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(255, 200, 100, 0.18);
    color: #ffc864;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    margin-top: 1px;
}
.v3-trustline-panel-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.35;
}
.v3-trustline-panel-title {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--v3-ink, #e8eaf0);
    letter-spacing: -0.005em;
}
.v3-trustline-panel-desc {
    font-size: 11.5px;
    color: var(--v3-mute, #8993a1);
}
.v3-trustline-panel-actions {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: center;
}
.v3-trustline-cancel,
.v3-trustline-setup {
    appearance: none;
    border: 0;
    cursor: pointer;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: 6px 12px;
    border-radius: 999px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    transition: background-color 0.18s var(--v3-ease, ease),
                color 0.18s var(--v3-ease, ease);
}
.v3-trustline-cancel {
    background: transparent;
    color: var(--v3-mute, #8993a1);
}
.v3-trustline-cancel:hover {
    background: rgba(255, 255, 255, 0.04);
    color: var(--v3-ink, #e8eaf0);
}
.v3-trustline-setup {
    background: linear-gradient(135deg, #ffc864, #ff9d4d);
    color: #1a1208;
    box-shadow: 0 0 12px rgba(255, 200, 100, 0.22);
}
.v3-trustline-setup:hover:not([disabled]) {
    filter: brightness(1.05);
    box-shadow: 0 0 18px rgba(255, 200, 100, 0.32);
}
.v3-trustline-setup[disabled],
.v3-trustline-setup.is-loading {
    cursor: progress;
    opacity: 0.78;
}
.v3-trustline-setup-arrow.fa-spinner { font-size: 10px; }

/* ============================================================
   A11y U1 — sr-only utility for screen-reader-only live regions.
   Standard pattern from WAI-ARIA / Tailwind sr-only.
   ============================================================ */
.v3-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
   Polish #3 — mint grid as ghost preview below the CTA.
   Pre-click: dimmed (opacity 0.42) with a hairline divider and a
              tiny eyebrow caption "After you register" so the user
              reads it as "preview", not as another set of controls.
   Post-click: buyDomainNew() drops .is-ghost → opacity 1 with a
              gentle fade-up so the active step takes focus.
   ============================================================ */
/* Framed mint preview block — clearly separates from CTA above.
   Border 8% alpha = visible hairline frame, not loud.  Caption sits
   inside box at top, always visible (text swaps via class).
   Larger margin-top (36px) carves a clear gap from the CTA glow.   */
.v3-mint-before {
    margin-top: 36px;
    /* Top padding bumped 14 → 22 so the caption ("MINT PROGRESS" /
       "AFTER YOU REGISTER") has breathing room from the border edge. */
    padding: 22px 18px 18px;
    position: relative;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.015);
    box-shadow: none;
    transform: translateY(0);
    transition: opacity 0.32s var(--v3-ease, ease),
                filter 0.32s var(--v3-ease, ease),
                border-color 0.32s var(--v3-ease, ease),
                background-color 0.32s var(--v3-ease, ease),
                box-shadow 0.32s var(--v3-ease, ease),
                transform 0.32s var(--v3-ease, ease);
}
.v3-mint-preview-caption {
    text-align: center;
    padding-top: 15px;
    margin-bottom: 16px;
    pointer-events: none;
}
.v3-mint-preview-caption-text {
    display: inline-block;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 9.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: rgba(255, 255, 255, 0.45);
    padding: 0 10px;
    transition: color 0.32s var(--v3-ease, ease);
}
/* Caption text swap via ::before content — ghost vs active. */
.v3-mint-before.is-ghost .v3-mint-preview-caption-text::before {
    content: 'After you register';
}
.v3-mint-before:not(.is-ghost) .v3-mint-preview-caption-text::before {
    content: 'Mint progress';
}
.v3-mint-before:not(.is-ghost) .v3-mint-preview-caption-text {
    color: var(--v3-accent, #25aae1);
}

/* Ghost preview — dimmed step cards, frame stays solid for clear
   "this is a labelled section" cue.                                  */
.v3-mint-before.is-ghost .v3-mint-before-grid {
    opacity: 0.45;
    filter: saturate(0.65);
    pointer-events: none;
    transition: opacity 0.32s var(--v3-ease, ease),
                filter 0.32s var(--v3-ease, ease);
}
.v3-mint-before:not(.is-ghost) .v3-mint-before-grid {
    opacity: 1;
    filter: saturate(1);
    animation: v3-mint-activate 0.42s var(--v3-ease, ease) both;
}
/* Active state — frame brightens + lifts ~2px with layered shadows so
   the user feels "now I'm focused inside this block".  Top hairline
   highlight + drop shadow + cyan ambient halo = 3D elevation feel.   */
.v3-mint-before:not(.is-ghost) {
    border-color: rgba(37, 170, 225, 0.28);
    background: rgba(37, 170, 225, 0.05);
    transform: translateY(-2px);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 14px 28px -10px rgba(0, 0, 0, 0.45),
        0 0 28px -4px rgba(37, 170, 225, 0.22);
}
@keyframes v3-mint-activate {
    from { opacity: 0.45; filter: saturate(0.65); transform: translateY(-3px); }
    to   { opacity: 1;    filter: saturate(1);    transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .v3-mint-before,
    .v3-mint-before .v3-mint-before-grid { animation: none; transition: none; }
}

/* ============================================================
   Polish #2 — inline 1-line "Set as primary" toggle (replaces the
   80px-tall .v3-primary-block card).  Description moved into a
   ⓘ tooltip so the body stays focused on price + CTA.
   ============================================================ */
.v3-primary-inline {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 2px auto 4px;
    padding: 6px 10px;
    cursor: pointer;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.85);
    border-radius: 999px;
    transition: background-color 0.18s var(--v3-ease, ease);
}
.v3-primary-inline:hover {
    background: rgba(255, 255, 255, 0.04);
}
.v3-primary-inline .v3-checkbox-input {
    position: absolute;
    width: 1px; height: 1px; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0);
}
.v3-primary-inline .v3-checkbox {
    width: 18px;
    height: 18px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.05);
    border: 1.5px solid rgba(255, 255, 255, 0.25);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: transparent;
    transition: all 0.18s var(--v3-ease, ease);
}
.v3-primary-inline .v3-checkbox-input:checked + .v3-checkbox {
    background: var(--v3-accent, #25aae1);
    border-color: var(--v3-accent, #25aae1);
    color: var(--v3-bg, #0e111a);
}
.v3-primary-inline .v3-checkbox-mark {
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
}
.v3-primary-inline .v3-checkbox-input:focus-visible + .v3-checkbox {
    outline: 2px solid var(--v3-accent, #25aae1);
    outline-offset: 2px;
}
.v3-primary-inline-label {
    line-height: 1.3;
    white-space: nowrap;
}

/* ⓘ tooltip — CSS-based, no JS.  Shows on hover (desktop) or focus
   (keyboard / touch focus).  data-tooltip attr carries the text.    */
.v3-primary-tip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.65);
    font-size: 12px;
    font-style: normal;
    cursor: help;
    position: relative;
    transition: background-color 0.18s var(--v3-ease, ease),
                color 0.18s var(--v3-ease, ease);
}
.v3-primary-tip:hover,
.v3-primary-tip:focus-visible {
    background: rgba(37, 170, 225, 0.18);
    color: var(--v3-accent, #25aae1);
    outline: none;
}
.v3-primary-tip[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%) translateY(2px);
    width: max-content;
    max-width: 280px;
    padding: 9px 12px;
    background: rgba(14, 17, 26, 0.98);
    color: var(--v3-ink, #e8eaf0);
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1.45;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    text-align: left;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.14s var(--v3-ease, ease),
                transform 0.14s var(--v3-ease, ease);
    z-index: 20;
}
.v3-primary-tip:hover::after,
.v3-primary-tip:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
@media (max-width: 520px) {
    .v3-primary-tip[data-tooltip]::after {
        max-width: 220px;
        left: auto;
        right: -8px;
        transform: translateY(2px);
    }
    .v3-primary-tip:hover::after,
    .v3-primary-tip:focus-visible::after { transform: translateY(0); }
}

/* ============================================================
   Design-critique #2 — STEP n OF 3 indicator pill in drawer header.
   Compact pill so the body of the card stays focused on the price
   + CTA decision moment.  setMintPhase() updates the text through
   the shared `.v3-mint-before-eyebrow` class.
   ============================================================ */
.v3-register-drawer-step {
    /* Override .v3-mint-before-eyebrow defaults for header context. */
    margin: 0 !important;
    padding: 4px 10px !important;
    font-family: var(--v3-mono, 'JetBrains Mono', monospace) !important;
    font-size: 9.5px !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.10em !important;
    color: var(--v3-accent, #25aae1) !important;
    background: rgba(37, 170, 225, 0.10) !important;
    border: 1px solid rgba(37, 170, 225, 0.25) !important;
    border-radius: 999px !important;
    white-space: nowrap;
    justify-self: end;
    line-height: 1;
}
@media (max-width: 520px) {
    .v3-register-drawer-step {
        font-size: 9px !important;
        padding: 3px 8px !important;
    }
}

/* ============================================================
   A11y O2 — visible focus indicator for all interactive elements
   inside the Register drawer (WCAG 2.4.7).  Outline-offset 2px
   gives the ring breathing room around pill shapes.
   ============================================================ */
.v3-currency-pill:focus-visible,
.v3-trustline-cancel:focus-visible,
.v3-trustline-setup:focus-visible {
    outline: 2px solid var(--v3-accent, #25aae1);
    outline-offset: 2px;
    border-radius: 999px;
}
.v3-register-drawer-back:focus-visible {
    outline: 2px solid var(--v3-accent, #25aae1);
    outline-offset: 2px;
    border-radius: 8px;
}

/* ============================================================
   Audit UI/UX §3.1 + §3.2 — Balance breakdown panel.
   Replaces hardcoded inline rgba(255,255,255,...) styles in the
   showInsufficientBalanceModal HTML builder.  Themeable.  100%
   max-width prevents iPhone-SE-width overflow.
   ============================================================ */
.v3-balance-breakdown {
    margin: 14px auto 0;
    padding: 10px 14px;
    max-width: 100%;        /* §3.2 — was 340px, now fluid */
    box-sizing: border-box;
    background: rgba(255, 255, 255, 0.025);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 10px;
    font-family: var(--v3-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 10.5px;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.68);
    text-align: left;
}
.v3-balance-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}
.v3-balance-divider {
    /* A11y P2 — bumped 0.06 → 0.14 for non-text contrast. */
    border-top: 1px solid rgba(255, 255, 255, 0.14);
    margin-top: 6px;
    padding-top: 6px;
}
.v3-balance-value {
    color: rgba(255, 255, 255, 0.92);
    font-weight: 500;
    white-space: nowrap;
}
.v3-balance-value.v3-balance-warn {
    color: rgba(251, 191, 36, 0.85);   /* amber — same hex tokenised */
}
.v3-balance-value.v3-balance-accent {
    color: var(--v3-accent, #5dc8f0);
    font-weight: 600;
}
.v3-balance-breakdown-note {
    color: rgba(255, 255, 255, 0.4);
    font-size: 9.5px;
    margin-left: 4px;
}

/* §3.3 audit fix — Insufficient-balance modal styling extracted from
   inline style attrs in search.html.  Keeping everything class-scoped
   means a future light-mode theme can override these via CSS variables
   without touching the JS that builds the markup.                     */
.v3-balance-modal {
    text-align: center;
    padding: 8px 4px;
}
.v3-balance-modal__icon {
    font-size: 32px;
    color: rgba(251, 191, 36, 0.95);
    margin-bottom: 10px;
}
.v3-balance-modal__heading {
    font-size: 14px;
    margin: 0 0 12px;
    color: var(--v3-ink, #fff);
    font-weight: 500;
}
.v3-balance-modal__body {
    font-size: 12px;
    color: rgba(255, 255, 255, 0.7);
    line-height: 1.55;
    margin: 0 0 4px;
}
.v3-balance-modal__hint {
    font-size: 10.5px;
    color: rgba(255, 255, 255, 0.45);
    display: block;
}
.v3-balance-modal__need-amt {
    color: var(--v3-accent-soft, #5dc8f0);
}
.v3-balance-modal__have-amt {
    color: rgba(255, 255, 255, 0.92);
}
.v3-balance-modal__setup-btn {
    margin-top: 18px;
    margin-right: 8px;
    background: linear-gradient(135deg, var(--v3-accent, #25aae1), var(--v3-accent-soft, #b08cff));
    color: var(--v3-bg, #0e111a);
    border: 0;
    padding: 9px 18px;
    border-radius: 999px;
    cursor: pointer;
    font-weight: 600;
    font-size: 12px;
}
.v3-balance-modal__close-btn {
    margin-top: 18px;
}

/* Audit UI/UX §2.3 — on mobile, stack Cancel/Enable buttons full-width
   so users don't fat-finger between them.  Min height 40px each.       */
@media (max-width: 520px) {
    .v3-trustline-panel { flex-wrap: wrap; }
    .v3-trustline-panel-actions {
        width: 100%;
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 10px;
        margin-top: 8px;
    }
    .v3-trustline-cancel,
    .v3-trustline-setup {
        width: 100%;
        min-height: 40px;
        font-size: 13px;
        padding: 10px 14px;
        justify-content: center;
    }
}

/* Compact Register card padding (was 48px 56px gap 18px → bloating drawer) */
.v3-public-sections .v3-register-card {
    padding: 28px 36px;
    gap: 12px;
}

@media (max-width: 640px) {
    /* A11y O3 — WCAG 2.5.5 target size ≥44px (was 36px after §2.1).
       Hard pass on touch devices.                                  */
    .v3-currency-pill { padding: 13px 16px; font-size: 12px; min-height: 44px; }
    .v3-currency-selector { padding: 4px; gap: 4px; }
    .v3-price-hero-value { font-size: 26px; }
    .v3-result-price-compact { padding: 10px 14px 13px; }
    .v3-public-sections .v3-register-card { padding: 22px 18px; gap: 10px; }
}

.v3-public-sections .v3-register-card {
    padding: 48px 56px;
    background: linear-gradient(180deg, rgba(37,170,225,.06), rgba(176,140,255,.03) 60%, transparent), var(--v3-glass-bg-strong);
    border: 1px solid var(--v3-glass-border-hi);
    border-radius: var(--v3-radius-lg);
    backdrop-filter: blur(14px) saturate(140%);
    box-shadow: var(--v3-depth-2);
    display: flex;
    flex-direction: column;
    gap: 18px;
    text-align: center;
    transition: border-color .3s var(--v3-ease), box-shadow .3s var(--v3-ease);
    position: relative;
}

.v3-register-card:hover {
    border-color: rgba(37,170,225,.3);
    box-shadow: var(--v3-depth-2), 0 0 28px rgba(37,170,225,.1);
}

.v3-register-card.is-loading {
    opacity: 0.5;
    pointer-events: none;
    transition: opacity .2s var(--v3-ease);
}

.v3-register-card.is-loading::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(5,6,8,.4);
    backdrop-filter: blur(2px);
    border-radius: inherit;
    pointer-events: none;
}

.v3-result-name {
    font-family: var(--v3-display);
    font-size: 34px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--v3-ink);
    line-height: 1.15;
    margin: 0;
}

.v3-result-meta {
    font-family: var(--v3-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-muted);
    margin-top: -8px;
}

/* 3-col price breakdown */
.v3-result-price-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1.2fr;
    gap: 1px;
    background: var(--v3-line);
    border: 1px solid var(--v3-line-2);
    border-radius: var(--v3-radius);
    overflow: hidden;
    margin-top: 4px;
}

.v3-price-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 16px 12px;
    background: var(--v3-bg-2);
}

.v3-price-label {
    font-family: var(--v3-mono);
    font-size: 9.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-muted);
}

.v3-price-value {
    font-family: var(--v3-display);
    font-size: 22px;
    font-weight: 700;
    line-height: 1;
    color: var(--v3-ink);
    letter-spacing: -0.02em;
}

.v3-price-unit {
    font-family: var(--v3-mono);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-muted);
}

.v3-price-original .v3-price-value {
    text-decoration: line-through;
    color: var(--v3-muted);
    font-weight: 500;
    font-size: 18px;
}

.v3-price-discount .v3-price-value { color: var(--v3-red); font-size: 18px; }
.v3-price-discount .v3-price-unit  { color: var(--v3-red); opacity: 0.85; }

.v3-price-final {
    background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
    box-shadow: none;
}

.v3-price-final .v3-price-value { color: var(--v3-accent); font-size: 24px; font-weight: 800; }
.v3-price-final .v3-price-label { color: var(--v3-accent); opacity: 0.9; }

/* When no discount: collapse to single full-width cell */
.v3-register-card[data-no-discount="1"] .v3-price-original,
.v3-register-card[data-no-discount="1"] .v3-price-discount { display: none; }

.v3-register-card[data-no-discount="1"] .v3-result-price-grid {
    grid-template-columns: 1fr;
}

/* "Step 1 of 3 / Confirm your domain" header */
.v3-mint-before {
    text-align: center;
    transition: --progress-1 800ms cubic-bezier(0.22, 1, 0.36, 1);
}

.v3-mint-before-eyebrow {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(37,170,225,.1);
    border: 1px solid rgba(37,170,225,.3);
    font-family: var(--v3-mono);
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-accent);
    margin-bottom: 10px;
}

.v3-mint-before-head h3 {
    font-family: var(--v3-display);
    font-size: 20px;
    font-weight: 600;
    color: var(--v3-ink);
    margin: 0 0 16px;
    letter-spacing: -0.015em;
}

/* (.v3-mint-before-grid + .v3-mint-step-card + .v3-mint-step-num +
   .v3-mint-step-desc rules moved to /css/v3-steps.css — single source
   of truth shared with Continue modal + future flows.)                 */

/* CTA */
.v3-result-cta-wrap {
    display: flex;
    justify-content: center;
    margin-top: 4px;
}

.v3-cta-buy,
.v3-public-sections .btn-buy.v3-cta-buy {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    max-width: 380px;
    /* Lock dimensions so "Register Now" → "Processing..." swap doesn't
       shift layout: fixed min-height + box-sizing keeps 1-px borders
       inside the box.  Padding stays constant.                          */
    box-sizing: border-box;
    min-height: 56px;
    padding: 0 32px !important;
    background: linear-gradient(135deg, var(--v3-accent), var(--v3-accent-soft)) !important;
    color: var(--v3-bg) !important;
    border: none !important;
    border-radius: 999px !important;
    font-family: var(--v3-mono);
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    line-height: 1;
    /* Polish #1 — bring back the cyan halo (was dropped in an earlier
       audit) because the currency pill now uses the same gradient and
       competed with the CTA for "primary action" signal.  Halo +
       brightness lift make the CTA win the focal hierarchy on the card. */
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.22) inset,
        0 0 32px rgba(37, 170, 225, 0.38),
        0 8px 24px -8px rgba(37, 170, 225, 0.45) !important;
    cursor: pointer;
    transition: filter .16s var(--v3-ease), background .2s var(--v3-ease),
                box-shadow .2s var(--v3-ease);
}

.v3-cta-buy:hover {
    background: linear-gradient(135deg, var(--v3-accent-soft), var(--v3-accent)) !important;
    filter: brightness(1.08);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.30) inset,
        0 0 48px rgba(37, 170, 225, 0.55),
        0 12px 32px -8px rgba(37, 170, 225, 0.60) !important;
}
.v3-cta-buy:active { filter: brightness(0.96); }

.v3-cta-buy::before {
    content: '⚡';
    margin-right: 4px;
    font-size: 15px;
}

.v3-result-fineprint {
    font-family: var(--v3-mono);
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption);
    color: var(--v3-muted);
    margin-top: -4px;
}

/* ---------- Card 3: Pricing tiers (static) ---------- */

.v3-public-sections .v3-pricing-card {
    background: var(--v3-glass-bg-strong);
    border: 1px solid var(--v3-glass-border-hi);
    border-radius: var(--v3-radius-lg);
    backdrop-filter: blur(14px) saturate(140%);
    box-shadow: var(--v3-depth-2);
    padding: 22px 32px;
    transition: border-color .3s var(--v3-ease), box-shadow .3s var(--v3-ease);
}

.v3-pricing-card:hover {
    border-color: rgba(37,170,225,.3);
    box-shadow: var(--v3-depth-2), 0 0 28px rgba(37,170,225,.1);
}

.v3-pricing-card summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0 4px;
    position: relative;
}

.v3-pricing-card summary::-webkit-details-marker { display: none; }
.v3-pricing-card summary > span { display: block; }

.v3-pricing-card summary::after {
    content: '+';
    font-family: var(--v3-mono);
    color: var(--v3-accent);
    font-size: 18px;
    font-weight: 400;
    line-height: 1;
    transition: transform .2s var(--v3-ease);
    margin-left: auto;
}

.v3-pricing-card details[open] summary::after { content: '−'; }

.v3-disclose-title {
    font-family: var(--v3-display);
    font-size: 14px;
    font-weight: 600;
    color: var(--v3-ink);
}

.v3-pricing-card summary:hover .v3-disclose-title { color: var(--v3-accent); }

.v3-result-disclose-body {
    padding: 10px 0 6px;
    animation: v3-disclose-fade .2s ease;
}

@keyframes v3-disclose-fade {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.v3-static-tiers {
    list-style: none;
    padding: 10px 4px 4px;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px 28px;
}

.v3-static-tiers li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 8px 0;
    font-family: var(--v3-mono);
    font-size: 10.5px;
    border-bottom: 1px solid rgba(255,255,255,.04);
}

.v3-static-tiers li:nth-last-child(-n+2) { border-bottom: none; }

.v3-static-tiers .t-label {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--v3-muted);
}

.v3-static-tiers .t-price {
    color: var(--v3-ink-soft);
    font-weight: 600;
    white-space: nowrap;
}

.v3-static-tiers-note {
    margin: 18px 0 0;
    padding: 14px 0 0;
    border-top: 1px solid rgba(255,255,255,.06);
    font-family: var(--v3-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--v3-green);
    text-align: center;
}

/* ======================================================================
   Register slide-up drawer (Phương án 3)
   ----------------------------------------------------------------------
   Drawer wraps #v3-register-card and slides up from bottom.  Backdrop is
   a sibling element (next to the drawer) — keeps DOM order natural and
   avoids the pitfall of trying to do a "show child + dim sibling" with a
   single parent.

   Open state is controlled by JS adding .is-open class on BOTH drawer
   and backdrop simultaneously.
   ====================================================================== */

/* Backdrop (sibling) — much darker so the search bar + AI block
   beneath are clearly out of focus.  Portalled to body so it sits
   above the sticky header.                                            */
.v3-register-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1190;             /* above .v3-header (100) and shell */
    background: rgba(2, 4, 12, 0.90);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 220ms ease;
}
.v3-register-drawer-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
}

/* Drawer container — TOP-anchored full-viewport modal with FADE-IN.
   No more bottom-slide.  Long Register content scrolls naturally inside
   the inner panel.  Wrapper covers full viewport, drawer-inner is a
   centered column with max-width.                                        */
.v3-register-drawer {
    position: fixed;
    inset: 0;
    z-index: 1200;             /* above backdrop (1190) and header (100) */
    display: flex;
    justify-content: center;
    align-items: flex-start; /* TOP anchor */
    pointer-events: none;
    visibility: hidden;
    opacity: 0;
    transition: opacity 220ms ease, visibility 0s linear 220ms;
}
.v3-register-drawer.is-open {
    visibility: visible;
    opacity: 1;
    transition: opacity 220ms ease, visibility 0s linear 0s;
}

/* Inner panel — uses the SAME tokens as bootbox / V3Modal so the
   register drawer feels identical to other modals in the app.            */
.v3-register-drawer-inner {
    position: relative;
    width: 100%;
    max-width: 720px;
    height: auto;
    max-height: calc(100vh - 56px);
    margin-top: 28px;
    margin-bottom: 28px;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    /* Polish v4 — sweet-spot between v2 (too faint) and v3 (too bold).
       Sits at ~⅔ of v3's intensity so the glow is unmistakably present
       but doesn't grab attention away from the price/CTA below.        */
    background:
        radial-gradient(140% 95% at 0% 0%,
            rgba(37, 170, 225, 0.12) 0%,
            transparent 60%),
        radial-gradient(130% 90% at 100% 100%,
            rgba(176, 140, 255, 0.09) 0%,
            transparent 62%),
        linear-gradient(180deg,
            rgba(37, 170, 225, 0.035) 0%,
            rgba(176, 140, 255, 0.02) 55%,
            transparent 100%),
        var(--v3-glass-bg-strong) !important;
    border: 1px solid var(--v3-glass-border-hi) !important;
    border-radius: var(--v3-radius-lg) !important;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.06),
        var(--v3-depth-2),
        0 0 40px rgba(37, 170, 225, 0.08) !important;
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    padding: 0;
    transform: scale(0.985);
    transition: transform 220ms ease;
    pointer-events: auto;
}
.v3-register-drawer.is-open .v3-register-drawer-inner {
    transform: scale(1);
}

/* Sticky 3-col header: [Back] [Title] [spacer] — title centered,
   Back on left, no close button.  Bottom border-line marks the title
   area from the content below.                                          */
/* Header layout + tokens MATCH the shared V3Modal (.v3-modal-header)
   so Register drawer + Registration Complete + other modals all look
   like one family.  Padding 14px 22px + border-bottom 0.06 + mono
   uppercase title 12px 600 tracking 0.08em.                            */
.v3-register-drawer-header {
    position: sticky;
    top: 0;
    z-index: 2;
    display: grid;
    /* Design-critique #2 — right slot now holds the step indicator pill
       (was a 32px spacer).  `auto` lets the badge size to content.    */
    grid-template-columns: 32px 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 14px 22px;
    /* Polish — transparent so the drawer-inner gradient shows through
       (header + body share the same ambient glow).  Hairline border
       keeps it visually anchored as a header.
       A11y P2 — border bumped 0.06 → 0.14 to clear WCAG 1.4.11 non-text
       contrast 3:1; remains visually subtle but discoverable.            */
    background: transparent !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14) !important;
}
.v3-register-drawer-title {
    margin: 0;
    text-align: center;
    font-family: var(--v3-mono, 'JetBrains Mono', monospace);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.85);
    line-height: 1.3;
}
.v3-register-drawer-spacer {
    width: 32px;
    height: 32px;
}
/* Back button — mirror v3-modal-close geometry (32×32 round, ghost)   */
.v3-register-drawer-back {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 999px;
    border: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.65);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background 160ms ease, color 160ms ease, opacity 160ms ease;
}
.v3-register-drawer-back:hover {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.95);
}
.v3-register-drawer-back:focus-visible {
    outline: 2px solid #6a8bff;
    outline-offset: 2px;
}
/* Disabled state while mint flow is running — prevent accidental exit.
   The lock class is added by v3-register-drawer.js whenever
   window.minting === true.                                               */
.v3-register-drawer.is-mint-locked .v3-register-drawer-back {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: none;
}

/* Override inner card frame — drawer wrapper now owns the chrome
   (gradient/glow lives on .v3-register-drawer-inner so header + body
   share one continuous surface).  Card stays transparent here.        */
.v3-register-drawer-inner > #v3-register-card {
    margin: 0 !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    padding: 28px 36px 32px !important;
    width: auto !important;
    max-width: none !important;
    text-align: center;
    color: rgba(255, 255, 255, 0.98);
}
.v3-register-drawer-inner .v3-result-fineprint {
    margin-top: 16px !important;
    color: rgba(255, 255, 255, 0.65) !important;
}
.v3-register-drawer-inner #v3-result-meta {
    margin-top: 6px;
    margin-bottom: 22px;
    color: rgba(255, 255, 255, 0.72) !important;
}
.v3-register-drawer-inner #v3-result-name,
.v3-register-drawer-inner #v3-result-meta {
    text-align: center;
}
.v3-register-drawer-inner .v3-mint-step-card:not(.is-active):not(.is-done):not(.is-error) .v3-mint-step-desc,
.v3-register-drawer-inner .v3-primary-block-desc {
    color: rgba(255, 255, 255, 0.78) !important;
}
.v3-register-drawer-inner .v3-mint-step-card:not(.is-active):not(.is-done):not(.is-error) .v3-mint-step-num {
    color: rgba(255, 255, 255, 0.95) !important;
    /* A11y P1 — bump border alpha 0.32 → 0.45 to pass WCAG 1.4.11
       non-text contrast 3:1.  Previously inactive step circles
       barely visible against dark drawer.                          */
    border-color: rgba(255, 255, 255, 0.45) !important;
    background: rgba(255, 255, 255, 0.04) !important;
}
.v3-register-drawer-inner #v3-result-name {
    color: #ffffff;
    font-size: 26px !important;       /* smaller than the 34px default */
    line-height: 1.15 !important;
}
/* Reserve vertical space under each step description so the tx-hash
   pill can fade in without bumping the modal height (causing layout
   shift when payment succeeds and the pill appears).                   */
.v3-register-drawer-inner .v3-mint-step-card {
    min-height: 88px;            /* num(28) + desc(32) + pill slot(20) + gaps */
    justify-content: flex-start;
}
.v3-register-drawer-inner .v3-mint-step-desc {
    /* Reduced 32 → 20: 12px font × 1.4 line-height ≈ 17px is enough
       for the 1-2 line descriptions; the old 32px made the card feel
       hollow and pushed the tx pill far from the desc line.        */
    min-height: 20px;
    margin-bottom: 2px;
}
/* Pre-allocate slot for the dynamically-inserted .v3-tx-pill so the
   layout never jumps when a tx hash lands.  Sized to match the real
   pill (18px + 2px gap).  Reduced from 18 → 14 since the desc no
   longer eats vertical space.                                       */
.v3-register-drawer-inner .v3-mint-step-card::after {
    content: '';
    display: block;
    min-height: 14px;
    margin-top: 2px;
    pointer-events: none;
}
/* Once the real pill (now a .v3-tx-pill-group span) is inserted,
   hide the placeholder so total card height stays identical — pill
   itself brings its own height + margin-top via .v3-tx-pill rule.  */
.v3-register-drawer-inner .v3-mint-step-card:has(.v3-tx-pill-group)::after {
    display: none;
}

/* Price grid + cards: stronger borders for sunlight readability */
.v3-register-drawer-inner .v3-price-cell {
    border-color: rgba(255, 255, 255, 0.14) !important;
}
.v3-register-drawer-inner .v3-price-label {
    color: rgba(255, 255, 255, 0.75) !important;
}
.v3-register-drawer-inner .v3-price-unit {
    color: rgba(255, 255, 255, 0.65) !important;
}
/* Primary block (Use as primary): stronger border + checkbox */
.v3-register-drawer-inner .v3-primary-block {
    border-color: rgba(255, 255, 255, 0.16) !important;
    background: rgba(255, 255, 255, 0.025) !important;
}
/* Cleanup overlapping decorations inside the modal: hide the accent
   divider line + tab dot above STEP 1, hide the primary-block-border
   leak.  Re-space mint-before so the stepper doesn't crash into the
   price grid above.                                                   */
.v3-register-drawer-inner .v3-mint-before {
    margin-top: 18px !important;
    padding-top: 0 !important;
    border-top: 0 !important;
}
.v3-register-drawer-inner .v3-mint-before::before,
.v3-register-drawer-inner .v3-mint-before::after {
    display: none !important;
}
.v3-register-drawer-inner .v3-mint-before-head {
    margin-bottom: 16px;
}
.v3-register-drawer-inner .v3-mint-before-grid {
    margin-top: 4px;
}

.v3-register-drawer-inner .v3-primary-block {
    margin-top: 24px;
}
.v3-register-drawer-inner .v3-result-cta-wrap {
    margin-top: 24px;
}

/* (close-button styles handled together with .v3-register-drawer-back
   in the sticky header block above)                                  */

/* Body scroll-lock helper class — set by JS during open */
body.v3-drawer-open {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
}

/* Tablet: tighter inner padding */
@media (max-width: 960px) {
    .v3-register-drawer-inner {
        max-width: 100%;
        border-radius: 18px 18px 0 0;
    }
    .v3-register-drawer-inner > #v3-register-card {
        padding: 6px 18px 24px;
    }
    .v3-register-drawer-header { padding: 12px 16px; }
}

/* Mobile: full-width */
@media (max-width: 560px) {
    .v3-register-drawer-inner {
        max-height: 92vh;
        border-radius: 16px 16px 0 0;
    }
    .v3-register-drawer-inner > #v3-register-card {
        padding: 4px 14px 28px;
    }
    .v3-register-drawer-header { padding: 10px 12px; }
}

/* ======================================================================
   TLD card "Register →" CTA button (action slot)
   ----------------------------------------------------------------------
   syncTldList fills .v3-tld-action with this button for Available cards.
   Whole card stays clickable too (delegated handler in search.js).
   ====================================================================== */
/* TLD Register CTA — uses the SAME cyan accent gradient as the Search
   button so primary actions across the page look identical.            */
.v3-tld-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 96px;
    padding: 7px 14px;
    background: linear-gradient(135deg, var(--v3-accent), var(--v3-accent-soft));
    color: var(--v3-bg);
    border: none;
    border-radius: 999px;
    font-family: var(--v3-mono, inherit);
    font-size: 12px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: var(--v3-track-caption, 0.04em);
    line-height: 1;
    cursor: pointer;
    box-shadow:
        0 0 18px rgba(37, 170, 225, 0.25),
        0 1px 0 rgba(255, 255, 255, 0.18) inset;
    transition: background-image 200ms ease, box-shadow 200ms ease, transform 140ms ease, filter 140ms ease;
    text-decoration: none;
    white-space: nowrap;
}
.v3-tld-cta:hover {
    background: linear-gradient(135deg, var(--v3-accent-soft), var(--v3-accent));
    box-shadow:
        0 0 26px rgba(37, 170, 225, 0.4),
        0 1px 0 rgba(255, 255, 255, 0.22) inset;
}
.v3-tld-cta:active {
    filter: brightness(0.95);
    transform: scale(0.97);
}
/* Spinner state — solid accent gradient stays; spinner icon sits on
   the dark text color (var(--v3-bg)) so it's visible against the
   bright cyan fill in both dark + sunlit screens.
   No min-width lock needed any more — JS now swaps ONLY the trailing
   arrow icon for the spinner (keeps "Register" text in place), so
   button width stays stable regardless of state.                    */
.v3-tld-cta.is-loading {
    pointer-events: none;
}
/* Spinner shares the arrow's font-size so swapping the icon class
   doesn't even nudge the trailing edge — width-identical to idle. */
.v3-tld-cta .fa-spinner,
.v3-tld-cta .fa-arrow-right { font-size: 11px; }
.v3-tld-cta:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* "View profile" CTA on Registered TLD cards — gentle white-tint
   pill, no cyan halo (the base .v3-tld-cta box-shadow would bleed
   through otherwise).                                              */
.v3-tld-cta-secondary {
    background: rgba(255, 255, 255, 0.04);
    color: #c8d0e4;
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: none;
}
.v3-tld-cta-secondary:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    box-shadow: none;
}
/* Just-registered View → keep same secondary visual; explicit so
   future tweaks (e.g. subtle cyan tint) localize here.            */
.v3-tld-cta-view { /* matches .v3-tld-cta-secondary by default */ }

/* ======================================================================
   AI card 2-button inline (Check + Register →)
   ----------------------------------------------------------------------
   Previous markup: <button.v3-ai-card> containing name/meta/arrow.
   New markup: <div.v3-ai-card> with hero (name + meta) on top, then a
   .v3-ai-card-actions row with 2 inline buttons.  Whole card click =
   Check (re-search).  Register button stops propagation.
   ====================================================================== */
/* Single-row horizontal card: [name . tld · cat] [Check] [Register].
   Much more compact than the stacked version.  Wraps on mobile.        */
.v3-ai-card {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    padding: 8px 10px 8px 12px;
    min-height: auto;
}
.v3-ai-card-name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13px;
    line-height: 1.2;
    color: #ffffff;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.v3-ai-card-tld {
    color: rgba(255, 255, 255, 0.62);
    font-weight: 400;
    margin-left: 1px;
}
.v3-ai-card-meta { display: none; }
.v3-ai-card-cat {
    flex: 0 0 auto;
    font-size: 10px;
    line-height: 1;
    padding: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.55);
    text-transform: lowercase;
    letter-spacing: 0.02em;
}
.v3-ai-card-actions {
    flex: 0 0 auto;
    display: flex;
    gap: 4px;
    margin-top: 0;
    width: auto;
}
/* Kill any inherited transform/scale on hover/active from the
   original .v3-ai-card rule + child buttons.  No size shifts.        */
.v3-ai-card:hover,
.v3-ai-card:active,
.v3-ai-card:focus,
.v3-ai-card-btn:hover,
.v3-ai-card-btn:active,
.v3-ai-card-btn:focus {
    transform: none !important;
    filter: none !important;
}
.v3-ai-card-btn {
    box-sizing: border-box;     /* border doesn't push layout */
}
.v3-ai-card-name,
.v3-ai-card-meta {
    grid-column: unset;
    grid-row: unset;
}

/* (older duplicate of .v3-ai-card-actions removed — see line ~5189) */

/* Icon-only square buttons.  No borders — just color + subtle bg on
   hover.  Border ring is added only on focus-visible for a11y.        */
.v3-ai-card-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    font-size: 11px;
    cursor: pointer;
    backgrou