@font-face{font-family:'Jost';font-style:normal;font-weight:300;font-display:swap;src:url(/src/fonts/jost-300-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Jost';font-style:normal;font-weight:300;font-display:swap;src:url(/src/fonts/jost-300-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Jost';font-style:normal;font-weight:400;font-display:swap;src:url(/src/fonts/jost-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Jost';font-style:normal;font-weight:400;font-display:swap;src:url(/src/fonts/jost-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Jost';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/jost-500-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Jost';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/jost-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Jost';font-style:normal;font-weight:600;font-display:swap;src:url(/src/fonts/jost-600-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Jost';font-style:normal;font-weight:600;font-display:swap;src:url(/src/fonts/jost-600-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Karla';font-style:normal;font-weight:300;font-display:swap;src:url(/src/fonts/karla-300-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Karla';font-style:normal;font-weight:300;font-display:swap;src:url(/src/fonts/karla-300-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Karla';font-style:normal;font-weight:400;font-display:swap;src:url(/src/fonts/karla-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Karla';font-style:normal;font-weight:400;font-display:swap;src:url(/src/fonts/karla-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Karla';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/karla-500-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Karla';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/karla-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/space-grotesk-500-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url(/src/fonts/space-grotesk-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url(/src/fonts/space-grotesk-700-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url(/src/fonts/space-grotesk-700-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Source Serif 4"; font-style:normal; font-weight:600; font-display:swap;
  src:url("/src/fonts/sourceserif-600-latin-ext.woff2") format("woff2"); unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Source Serif 4"; font-style:normal; font-weight:600; font-display:swap;
  src:url("/src/fonts/sourceserif-600-latin.woff2") format("woff2"); unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Source Serif 4"; font-style:normal; font-weight:700; font-display:swap;
  src:url("/src/fonts/sourceserif-700-latin-ext.woff2") format("woff2"); unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Source Serif 4"; font-style:normal; font-weight:700; font-display:swap;
  src:url("/src/fonts/sourceserif-700-latin.woff2") format("woff2"); unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/**
 * DISCOVERFILMS.US. One page, one wall, four filters and a search box.
 *
 * THE PALETTE AND THE CARD ARE CARRIED OVER WHOLE from the site this grew out
 * of, because the thing being reused is the part that was already right: a
 * near-black ground cut from one cool hue, warm off-white ink, one accent, and
 * a card that is a 16:9 still with a play control centered on it. Every value
 * below is a token, so the wall inverts by editing this block and nothing else.
 *
 * WHY A DARK GROUND HERE AND NOT THERE. The site this came from argued itself
 * onto a light ground because a wall of covers on black reads as a streaming
 * grid. This *is* a streaming grid. It is twelve thousand film stills and
 * nothing else, and the one thing it must do is get out of their way.
 */
:root{
  color-scheme:dark;
  --paper:#0d0f12; --paper-top:#08090b; --raised:#16191e; --sunk:#0a0c0f;
  --stripe:#131619; --footer-glow:#23262a;
  --ink:#e9e6e0; --ink2:#b0aca5; --ink3:#a4a09a;
  --title-ink:#f7f5f1; --rule:#33383f; --hair:#23272d;
  --ctl:#171a1f; --ctl-line:#2e333a; --ctl-ink:#a8a49d;
  --ctl-hover:#1e2228; --ctl-hover-line:#4a5058; --ctl-hover-ink:#f7f5f1;
  --accent:#e9b949; --accent-soft:#241c0d; --accent-line:#6b5424;
  --bar-ground:#050607;
  --measure:110rem;
  --head:"Space Grotesk","Avenir Next",Corbel,system-ui,sans-serif;
  --text:"Karla","Avenir Next",Corbel,system-ui,sans-serif;
  --meta:"Jost","Avenir Next",Corbel,system-ui,sans-serif;
  --display:"Source Serif 4",Georgia,"Times New Roman",serif;
}
*,*::before,*::after{box-sizing:border-box}
html{font-size:17px; scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} }
body{margin:0; background:var(--paper); color:var(--ink);
  font:1.02rem/1.72 var(--text); text-rendering:optimizeLegibility;
  /* NOTHING MAY MAKE THE PAGE WIDER THAN THE SCREEN. clip and not hidden:
     hidden makes the body a scroll container, which silently breaks the
     sticky masthead, and a sticky bar that stops sticking is a worse bug than
     the one being prevented. */
  overflow-x:clip}
.wrap{max-width:var(--measure); margin:0 auto; padding:0 clamp(1.1rem,2.4vw,2.2rem)}

.skip{position:absolute; left:-999px; top:0; z-index:20;
  background:var(--ctl); color:var(--ink); padding:.7rem 1rem; border:1px solid var(--accent)}
.skip:focus{left:.6rem; top:.6rem}

/* THE MASTHEAD. The name on the left, the search box on the right, and the
   filters on their own rows under both. It sticks, because a reader forty
   frames down the wall who wants a different decade should not have to go
   back up to find one. */
header.top{position:sticky; top:0; z-index:10;
  background:var(--bar-ground); border-bottom:1px solid var(--rule)}
.topin{display:flex; align-items:center; gap:.7rem 1.6rem; flex-wrap:wrap;
  padding-top:.75rem; padding-bottom:.55rem}
.brand{display:block; font-family:var(--head); font-weight:700;
  font-size:1.42rem; letter-spacing:-.022em; line-height:1.15;
  color:var(--title-ink); text-decoration:none; white-space:nowrap}
.brand:hover{color:var(--accent)}
.brand .dot{color:var(--accent)}
@media (max-width:44rem){ .brand{font-size:1.16rem} }

/* THE COUNT IS THE ONLY NUMBER ON THE PAGE and it moves as the filters move,
   which is the whole feedback a reader gets that a filter did anything. */
.count{margin:0; order:2; font-family:var(--meta); font-size:.7rem; font-weight:600;
  letter-spacing:.13em; text-transform:uppercase; color:var(--ink3);
  white-space:nowrap}
.count b{color:var(--accent); font-weight:600}

/* THE SEARCH BOX TAKES THE FAR EDGE, where the line about the site used to
   sit on the site this came from. It is the one control here that is not a
   filter row, so it is the one control that does not look like one. */
.find{order:2; margin-left:auto; display:flex; align-items:center; gap:.5rem;
  flex:1 1 16rem; max-width:24rem; min-width:11rem;
  background:var(--ctl); border:1px solid var(--ctl-line); border-radius:2px;
  padding:.36rem .6rem; transition:border-color .12s ease}
.find:focus-within{border-color:var(--accent)}
.find svg{flex:none; color:var(--ink3)}
.find input{flex:1 1 auto; min-width:0; background:none; border:0; outline:0;
  color:var(--ink); font:.82rem/1.4 var(--text)}
.find input::placeholder{color:var(--ink3)}
.find button{flex:none; display:none; background:none; border:0; cursor:pointer;
  color:var(--ink3); font-size:1rem; line-height:1; padding:0 .1rem}
.find button:hover{color:var(--accent)}
.find.on button{display:block}
/* THE SEARCH TAKES THE WHOLE ROW ON A PHONE. It carries margin-left:auto to
   hold the far edge of a wide masthead, and a 24rem cap that is wider than a
   390px screen. Together, on its own wrapped line, those pushed it off the
   right of the display: an input cut in half by the edge of the screen, with
   the page clipped rather than scrolling because the body clips. The auto
   margin and the cap are both for a bar with room in it. */
@media (max-width:44rem){
  .find{margin-left:0; flex:1 1 100%; max-width:none; min-width:0}
}


/* THE ONE PAGE THAT IS NOT THE WALL, which is the miss. It was also the empty
   state of three sections that no longer exist: Music, Comedy and Books came
   down on 16 September 2026, at his word, the day after they went up. This
   site is films. */
.state{max-width:34rem; margin:6rem auto; padding:0 1.4rem; text-align:center}
.state h1{margin:0 0 .6rem; font-family:var(--display); font-weight:700;
  font-size:2rem; letter-spacing:-.02em; color:var(--title-ink)}
.state p{margin:0 0 .8rem; color:var(--ink2); font-size:1rem; line-height:1.6}
.state .statenote{font-family:var(--meta); font-size:.7rem; font-weight:600;
  letter-spacing:.11em; text-transform:uppercase; color:var(--accent);
  line-height:1.7}


/* THE FILTER ROWS, AND EACH ONE IS A LINE THAT SCROLLS SIDEWAYS.
   Eleven decades, eighteen genres and fifty-two studios is eighty-one items.
   Wrapped, that is a five-line block of capitals pushing the first film below
   the fold on every screen; on one line each it costs three rows of about a
   centimetre and the wall starts where it should.
   THE LABEL SITS OUTSIDE THE SCROLLER. With three rows stacked, a row that
   scrolls away from its own name is a row you cannot identify, and the label
   is the one thing on it that must never move. */
.filters{border-top:1px solid var(--hair)}
.frow{display:flex; align-items:center; gap:0 1rem; padding:.3rem 0}
.frow + .frow{border-top:1px solid var(--hair)}
.flabel{flex:none; width:4.6rem; margin:0; font-family:var(--meta); font-weight:600;
  font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}
@media (max-width:44rem){ .flabel{width:3.4rem; font-size:.56rem; letter-spacing:.1em} }

/* THE ROW ITSELF, carried over from the topic bar it is modeled on: hidden
   scrollbar, and a mask that fades whichever edge has more behind it. The
   fade is drawn from the scroll position rather than painted on permanently,
   so at the far right there is no false promise of more. Without the script
   it is the right-hand fade and no left one, which is the state a reader
   lands in: scrolled to the start, with more to the right. */
.views{display:flex; flex-wrap:nowrap; gap:0 1.15rem; margin:0; padding:.22rem 0;
  flex:1 1 auto; min-width:0; max-width:none;
  overflow-x:auto; overscroll-behavior-x:contain;
  scrollbar-width:none; -ms-overflow-style:none;
  --fadel:0px; --fader:2.6rem;
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 var(--fadel),
    #000 calc(100% - var(--fader)), transparent 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 var(--fadel),
    #000 calc(100% - var(--fader)), transparent 100%)}
.views::-webkit-scrollbar{display:none}
.views.scrolled{--fadel:2.6rem}
.views.atend{--fader:0px}
.views > .view{flex:none; white-space:nowrap}

.view{font-family:var(--meta); font-weight:600; font-size:.72rem;
  letter-spacing:.13em; text-transform:uppercase; color:var(--ink3);
  text-decoration:none; white-space:nowrap; padding:.18rem 0 .2rem;
  border:0; border-bottom:1px solid transparent; background:none; cursor:pointer}
/* A DECADE IS 1970s AND NOT 1970S, at his word, 17 September 2026. Every label
   in this bar is set in tracked capitals, and text-transform took the s of a
   decade with it: the row read 2020S 2010S 1990S, which is not how anybody
   writes a decade. The transform comes off this row and the decades are typed
   the way they are read. Its own All is typed in capitals in the markup
   instead, so the word still matches the All on every other row. */
.views[data-kind="decade"] .view{text-transform:none; letter-spacing:.1em}
.view:hover{color:var(--ink)}
.view.here{color:var(--ink); border-bottom-color:var(--accent)}
/* A TIER HEADING INSIDE THE STUDIO ROW. Fifty-two studios in one alphabetical
   run tells a reader nothing about which of them is Warner Bros. and which is
   Zeitgeist. The three words are not controls and do not take a pointer. */
.vgroup{flex:none; align-self:center; font-family:var(--meta); font-weight:600;
  font-size:.58rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--accent); opacity:.75; white-space:nowrap;
  padding-left:.3rem; border-left:1px solid var(--rule)}
.frow:first-child .vgroup{border-left:0; padding-left:0}

/* THE YEAR ROW IS NOT THERE UNTIL A DECADE IS. Ten more items on the page at
   all times, nine of which are wrong for whatever the reader is looking at,
   is the row that makes the other three harder to read. */
.frow.years[hidden]{display:none}

/* THE WALL REACHES EVERY EDGE, 17 September 2026, at his word, on America,
   America's model. It had the page's own gutter down each side and a measure
   capping it at 110rem, which is right for a column of words and wrong for a
   wall of pictures: a grid of stills inside a margin reads as a panel of
   images placed on a page, and the same grid running off all four sides reads
   as the page. The masthead and the foot keep their gutter, because those are
   words.
   THE RULE IS ON main AND NOT ON .wall so the state and the empty message
   inherit it, and each carries its own padding back. */
main{width:100%; max-width:none; margin:0; padding:0}

/* THE WALL. Two across on a phone, and up from there by the width of a card
   rather than by a breakpoint somebody chose: auto-fill with a minimum keeps
   a still from ever being stretched past the size its own detail survives. */
.wall{display:grid; gap:1.9rem 1.2rem; margin:0; padding:0;
  list-style:none; grid-template-columns:repeat(auto-fill,minmax(15rem,1fr))}
@media (max-width:40rem){ .wall{gap:1.4rem .9rem;
  grid-template-columns:repeat(auto-fill,minmax(9.5rem,1fr))} }


/* THE TWO WAYS THE WALL IS DRAWN, and the control is two icons because the
   thing being chosen is a shape. A word would have to be "Grid" and "Tiles",
   which are names for what you get rather than pictures of it, and the picture
   is exactly what differs: boxes with air between them, or a square in
   quarters with none. */
/* FILMS OR TELEVISION. This sits beside the wordmark because it is the only
   control on the page that changes what the whole site is about; everything
   else narrows a library, this one swaps it. It is words rather than icons for
   the same reason: there is no glyph for "television" that a reader would not
   have to be taught, and two short words cost less than a tooltip.
   STATE IS CARRIED BY INK, the way the view toggle beside it does, because the
   masthead already has one bordered box in it and a second would read as an
   input rather than a switch. */
.ktoggle{order:1; display:flex; flex:none; gap:0 .1rem; align-items:center}
.kt{padding:.12rem .42rem; border:0; background:none; cursor:pointer;
  font:600 .74rem/1.4 var(--meta); letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink3); transition:color .12s ease}
.kt:hover{color:var(--ink)}
.kt.on{color:var(--accent)}
.kt:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:2px}
.kt[hidden]{display:none}

.vtoggle{order:2; display:flex; flex:none; gap:0 .55rem}
/* NO BOX, 17 September 2026, at his word. It was a bordered pill with a
   divider down the middle and a filled ground on the chosen half, which is the
   shape every other control on this site uses and the wrong one here: the
   masthead already carries a bordered box, the search, and two of them side by
   side read as two inputs. The icons are the control now and state is carried
   by ink alone, which is what the filter rows beside them do.
   THE FOCUS RING STAYS, and it is the one ring that cannot go. Without a box
   and without a ground, a keyboard has nothing at all to show it is here. It
   is drawn only for a keyboard, which is what focus-visible means. */
.vt{display:flex; align-items:center; justify-content:center;
  width:1.4rem; height:1.4rem; padding:0; border:0; background:none;
  cursor:pointer; color:var(--ink3); transition:color .12s ease}
@media (prefers-reduced-motion:reduce){ .vt{transition:none} }
.vt:hover{color:var(--ink)}
.vt.on{color:var(--accent)}
.vt:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:1px}

/* THE ONE THING IN THE BAR THAT IS NOT A FILTER OF THE WORK BUT A FILTER OF
   THE RECORD. Every other control asks what a reader wants to see; this one
   asks whether to show films this site knows about and cannot play. It is a
   checkbox because it is a yes or no about the whole wall rather than a choice
   among values, and it is checked to begin with because a wall of gray plates
   is the wrong first impression of a site made of pictures. */
.onlyplay{order:2; display:flex; align-items:center; gap:.4rem; flex:none;
  cursor:pointer; font-family:var(--meta); font-weight:600; font-size:.64rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink3);
  white-space:nowrap; user-select:none}
.onlyplay:hover{color:var(--ink)}
.onlyplay input{appearance:none; width:.85rem; height:.85rem; margin:0;
  border:1px solid var(--ctl-line); border-radius:2px; background:var(--ctl);
  cursor:pointer; position:relative; flex:none}
.onlyplay input:checked{background:var(--accent); border-color:var(--accent)}
/* THE TICK IS DRAWN AND NOT SET IN TYPE, so it lands on the same two pixels in
   every browser and does not move with the font. */
.onlyplay input:checked::after{content:""; position:absolute; left:.24rem; top:.06rem;
  width:.22rem; height:.45rem; border:solid var(--sunk);
  border-width:0 2px 2px 0; transform:rotate(42deg)}
.onlyplay input:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.onlyplay:has(input:checked){color:var(--ink)}
@media (max-width:52rem){ .onlyplay span{display:none} }
/* MUST WATCH SITS BESIDE THE TRAILER SWITCH AND KEEPS ITS WORD ON A PHONE,
   where the trailer switch drops its label: a bare box with no word is a
   control nobody can guess. Television has no canon, so it is not offered. */
@media (max-width:52rem){ .mustwatch span{display:inline} }
body.is-tv .mustwatch{display:none}

/* RANDOM, AND IT IS SET LIKE THE SWITCH BESIDE IT rather than like a button,
   because the masthead already carries exactly one boxed control and a second
   one next to it would read as a pair of inputs. Ink alone, the way the filter
   rows work. */
.rnd{order:2; display:block; flex:none;
  padding:0; border:0; background:none; cursor:pointer;
  font-family:var(--meta); font-weight:600; font-size:.64rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink3);
  white-space:nowrap; transition:color .12s ease}
@media (prefers-reduced-motion:reduce){ .rnd{transition:none} }
.rnd:hover{color:var(--accent)}
.rnd:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:1px}
/* THE WORD AND NOTHING ELSE, at his word. It had a shuffle arrow beside it and
   the arrow was doing no work: the label already says what the control does,
   and two crossing lines at fifteen pixels say it less clearly than six
   letters do. It keeps its word at every width for the same reason. */

/* THE HOVER BAR. Last row of the sticky masthead, so the words about a tile
   four thousand rows down still appear somewhere the reader is looking. It
   holds its height empty, because a bar that appears on hover would push the
   entire wall down a line every time the pointer crossed a picture. */
/* A FIXED HEIGHT, AND IT HAS TO BE FIXED RATHER THAN MINIMUM.
   WHAT HE SAW: hovering the first row of tiles, right against the bar, made
   the page shutter. It was a feedback loop and the bar was driving it. Idle it
   holds one line of eleven-pixel capitals and was clamped to its 2.1rem
   minimum; hovering put a one-rem serif title in it, which at the body's line
   height wants 2.47rem, so the bar grew by six pixels and pushed the whole wall
   down. The pointer, which had been on the first tile, was now over the bar
   instead. That un-hovered the tile, the bar went back to idle, the wall came
   back up, the tile was under the pointer again, and it hovered. Sixty times a
   second.
   THE FIX IS THAT NEITHER STATE MAY CHANGE THE HEIGHT. One fixed height,
   centered rather than aligned to a baseline that moves with the font, and
   explicit line heights on both children so a longer title or a different face
   cannot reach past it. min-height was the bug: it promises a floor and says
   nothing about a ceiling, which is exactly the wrong half of the guarantee
   for anything sitting above a wall that must not move. */
.hoverbar{display:flex; align-items:center; gap:0 .9rem;
  /* THE GUTTER COMES BACK AND THE VERTICAL PADDING STAYS AT NOTHING. This is
     a .wrap and inherits the masthead's side padding; the fixed-height rule
     above wrote padding:0 and took the sides with it, so the title sat hard
     against the edge of the screen while every label above it was inset. Only
     the top and bottom had to be zero, and saying so in one shorthand said
     more than it meant. box-sizing is border-box, so the side padding costs
     the height nothing and the bar still cannot change size. */
  height:2.5rem; padding:0 clamp(1.1rem,2.4vw,2.2rem);
  border-top:1px solid var(--hair); overflow:hidden; white-space:nowrap}
.hoverbar[hidden]{display:none}
.hbtitle{margin:0; font-family:var(--display); font-weight:600; font-size:1rem;
  line-height:1.2; color:var(--title-ink); overflow:hidden; text-overflow:ellipsis}
.hbmeta{margin:0; flex:none; font-family:var(--meta); font-weight:600; line-height:1.2;
  font-size:.66rem; letter-spacing:.11em; text-transform:uppercase; color:var(--ink3)}
/* EMPTY IS A PROMPT AND NOT A BLANK, once, before anything has been hovered. */
.hoverbar.idle .hbtitle{font-family:var(--meta); font-weight:600; font-size:.66rem;
  line-height:1.2; letter-spacing:.11em; text-transform:uppercase; color:var(--ink3)}

/* TWO LINES ON A PHONE, at his word: the title, and everything else under it.
   Side by side they were competing for about three hundred points of width,
   and the title - the one thing a reader is trying to read - is the half that
   loses, because the year, the studio and the director are a fixed string that
   does not shrink. Stacked, the title gets the whole width and the facts get
   their own line.
   THE HEIGHT IS FIXED AT TWO LINES AND NOT LET TO GROW, which is the same rule
   the one-line version is held to and for the same reason: this bar sits
   directly above the wall, so anything that changes its height moves the tiles
   out from under a thumb. Idle, the second line is empty and the first simply
   centers in a box that has not moved.
   AND BOTH LINES CLIP RATHER THAN WRAP. A long title on a narrow screen would
   otherwise take a third line and do exactly what the fixed height exists to
   prevent. */
@media (max-width:44rem){
  .hoverbar{flex-direction:column; align-items:flex-start; justify-content:center;
    gap:.08rem 0; height:3.25rem}
  .hbtitle{font-size:.94rem; max-width:100%}
  .hbmeta{font-size:.6rem; max-width:100%; overflow:hidden; text-overflow:ellipsis}
}

/* TILES: THE SAME WALL WITH THE WORDS AND THE GAPS TAKEN OUT. It is one
   surface of moving-picture stills, which is the thing the grid cannot be
   because a grid is a list of films and this is a wall of them. Denser, too:
   nothing under a tile means a tile can be smaller and still be read. */
.wall.tiles{gap:0; grid-template-columns:repeat(auto-fill,minmax(11rem,1fr))}
@media (max-width:40rem){
  .wall.tiles{gap:0; grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr))} }
.wall.tiles li.vid{contain-intrinsic-size:auto 7rem}
.wall.tiles .vtitle, .wall.tiles .vmeta, .wall.tiles .vwho{display:none}
/* NO BORDER, BECAUSE A BORDER BETWEEN TWO TOUCHING STILLS IS A TWO-PIXEL SEAM.
   The stills sit directly against each other and the ground shows through
   nothing. */
.wall.tiles .vshot{border:0}
/* AND THE PLAY CONTROL IS NOT DRAWN AT REST. Nine hundred play buttons on one
   screen is a pattern rather than an affordance; one, under the pointer, is
   the affordance. */
.wall.tiles .vplay{opacity:0; transition:opacity .12s ease, background .12s ease, transform .12s ease}
.wall.tiles li.vid a:hover .vplay, .wall.tiles li.vid a:focus-visible .vplay{opacity:1}
@media (prefers-reduced-motion:reduce){ .wall.tiles .vplay{transition:none} }
/* THE HOVER OUTLINE CAME OFF THE TILES, 17 September 2026, with the cover that
   replaced it. It was there because with no gaps and no borders there was
   nothing to say which tile was live; darkening the other eight hundred says
   it far louder, and a gold rule around one frame on top of that is two
   answers to a question that was asked once.
   THE SCALE IS NOT SUPPRESSED HERE ANY MORE EITHER. The note that took it off
   said a growing picture pushes its touching neighbours, and that was simply
   wrong: .vshot carries overflow:hidden, so the image grows inside a box whose
   size never changes and nothing outside it moves. Checked rather than
   reasoned about the second time.
   FOCUS KEEPS ITS RING, because a keyboard cannot see a brightness difference
   it did not cause by moving a pointer. */
.wall.tiles li.vid a:focus-visible .vshot{outline:2px solid var(--accent); outline-offset:-2px}
/* THE TILE A THUMB HAS TAPPED ONCE. It needs a mark of its own because the
   thing that marks a live tile on a desktop is the rest of the wall going
   dark, and that is driven by :hover, which a touch screen does not have. It
   takes the same gold rule a keyboard gets, for the same reason: something has
   been selected and not yet opened. */
.wall.tiles li.vid.armed .vshot{outline:2px solid var(--accent); outline-offset:-2px}
.wall.tiles li.vid.armed .vplay{opacity:1}
.wall.tiles .vplate{border-left-width:2px}

/* THE CARD IS DRAWN OR IT IS SKIPPED, and the browser decides which.
   content-visibility lets it skip layout and paint for anything off screen,
   and contain-intrinsic-size tells it how much room to leave so the scrollbar
   does not jump while it does. This is what makes a wall of twelve thousand
   scroll like a wall of sixty. */
li.vid{margin:0; position:relative;
  content-visibility:auto; contain-intrinsic-size:auto 15rem}
li.vid a{display:block; text-decoration:none; color:var(--ink); cursor:pointer}
.vshot{position:relative; display:block; aspect-ratio:16/9; overflow:hidden;
  background:var(--sunk); border:1px solid var(--rule)}
/* THE PICTURE MOVES AND NOTHING ELSE ON THE CARD DOES. The scale is clipped by
   the shot's own overflow, so a still that grows never touches the one beside
   it even with no gap between them, and the slow ease-out is America,
   America's: a picture that snaps reads as a rollover and one that drifts
   reads as a thing coming forward. */
.vshot img{width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .5s cubic-bezier(.2,.6,.2,1), filter .3s ease}
@media (prefers-reduced-motion:reduce){ .vshot img{transition:none} }
li.vid a:hover .vshot img,
li.vid a:focus-visible .vshot img{transform:scale(1.045)}
li.vid a:hover .vshot{border-color:var(--accent-line)}

/* AND THE REST OF THE WALL GOES UNDER A COVER. Pointing at one still darkens
   every other still on the page rather than only lifting the one under the
   pointer. On a wall of nine hundred frames, one frame coming up is a small
   signal in a large field; taking the field away is a large one, and it is the
   difference between a grid that responds and a grid that answers.
   IT IS A FILTER AND NOT A BOX ON TOP. No overlay element, nothing that can
   outlive the state that drew it, and the picture itself doing the work. A
   rule that takes something to nought and relies on a second rule to bring it
   back is one edit away from hiding content for good; a brightness filter
   cannot hide anything.
   ONE SELECTOR HOLDS BOTH HANDS. :has asks whether any still on this wall is
   under the pointer or under the keyboard, and :not excuses the two that could
   be: with a pointer on one frame and focus on another, both stay lit and
   everything else goes dark, which is the only reading of that state that is
   not a wall with nothing lit on it.
   IT ASKS FOR A POINTER FIRST. Touch reports :hover and keeps reporting it
   after the finger has gone, which on this rule is a wall that stays dark
   until the next tap somewhere else. hover:hover is the one question that
   separates a device that can point from one that cannot. */
@media (hover:hover){
  .wall:has(li.vid a:is(:hover,:focus-visible))
    li.vid a:not(:hover):not(:focus-visible) .vshot img{filter:brightness(.7)} }

.vplay{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  display:flex; align-items:center; justify-content:center;
  width:3.2rem; height:3.2rem; border-radius:50%;
  background:rgba(0,0,0,.62); color:#fff;
  border:1px solid rgba(255,255,255,.5); backdrop-filter:blur(2px);
  transition:background .12s ease, transform .12s ease}
@media (prefers-reduced-motion:reduce){ .vplay{transition:none} }
li.vid a:hover .vplay{background:var(--accent); color:var(--sunk);
  border-color:var(--accent); transform:translate(-50%,-50%) scale(1.07)}
li.vid a:focus-visible .vplay{background:var(--accent); color:var(--sunk)}
@media (max-width:40rem){ .vplay{width:2.4rem; height:2.4rem} }

/* A FILM WITH NO TRAILER KEEPS ITS PLACE AND SAYS WHY. It is not an error and
   it is not hidden: the sweep found the film and found no trailer, and a wall
   that quietly dropped those would be claiming a completeness it does not
   have. The plate carries the studio, which is the one fact the picture would
   have carried. */
.vplate{display:flex; align-items:flex-end; padding:.7rem;
  border-left:3px solid var(--accent-line)}
.vplate span{font-family:var(--meta); font-weight:600; font-size:.6rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink3)}
li.vid.noplay a{cursor:default}
li.vid.noplay .vplay{display:none}

.vtitle{display:block; margin-top:.5rem; font-weight:600; font-size:.88rem;
  line-height:1.32; color:var(--ink)}
li.vid a:hover .vtitle{color:var(--accent)}
.vmeta{display:block; margin-top:.22rem; font-family:var(--meta); font-weight:600;
  font-size:.66rem; letter-spacing:.04em; text-transform:uppercase; color:var(--ink3)}
.vwho{display:block; margin-top:.1rem; font-size:.74rem; color:var(--ink2)}
@media (max-width:40rem){
  .vtitle{font-size:.8rem} .vmeta{font-size:.58rem} .vwho{font-size:.68rem} }

/* NOTHING MATCHED, AND THE PAGE SAYS SO RATHER THAN GOING BLANK. */
.nothing{margin:4rem auto; max-width:34rem; padding:0 1.4rem; text-align:center; color:var(--ink2)}
.nothing h2{font-family:var(--display); font-weight:600; font-size:1.4rem;
  color:var(--title-ink); margin:0 0 .5rem}
.nothing button{margin-top:1rem; font-family:var(--meta); font-weight:600;
  font-size:.7rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink); background:var(--ctl); border:1px solid var(--ctl-line);
  border-radius:2px; padding:.5rem .9rem; cursor:pointer}
.nothing button:hover{background:var(--ctl-hover); border-color:var(--ctl-hover-line)}

/* SHOW MORE. The wall draws a screenful; this button draws the next one. */
.more{display:block; margin:2rem auto 0; font:inherit; font-family:var(--meta); font-size:.85rem; letter-spacing:.06em;
  color:inherit; background:transparent; border:1px solid currentColor; border-radius:3px; padding:.6rem 1.4rem; cursor:pointer}
.more:hover, .more:focus-visible{color:var(--accent)}
.more[hidden]{display:none}
.loading, .more{padding:0 1.4rem}
.loading{margin:1.4rem 0 0; text-align:center; font-family:var(--meta);
  font-size:.66rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}

/* THE PLAYER OPENS OVER THE PAGE AND TAKES THE FILM'S OWN SHAPE. The iframe
   is created on open and destroyed on close, which is both how the sound
   stops and how YouTube's player, which is about a megabyte, is never loaded
   by a reader who did not press anything. */
dialog.player{padding:0; border:0; background:none; max-width:min(96vw,74rem);
  width:100%; color:var(--ink); overflow:visible}
/* THE ARROWS NEED ROOM BESIDE THE FILM, and the film is already capped at
   74rem, so the dialog is narrowed rather than the arrows moved inward. */
/* NO ROOM NEEDS RESERVING BESIDE THE FILM ANY MORE, because the arrows are on
   it. The panel can take the width it wants at every size. */
.pstage{position:relative}
dialog.player::backdrop{background:rgba(0,0,0,.84)}
.pbox{position:relative; aspect-ratio:16/9; background:#000;
  border:1px solid var(--rule)}
.pbox iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
/* A FILM WITH NO TRAILER CAN STILL BE ARROWED THROUGH. The wall holds back
   films that cannot play, so this is only reached when a key dies between one
   sweep and the next, but the arrows must not open an empty black box when it
   happens. */
/* ONE SHEET OVER THE WHOLE PICTURE, AND IT REPLACED TWO STRIPS DOWN THE SIDES.
   The strips were a fifth of the width each and a swipe had to begin inside
   one of them. Nobody swipes from the edge of a video: a thumb lands in the
   middle and travels, which is exactly where a cross-origin iframe swallows
   every touch. They caught almost nothing.
   IT STOPS ABOVE THE CONTROL BAR. YouTube's scrubber, its fullscreen button
   and its settings all live along the bottom edge, and those have to stay
   directly pressable - a sheet over them would trade one broken gesture for
   three. The bottom fifth is left alone.
   A TAP IS NOT LOST, IT IS FORWARDED. Covering the picture takes away tapping
   it to pause, so the tap is read here and sent to the player as a command
   through its own postMessage API. That costs an enablejsapi flag on the embed
   and nothing else.
   touch-action:pan-y KEEPS VERTICAL SCROLLING THE BROWSER'S JOB, so a finger
   moving down the screen still scrolls and only sideways movement is ours. */
.pswipe{display:none}
@media (hover:none){
  .pswipe{display:block; position:absolute; left:0; right:0; top:0; bottom:19%;
    z-index:3; touch-action:pan-y; -webkit-tap-highlight-color:transparent}
}
.pnone{position:absolute; inset:0; display:flex; align-items:center;
  justify-content:center; font-family:var(--meta); font-size:.7rem;
  font-weight:600; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}
.pcap{display:flex; align-items:baseline; gap:.8rem; flex-wrap:wrap;
  padding:.7rem .2rem 0}
.pcap h2{margin:0; font-family:var(--display); font-weight:600; font-size:1.1rem;
  color:var(--title-ink)}
.pcap p{margin:0; font-family:var(--meta); font-size:.68rem; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink3)}
/* THE NARROW LAYOUT, AND THE [open] ON IT IS THE WHOLE BUG THIS ONCE HAD.
   A closed dialog is display:none in the user agent stylesheet. This block set
   display:flex without qualification, which overrode that at every width under
   66rem: the player was therefore permanently rendered, in normal flow, at the
   foot of the page. On a phone that is a stray video box under the wall that
   cannot be closed, because it was never open and close() on a closed dialog
   does nothing. It also dragged the page wider than the screen. One selector,
   four symptoms.
   THE LESSON IS THAT display ON A dialog IS NOT A COSMETIC PROPERTY. It is the
   mechanism by which the element is shut, so any rule that sets it has to say
   which state it is describing. */
@media (max-width:66rem){
  dialog.player[open]{display:flex; flex-wrap:wrap; gap:.55rem;
    max-width:100%; width:100%; margin:0; padding:0 .7rem}
  .pstage{flex:1 0 100%; order:1}
  .pcap{flex:1 0 100%; order:2; padding:0}
  .pwhere{flex:1 0 100%; order:3; margin:0}
  /* THE ARROWS STAY ON THE PICTURE ON A PHONE TOO. They used to come down to
     the foot as two wide bars, which worked and put them where a thumb was not
     looking; on the picture they are where the film is. */
  .pstage .pstep{position:absolute; width:2.6rem; height:2.6rem; flex:none;
    border-radius:50%; background:rgba(0,0,0,.62)}
  /* THE ARROWS BECOME TWO HALVES OF A ROW a thumb cannot miss, which is the
     reliable half of stepping on a phone: a swipe that starts on the video
     cannot be seen from here, and these always can be. */
  /* AND CLOSE COMES INTO THE FLOW. It was pinned 2.3rem above the dialog,
     which on a phone is either under the browser chrome or off the top of the
     screen entirely - a close button nobody can reach on the one layout where
     there is no Escape key. */
  .pclose{position:static; order:0; margin-left:auto; flex:none;
    padding:.5rem .9rem; font-size:.7rem}
}
/* THE ARROWS SIT OUTSIDE THE PICTURE AND NOT ON IT. On it they would cover
   the film and fight YouTube's own controls, which live along the bottom edge
   and in the middle. Beside it they are always in the same place and never
   over anything. On a narrow screen there is no room beside, so they come down
   under the caption and become two big targets a thumb can hit. */
.pstep{position:absolute; top:calc(50% - 1.6rem); z-index:2;
  display:flex; align-items:center; justify-content:center;
  width:3.2rem; height:3.2rem; padding:0; border-radius:50%;
  background:rgba(0,0,0,.5); color:var(--ink);
  border:1px solid var(--ctl-line); cursor:pointer;
  transition:background .12s ease, color .12s ease, border-color .12s ease}
/* ON THE PICTURE, AT ITS VERTICAL MIDDLE, AND CLEAR OF YOUTUBE'S CONTROLS,
   which live along the bottom edge and in the center. A disc at the left and
   right edges is the one place on a video that is always safe and always
   findable. */
.pprev{left:.7rem}
.pnext{right:.7rem}
.pstage .pstep{top:50%; transform:translateY(-50%); z-index:4;
  background:rgba(0,0,0,.62); backdrop-filter:blur(2px)}
.pstage .pstep:hover{background:var(--accent); color:var(--sunk); border-color:var(--accent)}
.pstage .pstep[disabled]{opacity:.25}
.pstage .pstep[disabled]:hover{background:rgba(0,0,0,.62); color:var(--ink)}
.pstep:hover{background:var(--ctl-on); color:var(--accent); border-color:var(--accent)}
.pstep:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
/* AN END IS SHOWN AND NOT HIDDEN. A control that disappears at the last film
   moves the other one, and a reader who was pressing in one place is suddenly
   pressing in another. */
.pstep[disabled]{opacity:.25; cursor:default; background:none}
.pstep[disabled]:hover{background:none; color:var(--ink); border-color:var(--ctl-line)}
@media (prefers-reduced-motion:reduce){ .pstep{transition:none} }

/* WHERE YOU ARE IN THE SET YOU FILTERED, which is the one thing arrows cannot
   say by themselves: eleven of ninety-four tells a reader both that there is
   more and how much. */
.pwhere{margin:.5rem .2rem 0; font-family:var(--meta); font-weight:600;
  font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}

.pclose{position:absolute; top:-2.5rem; right:0; background:var(--ctl);
  color:var(--ctl-ink); border:1px solid var(--ctl-line); border-radius:2px;
  font-family:var(--meta); font-weight:600; font-size:.66rem; letter-spacing:.13em;
  text-transform:uppercase; padding:.35rem .7rem; cursor:pointer}
.pclose:hover{background:var(--ctl-hover); color:var(--ctl-hover-ink);
  border-color:var(--ctl-hover-line)}

/* THE FOOT, AND IT IS ONE LINE. There are no other pages to link to. */
footer.foot{margin-top:2rem; border-top:1px solid var(--rule);
  background:linear-gradient(var(--stripe), var(--footer-glow))}
.footin{display:flex; flex-wrap:wrap; gap:.4rem 1.6rem; align-items:baseline;
  padding:1.5rem 0 1.8rem}
.footin p{margin:0; font-family:var(--meta); font-size:.64rem; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink3)}
.footin a{color:var(--ink2); text-decoration:none; border-bottom:1px solid var(--rule)}
.footin a:hover{color:var(--accent); border-bottom-color:var(--accent)}
.footin .seedline{color:var(--accent)}

/* ---- THE GAME -------------------------------------------------------------
   A film with one fact removed. Everything the wall already knows about a film
   is on the card except one line, and the trailer is what getting it back
   earns you - which is the whole reason this belongs on this site rather than
   being a quiz that happens to be about films.
   IT IS A PANEL AND NOT A WALL, so it is sized like a thing you read rather
   than like a thing you scan. */
dialog.quiz{padding:0; border:0; background:none; color:var(--ink);
  max-width:min(94vw, 38rem); width:100%}
dialog.quiz::backdrop{background:rgba(0,0,0,.88)}
.qsheet{position:relative; padding:1.5rem 1.6rem 1.4rem;
  background:var(--raised); border:1px solid var(--rule); border-radius:3px;
  box-shadow:0 24px 60px rgba(0,0,0,.6)}

.qhead{display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap; margin:0 0 1.1rem}
.qstreak{margin:0; font-family:var(--meta); font-weight:600; font-size:.66rem;
  letter-spacing:.13em; text-transform:uppercase; color:var(--ink3)}
.qstreak b{color:var(--accent); font-size:1.1rem; letter-spacing:0}
.qbest{margin-left:.7rem; color:var(--ink3)}

/* THE CLUE IS A QUIET CONTROL. It is there for somebody who is stuck and it
   should not be the thing the eye lands on first, because the game is typing
   the answer. */
.qhints{display:flex; gap:.4rem}
.qm{padding:.34rem .75rem; cursor:pointer; background:none;
  border:1px dashed var(--ctl-line); border-radius:2px;
  font-family:var(--meta); font-weight:600; font-size:.6rem; letter-spacing:.11em;
  text-transform:uppercase; color:var(--ink3)}
.qm:hover{color:var(--accent); border-color:var(--accent); border-style:solid}
.qm[hidden]{display:none}

/* THE CARD OF FACTS. A definition list because that is what it is: four
   labels and four values, one of which is missing. */
.qfields{margin:0; padding:0}
.qrow{display:flex; gap:.9rem; align-items:baseline; padding:.42rem 0;
  border-top:1px solid var(--hair)}
.qrow:first-child{border-top:0}
.qrow dt{flex:none; width:5.2rem; margin:0; font-family:var(--meta); font-weight:600;
  font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}
.qrow dd{margin:0; font-size:.98rem; color:var(--ink)}
.qrow.qmissing dd{font-family:var(--meta); font-weight:600; font-size:.66rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--accent)}

.qanswer{margin-top:1.1rem}
.qopts{display:grid; grid-template-columns:1fr 1fr; gap:.5rem; margin-top:.7rem}
@media (max-width:34rem){ .qopts{grid-template-columns:1fr} }
.qopt{padding:.6rem .8rem; text-align:left; cursor:pointer;
  background:var(--ctl); border:1px solid var(--ctl-line); border-radius:2px;
  color:var(--ink); font:inherit; font-size:.88rem; line-height:1.3}
.qopt:hover:not(:disabled){background:var(--ctl-hover); border-color:var(--ctl-hover-line)}
.qopt:disabled{cursor:default}
/* RIGHT AND WRONG ARE NOT COLOR ALONE. The chosen wrong answer is struck
   through and the right one is marked, so the result survives a reader who
   cannot tell the green from the red. */
.qopt.right{border-color:var(--accent); color:var(--accent); background:var(--accent-soft)}
.qopt.right::after{content:" \2713"; font-weight:700}
.qopt.wrong{opacity:.55; text-decoration:line-through}

.qtype{display:flex; gap:.5rem}
.qtype input{flex:1 1 auto; min-width:0; padding:.6rem .7rem; font:inherit; font-size:.95rem;
  color:var(--ink); background:var(--ctl); border:1px solid var(--ctl-line); border-radius:2px}
.qtype input:focus{outline:0; border-color:var(--accent)}
.qtype button{flex:none; padding:.6rem 1rem; cursor:pointer;
  font-family:var(--meta); font-weight:600; font-size:.66rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--sunk); background:var(--accent);
  border:1px solid var(--accent); border-radius:2px}

/* THE LETTER, SET LIKE A WHISPER RATHER THAN AN ANSWER. It sits under the box
   where a reader is already looking and takes the accent, because it is the
   one thing on the panel that was not there a second ago. */
.qfirst{margin:.6rem 0 0; font-family:var(--meta); font-weight:600; font-size:.66rem;
  letter-spacing:.13em; text-transform:uppercase; color:var(--accent)}
.qfirst b{font-family:var(--display); font-size:1.05rem; letter-spacing:0}

.qverdict{margin:.8rem 0 0; font-family:var(--meta); font-weight:600; font-size:.68rem;
  letter-spacing:.12em; text-transform:uppercase}
.qverdict.yes{color:var(--accent)}
.qverdict.no{color:var(--ink2)}

/* THE REWARD. The trailer, in the panel, the moment it is earned. */
.qafter[hidden]{display:none}
.qafter{margin-top:1rem}
.qbox{position:relative; aspect-ratio:16/9; background:#000; border:1px solid var(--rule)}
.qbox iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
.qnext{width:100%; margin-top:.7rem; padding:.7rem; cursor:pointer;
  font-family:var(--meta); font-weight:600; font-size:.68rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink); background:var(--ctl);
  border:1px solid var(--ctl-line); border-radius:2px}
.qnext:hover{background:var(--ctl-hover); border-color:var(--accent); color:var(--accent)}

/* THE GAME'S OWN FILTERS, and they are set like a form rather than like the
   bar upstairs: four things chosen once at the start of a sitting, not a row
   somebody sweeps along while browsing. */
.qsettings{display:grid; grid-template-columns:repeat(4, 1fr); gap:.5rem;
  padding:0 0 1rem; margin:0 0 1rem; border-bottom:1px solid var(--hair)}
@media (max-width:34rem){ .qsettings{grid-template-columns:1fr 1fr} }
.qsettings label{display:flex; flex-direction:column; gap:.25rem; min-width:0}
.qsettings span{font-family:var(--meta); font-weight:600; font-size:.58rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink3)}
.qsettings select{width:100%; padding:.35rem .4rem; font:inherit; font-size:.8rem;
  color:var(--ink); background:var(--ctl); border:1px solid var(--ctl-line);
  border-radius:2px; cursor:pointer}
.qsettings select:focus{outline:0; border-color:var(--accent)}
/* HOW MANY FILMS THE SETTINGS LEAVE, because a reader who narrows to one year
   and one studio should be told they are now guessing among eleven films
   rather than discovering it by seeing the same one twice. */
.qpool{grid-column:1 / -1; margin:.2rem 0 0; font-family:var(--meta); font-weight:600;
  font-size:.6rem; letter-spacing:.12em; text-transform:uppercase; color:var(--ink3)}
.qpool.thin{color:var(--accent)}

/* ---- THE CLAPPERBOARD -----------------------------------------------------
   BIGGER AND OUT OF THE CORNER, at his word. It was 58 pixels pinned to the
   top right, in the panel's own greys, where it read as a decoration somebody
   had forgotten to remove. It is 84 now, on the left of the header beside the
   streak it is reacting to, and it is painted rather than tinted: a gold slate
   and a warm body against the dark, so it is plainly a character.
   THE MOTION OVERSHOOTS. The old bob was a sine wave between two positions,
   which is a thing moving rather than a thing alive. Everything here lands
   past where it is going and settles back, which is the whole difference.
   IT IS aria-hidden AND HAS TO BE. Everything it says is said in words nearby
   - the verdict line, the streak - so to a screen reader it is decoration
   repeating what has already been read out. */
.qtop{display:flex; align-items:center; gap:1rem; margin:0 0 1.1rem}
.clap{flex:none; width:84px; height:77px; pointer-events:none}
.qhead{flex:1 1 auto; display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap; margin:0}

.clap-shadow{fill:#000; opacity:.45}
.clap-slate{fill:var(--accent)}
.clap-stripe{stroke:#1a1206; stroke-width:4; stroke-linecap:round}
.clap-body{fill:#2a2f38; stroke:#4a525e; stroke-width:2}
.clap-eye{fill:#f7f5f1}
.clap-pupil{fill:#12151a; transition:transform .18s ease}
.clap-mouth{fill:none; stroke:#8d95a1; stroke-width:2.4; stroke-linecap:round; transition:d .2s ease}
.clap-spark{fill:var(--accent); opacity:0}

.clap-top{transform-origin:7px 16px; transition:transform .3s cubic-bezier(.34,1.7,.5,1)}
.clap-all{transform-origin:36px 58px}

/* IDLE: a slow breath with a squash at the bottom of it, and a blink of the
   slate every few seconds. */
.clap-all{animation:clapbob 2.8s cubic-bezier(.45,0,.55,1) infinite}
@keyframes clapbob{
  0%,100%{transform:translateY(0) scale(1,1)}
  40%{transform:translateY(-5px) scale(.98,1.03)}
  70%{transform:translateY(0) scale(1.04,.95)}
  85%{transform:translateY(0) scale(1,1)}
}
.clap .clap-top{animation:clapidle 5s ease-in-out infinite}
@keyframes clapidle{0%,90%,100%{transform:rotate(0)}94%{transform:rotate(-18deg)}}

/* RIGHT: it leaps, claps twice and throws sparks. */
.clap.yes .clap-all{animation:clapyes .42s cubic-bezier(.3,1.7,.5,1) 3}
@keyframes clapyes{
  0%{transform:translateY(0) scale(1.12,.86)}
  30%{transform:translateY(-16px) scale(.92,1.12)}
  70%{transform:translateY(0) scale(1.1,.9)}
  100%{transform:translateY(0) scale(1,1)}
}
.clap.yes .clap-top{animation:clapsnap .42s cubic-bezier(.3,1.7,.5,1) 3}
@keyframes clapsnap{0%,100%{transform:rotate(0)}40%{transform:rotate(-40deg)}}
.clap.yes .clap-spark{animation:clapspark 1s ease-out 1}
@keyframes clapspark{0%{opacity:0;transform:scale(.3)}30%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.5)}}
.clap.yes .clap-mouth{d:path("M27 46 Q36 56 45 46")}

/* WRONG: it drops, the slate hangs open, the eyes fall. */
.clap.no .clap-all{animation:clapno .5s cubic-bezier(.3,1.4,.6,1) 1}
@keyframes clapno{0%{transform:translateY(0) scale(1,1)}40%{transform:translateY(3px) scale(1.1,.88)}100%{transform:translateY(0) scale(1,1)}}
.clap.no .clap-top{transform:rotate(-11deg)}
.clap.no .clap-pupil{transform:translateY(2.4px)}
.clap.no .clap-mouth{d:path("M27 52 Q36 45 45 52")}

/* AND IT WINDS UP WITH THE STREAK. */
.clap.hot .clap-all{animation-duration:1.4s}
.clap.blazing .clap-all{animation-duration:.8s}
.clap.blazing .clap-top{animation:clapidle 1.4s ease-in-out infinite}
.clap.blazing .clap-slate{fill:#ffd873}

@media (prefers-reduced-motion: reduce){
  .clap-all, .clap .clap-top{animation:none !important}
  .clap-top, .clap-pupil, .clap-mouth{transition:none}
}
@media (max-width:30rem){ .clap{display:none} }
