/* =====================================================
   FILM.CSS
   Page-specific styles for film.asp
   ===================================================== */


/* ===================== HERO ===================== */
.hero {
    min-height: 85vh;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    display: flex;
    align-items: flex-end;
    padding: 0 60px 80px;
}

.hero-content {
    max-width: 720px;
}

/* ===================== HERO BADGES =====================
   .badge-winner / .badge-rated are shared with the film cards, where
   they are absolutely positioned over the thumbnail. In the hero they
   must sit in normal flow ABOVE the <h1> - inheriting the card rule is
   what made the badge overlap the title. These selectors are two
   classes deep so they beat the bare .badge-* rules, and film.css is
   linked after components.css via extraHead. */
.hero-content .hero-badges {
    position: static;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px;
}

.hero-content .badge-winner,
.hero-content .badge-rated {
    position: static;
    inset: auto;
    transform: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    max-width: 100%;
    /* min-height 28px: the hero badge is a real link, and Lighthouse
       fails interactive targets smaller than 24x24. */
    min-height: 28px;
    box-sizing: border-box;
    padding: 6px 14px;
    border-radius: 999px;
    background: linear-gradient(135deg, #f6d365, #d4af37);
    color: #1a1206;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .06em;
    line-height: 1;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}

.hero-content .badge-winner .badge-icon,
.hero-content .badge-rated .badge-icon {
    width: 14px;
    height: 14px;
    fill: currentColor;
    flex: 0 0 auto;
}

.hero-content .badge-winner:hover,
.hero-content .badge-winner:focus-visible { filter: brightness(1.06); }


.hero-content h1 {
    font-size: 52px;
    margin: 0 0 10px 0;
    letter-spacing: -0.5px;
    line-height: 1.1;
}

.meta {
    font-size: 14px;
    color: var(--muted, #aaa);
    margin-bottom: 14px;
    line-height: 1.4;
}

.meta-link {
    color: var(--muted, #aaa);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: color .2s, border-color .2s;
}

.meta-link:hover {
    color: #fff;
    border-bottom-color: #fff;
}

.filmmaker-link {
    color: var(--muted, #aaa);
    text-decoration: none;
    border-bottom: 1px dotted var(--muted, #aaa);
    transition: color .2s, border-color .2s;
    cursor: pointer;
}

.filmmaker-link:hover {
    color: #fff;
    border-bottom-color: #fff;
}

/* ===========================
   Film Tags
=========================== */

.tags {
    margin: 10px 0px 10px 0px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

    /* tag chip */
    .tags .tag {
        display: inline-block;
        padding: 6px 14px;
        font-size: 13px;
        font-weight: 500;
        color: #fff;
        text-decoration: none;
        background: rgba(255,255,255,0.08);
        border: 1px solid rgba(255,255,255,0.15);
        border-radius: 10px;
        backdrop-filter: blur(4px);
        transition: all .18s ease;
    }

        /* hover */
        .tags .tag:hover {
            background: #d4af37; /* FOA gold */
            border-color: #d4af37;
            color: #000;
            transform: translateY(-1px);
        }

        /* active click */
        .tags .tag:active {
            transform: scale(.96);
        }

.hero-content > p {
    color: var(--muted2, #ccc);
    line-height: 1.6;
    max-width: 620px;
    margin: 0 0 18px 0;
    font-size: 15px;
}

.hero-btns {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

/* ---- Share row ----
   Deliberately quieter than .watch-btn / .vote-btn: sharing is a
   secondary action and must not compete with Play. Wraps on narrow
   screens rather than scrolling, and every control is >=38px tall so it
   stays a comfortable touch target. */
/* Sits under the synopsis in the Overview tab now, not in the hero, so
   it needs separating from the paragraph above rather than from the
   buttons it used to follow. */
.share-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid rgba(255, 255, 255, .09);
}

/* Two icon styles: outline marks (copy link, email) are drawn with
   strokes, brand marks are solid paths. Both sized identically so the
   buttons line up regardless of which they carry. */
.share-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    margin-right: 7px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.share-icon--solid {
    fill: currentColor;
    stroke: none;
}

.share-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .45);
    margin-right: 2px;
}

.share-btn {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    padding: 8px 15px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .14);
    background: rgba(255, 255, 255, .06);
    color: #dcdcdc;
    font: inherit;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.share-btn:hover,
.share-btn:focus-visible {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}

/* The copy button swaps its own label to "Copied"; the width change
   would otherwise shuffle the buttons beside it. */
#btnCopyLink {
    min-width: 104px;
    justify-content: center;
}

.share-btn.is-copied {
    background: rgba(120, 220, 150, .16);
    border-color: rgba(120, 220, 150, .45);
    color: #b7f0c8;
}

.watch-btn {
    background: #fff;
    color: #000;
    border: none;
    border-radius: 10px;
    padding: 14px 26px;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    font-family: inherit;
    transition: transform .2s ease;
}

.watch-btn:hover { transform: scale(1.04); }

.donate-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--accent, #d60000);
    color: #fff;
    border: none;
    border-radius: 10px;
    padding: 14px 26px;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    text-decoration: none;
    font-family: inherit;
    transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.donate-btn:hover {
    background: #b30000;
    transform: translateY(-3px) scale(1.06);
    box-shadow: 0 12px 30px rgba(214,0,0,0.35);
}

/* ===========================
   Vote Button
   =========================== */

.vote-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0px;
    padding: 12px 12px;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .3px;
    border: 1px solid #ffd54a;
    background: linear-gradient(135deg,#ffd54a,#ffb300);
    color: #111;
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease, background .2s ease;
}

    .vote-btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 20px rgba(0,0,0,.35), 0 0 12px rgba(255,213,74,.6);
        background: linear-gradient(135deg,#ffe27a,#ffc72c);
    }

    .vote-btn:active {
        transform: translateY(0);
        box-shadow: 0 4px 10px rgba(0,0,0,.3);
    }

    .vote-btn:focus {
        outline: none;
        box-shadow: 0 0 0 2px rgba(255,213,74,.5), 0 0 0 4px rgba(0,0,0,.6);
    }

.vote-icon {
    width: 18px;
    height: 18px;
    fill: currentColor;
    margin-right: 6px;
    flex-shrink: 0;
}


/* ===================== CONTENT PANEL ===================== */
.content {
    max-width: 1040px;
    margin: -34px auto 48px;
    padding: 34px 60px 54px;
    background: var(--panel, rgba(255,255,255,0.02));
    border-radius: 16px;
    backdrop-filter: blur(12px);
}


/* ===================== TABS ===================== */
.tab-bar {
    display: flex;
    gap: 30px;
    border-bottom: 1px solid var(--line, #222);
    margin-bottom: 26px;
    position: relative;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.tab-bar::-webkit-scrollbar { display: none; }

.tab-btn {
    background: none;
    border: none;
    color: #888;
    font-size: 15px;
    font-weight: 700;
    padding: 0 0 12px 0;
    cursor: pointer;
    white-space: nowrap;
    font-family: inherit;
    transition: color .15s;
}

.tab-btn:hover  { color: #bbb; }
.tab-btn.active { color: #fff; }

.tab-indicator {
    position: absolute;
    bottom: -1px;
    height: 3px;
    background: #fff;
    transition: left .25s ease, width .25s ease;
    border-radius: 3px;
}

.tab-content {
    display: none;
    animation: fadeUp .35s ease;
    color: var(--muted2, #ccc);
    line-height: 1.7;
}

.tab-content.active { display: block; }

.tab-content > p { margin: 0 0 16px 0; }

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}


/* ===================== FILM DETAILS TAB ===================== */
.film-details-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 40px;
    margin-top: 18px;
}

.film-details-grid .item {
    padding: 10px 0;
    border-bottom: 1px solid var(--line, #222);
    font-size: 14px;
    color: #ccc;
}

.film-details-grid strong {
    color: #fff;
    font-weight: 700;
}

.detail-link {
    color: var(--muted2, #ccc);
    text-decoration: none;
    border-bottom: 1px dotted rgba(255,255,255,0.25);
    transition: color .2s, border-color .2s;
}

.detail-link:hover {
    color: #fff;
    border-bottom-color: #fff;
}


/* ===================== TRANSCRIPT TAB ===================== */
.transcript-text {
    max-width: 760px;
    font-size: 15px;
    line-height: 1.8;
    color: var(--muted2, #ccc);
}

.transcript-text p        { margin: 0 0 18px 0; }
.transcript-text strong   { color: #fff; }


/* ===================== COMMENTS TAB ===================== */
.comments-section { max-width: 700px; }

.comment-form {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin-bottom: 32px;
}

.comment-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, #444, #666);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 700;
    color: #ddd;
}

.comment-input-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.comment-input {
    width: 100%;
    min-height: 72px;
    background: rgba(255,255,255,0.06);
    border: 1px solid var(--line, #222);
    border-radius: 10px;
    padding: 12px 14px;
    color: #fff;
    font-family: inherit;
    font-size: 14px;
    resize: vertical;
    transition: border-color .2s;
}

.comment-input:focus {
    outline: none;
    border-color: rgba(255,255,255,0.3);
}

.comment-input::placeholder { color: #555; }

.comment-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

.comment-submit {
    padding: 9px 22px;
    background: #fff;
    color: #000;
    border: none;
    border-radius: 8px;
    font-weight: 700;
    font-size: 13px;
    cursor: pointer;
    font-family: inherit;
    transition: opacity .2s, transform .15s;
}

.comment-submit:hover:not(:disabled) { transform: scale(1.03); }

.comment-submit:disabled {
    opacity: 0.35;
    cursor: default;
    transform: none;
}

.comment-count {
    font-size: 13px;
    color: #555;
    margin-bottom: 18px;
}

.comment-list {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.comment-item {
    display: flex;
    gap: 12px;
    padding: 18px 0;
    border-bottom: 1px solid var(--line, #222);
    animation: fadeUp .3s ease;
}

.comment-item:first-child { padding-top: 0; }

.comment-body { flex: 1; }

.comment-author {
    font-weight: 700;
    color: #fff;
    font-size: 14px;
}

.comment-time {
    font-size: 12px;
    color: #555;
    margin-left: 10px;
}

/* ---------- Pending comment ----------
   A comment the visitor has just posted. It is stored with
   Approved = 0 and film.asp only renders Approved = 1, so it is NOT
   public yet and must not look like the approved comments around it.
   Muted, dashed edge, explicit badge - the styling is the honest part;
   the status message alone was not enough. */
.comment-item.is-pending {
    opacity: 0.72;
    border-bottom-style: dashed;
    border-left: 2px solid var(--gold, #b99757);
    padding-left: 12px;
}

.comment-item.is-pending .comment-text {
    font-style: italic;
}

.comment-pending-badge {
    display: inline-block;
    margin-left: 10px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(185, 151, 87, 0.15);
    border: 1px solid rgba(185, 151, 87, 0.35);
    color: var(--gold, #b99757);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    vertical-align: middle;
}

.comment-text {
    margin: 5px 0 0;
    font-size: 14px;
    color: var(--muted2, #ccc);
    line-height: 1.55;
}


/* ===================== RELATED FILMS ===================== */
.related {
    width: 100%;
    padding: 10px 0 60px;
}

.related-inner { padding: 0 60px; }

.related-inner > h2 {
    margin: 0 0 18px 0;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.2px;
}

.carousel-wrapper { position: relative; }

.carousel {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scroll-behavior: smooth;
    padding-bottom: 8px;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.carousel::-webkit-scrollbar { display: none; }

/* film.css — search-card badges missing on film.asp */
.carousel .badge-rated{
    position:absolute;top:10px;left:10px;z-index:2;
    display:inline-flex;align-items:center;gap:4px;
    padding:4px 10px;border-radius:999px;
    font-size:.75rem;font-weight:700;
    background:#f4b942;color:#111;
}
.carousel .badge-icon{width:14px;height:14px;fill:currentColor;flex:0 0 auto}

.film-card-title {
    margin: 0;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
}

/* Related card */
.card {
    position: relative;
    min-width: 240px;
    width: 240px;
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    overflow: hidden;
    cursor: pointer;
    scroll-snap-align: start;
    transform: translateZ(0);
    transition: transform .22s ease;
    background: #111;
    text-decoration: none;
    color: inherit;
    display: block;
}

.card:hover { transform: scale(1.06); }

.card .poster,
.card .preview {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.card .poster { object-fit: cover; }
.card .preview { display: none; background: #000; }

.tooltip {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 12px 12px 10px;
    background: linear-gradient(to top, rgba(0,0,0,0.92), rgba(0,0,0,0.05));
    opacity: 0;
    transition: opacity .2s ease;
    pointer-events: none;
}

.card:hover .tooltip { opacity: 1; }

.tooltip strong {
    display: block;
    font-size: 14px;
    color: #fff;
}

.tooltip span {
    display: block;
    font-size: 12px;
    color: #cfcfcf;
    margin-top: 3px;
}

.carousel-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0,0,0,0.65);
    border: 1px solid rgba(255,255,255,0.12);
    color: #fff;
    width: 42px;
    height: 42px;
    border-radius: 999px;
    cursor: pointer;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    transition: background .2s;
}

.carousel-btn:hover { background: rgba(0,0,0,0.85); }
.carousel-btn.left  { left: -18px; }
.carousel-btn.right { right: -18px; }
.carousel-btn:active { transform: translateY(-50%) scale(0.97); }


/* ===================== VIDEO MODAL ===================== */
.modal {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.92);
    backdrop-filter: blur(6px);
    justify-content: center;
    align-items: center;
    z-index: 5000;
    padding: 20px;
    animation: modalFadeIn .2s ease;
    background: rgba(0,0,0,0.85);
    backdrop-filter: blur(6px);
}

.modal.active { display: flex; }

@keyframes modalFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Centred flex column with the toolbar in normal flow immediately
   above the video frame. Migrated from the inline <style> block in
   film.asp (the position:static/inset:auto neutralisers in that block
   were no-ops and have been dropped). */
.modal-inner {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: min(1100px, 94vw);
    height: 100%;
    max-height: 100vh;
    margin: 0 auto;
    padding: 6px 0;
    box-sizing: border-box;
}

.modal-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2px;
    width: 100%;
    margin: 0 0 2px;
    padding: 0;
}

.modal-title {
    min-width: 0;
    font-size: 15px;
    font-weight: 700;
    color: #ccc;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.modal-close {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(255,255,255,0.1);
    border: 1px solid rgba(255,255,255,0.15);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background .15s, transform .15s;
}

.modal-close:hover {
    background: rgba(255,255,255,0.2);
    transform: scale(1.08);
}

.modal-close svg {
    width: 16px;
    height: 16px;
}

.modal .frame-wrap {
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 30px 80px rgba(0,0,0,0.6);
}

.modal iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.modal-hint {
    text-align: center;
    font-size: 12px;
    /* was #444 on a near-black backdrop: ~2.5:1, a contrast failure.
       #8f8f8f clears 4.5:1 against the 85%-black modal background. */
    color: #8f8f8f;
    margin: 10px 0 0;
}

.modal-hint kbd {
    background: rgba(255,255,255,0.08);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 11px;
    font-family: inherit;
    color: #c8c8c8;
}


/* ===================== VIDEO MODAL OVERLAYS ===================== */
/* Sponsor preroll (before the film) and post-roll endcard (after it).
   Both are absolutely positioned inside .frame-wrap and share one skin.
   Migrated out of the inline <style> block in film.asp. */

.frame-wrap { position: relative; }

.sponsor-intro,
.film-endcard {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 24px;
    text-align: center;
    color: #fff;
    background:
        radial-gradient(circle at top right, rgba(244,185,66,.25), transparent 34%),
        linear-gradient(135deg, #12222f, #070d13);
    transition: opacity .35s ease, visibility .35s ease;
}

/* Preroll starts visible and is hidden at handoff. */
.sponsor-intro { z-index: 2; opacity: 1; visibility: visible; }
.sponsor-intro.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }

/* Endcard starts hidden and is revealed on ENDED. z-index 3 so it also
   covers YouTube's in-iframe related-video end screen. */
.film-endcard { z-index: 3; opacity: 0; visibility: hidden; pointer-events: none; }
.film-endcard.is-visible { opacity: 1; visibility: visible; pointer-events: auto; }

.sponsor-content,
.endcard-content { max-width: 620px; }

.sponsor-intro .presented-by,
.endcard-kicker {
    margin: 0 0 12px;
    font-size: .9rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .85;
}

/* The sponsor's name, set as type. This is the preroll's headline now
   rather than a stand-in for a missing image, so the bordered chip it
   used to be - 2px outline, tinted panel, 200x72 minimum - has gone:
   an empty framed box on screen reads as a logo that failed to load.
   Plain white text on the dark backdrop simply reads as the name. */
.sponsor-intro .sponsor-logo {
    margin-bottom: 16px;
    font-size: clamp(1.6rem, 4vw, 2.6rem);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.01em;
}

/* Sponsor logos are drawn for white paper, and this screen is nearly
   black - the NOVA wordmark is navy and gold and would all but vanish on
   it. The plate is white so the logo is shown the way its owner intends,
   rounded so it reads as a deliberate frame rather than a stray
   rectangle. background covers any future logo supplied with a
   transparent background instead of a baked-in white one. */
.sponsor-intro .sponsor-logo-img {
    max-width: min(320px, 70%);
    max-height: 110px;
    margin-bottom: 16px;
    border-radius: 10px;
    background: #fff;
}

.sponsor-intro .sponsor-message,
.endcard-message {
    margin: 0 0 20px;
    font-size: clamp(.95rem, 2vw, 1.15rem);
    line-height: 1.5;
}

.endcard-title {
    margin: 0 0 10px;
    font-size: clamp(1.4rem, 3.5vw, 2.2rem);
    font-weight: 800;
    line-height: 1.2;
}

.endcard-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

/* ---- NOVA offer, pre-roll ------------------------------------------
   One quiet line under the supporter credit. The pre-roll has a four
   second countdown and one job - getting out of the way of the film -
   so this is a link, not a button: nothing here should compete with
   "Play film now" or be pressed by accident on the way past. */
.sponsor-offer {
    display: inline-block;
    margin: 6px 0 2px;
    color: #f4b942;
    font-size: .95rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.sponsor-offer:hover,
.sponsor-offer:focus-visible { color: #fff; }

/* ---- NOVA offer, endcard -------------------------------------------
   The real ask, and the only slot where one is fair: the viewer has
   just finished a film about what people with disability can do.

   Sits BELOW the festival's own actions and is styled as a panel rather
   than a third button, so it reads as "and by the way" instead of
   competing with Vote. A gold left edge ties it to the sponsor pre-roll
   they saw four seconds before the film. */
.endcard-nova {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    justify-content: center;
    text-align: left;
    margin: 22px auto 0;
    max-width: 560px;
    padding: 14px 18px;
    background: rgba(255,255,255,.06);
    border: 1px solid rgba(255,255,255,.10);
    border-left: 4px solid #f4b942;
    border-radius: 12px;
}

/* .endcard-nova-logo removed with the img it styled - the endcard promo
   is text only now. .endcard-nova is still a flex row: the text block
   and the CTA are the two items. */

.endcard-nova-text { flex: 1 1 220px; min-width: 0; }

.endcard-nova-head {
    margin: 0 0 2px;
    font-size: 1rem;
    font-weight: 800;
    color: #fff;
    line-height: 1.3;
}

.endcard-nova-body {
    margin: 0;
    font-size: .85rem;
    line-height: 1.55;
    color: rgba(255,255,255,.78);
}

.endcard-nova-cta {
    flex: 0 0 auto;
    padding: 10px 18px;
    border-radius: 8px;
    background: #f4b942;
    color: #191100;
    font-size: .9rem;
    font-weight: 800;
    text-decoration: none;
    white-space: nowrap;
}
.endcard-nova-cta:hover,
.endcard-nova-cta:focus-visible { background: #ffd071; color: #000; }

@media (max-width: 520px) {
    .endcard-nova { text-align: center; }
    .endcard-nova-cta { width: 100%; text-align: center; }
}

/* Secondary "keep watching" links: deliberately quieter than the
   primary CTA so the vote / screenings button stays the obvious action. */
.endcard-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 18px;
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
    font-size: .9rem;
}

.endcard-links a,
.endcard-link-btn {
    appearance: none;
    padding: 0;
    border: 0;
    background: none;
    color: rgba(255,255,255,.85);
    font: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.endcard-links a:hover,
.endcard-links a:focus-visible,
.endcard-link-btn:hover,
.endcard-link-btn:focus-visible { color: #f4b942; }

.endcard-links a:focus-visible,
.endcard-link-btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.sponsor-intro .play-now,
.endcard-btn {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 12px 22px;
    border: 0;
    border-radius: 999px;
    font-family: inherit;
    font-size: 1rem;
    font-weight: 800;
    text-decoration: none;
    cursor: pointer;
}

.sponsor-intro .play-now,
.endcard-btn.primary { background: #f4b942; color: #111; }

.endcard-btn.secondary {
    background: rgba(255,255,255,.12);
    border: 1px solid rgba(255,255,255,.4);
    color: #fff;
}

.endcard-btn.ghost {
    background: transparent;
    color: #fff;
    text-decoration: underline;
}

.sponsor-intro .play-now:hover,
.sponsor-intro .play-now:focus-visible,
.endcard-btn:hover,
.endcard-btn:focus-visible { filter: brightness(1.08); }

.sponsor-intro .play-now:focus-visible,
.endcard-btn:focus-visible { outline: 3px solid #fff; outline-offset: 4px; }

.sponsor-intro .countdown {
    min-height: 1.4em;
    margin: 12px 0 0;
    font-size: .85rem;
    opacity: .8;
}

/* Short viewports: the endcard has more content than the preroll and
   is constrained by the 16:9 frame, so let it scroll rather than clip. */
@media (max-height: 520px) {
    .film-endcard { place-items: start center; overflow-y: auto; padding: 16px; }
    .endcard-kicker { margin-bottom: 6px; }
    .endcard-title { font-size: 1.2rem; }
    .endcard-message { margin-bottom: 12px; font-size: .9rem; }
    .endcard-links { margin-top: 12px; font-size: .82rem; }
    .sponsor-intro .play-now,
    .endcard-btn { min-height: 42px; padding: 9px 18px; font-size: .92rem; }
}

@media (prefers-reduced-motion: reduce) {
    .sponsor-intro,
    .film-endcard { transition: none; }
}


/* ===================== FLOATING DONATE ===================== */
/* .floating-donate moved to base.css. It is emitted by
   includes/layout_bottom.asp on every page now, and film.css is the
   only stylesheet film.asp loads - which is precisely why the button
   appeared here and nowhere else on the site. */


/* ===================== RESPONSIVE ===================== */
@media (max-width: 980px) {
    .hero              { padding: 0 20px 46px; min-height: 72vh; }
    .hero-content h1   { font-size: 36px; }
    .content           { padding: 26px 20px 44px; margin: -22px 12px 40px; }
    .related-inner     { padding: 0 20px; }
    .carousel-btn      { display: none; }
}

@media (max-width: 640px) {
    .hero-content h1        { font-size: 32px; }
    .film-details-grid      { grid-template-columns: 1fr; }
    .card                   { min-width: 190px; width: 190px; }
    .comment-form           { flex-direction: column; }
}

@media (hover: none) {
    .card:hover       { transform: none; }
    .card:hover .tooltip { opacity: 1; }
}




/* ===========================
   VOTE MODAL
=========================== */

.vote-modal {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.85);
    backdrop-filter: blur(6px);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.vote-card {
    width: 440px;
    max-width: 92%;
    border-radius: 14px;
    overflow: hidden;
    background: rgba(20,20,20,.95);
    border: 1px solid rgba(255,255,255,.08);
    box-shadow: 0 40px 90px rgba(0,0,0,.7);
    color: #eee;
}

/* HEADER */

.vote-header {
    padding: 18px 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid rgba(255,255,255,.08);
}

.vote-title {
    font-size: 20px;
    font-weight: 700;
    margin: 0;
}

.vote-close {
    border: none;
    background: none;
    font-size: 26px;
    color: #aaa;
    cursor: pointer;
}

    .vote-close:hover {
        color: #fff;
    }

/* BODY */

.vote-body {
    padding: 16px 30px 32px;
}

.vote-film {
    text-align: center;
    margin-bottom: 22px;
}

.vote-film-title {
    display: block;
    font-size: 24px;
    font-weight: 700;
    color: #d4af37;
}

.vote-film-meta {
    font-size: 13px;
    color: #aaa;
}

/* FORM */

.vote-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

    .vote-form input,
    .vote-form select {
        width: 100%;
        padding: 14px;
        border-radius: 8px;
        border: 1px solid rgba(255,255,255,.12);
        background: rgba(255,255,255,.05);
        color: #fff;
        font-size: 15px;
    }

        /* "Democratic Republic of the Congo" is 32 characters and was
           being sliced off mid-word in the closed select. A native
           select clips its selected text with no ellipsis and no
           warning, so the reader cannot tell whether they are looking
           at a truncated name or the wrong country.

           Room reserved on the right for the arrow, which otherwise
           sits on top of the last few letters, and an ellipsis so a
           name too long for the control still reads as truncated
           rather than as a different country. */
        .vote-form select {
            padding-right: 36px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .vote-form select option {
            color: #000;
            background: #fff;
        }

        .vote-form input:focus,
        .vote-form select:focus {
            outline: none;
            border-color: #d4af37;
        }

/* first/last row */

/* Preview banner. Only ever rendered for an address on PREVIEW_IPS,
   looking at a film the public cannot reach - so it has to be
   unmistakable. A tester who cannot tell preview from live will report
   correct behaviour as a bug. */
.film-preview-flag {
    max-width: 760px;
    margin: 0 0 16px;
    padding: 12px 16px;
    border-radius: 10px;
    background: rgba(212,175,55,.12);
    border: 1px solid rgba(212,175,55,.45);
    border-left: 4px solid #d4af37;
    color: #efe4c4;
    font-size: 14.5px;
    line-height: 1.6;
}
.film-preview-flag strong { color: #fff; }

/* ---- Vote form fields ----------------------------------------------
   One .vote-field per label+control pair, so the form's 12px gap falls
   BETWEEN fields and never between a label and the thing it names.

   column, not row. The wrapper was briefly display:flex with the default
   row direction, which put each label to the LEFT of its input - the
   labels are real and visible (see film.asp), so a row direction lays
   them out beside the field rather than above it.

   Still flex rather than plain block: an <input> is inline-level, so a
   block wrapper picks up the line box descender underneath it and the
   name row stands a few pixels taller than the fields below, which is
   what threw the spacing out in the first place. */
.vote-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

    .vote-field label {
        font-size: 13px;
        font-weight: 600;
        letter-spacing: .2px;
        color: #cfd4dc;
    }

    /* Says the field can be skipped, without competing with the label. */
    .vote-optional {
        font-weight: 500;
        font-size: 12px;
        color: #8b929c;
        text-transform: lowercase;
    }

/* ---- A field that was rejected -------------------------------------
   The status line at the top of the form said what was wrong but never
   which box it was wrong in, which on a four-field form is most of the
   answer missing.

   Red on the border AND a message underneath, not colour alone - about
   one man in twelve cannot reliably separate this red from the normal
   border, and colour on its own carries nothing to a screen reader
   either. The message is role="alert" and the input gets aria-invalid,
   so it is announced rather than merely drawn. */
.vote-field.is-invalid input,
.vote-field.is-invalid select {
    border-color: #e5534b;
    background: rgba(229, 83, 75, 0.08);
}

.vote-field.is-invalid input:focus,
.vote-field.is-invalid select:focus {
    border-color: #e5534b;
    box-shadow: 0 0 0 3px rgba(229, 83, 75, 0.22);
}

.vote-field.is-invalid label {
    color: #ffb4ae;
}

.vote-field-error {
    font-size: 12.5px;
    line-height: 1.4;
    color: #ffb4ae;
}

.name-row {
    display: flex;
    gap: 12px;
}

    /* flex:1 1 0 so the two halves are equal whatever their labels say.
       min-width:0 because a flex item will not shrink below its
       intrinsic width without it, which is what pushes a two-up row out
       of a narrow modal. */
    .name-row > .vote-field {
        flex: 1 1 0;
        min-width: 0;
    }

    .name-row input {
        flex: 1;
    }

/* submit */

/* ---- Vote step 2: the emailed code ----
   The input is deliberately large, monospaced and widely tracked. People
   are transcribing six digits from a phone notification, often on the
   same phone, and a normal-sized field is where that goes wrong. */
.vote-code-step { text-align: center; }

/* ---- Category board after a confirmed vote -------------------------
   Rendered by renderCategoryBoard() in film.js, and deliberately the
   same shape as the .vc-list block on vote_confirmed.asp: the two are
   the same information at the same moment, reached by two routes, and
   they should not look like two different features. */
.vote-cat-board {
    text-align: left;
    margin: 22px 0 4px;
    padding: 18px 18px 6px;
    background: rgba(255,255,255,.04);
    border: 1px solid rgba(255,255,255,.09);
    border-radius: 12px;
}
.vote-cat-board h4 {
    font-size: 15.5px;
    font-weight: 800;
    margin: 0 0 4px;
    color: #fff;
}
.vote-cat-board > p {
    font-size: 13px;
    color: #9a9a9a;
    margin: 0 0 12px;
}
.vote-cat-list { list-style: none; margin: 0; padding: 0; }
.vote-cat-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 0;
    border-bottom: 1px solid rgba(255,255,255,.06);
}
.vote-cat-item:last-child { border-bottom: 0; }
.vote-cat-mark {
    flex: 0 0 auto;
    width: 20px; height: 20px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 900;
}
.vote-cat-mark.done { background: #0d7a45; color: #fff; }
.vote-cat-mark.todo { background: rgba(255,255,255,.09); color: #8b8b8b; }
.vote-cat-name { flex: 1 1 auto; font-size: 14.5px; color: #ddd; }
.vote-cat-item.is-done .vote-cat-name { color: #8f8f8f; }
.vote-cat-state { flex: 0 0 auto; font-size: 12px; color: #8b8b8b; }
.vote-cat-go {
    flex: 0 0 auto;
    font-size: 12.5px;
    font-weight: 700;
    color: #7fb0ff;
    text-decoration: none;
    border: 1px solid rgba(127,176,255,.35);
    border-radius: 7px;
    padding: 5px 11px;
}
.vote-cat-go:hover { background: rgba(127,176,255,.12); color: #fff; }

/* The "not counted yet" warning. A boxed alert rather than another line
   of body copy: this is the one sentence on the step that decides
   whether the vote ever counts, and as plain text under a heading it was
   being skipped by people who assumed pressing submit was voting. */
.vote-code-warn {
    text-align: left;
    font-size: 14.5px;
    line-height: 1.65;
    color: #f0e2c0;
    background: rgba(208, 169, 76, 0.12);
    border: 1px solid rgba(208, 169, 76, 0.45);
    border-left: 4px solid #d0a94c;
    border-radius: 10px;
    padding: 14px 16px;
    margin: 0 0 14px;
}
.vote-code-warn strong { color: #fff; }

.vote-code-note {
    font-size: 13.5px;
    color: #d0a94c;
    margin: 4px 0 18px;
}

/* "Is that address wrong? Change it and send again"

   Sits directly under the box showing the address back, because that is
   where somebody notices they typed gmail.con. Deliberately quieter than
   the gold warning above it and louder than the grey "Start again" at
   the bottom: correcting a typo is the second most likely thing to be
   wanted on this screen, after typing the code.

   Kept OUT of the role="alert" paragraph above. A live region should
   announce the message, not a control the screen reader then has to
   describe mid-announcement. */
.vote-email-fix-line {
    text-align: left;
    font-size: 13.5px;
    color: #cfcfcf;
    margin: -6px 0 14px;
}

.vote-email-fix {
    padding: 4px 8px;
    border: 0;
    background: none;
    color: #e0be6a;
    font: inherit;
    font-size: 13.5px;
    text-decoration: underline;
    cursor: pointer;
    /* Line-length target, not a tap target - it sits inside a sentence.
       The 44px rule is met by the padding plus the line box. */
    min-height: 32px;
}

.vote-email-fix:hover,
.vote-email-fix:focus-visible { color: #fff; }

.vote-code-input {
    width: 100%;
    max-width: 260px;
    margin: 0 auto 14px;
    display: block;
    padding: 16px 12px;
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 12px;
    background: rgba(255, 255, 255, .06);
    color: #fff;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: 10px;
    text-align: center;
    text-indent: 10px; /* offsets the trailing letter-spacing so digits sit centred */
    outline: 0;
}

.vote-code-input::placeholder { color: rgba(255, 255, 255, .22); }

.vote-code-input:focus {
    border-color: rgba(255, 255, 255, .4);
    background: rgba(255, 255, 255, .09);
}

.vote-code-resend {
    display: block;
    margin: 14px auto 0;
    padding: 6px 10px;
    border: 0;
    background: none;
    color: #9d9d9d;
    font: inherit;
    font-size: 13.5px;
    text-decoration: underline;
    cursor: pointer;
}

.vote-code-resend:hover,
.vote-code-resend:focus-visible { color: #fff; }

/* flex, so the icon and the label sit on one baseline and stay centred
   together. The button was block with centred text; adding an inline SVG
   to that leaves the glyph riding high on the text baseline. */
.vote-submit {
    margin-top: 4px;
    padding: 15px;
    border-radius: 8px;
    border: none;
    background: #d4af37;
    color: #000;
    font-weight: 700;
    font-size: 15px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
}

    .vote-submit:hover {
        background: #e3c25c;
    }

/* currentColor, so the tick follows the button text through the hover
   and any future theme change rather than being pinned to black. */
.vote-submit-icon {
    width: 18px;
    height: 18px;
    fill: currentColor;
    flex-shrink: 0;
}

/* ---- A vote that cannot proceed ----------------------------------
 *
 * Shown INSTEAD of the form when submit_vote.asp returns final:true -
 * already voted in this category, voting closed, a daily limit reached.
 * Matches .vote-success-modal rather than the inline error style,
 * because it is the same kind of thing: an outcome, not a correction.
 */
.vote-final-modal {
    text-align: center;
    padding: 6px 20px 8px;
}

.vote-final-icon svg {
    width: 42px;
    height: 42px;
    fill: #d4af37;
    opacity: .9;
}

.vote-final-modal h3 {
    margin: 14px 0 8px;
    font-size: 1.05rem;
    line-height: 1.4;
    color: #fff;
}

.vote-final-modal p {
    margin: 0;
    color: var(--muted2);
    font-size: .9rem;
    line-height: 1.6;
}

.vote-note {
    text-align: center;
    font-size: 12px;
    color: #888;
}

/* The Turnstile widget on the vote form.
 *
 * WAS display:none, under a comment reading "Turnstile hidden
 * initially" - and nothing anywhere ever set it back. Not film.js, not
 * another rule, not an inline style. It was hidden permanently.
 *
 * Voting still worked, which is what made this hard to see: a widget in
 * a display:none container still runs, still passes a non-interactive
 * challenge, and still writes cf-turnstile-response into the form. So
 * the token arrives and the vote goes through, and the only symptom is
 * that nobody can see the box.
 *
 * It fails the moment Cloudflare decides a visitor needs to INTERACT.
 * Then the token is never issued, submit_vote.asp answers "Security
 * verification failed", and the page asks the visitor to complete a
 * check they cannot see and cannot reach. That is exactly the bug
 * reported from testing, and it is unrecoverable from the visitor's
 * side - reloading gets them the same invisible challenge.
 *
 * flex, not block, because justify-content was already here waiting for
 * it - the centring was written against a display value the rule never
 * had.
 *
 * No other page carries this rule; contact, register and
 * forgot_password all render the same widget visibly. */
.cf-turnstile {
    display: flex;
    justify-content: center;
    margin: 4px 0 14px;
}

/* mobile */

@media(max-width:500px) {

    .name-row {
        flex-direction: column;
    }
}

.youtube-facade {
    position: relative;
    width: 100%;
    aspect-ratio: 16/9;
    cursor: pointer;
    background: #000;
}

    .youtube-facade img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

.yt-play-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    width: 70px;
    height: 70px;
    border-radius: 50%;
    border: none;
    background: rgba(0,0,0,.6);
    color: white;
    font-size: 28px;
    cursor: pointer;
}

.yt-play-btn {
    transition: transform .2s ease, background .2s;
}

.youtube-facade:hover .yt-play-btn {
    transform: translate(-50%,-50%) scale(1.1);
    background: rgba(0,0,0,.8);
}


/* ---------- Breadcrumb (inside .hero-content) ---------- */
.breadcrumb {
    margin: 0 0 .5rem;
    font-size: .8rem;
}

.breadcrumb-list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.breadcrumb-item {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
}

/* Sits over the hero still, so it needs a shadow to stay legible on a
   bright frame. The gradient overlay handles the bottom of the hero,
   not the top where this now lives. */
.breadcrumb-item a,
.breadcrumb-item [aria-current="page"],
.breadcrumb-sep {
    text-shadow: 0 1px 3px rgba(0, 0, 0, .8);
}

.breadcrumb-item a {
    color: rgba(255, 255, 255, .75);
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

.breadcrumb-item a:hover,
.breadcrumb-item a:focus-visible {
    color: #fff;
    border-bottom-color: currentColor;
}

.breadcrumb-sep {
    color: rgba(255, 255, 255, .45);
}

.breadcrumb-item [aria-current="page"] {
    color: rgba(255, 255, 255, .95);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 40ch;
}

@media (max-width: 640px) {
    .breadcrumb-item:first-child { display: none; }
    .breadcrumb-item [aria-current="page"] { max-width: 20ch; }
}

/* ===================== SCREENING ADVERT =====================
   The Australia-only band under the related-films carousel.

   This markup shipped with NO rules behind it at all, so it rendered as
   a bare heading and an unstyled <ul> - the content was right and it
   looked like a mistake. Matching the language of screenings.asp on
   purpose: gold accent, dark card, date on the left where the eye scans
   for it. Somebody who follows "All screening dates" should land
   somewhere that looks like where they came from. */
.film-screenings {
    margin: 0 60px 60px;
    padding: 26px 30px;
    background: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.012));
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}

.fs-head h2 {
    margin: 0 0 4px;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.2px;
}

.fs-head p {
    margin: 0;
    color: var(--muted);
    font-size: 14px;
}

.fs-list {
    list-style: none;
    margin: 18px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
}

.fs-item {
    display: grid;
    /* The date column is sized to its content rather than fixed - "Wed 3
       Sep" and "Tue 22 Sep" are different widths and a fixed column
       either clips one or leaves a gap after the other. */
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 20px;
    align-items: center;
    padding: 12px 16px;
    background: rgba(255,255,255,.025);
    border: 1px solid rgba(255,255,255,.06);
    border-radius: var(--radius);
}

.fs-when {
    display: grid;
    gap: 1px;
    /* Stops "Wed 16 Sep" wrapping to two lines in the narrow column. */
    white-space: nowrap;
}

.fs-date {
    font-weight: 700;
    font-size: 14px;
    color: #fff;
    font-variant-numeric: tabular-nums;
}

.fs-time {
    font-size: 12.5px;
    color: var(--gold);
    font-weight: 600;
}

/* min-width:0 so a long venue name shrinks and ellipsises instead of
   pushing the Book button off the row. A grid item will not go below its
   min-content width without it. */
.fs-detail {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.fs-title {
    font-size: 15px;
    font-weight: 600;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fs-where {
    font-size: 13px;
    color: var(--muted2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fs-book {
    padding: 8px 18px;
    border-radius: 999px;
    background: var(--gold);
    color: #111;
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: filter .2s ease;
}

.fs-book:hover,
.fs-book:focus-visible { filter: brightness(1.12); }

/* Where there is no ticket URL. The row would otherwise end in empty
   space and read as though the Book link had failed to load. */
.fs-free {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--gold);
    white-space: nowrap;
}

.fs-all {
    margin: 16px 0 0;
    font-size: 14px;
}

.fs-all a {
    color: var(--gold);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1px solid transparent;
}

.fs-all a:hover,
.fs-all a:focus-visible { border-bottom-color: currentColor; }

@media (max-width: 980px) {
    .film-screenings { margin: 0 20px 44px; padding: 22px 20px; }
}

@media (max-width: 640px) {
    /* The date moves above the title and the button spans the row, so
       the tap target is the whole width rather than a corner of it. */
    .fs-item {
        grid-template-columns: 1fr;
        gap: 8px;
        align-items: start;
    }
    .fs-when {
        display: flex;
        gap: 8px;
        align-items: baseline;
    }
    .fs-book { text-align: center; }
}
