/* File Convert — state and transition rules for the site.js components.
   Layout and decoration belong to the page stylesheets; everything here is
   only what the behaviour layer needs to look right while it moves.

   Tokens (--brand, --ink, --border, …) are defined once in form.css and
   re-pointed at the semantic --t-* scale by theme.css; neither set is ever
   redeclared here. Every selector is either a data- hook owned by site.js or
   an `fx-`/`pw`-prefixed class, so nothing can collide with the other
   stylesheets.

   Status hues (copy confirmation, password strength) are the one thing the
   theme scale does not cover, so they get their own `--fx-` namespace below —
   new properties, layered over theme.css rather than overriding it. Every
   literal colour that used to be inline in this file now lives there, with a
   dark-theme value beside it. */

:root {
    /* Copy button: success ink and its wash. */
    --fx-ok: #147a45;
    --fx-ok-soft: rgba(20, 122, 69, 0.08);

    /* Password meter, bar fill: weakest to strongest. */
    --fx-score-0: #d93025;
    --fx-score-1: #e8710a;
    --fx-score-2: #e0b000;
    --fx-score-3: #4a9d5f;
    --fx-score-4: #147a45;

    /* Password meter, label ink. Darker than the bar so small text still
       clears contrast against the page surface. */
    --fx-score-ink-0: #c5221f;
    --fx-score-ink-1: #b45a05;
    --fx-score-ink-2: #8a6d00;
    --fx-score-ink-3: #3d7f4d;
    --fx-score-ink-4: #147a45;
}

:root[data-theme="dark"] {
    --fx-ok: #4ade80;
    --fx-ok-soft: rgba(74, 222, 128, 0.14);

    --fx-score-0: #f87171;
    --fx-score-1: #fb923c;
    --fx-score-2: #facc15;
    --fx-score-3: #4ade80;
    --fx-score-4: #22c55e;

    /* Inverted: on a near-black surface the light end of each hue is the
       readable one. */
    --fx-score-ink-0: #fca5a5;
    --fx-score-ink-1: #fdba74;
    --fx-score-ink-2: #fde047;
    --fx-score-ink-3: #86efac;
    --fx-score-ink-4: #4ade80;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --fx-ok: #4ade80;
        --fx-ok-soft: rgba(74, 222, 128, 0.14);

        --fx-score-0: #f87171;
        --fx-score-1: #fb923c;
        --fx-score-2: #facc15;
        --fx-score-3: #4ade80;
        --fx-score-4: #22c55e;

        --fx-score-ink-0: #fca5a5;
        --fx-score-ink-1: #fdba74;
        --fx-score-ink-2: #fde047;
        --fx-score-ink-3: #86efac;
        --fx-score-ink-4: #4ade80;
    }
}

/* ------------------------------------------------------------------ *
 * Shared: the visually hidden live region site.js injects
 * ------------------------------------------------------------------ */

.fx-live {
    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;
}

/* ------------------------------------------------------------------ *
 * 1. Accordion
 * ------------------------------------------------------------------ */

[data-accordion-panel] {
    overflow: hidden;
}

/* Only animating elements carry the transition, so opening a panel with no
   inline height set (reduced motion, hash deep-link) is instant. */
[data-accordion-panel].fx-acc-animating {
    transition: height 240ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: height;
}

[data-accordion-trigger] {
    cursor: pointer;
}

[data-accordion-trigger] .fx-acc-icon,
[data-accordion-trigger] [data-accordion-icon] {
    transition: transform 200ms ease;
}

[data-accordion-trigger][aria-expanded="true"] .fx-acc-icon,
[data-accordion-trigger][aria-expanded="true"] [data-accordion-icon] {
    transform: rotate(180deg);
}

/* ------------------------------------------------------------------ *
 * 2. Tabs
 * ------------------------------------------------------------------ */

[data-tabs] [role="tablist"] {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--t-border);
}

[data-tab] {
    cursor: pointer;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--t-muted);
    font: inherit;
    transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}

[data-tab]:hover {
    color: var(--t-highlighted);
}

[data-tab][aria-selected="true"] {
    color: var(--primary-500);
    border-bottom-color: var(--primary-500);
}

/* The mid-ramp red goes muddy on a near-black surface; the light end reads. */
:root[data-theme="dark"] [data-tab][aria-selected="true"] {
    color: var(--primary-300);
    border-bottom-color: var(--primary-400);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) [data-tab][aria-selected="true"] {
        color: var(--primary-300);
        border-bottom-color: var(--primary-400);
    }
}

[data-tab]:focus-visible,
[data-accordion-trigger]:focus-visible,
[data-copy]:focus-visible,
[data-megamenu-toggle]:focus-visible,
[data-password-toggle]:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 2px;
}

[data-tab-panel] {
    animation: fx-panel-in 180ms ease both;
}

[data-tab-panel]:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 4px;
}

@keyframes fx-panel-in {
    from {
        opacity: 0;
        transform: translateY(4px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* ------------------------------------------------------------------ *
 * 3. Copy to clipboard
 * ------------------------------------------------------------------ */

[data-copy] {
    cursor: pointer;
    transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}

[data-copy].is-copied {
    color: var(--fx-ok);
    border-color: var(--fx-ok);
    background: var(--fx-ok-soft);
}

[data-copy].is-copy-failed {
    color: var(--brand-dark);
    border-color: var(--primary-500);
    background: var(--brand-tint);
}

:root[data-theme="dark"] [data-copy].is-copy-failed {
    color: var(--primary-300);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) [data-copy].is-copy-failed {
        color: var(--primary-300);
    }
}

/* ------------------------------------------------------------------ *
 * 5. Filter empty state
 * ------------------------------------------------------------------ */

[data-filter-empty] {
    padding: 28px 20px;
    border: 1px dashed var(--t-border-strong);
    border-radius: var(--radius);
    background: var(--t-elevated);
    color: var(--t-muted);
    text-align: center;
}

/* The hidden attribute has to beat any display rule a page stylesheet puts
   on a filtered item or section. */
[data-filter-item][hidden],
[data-filter-section][hidden],
[data-filter-empty][hidden],
[data-price-monthly][hidden],
[data-price-yearly][hidden] {
    display: none !important;
}

/* ------------------------------------------------------------------ *
 * 6. Mega-menu
 * ------------------------------------------------------------------ */

[data-megamenu] {
    position: relative;
}

[data-megamenu-toggle] {
    cursor: pointer;
}

[data-megamenu-panel] {
    z-index: 60;
    border: 1px solid var(--t-border);
    border-radius: var(--radius-lg, var(--radius));
    background: var(--t-surface);
    color: var(--t-default);
    box-shadow: var(--shadow-card);
}

/* Desktop: an overlay hung under the header bar, faded and nudged into
   place. `hidden` still governs presence — this only styles the motion. */
@media (min-width: 900px) {
    [data-megamenu-panel] {
        position: absolute;
        top: calc(100% + 8px);
        left: 0;
        min-width: 260px;
        max-width: min(880px, calc(100vw - 32px));
        max-height: calc(100vh - var(--header-h) - 32px);
        overflow-y: auto;
        opacity: 0;
        transform: translateY(-6px);
        transition: opacity 160ms ease, transform 160ms ease;
    }

    [data-megamenu].is-open > [data-megamenu-panel] {
        opacity: 1;
        transform: none;
    }
}

/* Below the breakpoint the panel is part of the drawer, not floating over
   it: static flow, no shadow, no transform to fight the drawer's own. */
@media (max-width: 899px) {
    [data-megamenu-panel] {
        position: static;
        width: 100%;
        margin: 6px 0 4px;
        box-shadow: none;
        background: var(--t-elevated);
    }
}

/* ------------------------------------------------------------------ *
 * 9. Mobile nav drawer
 *
 * State only. The header's own appearance — colours, spacing, the shape of
 * the links — belongs to the chrome stylesheet; all this does is decide
 * whether the drawer is on screen and how it gets there.
 * ------------------------------------------------------------------ */

@media (max-width: 899px) {
    [data-site-nav] {
        overflow-y: auto;
        /* Collapsed rather than display:none so the panel can animate, and
           so a mid-transition tab stop is not a surprise. */
        max-height: 0;
        opacity: 0;
        visibility: hidden;
        transition: max-height 240ms cubic-bezier(0.4, 0, 0.2, 1),
                    opacity 160ms ease,
                    visibility 0s linear 240ms;
    }

    [data-site-nav].is-nav-open {
        max-height: calc(100vh - var(--header-h));
        opacity: 1;
        visibility: visible;
        transition: max-height 240ms cubic-bezier(0.4, 0, 0.2, 1),
                    opacity 160ms ease,
                    visibility 0s;
    }

    /* The page behind a full-height drawer must not scroll under it. */
    body.fx-nav-open {
        overflow: hidden;
    }
}

/* Above the breakpoint the nav is an ordinary horizontal bar. Reset hard so
   a drawer left open across a resize can never strand the desktop layout. */
@media (min-width: 900px) {
    [data-site-nav],
    [data-site-nav].is-nav-open {
        max-height: none;
        opacity: 1;
        visibility: visible;
    }

    body.fx-nav-open {
        overflow: visible;
    }
}

[data-nav-toggle] {
    cursor: pointer;
}

[data-nav-toggle]:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 * 7 & 8. Password field and strength meter
 * ------------------------------------------------------------------ */

.pwfield {
    position: relative;
    display: block;
}

.pwfield > input {
    width: 100%;
    padding-right: 44px;
}

[data-password-toggle] {
    position: absolute;
    top: 50%;
    right: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    transform: translateY(-50%);
    border: 0;
    border-radius: var(--radius-sm, 4px);
    background: transparent;
    color: var(--t-muted);
    cursor: pointer;
    transition: color 150ms ease, background-color 150ms ease;
}

[data-password-toggle]:hover {
    color: var(--t-highlighted);
    background: var(--t-elevated);
}

[data-password-toggle].is-revealed {
    color: var(--primary-500);
}

[data-password-strength] {
    margin-top: 8px;
}

.pwmeter__bar {
    height: 5px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--t-accented);
}

.pwmeter__bar > span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: inherit;
    background: var(--t-dimmed);
    transition: width 220ms ease, background-color 220ms ease;
}

.pwmeter__label {
    margin: 6px 0 0;
    font-size: 13px;
    color: var(--t-muted);
}

/* Colour steps. Widths are set inline by site.js; these only carry hue, so a
   page can restyle the bar without the score losing meaning. */
[data-password-strength][data-score="0"] .pwmeter__bar > span { background: var(--fx-score-0); }
[data-password-strength][data-score="1"] .pwmeter__bar > span { background: var(--fx-score-1); }
[data-password-strength][data-score="2"] .pwmeter__bar > span { background: var(--fx-score-2); }
[data-password-strength][data-score="3"] .pwmeter__bar > span { background: var(--fx-score-3); }
[data-password-strength][data-score="4"] .pwmeter__bar > span { background: var(--fx-score-4); }

[data-password-strength][data-score="0"] .pwmeter__label { color: var(--fx-score-ink-0); }
[data-password-strength][data-score="1"] .pwmeter__label { color: var(--fx-score-ink-1); }
[data-password-strength][data-score="2"] .pwmeter__label { color: var(--fx-score-ink-2); }
[data-password-strength][data-score="3"] .pwmeter__label { color: var(--fx-score-ink-3); }
[data-password-strength][data-score="4"] .pwmeter__label { color: var(--fx-score-ink-4); }

/* ------------------------------------------------------------------ *
 * Reduced motion — everything above still works, it just stops moving.
 * ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    [data-accordion-panel].fx-acc-animating,
    [data-accordion-trigger] .fx-acc-icon,
    [data-accordion-trigger] [data-accordion-icon],
    [data-tab],
    [data-copy],
    [data-megamenu-panel],
    [data-password-toggle],
    [data-site-nav],
    .pwmeter__bar > span {
        transition: none !important;
    }

    [data-tab-panel] {
        animation: none !important;
    }
}
