/* ============================================
   Disto é que eu gosto! — Página de entrada
   ============================================

   Two quite different layouts, not one layout that stretches:

     phone   the photos fill the screen and the login floats on top of them
             as a frosted card, so the people in the photos are the page
     desktop the classic split — photos on the left, login on the right

   Mobile-first, so the base rules below are the phone layout and the
   min-width: 900px block rebuilds it as the split.
   ============================================ */

:root {
    --bg: #ffffff;
    --ink: #111111;
    --ink-soft: #555555;
    --ink-faint: #8a8a8a;
    --line: #e6e6e6;
    --line-strong: #d0d0d0;
    --field-bg: #ffffff;
    --accent: #e63946;
    --accent-soft: #fdeef0;
    --radius: 12px;
    --radius-lg: 22px;
    --shadow-lift: 0 6px 20px rgba(0, 0, 0, 0.09);
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
    /* How long each photo is held, and how long the crossfade takes. Kept
       here so login.js can read it instead of hard-coding the same number
       in two places. */
    --fade-duration: 1400ms;
}

* {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

.login-body {
    margin: 0;
    /* Dark, because on a phone this is what shows behind the photos while
       they load, and behind the frosted card at the edges. */
    background: #241d18;
    color: var(--ink);
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.6;
    min-height: 100dvh;
}

.login-split {
    position: relative;
    min-height: 100dvh;
}

/* ── Galeria ────────────────────────────────────────────────────────── */

/* Fixed, not scrolling: the card slides over a still backdrop, which is what
   makes it read as glass rather than as a header image. */
.login-gallery {
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: #241d18;
    z-index: 0;
}

.gallery-frame {
    position: absolute;
    inset: 0;
}

.gallery-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Biased above centre: in family photographs the faces sit in the upper
       half, and a plain centre crop cuts them on a tall phone screen. */
    object-position: center 38%;
    opacity: 0;
    /* The slow drift stops three stills from looking like a broken slideshow.
       Transform only, so it stays on the compositor and never repaints. */
    transform: scale(1.06);
    transition: opacity var(--fade-duration) ease-in-out,
                transform 9s linear;
    will-change: opacity, transform;
}

.gallery-img.is-active {
    opacity: 1;
    transform: scale(1);
}

/* Darkens the photo just enough that a white card floats off it, and that the
   photo cannot fight the card for attention. */
.gallery-veil {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(to bottom,
            rgba(20, 14, 10, 0.42) 0%,
            rgba(20, 14, 10, 0.24) 40%,
            rgba(20, 14, 10, 0.52) 100%);
    pointer-events: none;
}

/* Belongs to the desktop split; on a phone the card's own kicker says it */
.gallery-caption {
    display: none;
}

/* ── Painel ─────────────────────────────────────────────────────────── */

.login-panel {
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: center;
    /* NOT align-items: center — a centred flex item that overflows puts its
       own top above the scroll origin, where nothing can reach it. The auto
       margin below centres when there is room and collapses when there is
       not. */
    align-items: flex-start;
    min-height: 100dvh;
    /* Generous top padding so a band of photograph shows above the card
       instead of the card starting at the very top of the screen. */
    padding: 56px 16px calc(32px + env(safe-area-inset-bottom, 0px));
}

.login-panel-inner {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 420px;
    margin-block: auto;

    /* Muted greys are darkened on the glass: the values that pass on solid
       white do not pass over a photograph. They are darker again now that the
       card is thinner glass (0.65) — at that alpha the worst possible
       composite is about #9e9e9e, and #3d3d3d against it is only 4.05:1.
       #333333 clears 4.5:1 with room to spare. */
    --ink-soft: #2e2e2e;
    --ink-faint: #333333;
    --line: #b4b4b4;
    --line-strong: #949494;
}

/* ── O cartão de vidro ──
   Thin enough to see the photograph through, which is the whole point of
   putting it there — but the alpha is still a contrast decision, not only a
   taste one. Over a near-black photo the composite bottoms out around
   #9e9e9e, so every colour used on this card is picked to clear 4.5:1
   against THAT, not against white. Lower this and the greys above have to
   come down with it, or the small print stops being readable on a dark
   photo while looking perfectly fine on a bright one.

   The heavier blur and the brightness lift are what stop thin glass from
   looking like a smear: blur flattens whatever is behind the text, and the
   lift pulls a dark photo up toward mid-grey underneath the card only. */
.login-card {
    background: rgba(255, 255, 255, 0.65);
    -webkit-backdrop-filter: blur(30px) saturate(150%) brightness(1.12);
    backdrop-filter: blur(30px) saturate(150%) brightness(1.12);
    border: 1px solid rgba(255, 255, 255, 0.6);
    border-radius: var(--radius-lg);
    padding: 26px 22px 24px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.34);
}

/* Firefox only shipped backdrop-filter by default recently, and it can still
   be switched off. Without the blur the glass must carry the contrast alone. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .login-card,
    .login-footer {
        background: rgba(255, 255, 255, 0.95);
    }
}

.login-header {
    margin-bottom: 22px;
}

.kicker {
    margin: 0 0 10px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
    /* The station name wraps on a phone; balance stops it leaving "FM"
       alone on the second line. Ignored where unsupported. */
    text-wrap: balance;
}

.login-title {
    margin: 0;
    font-size: clamp(1.8rem, 6.5vw, 2.4rem);
    line-height: 1.12;
    letter-spacing: -0.025em;
}

.login-sub {
    margin: 12px 0 0;
    color: var(--ink-soft);
    font-size: 0.98rem;
}

.login-sub strong {
    color: var(--ink);
    font-weight: 600;
}

/* ── Formulário ─────────────────────────────────────────────────────── */

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

.field {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.field label {
    font-size: 0.88rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.field input {
    width: 100%;
    /* 16px is the threshold below which iOS Safari zooms the page on focus.
       Never go under it on an input. */
    font: inherit;
    font-size: 16px;
    color: var(--ink);
    /* Nearly opaque even on the glass: a translucent field over a photo makes
       what you are typing genuinely hard to read. */
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 13px 15px;
    /* 46px keeps the tap target above the 44px minimum on a phone */
    min-height: 46px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease,
                background 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}

.field input::placeholder {
    /* #9a9a9a measured 2.69:1 over the photo — the worst contrast anywhere on
       the page, on the one hint telling someone what to type. */
    color: #6b6b6b;
}

.field input:hover {
    border-color: #8e8e8e;
}

.field input:focus {
    outline: none;
    background: #ffffff;
    border-color: var(--ink);
    box-shadow: 0 0 0 3px rgba(17, 17, 17, 0.14);
}

/* Set by login.js when the server rejects the pair. Both fields are marked,
   because we never say which of the two was wrong. */
.field input.is-invalid {
    border-color: var(--accent);
}

.field input.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(230, 57, 70, 0.2);
}

.field input:disabled {
    background: rgba(240, 240, 240, 0.9);
    color: var(--ink-faint);
}

/* ── Mostrar/ocultar palavra-passe ──────────────────────────────────── */

.field-password {
    position: relative;
    display: flex;
}

.field-password input {
    /* Room for the eye button, so a long password never slides under it */
    padding-right: 52px;
}

.reveal-btn {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    border-radius: var(--radius);
    padding: 0;
    color: var(--ink-faint);
    cursor: pointer;
}

.reveal-btn:hover {
    color: var(--ink);
}

.reveal-btn:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: -2px;
}

.reveal-btn svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

.reveal-btn .icon-eye-off {
    display: none;
}

.reveal-btn[aria-pressed="true"] .icon-eye {
    display: none;
}

.reveal-btn[aria-pressed="true"] .icon-eye-off {
    display: block;
}

/* ── Erro ───────────────────────────────────────────────────────────── */

.login-error {
    margin: 0;
    padding: 11px 13px;
    background: rgba(253, 238, 240, 0.95);
    border: 1px solid rgba(230, 57, 70, 0.35);
    border-left: 3px solid var(--accent);
    border-radius: 10px;
    color: #8e1c25;
    font-size: 0.9rem;
    line-height: 1.45;
}

.login-error[hidden] {
    display: none;
}

/* ── Botão ──────────────────────────────────────────────────────────── */

.login-btn {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    min-height: 50px;
    margin-top: 2px;
    padding: 14px 20px;
    background: #111111;
    color: #ffffff;
    border: 1px solid #111111;
    border-radius: var(--radius);
    font: inherit;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.08s ease, opacity 0.15s ease;
}

.login-btn:hover:not(:disabled) {
    background: #000000;
}

.login-btn:active:not(:disabled) {
    transform: translateY(1px);
}

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

.login-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.login-btn-spinner {
    display: none;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #ffffff;
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

.login-btn.is-busy .login-btn-spinner {
    display: block;
}

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

/* ── Rodapé ─────────────────────────────────────────────────────────── */

/* A second, quieter panel under the card rather than more content inside it.
   In the card the legal text made the whole thing fill a phone screen, and
   the photographs — the actual point of the page — never showed at all. */
.login-footer {
    margin-top: 14px;
    padding: 16px 18px;
    border-radius: var(--radius-lg);
    background: rgba(255, 255, 255, 0.65);
    -webkit-backdrop-filter: blur(30px) saturate(140%) brightness(1.12);
    backdrop-filter: blur(30px) saturate(140%) brightness(1.12);
    border: 1px solid rgba(255, 255, 255, 0.5);
    /* Small, but never below the ~12px where legal text stops being legible
       to the people this archive is actually for. This is the smallest text
       on the page sitting on the thinnest glass, so it is the first thing to
       fail — hence near-black rather than the grey it would be on paper. */
    font-size: 0.74rem;
    line-height: 1.5;
    color: #2e2e2e;
    --ink-soft: #2a2a2a;
    --ink-faint: #2e2e2e;
}

.footer-line {
    margin: 0 0 10px;
    color: var(--ink-soft);
}

.footer-line strong {
    color: var(--ink);
    font-weight: 600;
}

.footer-legal {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}

.footer-legal p {
    margin: 0 0 7px;
}

.footer-legal p:last-child {
    margin-bottom: 0;
}

.footer-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0 0;
}

.footer-meta a {
    color: var(--ink-soft);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.footer-meta a:hover {
    color: var(--ink);
}

/* ══ Ecrã largo: o split clássico ═══════════════════════════════════════
   Everything above is rebuilt here: the photos stop being a backdrop and
   become the left half, and the card stops being glass and becomes the
   right half of the page. */

@media (min-width: 900px) {
    .login-body {
        background: var(--bg);
    }

    .login-split {
        display: grid;
        grid-template-columns: 1.05fr 1fr;
        /* Never taller than the window — the panel scrolls on its own */
        height: 100dvh;
        min-height: 0;
    }

    .login-gallery {
        position: relative;
        inset: auto;
    }

    /* A wide window shows the whole frame, so the crop can sit at the middle */
    .gallery-img {
        object-position: center center;
    }

    .gallery-veil {
        background: linear-gradient(
            to top,
            rgba(0, 0, 0, 0.42) 0%,
            rgba(0, 0, 0, 0.12) 34%,
            rgba(0, 0, 0, 0) 62%
        );
    }

    .gallery-caption {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        gap: 2px;
        margin: 0;
        padding: 32px 34px;
        color: #ffffff;
        font-size: 0.8rem;
        font-weight: 600;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
        pointer-events: none;
    }

    .gallery-caption-line:last-child {
        opacity: 0.82;
        letter-spacing: 0.08em;
        font-weight: 500;
        text-transform: none;
    }

    /* Nothing to show (no photos yet): keep the column, drop the black slab */
    .login-gallery.is-empty {
        background: #f2f2f2;
    }

    .login-gallery.is-empty .gallery-veil,
    .login-gallery.is-empty .gallery-caption {
        display: none;
    }

    .login-panel {
        min-height: 0;
        background: var(--bg);
        padding: 48px 56px;
        overflow-y: auto;
    }

    /* Back to a plain page, no glass anywhere */
    .login-panel-inner {
        max-width: 400px;
        --ink-soft: #555555;
        --ink-faint: #8a8a8a;
        --line: #e6e6e6;
        --line-strong: #d0d0d0;
    }

    .login-card,
    .login-footer {
        background: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        border: 0;
        border-radius: 0;
        padding: 0;
        box-shadow: none;
    }

    .field input {
        background: var(--field-bg);
    }

    .login-error {
        background: var(--accent-soft);
    }

    .login-footer {
        margin-top: auto;
        padding-top: 40px;
        font-size: 0.76rem;
        color: var(--ink-faint);
        --ink-soft: #555555;
        --ink-faint: #8a8a8a;
    }

    .footer-legal {
        padding: 12px 14px;
        border: 1px solid var(--line);
        border-radius: var(--radius);
        background: #fbfbfb;
    }
}

@media (min-width: 1280px) {
    .login-panel {
        padding: 56px 80px;
    }

    .login-panel-inner {
        max-width: 420px;
    }
}

/* ── Telemóvel deitado ──────────────────────────────────────────────── */

@media (max-width: 899px) and (max-height: 520px) {
    /* Short and wide: shrink the card's own padding rather than hide the
       photos, since here they are the background, not a banner taking space. */
    .login-panel {
        padding: 16px;
    }

    .login-card {
        padding: 18px 18px 16px;
    }

    .login-header {
        margin-bottom: 16px;
    }
}

/* ── Preferências do sistema ────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    /* Keep the crossfade — a hard cut between photos is more jarring than a
       fade — but drop the drift and shorten it considerably. */
    .gallery-img {
        transform: none;
        transition: opacity 320ms ease-in-out;
    }

    .gallery-img.is-active {
        transform: none;
    }

    .login-btn,
    .field input {
        transition: none;
    }

    .login-btn:active:not(:disabled) {
        transform: none;
    }

    .login-btn-spinner {
        animation-duration: 2s;
    }
}

@media (prefers-contrast: more) {
    .login-card,
    .login-footer {
        background: #ffffff;
    }

    .login-panel-inner {
        --ink-soft: #333333;
        --ink-faint: #444444;
        --line: #999999;
        --line-strong: #666666;
    }
}
