/*
 * Jade firmware pages, dark rebrand: fwupgrade.html (update over USB),
 * download.html and download-success.html (air-gapped download).
 * Source: Figma "Firmware Update" section + designer handoff.
 *
 * Each page is a single layout; which parts are visible is driven by
 * <body data-state="..."> (setState() in js/jade.js, showScreen() in
 * js/download.js). Every element that belongs to a screen carries
 * data-for="state1 state2 ...".
 */

/* ---- Tokens (Blockstream Design System, Color = Dark) ------------------ */
:root {
    --color-bg-canvas: #121e29;
    --color-text-primary: #fff;
    --color-text-secondary: #c5d0dd;
    --color-text-eyebrow: #dbc0a1;
    --color-action-primary: #0066cd;
    --color-action-primary-text: #fff;
    --color-bg-glass: rgba(255, 255, 255, 0.08);
    --color-border-default: #3e4246;
    --color-border-strong: #747b82;
    --color-border-outline: #fff;
    --color-card-border: rgba(70, 109, 134, 0.6);
    --color-scrim: rgba(8, 20, 31, 0.8);
    --deco-line-start: #dbc0a1;
    --deco-line-mid: #889eb2;
    --deco-line-end: #0066cd;

    --font-family-content: Manrope, system-ui, sans-serif;
    --font-family-ui: "JetBrains Mono", ui-monospace, monospace;

    --size-h1: 56px;
    --size-h2: 32px;
    --size-h3: 26px;
    --size-h4: 20px;
    --size-p1: 22px;
    --size-p2: 18px;
    --size-p3: 16px;
    --size-ui1: 16px;
    --size-ui2: 14px;

    --button-padding-x: 40px;
    --button-padding-y: 17px;
    --card-padding: 30px;
    --ease-state: cubic-bezier(0.32, 0.72, 0, 1);
}

@media (max-width: 1180px) {
    :root {
        --size-h1: 44px;
        --size-p1: 20px;
    }
}

@media (max-width: 900px) {
    :root {
        --size-h1: 32px;
        --size-h2: 26px;
        --size-p1: 18px;
        --size-p2: 16px;
    }
}

/* ---- Base --------------------------------------------------------------- */
* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    min-height: 100%;
    background: var(--color-bg-canvas);
    color: var(--color-text-primary);
    font-family: var(--font-family-content);
    -webkit-font-smoothing: antialiased;
}

[hidden],
.hidden {
    display: none !important;
}

main {
    min-height: 100vh;
    overflow-x: clip;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 80px 24px;
}

.layout {
    width: 100%;
    max-width: 1280px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
}

.copy {
    flex: 0 1 600px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.logo img {
    display: block;
    width: 198px;
    height: auto;
}

h1 {
    margin: 0;
    font-weight: 500;
    font-size: var(--size-h1);
    line-height: 1.4;
    letter-spacing: -0.01em;
}

h1 em {
    font-style: normal;
    color: var(--color-action-primary);
}

.sub {
    margin: 0;
    font-size: var(--size-p1);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.note {
    margin: 0;
    font-size: var(--size-p2);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

/* "Confirm on Jade": one text block with 30px paragraph spacing */
.confirm-body {
    display: flex;
    flex-direction: column;
    gap: 30px;
}

.hash {
    margin: 0;
    font: 400 18px/1.55 var(--font-family-ui);
    color: var(--color-text-secondary);
    white-space: pre;
}

/* ---- Actions row (Figma "CTA") ------------------------------------------ */
.actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding-top: 16px;
}

.row {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.btn {
    appearance: none;
    border: 0;
    border-radius: 0;
    height: 56px;
    padding: var(--button-padding-y) var(--button-padding-x);
    font: 400 var(--size-ui1) / 1.4 var(--font-family-ui);
    color: var(--color-action-primary-text);
    background: var(--color-action-primary);
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    transition: filter 0.15s ease, opacity 0.15s ease;
}

.btn:hover {
    filter: brightness(1.12);
}

.btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 3px;
}

.btn.outline {
    background: var(--color-bg-glass);
    box-shadow: inset 0 0 0 1px var(--color-border-outline);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
}

.btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
    filter: none;
}

.req {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--size-p3);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.req img {
    width: 20px;
    height: 20px;
}

/* Spinner: 36px, full track ring + 180deg arc, 1.3 stroke */
.spinner {
    width: 36px;
    height: 36px;
    margin-top: 16px;
    border-radius: 50%;
    border: 1.3px solid var(--color-border-default);
    border-top-color: var(--color-action-primary);
    border-left-color: var(--color-action-primary);
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* Updating: padding-top 16, 4px track, accent fill, % below (heading/H3) */
.progress {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-top: 16px;
}

#fwprogress {
    appearance: none;
    -webkit-appearance: none;
    display: block;
    width: 100%;
    height: 4px;
    border: 0;
    background: var(--color-border-default);
    color: var(--color-action-primary);
}

#fwprogress::-webkit-progress-bar {
    background: var(--color-border-default);
}

#fwprogress::-webkit-progress-value {
    background: var(--color-action-primary);
}

#fwprogress::-moz-progress-bar {
    background: var(--color-action-primary);
}

.progress .pct {
    font-weight: 500;
    font-size: var(--size-h3);
    line-height: 1.4;
    letter-spacing: -0.01em;
    color: var(--color-text-secondary);
}

/* ---- Art column ---------------------------------------------------------- */
.art {
    position: relative;
    flex: 0 1 640px;
    min-width: 0;
    aspect-ratio: 640 / 600;
}

.slot {
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
}

/* animated state art: <object> so the SVG's own script runs */
.slot object,
.slot object > img {
    display: block;
    width: 100%;
    height: 100%;
}

/* Landing art: render 560 wide on the art box's right edge, rings (10%)
   centred on the render */
.slot .rings {
    position: absolute;
    left: 56.25%;
    top: 50%;
    width: 118.25%;
    transform: translate(-50%, -50%);
    opacity: 0.1;
    pointer-events: none;
    user-select: none;
}

.slot .render {
    position: absolute;
    right: 0;
    top: 50%;
    width: 87.5%;
    transform: translateY(-50%);
}

/* ---- Screen switching ---------------------------------------------------- */
.state {
    flex-direction: column;
    gap: 24px;
    animation: state-in 0.28s ease both;
}

[data-for] {
    display: none;
}

body[data-state="landing"] [data-for~="landing"],
body[data-state="unsupported"] [data-for~="unsupported"],
body[data-state="connect"] [data-for~="connect"],
body[data-state="busy"] [data-for~="busy"],
body[data-state="unlock"] [data-for~="unlock"],
body[data-state="scanning"] [data-for~="scanning"],
body[data-state="uptodate"] [data-for~="uptodate"],
body[data-state="select"] [data-for~="select"],
body[data-state="none"] [data-for~="none"],
body[data-state="confirm"] [data-for~="confirm"],
body[data-state="updating"] [data-for~="updating"],
body[data-state="updated"] [data-for~="updated"],
body[data-state="failed"] [data-for~="failed"],
body[data-state="downloaded"] [data-for~="downloaded"] {
    display: flex;
}

@keyframes state-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* ---- Version picker (frames 5 / 5a / 5b) -------------------------------- */
.picker {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
}

.vpw {
    position: relative;
    width: 100%;
}

.vp {
    width: 100%;
}

/* Show all: 440px viewport, 4px scrollbar, bottom fade (120px) that
   disappears once the list is scrolled to the end */
.vp.scroll {
    height: 440px;
    overflow-y: auto;
}

.vpw.scroll::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: calc(100% - 12px);
    height: 120px;
    pointer-events: none;
    background: linear-gradient(
        180deg,
        rgba(18, 30, 41, 0),
        var(--color-bg-canvas)
    );
    transition: opacity 0.2s ease;
}

.vpw.scroll.at-end::after {
    opacity: 0;
}

@supports not selector(::-webkit-scrollbar) {
    .vp.scroll {
        scrollbar-width: thin;
        scrollbar-color: #fff var(--color-border-default);
    }
}

.vp.scroll::-webkit-scrollbar {
    width: 4px;
}

.vp.scroll::-webkit-scrollbar-track {
    background: var(--color-border-default);
}

.vp.scroll::-webkit-scrollbar-thumb {
    background: #fff;
    border-radius: 2px;
}

#firmware_available {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.vp.scroll #firmware_available {
    width: calc(100% - 8px);
}

/* card = radio input (visually hidden, keeps keyboard + form semantics) +
   label. Written to also work for the generated markup in ota.js */
#firmware_available > div {
    position: relative;
}

#firmware_available input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

#firmware_available label {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    height: auto;
    padding: 20px 24px;
    cursor: pointer;
    background: var(--color-bg-glass);
    border: 1px solid var(--color-border-default);
    border-radius: 0;
}

#firmware_available label:hover {
    border-color: var(--color-border-strong);
}

#firmware_available input[type="radio"]:checked + label {
    border: 2px solid var(--color-action-primary);
    padding: 19px 23px;
}

/* locked while the chosen firmware downloads (lockVersionPicker) */
#firmware_available input[type="radio"]:disabled + label {
    cursor: default;
}

#firmware_available input[type="radio"]:disabled:not(:checked) + label {
    border-color: var(--color-border-default);
    opacity: 0.4;
}

#firmware_available input[type="radio"]:focus-visible + label {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

.ct-line {
    display: flex;
    align-items: center;
    gap: 16px;
}

.ct-title {
    flex: 1;
    min-width: 0;
    font-weight: 500;
    font-size: var(--size-h4);
    line-height: 1.4;
    letter-spacing: -0.01em;
}

.ct-label {
    font: 500 16px / 1.4 var(--font-family-ui);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.ct-label.ct-stable {
    color: var(--color-text-eyebrow);
}

.ct-desc {
    font-size: var(--size-p3);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

@media (max-width: 600px) {
    .ct-line {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
    }
}

.link {
    all: unset;
    cursor: pointer;
    font-weight: 500;
    font-size: 16px;
    line-height: 1.4;
    color: var(--color-text-primary);
    align-self: center;
}

.link:hover {
    text-decoration: underline;
}

.link:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 4px;
}

/* 5b: empty state keeps the card-panel look */
body:not([data-state="none"]) #empty,
body[data-state="none"] .vpw {
    display: none;
}

/* ---- Card panel (footer cards, empty state) ----------------------------- */
.panel,
.fcard {
    position: relative;
    background: var(--color-bg-glass);
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    box-shadow: 0 10px 15px rgba(0, 0, 0, 0.06);
}

.panel::before,
.fcard::before {
    content: "";
    position: absolute;
    inset: 0;
    padding: 1px;
    pointer-events: none;
    background: linear-gradient(
        180deg,
        var(--deco-line-start) 10%,
        var(--deco-line-mid) 40%,
        var(--deco-line-end) 90%
    );
    -webkit-mask: linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
}

.panel {
    width: 100%;
    padding: calc(var(--card-padding) + 1px);
}

.panel p {
    margin: 0;
    font-size: var(--size-p3);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

/* ---- Footer cards (below the fold) -------------------------------------- */
.footer {
    flex-direction: column;
    align-items: center;
    padding: 80px 24px 120px;
}

.footer .cards {
    width: 100%;
    max-width: 1280px;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 30px;
    align-items: stretch;
}

/* download pages: fewer cards than columns, so centre them (same 407px card
   width as the 3-column grid; one column on small screens, below) */
.footer .cards.centered {
    grid-template-columns: repeat(auto-fit, minmax(0, 407px));
    justify-content: center;
}

.fcard {
    padding: var(--card-padding);
    min-height: 240px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 20px;
}

.fcard .top {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.fcard .head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.fcard .head img {
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
}

.fcard h3 {
    margin: 0;
    font-weight: 500;
    font-size: var(--size-h4);
    line-height: 1.4;
    letter-spacing: -0.01em;
}

.fcard .eyebrow {
    font: 500 16px / 1.4 var(--font-family-ui);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-eyebrow);
    white-space: nowrap;
}

.fcard p {
    margin: 0;
    font-size: var(--size-p3);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.fcard a {
    font: 400 var(--size-ui2) / 1.4 var(--font-family-ui);
    color: var(--color-text-primary);
    text-decoration: none;
    display: inline-flex;
    gap: 8px;
    align-items: center;
    align-self: flex-start;
}

.fcard a:hover {
    text-decoration: underline;
}

/* arrow lives in an 18x14 slot; hover nudges it 4px without reflow */
.fcard a .arw {
    width: 18px;
    height: 14px;
    display: inline-flex;
    align-items: center;
}

.fcard a .arw img {
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

.fcard a:hover .arw img {
    transform: translateX(4px);
}

@media (max-width: 1180px) {
    .footer .cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 900px) {
    .footer {
        padding: 40px 16px 120px;
    }

    .footer .cards,
    .footer .cards.centered {
        grid-template-columns: 1fr;
    }

    .fcard {
        min-height: 0;
    }
}

/* ---- Custom blind oracle modal (frame 6) -------------------------------- */
.backdrop {
    position: fixed;
    inset: 0;
    background: var(--color-scrim);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    z-index: 5;
}

.modal {
    width: 640px;
    max-width: 100%;
    max-height: 100%;
    overflow-y: auto;
    background: var(--color-bg-canvas);
    border: 1px solid var(--color-card-border);
    padding: 48px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.modal h2 {
    margin: 0;
    font-weight: 500;
    font-size: var(--size-h2);
    line-height: 1.4;
    letter-spacing: -0.01em;
}

.modal p {
    margin: 0;
    font-size: var(--size-p3);
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.modal .row {
    gap: 16px;
}

.checks {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.check {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: var(--size-p3);
    line-height: 1.55;
    cursor: pointer;
    word-break: break-all;
}

.check + .check {
    border-top: 1px solid var(--color-border-default);
    padding-top: 16px;
}

.check input {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    margin: 0;
    border: 1.5px solid var(--color-border-strong);
    border-radius: 0;
    display: grid;
    place-items: center;
    cursor: pointer;
}

.check input:checked {
    background: var(--color-action-primary);
    border-color: var(--color-action-primary);
}

.check input:checked::after {
    content: "";
    width: 10px;
    height: 6px;
    border: solid #fff;
    border-width: 0 0 2px 2px;
    transform: translate(0, -1px) rotate(-45deg);
}

.check input:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* ---- Small screens: art stacks above the copy --------------------------- */
@media (max-width: 900px) {
    main {
        align-items: flex-start;
        padding: 40px 16px 120px;
    }

    .layout {
        flex-direction: column-reverse;
        gap: 24px;
    }

    .art {
        width: 100%;
        max-width: 480px;
        flex: 0 0 auto;
        margin: 0 auto;
    }

    body[data-state="select"] .art,
    body[data-state="none"] .art {
        aspect-ratio: auto;
        max-width: none;
    }

    body[data-state="select"] .slot,
    body[data-state="none"] .slot {
        position: static;
    }

    .copy {
        width: 100%;
        flex: 0 0 auto;
    }

    .logo img {
        width: 160px;
    }

    .btn {
        width: 100%;
        justify-content: center;
    }

    .row {
        width: 100%;
    }

    .modal {
        padding: 30px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .state {
        animation: none;
    }

    .spinner {
        animation: none;
    }
}
