/**
 * Discover — the stream-deck skin.
 *
 * Ported from stitch_minimalist_web_page_design (3), "Apex Neon // Stream
 * Deck - Discover Core".
 *
 * Fourth screen in this language. Same constraint as the other three: the
 * mock is a Tailwind CDN build with its own config, this app's tuka.css is a
 * compiled artifact with no build step, and a class that is not already in it
 * renders as nothing at all -- silently. So the design is real CSS.
 *
 * Sibling to battle.css (.bt), comms.css (.cx) and party.css (.pt). Four
 * files now share a chamfer, a glow and an equaliser. That is two more than
 * is comfortable and the duplication should be pulled into one place before
 * a fifth screen arrives; it is still apart here because merging means
 * touching three screens that already work.
 *
 * Scoped under `.rl`.
 */

/* ------------------------------------------------------------- tokens */

.rl {
    --rl-bg: #08090d;
    --rl-surface: #0f1016;
    --rl-low: #13141b;
    --rl-card: #181922;
    --rl-high: #22232f;

    --rl-pink: #ff007f;
    --rl-cyan: #00f0ff;
    --rl-violet: #8512e0;
    --rl-gold: #ffcc00;

    --rl-accent: var(--rl-pink);

    /*
     * How much vertical room the header and the bottom dock take.
     *
     * A feed of full-bleed video has to know exactly how tall one card is,
     * or the scroll-snap lands mid-card. The mock puts a fixed header above
     * the stage, so the old `100vh - 72px` is no longer the answer. The
     * measured value is written here from script on load and on resize; this
     * is the fallback for the first paint and for the case where script
     * never runs.
     */
    --rl-chrome: 192px;
}

/* ------------------------------------------------------------ surface */

.rl-grid {
    background-size: 28px 28px;
    background-image:
        linear-gradient(to right, rgba(255, 0, 127, .035) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(0, 240, 255, .025) 1px, transparent 1px);
}

/*
 * Scanlines, at a third of the mock's weight.
 *
 * Same call as on Messages and Party: the mock runs a 35%-black stripe every
 * 4px at opacity .25. Over a photograph that is a texture; over somebody's
 * face in a video it is a defect. Off entirely for anyone who has asked for
 * more contrast.
 */
.rl-scan {
    background: linear-gradient(rgba(18, 16, 26, 0) 50%, rgba(0, 0, 0, .35) 50%);
    background-size: 100% 4px;
    opacity: .09;
}

@media (prefers-contrast: more) {
    .rl-scan { display: none; }
}

/* -------------------------------------------------------------- shape */

.rl-chamfer {
    clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 7px,
                       100% 100%, 7px 100%, 0 calc(100% - 7px));
}

.rl-chamfer-md {
    clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px,
                       100% 100%, 12px 100%, 0 calc(100% - 12px));
}

.rl-slant { clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%); }

/* ------------------------------------------------------------- glass */

.rl-glass {
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    background-image: linear-gradient(135deg, rgba(19, 20, 29, .85) 0%, rgba(10, 11, 16, .94) 100%);
    border: 1px solid rgba(255, 255, 255, .09);
}

/* The mock's tactile control pill, used for every button on the rail. */
.rl-pill {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 9999px;
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    background-image: linear-gradient(145deg, rgba(26, 28, 40, .9) 0%, rgba(13, 14, 21, .95) 100%);
    border: 1px solid color-mix(in srgb, var(--rl-accent) 40%, transparent);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .65),
                0 0 16px color-mix(in srgb, var(--rl-accent) 40%, transparent);
    color: var(--rl-accent);
    transition: transform .12s ease;
}

.rl-pill:active { transform: scale(.9); }

.rl-pill--pink  { --rl-accent: var(--rl-pink); }
.rl-pill--cyan  { --rl-accent: var(--rl-cyan); }
.rl-pill--gold  { --rl-accent: var(--rl-gold); }
.rl-pill--plain {
    --rl-accent: #ffffff;
    border-color: rgba(255, 255, 255, .2);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .65);
    color: #e2e8f0;
}
.rl-pill--danger { --rl-accent: #ff5449; }

/* --------------------------------------------------------- typography */

.rl-mono {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: .04em;
}

.rl-display {
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 800;
    font-style: italic;
    letter-spacing: -.02em;
    text-transform: uppercase;
}

/* ------------------------------------------------- the stage chassis */

/*
 * The bracketed viewport.
 *
 * In the mock this frames a reconstruction of the video's own content -- the
 * Urdu meme, rebuilt as HTML. That cannot be carried over: the words are
 * pixels inside somebody's video, not data this app holds. So the frame does
 * the job it looks like it is doing and frames the video itself, with the
 * spec strip above it and the audio strip below.
 *
 * Pointer-events are off throughout: tapping the video toggles sound, and a
 * decorative border must not swallow that.
 */
.rl-frame {
    position: absolute;
    pointer-events: none;
    border-top: 1px solid rgba(0, 240, 255, .4);
    border-bottom: 1px solid rgba(255, 0, 127, .4);
    border-left: 2px solid var(--rl-cyan);
    border-right: 2px solid var(--rl-pink);
    box-shadow: 0 0 35px rgba(0, 240, 255, .2), 0 0 50px rgba(255, 0, 127, .18);
    border-radius: 2px;
}

/* The four sci-fi corner brackets. */
.rl-frame::before,
.rl-frame::after {
    content: '';
    position: absolute;
    width: .75rem;
    height: .75rem;
}

.rl-frame::before {
    top: -6px; left: -6px;
    border-top: 2px solid var(--rl-cyan);
    border-left: 2px solid var(--rl-cyan);
}

.rl-frame::after {
    bottom: -6px; right: -6px;
    border-bottom: 2px solid var(--rl-pink);
    border-right: 2px solid var(--rl-pink);
}

.rl-frame__tr,
.rl-frame__bl {
    position: absolute;
    width: .75rem;
    height: .75rem;
}

.rl-frame__tr {
    top: -6px; right: -6px;
    border-top: 2px solid var(--rl-cyan);
    border-right: 2px solid var(--rl-cyan);
}

.rl-frame__bl {
    bottom: -6px; left: -6px;
    border-bottom: 2px solid var(--rl-pink);
    border-left: 2px solid var(--rl-pink);
}

/* The spec strips that ride the frame's top and bottom edges. */
.rl-spec {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .25rem .5rem;
    font-size: 8.5px;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: .08em;
    background: rgba(6, 7, 10, .72);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.rl-spec--top    { top: 0;    border-bottom: 1px solid rgba(255, 255, 255, .1); }
.rl-spec--bottom { bottom: 0; border-top: 1px solid rgba(255, 255, 255, .1); }

/* ---------------------------------------------------- stage layout */

/*
 * Every overlay on a card is placed here rather than with utility classes.
 *
 * The positions the mock needs are arbitrary values -- top-[52px],
 * bottom-[188px] -- and arbitrary values are exactly what the compiled sheet
 * does not have. Declaring them once, by name, also means the four blocks
 * that have to clear each other are defined next to each other instead of
 * scattered across the markup as numbers nobody can check.
 */
.rl-badges  { position: absolute; top: .75rem; left: .75rem; right: .75rem; z-index: 30; }
.rl-frame   { top: 3.25rem; left: .75rem; right: .75rem; bottom: 11.75rem; z-index: 20; }
/*
 * The rail sits inside the frame, clear of its lower spec strip.
 *
 * 11.75rem puts the frame's bottom edge there and the strip occupies the
 * ~20px above it, so the rail's last control stops at 13.5rem. At 8.5rem the
 * share button and its count landed on top of "REEL #371" and the caption
 * underneath it.
 */
.rl-rail    { position: absolute; right: .75rem; bottom: 13.5rem; z-index: 30; }
.rl-intel   { position: absolute; left: 1rem; right: 5.5rem; bottom: 3.25rem; z-index: 30; }
.rl-scrubwrap { position: absolute; left: 1rem; right: 1rem; bottom: 1rem; z-index: 30; }

/* ------------------------------------------------------- equaliser */

@keyframes rl-eq {
    0%, 100% { height: 4px; }
    50%      { height: 16px; }
}

.rl-eq { display: inline-flex; align-items: flex-end; gap: 2px; height: 16px; }
.rl-eq > i {
    display: block;
    width: 2px;
    height: 4px;
    border-radius: 1px;
    background: currentColor;
    animation: rl-eq .9s ease-in-out infinite;
}
.rl-eq > i:nth-child(1) { animation-duration: .8s; }
.rl-eq > i:nth-child(2) { animation-duration: 1.1s; animation-delay: .2s; }
.rl-eq > i:nth-child(3) { animation-duration: .6s;  animation-delay: .4s; }
.rl-eq > i:nth-child(4) { animation-duration: 1.3s; animation-delay: .1s; }
.rl-eq > i:nth-child(5) { animation-duration: .9s;  animation-delay: .3s; }

/*
 * The bars stand still when the sound is off.
 *
 * A dancing equaliser over a muted video is the same lie as a pulsing mic
 * ring on a silent seat: it is the one thing on the strip whose whole job is
 * to say whether anything is playing.
 */
.rl-eq--off > i { animation: none; height: 3px; opacity: .45; }

/* --------------------------------------------------------- the disc */

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

.rl-disc {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 9999px;
    background: rgba(0, 0, 0, .85);
    border: 2px solid var(--rl-cyan);
    box-shadow: 0 0 14px rgba(0, 240, 255, .6);
    animation: rl-spin 9s linear infinite;
}

/* Stopped, when the sound is. */
.rl-disc--off {
    animation: none;
    border-color: rgba(255, 255, 255, .25);
    box-shadow: none;
}

.rl-disc__core {
    width: 1rem;
    height: 1rem;
    border-radius: 9999px;
    background-image: linear-gradient(to top right, var(--rl-pink), var(--rl-violet), var(--rl-cyan));
    display: flex;
    align-items: center;
    justify-content: center;
}

.rl-disc--off .rl-disc__core { background-image: none; background: #3a3b45; }

.rl-disc__pin {
    width: .375rem;
    height: .375rem;
    border-radius: 9999px;
    background: #000;
}

/* --------------------------------------------------------- ticker */

@keyframes rl-ticker {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}

.rl-ticker {
    overflow: hidden;
    white-space: nowrap;
    mask-image: linear-gradient(90deg, transparent 0%, black 10%, black 90%, transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 10%, black 90%, transparent 100%);
}

.rl-ticker__track {
    display: inline-block;
    animation: rl-ticker 18s linear infinite;
}

/* ------------------------------------------------------- scrubber */

.rl-scrub {
    position: relative;
    width: 100%;
    height: 4px;
    border-radius: 9999px;
    background: rgba(255, 255, 255, .15);
}

.rl-scrub__fill {
    height: 100%;
    border-radius: 9999px;
    background-image: linear-gradient(to right, var(--rl-cyan), var(--rl-violet), var(--rl-pink));
    box-shadow: 0 0 8px var(--rl-pink);
    width: 0;
}

.rl-scrub__head {
    position: absolute;
    top: -2px;
    left: 0;
    width: .5rem;
    height: .5rem;
    margin-left: -.25rem;
    border-radius: 9999px;
    background: #7df4ff;
    border: 1px solid #fff;
    box-shadow: 0 0 8px var(--rl-cyan);
}

/* ---------------------------------------------------------- caption */

/*
 * Hashtags and mentions, picked out of the creator's own caption.
 *
 * The mock colours them by hand because its caption is written into the
 * markup. Here the caption is whatever the creator typed, so the colouring
 * is done over the real text -- which is the only version of this that keeps
 * working on the next video.
 */
.rl-tag     { color: #7df4ff; font-weight: 600; }
.rl-mention { color: var(--rl-cyan); font-weight: 700; }

/* ------------------------------------------------------------ slate */

/* The mock's text ladder, which tuka.css has none of. Scoped, so these
   names still mean nothing anywhere else in the app. */
.rl .text-slate-100 { color: #f1f5f9; }
.rl .text-slate-200 { color: #e2e8f0; }
.rl .text-slate-300 { color: #cbd5e1; }
.rl .text-slate-400 { color: #94a3b8; }
.rl .text-slate-500 { color: #64748b; }
.rl .text-slate-600 { color: #475569; }

/* Used on every horizontal strip in this app and absent from the compiled
   sheet, so those strips all show a scrollbar. Scoped here as on Party. */
.rl .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.rl .no-scrollbar::-webkit-scrollbar { display: none; }

/* ------------------------------------------------------- borrowed utils */

/*
 * Utilities this screen uses that the compiled sheet does not define. Each
 * one of these renders as nothing at all and reports nothing, which is how
 * they survived unnoticed -- `underline-offset-2` on the creator's name and
 * `p-margin` on the gift sheet were both already here and both already dead.
 *
 * Scoped to `.rl`, so the names still mean nothing anywhere else.
 */
.rl .underline          { text-decoration-line: underline; }
.rl .underline-offset-2 { text-underline-offset: 2px; }
.rl .pb-2\.5           { padding-bottom: .625rem; }
.rl .px-5               { padding-left: 1.25rem; padding-right: 1.25rem; }
.rl .p-margin           { padding: 1rem; }
.rl .bg-outline\/40     { background-color: rgba(172, 135, 143, .4); }
.rl .border-outline\/50 { border-color: rgba(172, 135, 143, .5); }
.rl .transition-\[width\] {
    transition-property: width;
    transition-duration: .2s;
    transition-timing-function: cubic-bezier(.4, 0, .2, 1);
}

@media (prefers-reduced-motion: reduce) {
    .rl-eq > i,
    .rl-disc,
    .rl-ticker__track { animation: none; }
    .rl-eq > i { height: 10px; }
    .rl-ticker__track { transform: none; }
}
