/* ==========================================================================
   Fish&Monkeys Productions — Design tokens
   ========================================================================== */
:root {
    --ink: #0b0d10;
    --panel: #14181d;
    --line: rgba(255,255,255,0.14);
    --paper: #f3f1ea;
    --paper-line: rgba(0,0,0,0.14);
    --text-on-dark: #f3f1ea;
    --text-on-dark-muted: rgba(255,255,255,0.58);
    --text-on-paper: #14181d;
    --text-on-paper-muted: rgba(0,0,0,0.6);
    --blue: #00adee;
    --tally-red: #e8291c; /* live broadcast tally red — used only for the PGM/on-air indicator */

    --font-display: "Barlow Condensed", sans-serif;
    --font-body: "Inter", sans-serif;
    --font-mono: "IBM Plex Mono", monospace;

    --section-pad: clamp(48px, 8vw, 96px);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    padding: 0;
    background: var(--ink);
    color: var(--text-on-dark);
    font-family: var(--font-body);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
    font-family: var(--font-display);
    text-transform: uppercase;
    font-weight: 800;
    letter-spacing: 0.01em;
    line-height: 1.02;
    margin: 0 0 0.4em;
}

h1 { font-size: clamp(2.6rem, 6vw, 5rem); }
h2 { font-size: clamp(2rem, 4.2vw, 3.2rem); }
h3 { font-size: clamp(1.2rem, 2vw, 1.5rem); font-weight: 700; margin-bottom: 0.3em; }

p { margin: 0 0 1em; }

a { color: inherit; }

.skip-link {
    position: absolute;
    left: -999px;
    top: 0;
    background: var(--blue);
    color: #000;
    padding: 10px 16px;
    z-index: 100;
    font-weight: 600;
}
.skip-link:focus {
    left: 10px;
    top: 10px;
}

:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 3px;
}

.eyebrow {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    color: var(--blue);
    margin: 0 0 0.9em;
}

/* Anchor-scroll offset — without this, clicking a nav link scrolls the
   target section's true top edge flush with the viewport top, which is
   then hidden behind the sticky header (cutting off the eyebrow). --header-h
   is kept in sync with the header's real height by script.js (it changes
   at the site's existing logo-size breakpoints), plus a little breathing
   room on top. This only affects where anchor-scrolling stops — it adds
   no visual padding/space to the section itself. */
section[id] {
    scroll-margin-top: calc(var(--header-h, 145px) + 20px);
}

/* ==========================================================================
   Header
   ========================================================================== */
.site-header {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 6px clamp(20px, 4vw, 48px);
    background: rgba(0, 0, 0, 0.92);
    backdrop-filter: blur(6px);
    border-bottom: 1px solid var(--line);
}

.wordmark a,
.site-footer > a {
    display: inline-block;
    text-decoration: none;
}

/* Logo — sized up significantly per feedback. Height-based scaling keeps the
   wordmark's aspect ratio intact; adjust --logo-h if you want it larger or
   smaller still. Header padding above is intentionally tight so a tall logo
   doesn't force an oversized header bar. */
.wordmark {
    --logo-h: 132px;
    flex-shrink: 0;
}
.wordmark img {
    height: var(--logo-h);
    width: auto;
    display: block;
}
@media (max-width: 900px) {
    .wordmark { --logo-h: 96px; }
}
@media (max-width: 480px) {
    .wordmark { --logo-h: 72px; }
}
@media (max-width: 400px) {
    /* At 72px tall this logo renders roughly 300px+ wide (it's a wide
       horizontal wordmark), which on a ~375px-wide phone left almost no
       room before the hamburger button — this is what was causing them
       to visually collide. Shrinking further here fixes it. */
    .wordmark { --logo-h: 50px; }
}

nav ul {
    list-style: none;
    display: flex;
    gap: clamp(20px, 3.4vw, 42px);
    margin: 0;
    padding: 0;
}

nav ul li a {
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: clamp(1rem, 1.3vw, 1.3rem);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-on-dark);
    position: relative;
    padding-bottom: 4px;
}

nav ul li a::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 0;
    background: var(--blue);
    transition: width 0.25s ease;
}

nav ul li a:hover::after,
nav ul li a:focus-visible::after {
    width: 100%;
}

.hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    z-index: 40;
    position: relative;
}
.hamburger span {
    display: block;
    height: 2px;
    width: 100%;
    background: var(--text-on-dark);
    transition: transform 0.2s ease, opacity 0.2s ease;
}
.hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media screen and (max-width: 1199px) {
    .hamburger { display: flex; }

    nav#nav-menu {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100vh;
        background: var(--ink);
        display: none;
        z-index: 25;
        padding-top: 90px;
    }
    nav#nav-menu.show { display: block; }

    nav#nav-menu ul {
        flex-direction: column;
        align-items: center;
        padding: 20px 0;
        gap: 28px;
    }
    nav#nav-menu ul li a { font-size: 1.5rem; }

    body.menu-open { overflow: hidden; }
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
    padding: clamp(40px, 6vw, 80px) clamp(20px, 4vw, 48px) 20px;
    background:
        repeating-linear-gradient(180deg, rgba(255,255,255,0.02) 0px, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 3px),
        radial-gradient(1200px 600px at 80% -10%, rgba(0,173,238,0.10), transparent 60%),
        var(--ink);
}

.hero-inner {
    max-width: 1240px;
    margin: 0 auto;
}

.hero-headline {
    text-align: center;
    max-width: 900px;
    margin: 0 auto clamp(32px, 5vw, 56px);
}

.hero-grid {
    display: grid;
    grid-template-columns: 2fr 5fr; /* multiviewer now the clear focal point of the row */
    gap: clamp(32px, 5vw, 64px);
    align-items: center;
}

@media (max-width: 1199px) {
    /* Everything below reacts together at the same breakpoint the hamburger
       nav uses, so there's no awkward in-between zone where the nav has
       already collapsed to a hamburger but the hero is still trying to
       force a cramped two-column layout into a narrowing viewport — that
       mismatch was the main reason the multiviewer looked too small. */

    .hero-grid { grid-template-columns: 1fr; }

    /* text-align only centers wrapped text lines within a box — it doesn't
       center the box itself. .hero-lede has its own max-width narrower than
       the column, so without margin:auto it was still sitting flush-left
       (its text balanced, but the paragraph's own position wasn't centered
       — this was the "aligned the body of text but not the section" gap). */
    .hero-copy {
        text-align: center;
    }
    .hero-lede {
        margin-left: auto;
        margin-right: auto;
    }

    /* .ident is a flex row, and text-align has no effect on flex children —
       only justify-content does. This is why it stayed left-aligned even
       though the surrounding text centered correctly. */
    .ident {
        justify-content: center;
    }

    .hero-actions {
        justify-content: center;
    }

    /* Hero buttons: ~12% smaller than the original desktop size net (the
       first pass went 20% smaller; this brings them back up 10% from that,
       per feedback that they'd gone too small). */
    .hero-actions .btn {
        font-size: 0.75rem;
        padding: 12px 23px;
    }
}

.hero-lede {
    max-width: 46ch;
    color: var(--text-on-dark-muted);
    font-size: 1.05rem;
}

.ident {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    color: var(--text-on-dark);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 1.6em 0;
}
.ident-dot { color: var(--blue); font-size: 0.5rem; }

.hero-actions {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 1.6em;
}

.btn {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 14px 26px;
    border-radius: 2px;
    display: inline-block;
    transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn-primary {
    background: var(--blue);
    color: #000;
    font-weight: 600;
}
.btn-primary:hover { transform: translateY(-2px); background: #33bef2; }

.btn-ghost {
    border: 1px solid var(--line);
    color: var(--text-on-dark);
}
.btn-ghost:hover { border-color: var(--blue); color: var(--blue); }

/* ==========================================================================
   Multiviewer / monitor stack — now media-capable (image or video per tile)
   ========================================================================== */
.multiviewer {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: auto;
    gap: 6px;
    background: #000;
    padding: 6px;
    border-radius: 4px;
    border: 1px solid var(--line);
}

/* Placed directly after the base rule above (not inside the earlier hero
   media query block) so it reliably overrides it — a same-specificity rule
   declared earlier in the file loses to one declared later regardless of
   whether its own media condition currently matches, which is exactly what
   broke this the first time: the override existed, but the unconditional
   base rule after it in the file was always winning. All 6 tiles stay —
   this only changes 3 columns to 2, giving 3 rows of 2 instead of hiding
   anything. */
@media (max-width: 1199px) {
    .multiviewer {
        grid-template-columns: repeat(2, 1fr);
    }
}

.mv-tile {
    position: relative;
    background: #141414;
    border: 1px solid #262626;
    overflow: hidden;
    aspect-ratio: 16 / 9;
}

.mv-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.mv-tag {
    position: absolute;
    left: 0;
    bottom: 0;
    z-index: 2;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.05em;
    color: #fff;
    padding: 5px 7px;
    background: linear-gradient(0deg, rgba(0,0,0,0.65), transparent);
}

/* PGM = programme output / on-air. This is the one exception to the black+blue
   brand palette: broadcast tally lights are conventionally red, so the PGM
   outline and REC indicator use --tally-red rather than the brand blue.

   The .mv-pgm class itself is added/removed by script.js (initMultiviewerTally),
   which cycles it between tiles every few seconds to simulate a vision mixer
   switching sources — it's never hardcoded onto a specific tile in the HTML. */
.mv-pgm {
    border-color: var(--tally-red);
    box-shadow: 0 0 0 1px var(--tally-red), 0 0 18px rgba(232,41,28,0.55);
    animation: tally-pulse 1.8s ease-in-out infinite;
}

.mv-rec {
    position: absolute;
    top: 6px;
    right: 7px;
    z-index: 2;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    color: var(--tally-red);
    letter-spacing: 0.05em;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
    opacity: 0;
    transition: opacity 0.2s ease;
}

/* Only the tile currently selected as PGM shows its REC label */
.mv-pgm .mv-rec {
    opacity: 1;
}

@keyframes tally-pulse {
    0%, 100% { box-shadow: 0 0 0 1px var(--tally-red), 0 0 18px rgba(232,41,28,0.55); }
    50% { box-shadow: 0 0 0 1px var(--tally-red), 0 0 5px rgba(232,41,28,0.22); }
}

.timecode {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.1em;
    color: var(--text-on-dark-muted);
    text-align: center;
    max-width: 1240px;
    margin: 28px auto 0;
    padding-top: 18px;
    border-top: 1px solid var(--line);
}

/* ==========================================================================
   Shared section layout
   ========================================================================== */
.section {
    padding: var(--section-pad) clamp(20px, 4vw, 48px);
}

.section-inner {
    max-width: 780px;
    margin: 0 auto;
    text-align: center;
}

.section-inner-narrow { max-width: 560px; }

.section-dark {
    background: var(--panel);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}

.section-paper {
    background: var(--paper);
    color: var(--text-on-paper);
}

.section-paper h2 { color: var(--text-on-paper); }
.section-paper .eyebrow { color: var(--blue); }

.lede {
    color: var(--text-on-dark-muted);
    max-width: 60ch;
    margin-left: auto;
    margin-right: auto;
}

.lede-dark {
    color: var(--text-on-paper-muted);
    max-width: 68ch;
    margin-left: auto;
    margin-right: auto;
}

/* Credential ticker */
.ticker {
    margin-top: clamp(32px, 5vw, 56px);
    border-top: 1px solid var(--paper-line);
    border-bottom: 1px solid var(--paper-line);
    overflow: hidden;
    padding: 16px 0;
}

.ticker-track {
    display: flex;
    align-items: center;
    gap: 48px;
    white-space: nowrap;
    width: max-content;
    will-change: transform;
    /* Position is driven entirely by script.js (initTicker), which measures
       the rendered item width and clones enough copies to always fill the
       screen before looping. Do not add a CSS animation/keyframe here —
       that's what caused a previous version to run out of content and
       snap back after a couple of loops. */
}

/* Fixed tile size regardless of the source image's own dimensions — this
   keeps the marquee's width measurable the instant the tiles are inserted,
   without waiting for each logo to finish loading, and keeps every logo a
   consistent size even though real logos will vary a lot in proportions. */
.ticker-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 150px;
    height: 60px;
    flex-shrink: 0;
}
.ticker-logo img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}

/* ==========================================================================
   Pull-quote — standalone magazine-style statement between About and Services
   ========================================================================== */
.pull-quote {
    background: var(--ink);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    padding: clamp(64px, 11vw, 150px) clamp(20px, 4vw, 48px);
    text-align: center;
}

.pull-quote-inner {
    max-width: 1000px;
    margin: 0 auto;
}

.pull-quote-line {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(2.1rem, 5.4vw, 4.1rem);
    line-height: 1.08;
    letter-spacing: 0.002em;
    margin: 0;
    color: var(--text-on-dark);
}

.pull-quote-line + .pull-quote-line {
    margin-top: 0.2em;
}

.pull-quote-highlight {
    color: var(--blue);
}

/* ==========================================================================
   Services / channel grid
   ========================================================================== */
/* Fixed column counts (not auto-fit) so the 6 service cards always sit in
   even rows — 3+3 on desktop, 2+2+2 on tablet, single column on mobile —
   never an orphaned 4+2 split. */
.channel-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    max-width: 1160px;
    margin: clamp(32px, 5vw, 56px) auto 0;
}
@media (max-width: 900px) {
    .channel-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
    .channel-grid { grid-template-columns: 1fr; }
}

.channel-card {
    background: var(--ink);
    border: 1px solid var(--line);
    border-radius: 3px;
    overflow: hidden;
    text-align: left;
    position: relative;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

/* Image slot — background-image (set inline per card in the HTML) rather
   than an <img> tag, so a not-yet-added file just falls back to this
   textured panel instead of showing a broken-image icon. Once a real file
   exists at the path referenced in the HTML, it displays automatically. */
.channel-media {
    aspect-ratio: 16 / 9;
    background-color: var(--panel);
    background-size: cover;
    background-position: center;
    border-bottom: 1px solid var(--line);
}

.channel-body {
    padding: 26px 24px;
}

.channel-body p:last-of-type { margin-bottom: 0; }

.channel-body p:not(.channel-tag):not(.channel-to-air) {
    color: var(--text-on-dark-muted);
    font-size: 0.95rem;
}

.channel-tag {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    color: var(--blue);
    margin-bottom: 0.8em;
}

.channel-to-air {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    color: var(--blue);
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 0.2s ease, transform 0.2s ease;
    margin-top: 14px !important;
}

.channel-card:hover,
.channel-card:focus-within {
    border-color: var(--blue);
    box-shadow: 0 0 0 1px var(--blue), 0 0 24px rgba(0,173,238,0.18);
    transform: translateY(-3px);
}

.channel-card:hover .channel-to-air,
.channel-card:focus-within .channel-to-air {
    opacity: 1;
    transform: translateY(0);
}

/* ==========================================================================
   Showreel — same image/video-capable tile pattern as the multiviewer
   ========================================================================== */
/* 2x2 by default now (was 4-across) — bigger tiles, per feedback that they
   were too small to see properly. Below ~700px this switches to a
   one-at-a-time carousel instead (see .is-carousel rules further down and
   initShowreelCarousel in script.js) rather than squeezing to a single
   narrow column. */
.reel-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    max-width: 1160px;
    margin: clamp(32px, 5vw, 56px) auto 0;
}

.reel-tile {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: 3px;
    overflow: hidden;
    border: 1px solid var(--paper-line);
    cursor: pointer;
}

.reel-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* The grid-tile rule above (object-fit: cover, 100%/100%) is exactly what
   was stretching/cropping the video once it became the browser's fullscreen
   element — that CSS still applies while fullscreen, it doesn't get reset
   automatically. This overrides it back to "contain" only in that state, so
   the video letterboxes to its real aspect ratio (black bars top/bottom or
   side/side as needed) instead of filling the screen regardless of shape.
   Doesn't apply to iOS's own native video-fullscreen mode (webkitEnterFullscreen)
   — that's Apple's own player UI, not CSS-controlled, and already handles
   aspect ratio correctly on its own. */
.reel-media:fullscreen,
.reel-media:-webkit-full-screen,
.reel-media:-ms-fullscreen {
    object-fit: contain;
    width: 100%;
    height: 100%;
    background: #000;
}

.reel-tag {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
    margin: 0;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    color: var(--text-on-dark-muted);
    background: rgba(0,0,0,0.7);
    padding: 3px 7px;
    border-radius: 2px;
}

.reel-item {
    display: flex;
    flex-direction: column;
}

.reel-caption {
    padding-top: 12px;
}

.reel-title {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text-on-paper);
    margin: 0 0 4px;
    text-transform: none;
    letter-spacing: normal;
}

.reel-meta {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-on-paper-muted);
    margin: 0 0 8px;
}

.reel-link {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.03em;
    color: var(--blue);
    text-decoration: none;
    margin: 0 0 6px;
}
.reel-link:hover,
.reel-link:focus-visible {
    text-decoration: underline;
}

/* Non-clickable variant — for footage that's available to rights holders
   only rather than publicly linkable. Same rhythm as .reel-link, but no
   link colour/underline since there's nothing to click. */
.reel-link-note {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.03em;
    font-style: italic;
    color: var(--text-on-paper-muted);
    margin: 0 0 6px;
}

.reel-copyright {
    font-size: 0.72rem;
    color: var(--text-on-paper-muted);
    margin: 0;
}

.reel-tile:hover,
.reel-tile:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

/* Play button overlay — a visible affordance on the still frame so it's
   obvious the tile is clickable, not just decorative. Purely visual
   (pointer-events: none) — clicks pass through to the tile's own click
   handler in script.js, which is what actually starts playback, so there's
   no separate button logic to keep in sync with it. Hidden once playing or
   once a clip has ended (the Restart overlay takes over that state instead). */
.reel-play-overlay {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: rgba(0,0,0,0.55);
    border: 1px solid rgba(255,255,255,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.reel-play-overlay::after {
    content: '';
    display: block;
    margin-left: 4px; /* optical centering — a triangle's visual centre sits left of its bounding box centre */
    border-style: solid;
    border-width: 10px 0 10px 16px;
    border-color: transparent transparent transparent #fff;
}

.reel-tile.is-playing .reel-play-overlay,
.reel-tile.is-ended .reel-play-overlay {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.85);
}

@media (max-width: 700px) {
    .reel-play-overlay {
        width: 44px;
        height: 44px;
    }
    .reel-play-overlay::after {
        border-width: 8px 0 8px 13px;
    }
}

.reel-mute-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 3;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    color: #fff;
    background: rgba(0,0,0,0.7);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: 4px 8px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease, border-color 0.2s ease;
}
.reel-mute-btn:hover,
.reel-mute-btn:focus-visible {
    border-color: var(--blue);
}

.reel-fullscreen-btn {
    position: absolute;
    bottom: 10px;
    right: 10px;
    z-index: 3;
    font-size: 0.85rem;
    line-height: 1;
    color: #fff;
    background: rgba(0,0,0,0.7);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: 4px 7px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease, border-color 0.2s ease;
}
.reel-fullscreen-btn:hover,
.reel-fullscreen-btn:focus-visible {
    border-color: var(--blue);
}

@media (max-width: 700px) {
    .reel-fullscreen-btn {
        font-size: 0.75rem;
        padding: 3px 6px;
    }
}

/* Visible on hover/keyboard-focus, and also while actively playing — the
   latter covers touch devices, which don't have a true hover state but do
   get a play-state class from script.js the moment the tile is tapped. */
.reel-tile:hover .reel-mute-btn,
.reel-tile:focus-within .reel-mute-btn,
.reel-tile.is-playing .reel-mute-btn,
.reel-tile:hover .reel-fullscreen-btn,
.reel-tile:focus-within .reel-fullscreen-btn,
.reel-tile.is-playing .reel-fullscreen-btn {
    opacity: 1;
}

@media (max-width: 700px) {
    /* On touch devices this stays visible for the whole clip (there's no
       hover-out to hide it), so it needs to be small enough not to
       dominate the tile the way the desktop corner-tag size did. */
    .reel-mute-btn {
        font-size: 0.52rem;
        padding: 3px 6px;
    }
}

/* Restart overlay — a finished clip freezes on its last frame rather than
   looping, and this is the only way to bring it back (see script.js: hover
   and click deliberately do nothing once a clip has ended, so it never
   silently restarts on its own). Centred and prominent since it's the sole
   available action at that point, unlike the smaller corner-tag mute button. */
.reel-restart-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 4;
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    color: #fff;
    background: rgba(0,0,0,0.75);
    border: 1px solid var(--blue);
    border-radius: 3px;
    padding: 10px 20px;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, background 0.2s ease;
}
.reel-restart-btn:hover,
.reel-restart-btn:focus-visible {
    background: rgba(0,173,238,0.25);
}

.reel-tile.is-ended .reel-restart-btn {
    opacity: 1;
    pointer-events: auto;
}

@media (max-width: 700px) {
    .reel-restart-btn {
        font-size: 0.68rem;
        padding: 8px 16px;
    }
}

/* ==========================================================================
   Showreel carousel (phones only) — script.js (initShowreelCarousel) adds
   the .is-carousel class below this breakpoint and shows exactly one
   .reel-item at a time by toggling .is-active-slide, rather than sliding a
   flex track with transform. Above this breakpoint .is-carousel is removed
   and the normal 2x2 grid above applies — nothing here does anything on
   tablet/desktop.

   (This replaced an earlier transform-based version that positioned all
   four items side by side and slid between them — on some mobile browsers,
   video elements that are technically laid out but clipped off-screen via
   overflow:hidden don't reliably load/play until they're actually visible,
   which is why only the first clip worked. Showing/hiding via display
   avoids that entirely: an inactive clip isn't rendered at all until it's
   its turn, so there's nothing ambiguous for the browser to defer.) */
@media (max-width: 700px) {
    .reel-grid.is-carousel {
        display: block;
    }
    .reel-grid.is-carousel .reel-item {
        display: none;
    }
    .reel-grid.is-carousel .reel-item.is-active-slide {
        display: flex;
    }
}

.reel-carousel-nav {
    display: none; /* only shown in carousel mode, via the rule below */
    align-items: center;
    justify-content: center;
    gap: 18px;
    margin: 18px auto 0;
}
@media (max-width: 700px) {
    .reel-carousel-nav.is-active {
        display: flex;
    }
}

.reel-carousel-arrow {
    background: none;
    border: 1px solid var(--paper-line);
    color: var(--text-on-paper);
    width: 36px;
    height: 36px;
    border-radius: 50%;
    font-family: var(--font-mono);
    font-size: 1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.2s ease, color 0.2s ease;
}
.reel-carousel-arrow:hover,
.reel-carousel-arrow:focus-visible {
    border-color: var(--blue);
    color: var(--blue);
}

.reel-carousel-dots {
    display: flex;
    align-items: center;
    gap: 8px;
}

.reel-carousel-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    border: none;
    background: var(--paper-line);
    cursor: pointer;
    padding: 0;
}
.reel-carousel-dot.is-active {
    background: var(--blue);
}

/* ==========================================================================
   Contact
   ========================================================================== */
.contact-panel {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 1.6em auto;
    max-width: 420px;
}

.contact-line {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: 0.95rem;
    color: var(--text-on-dark);
    background: var(--ink);
    border: 1px solid var(--line);
    padding: 14px 16px;
    border-radius: 3px;
    transition: border-color 0.2s ease;
}
.contact-line:hover,
.contact-line:focus-visible {
    border-color: var(--blue);
}
.contact-line .channel-tag { margin: 0; min-width: 40px; }

/* Contact form */
.contact-form {
    margin-top: 1.8em;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.form-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.form-row label {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-on-dark-muted);
}

.form-row input,
.form-row textarea {
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--text-on-dark);
    background: var(--ink);
    border: 1px solid var(--line);
    border-radius: 3px;
    padding: 12px 14px;
    resize: vertical;
}

.form-row input:focus,
.form-row textarea:focus {
    outline: none;
    border-color: var(--blue);
}

.contact-form .btn {
    align-self: center;
    border: none;
    cursor: pointer;
    font-family: var(--font-mono);
}

/* Honeypot spam trap — invisible to real visitors, never affects layout */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.form-status {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.03em;
    margin: 0;
    min-height: 1.2em;
    text-align: center;
}
.form-status.is-success { color: var(--blue); }
.form-status.is-error { color: var(--tally-red); }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
    background: var(--ink);
    border-top: 1px solid var(--line);
    text-align: center;
    padding: 28px 20px;
}

.footer-logo {
    display: block;
    height: 56px;
    width: auto;
    margin: 0 auto 18px;
}

.site-footer p {
    margin: 0.2em 0;
    font-size: 0.8rem;
    color: var(--text-on-dark-muted);
}

.footer-tag {
    font-family: var(--font-mono);
    letter-spacing: 0.1em;
    color: var(--blue) !important;
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .mv-pgm {
        animation: none !important;
    }
    html { scroll-behavior: auto; }
}
