/* flockldn.com landing: two reels of past flyers, then the mark, "Coming soon.", the social links and the current night.
   Same tokens as the Halloween page (styles.css), calmer: the flyers are the show.
   Heights use --u: 1svh where the browser has it, 1vh otherwise. */

:root {
  --void: #020203; --text: #ececef; --text-2: #c9cdd3; --muted: #9a9ea6;
  --pink: 255, 46, 136; --cyan: 40, 220, 255;
  --gap: 10px;
  --mark: 88px;
  /* One banner's preferred height. There are two, one above the block and one below it, and each shrinks below this
     whenever the screen is too short for both banners plus the block between them, so the page fits one screen and
     never scrolls (short of a phone held sideways). The two together take the same room the stacked rows used to. */
  --u: 1vh;
  --reel: calc(27 * var(--u));
  --banner-max: var(--reel);
  /* The floor each banner shrinks to. The lower row's track carries 2 x --gap of margin on top of this,
     so the two strips still floor at the same height; 40 keeps the pair costing what 50 did before. */
  --banner-min: 40px;
  --mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  --serif: 'Instrument Serif', 'Times New Roman', serif;
}
@supports (height: 1svh) { :root { --u: 1svh; } }
html, body { margin: 0; background: var(--void); color: var(--text); }
body { overflow-x: hidden; font-family: var(--mono); -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }

/* Four rows filling exactly one screen: a banner of flyers, the centred block, a second banner, the footer. Both
   banners shrink when space is short, so the page never scrolls. */
/* The lower banner carries a gap above and below it (see .reels-bottom), and a grid item's margins come out of
   its own track, so its row is that much taller than the upper one. Without the extra the flyers along the
   bottom render 20px shorter, and hence narrower, than the ones along the top. */
.page { display: grid; grid-template-rows: minmax(var(--banner-min), var(--banner-max)) 1fr minmax(calc(var(--banner-min) + 2 * var(--gap)), calc(var(--banner-max) + 2 * var(--gap))) auto; box-sizing: border-box; height: 100vh; height: 100svh; padding-top: calc(12px + env(safe-area-inset-top)); padding-bottom: env(safe-area-inset-bottom); }

/* ---------- Reels ---------- */

/* One banner holds one reel. Two banners, top and bottom, each its own grid row on .page. */
.reels { position: relative; display: grid; min-height: 0; }
/* The bottom banner keeps a gap on both sides: without the lower one the flyers sit flush against the footer. */
.reels-bottom { margin-top: var(--gap); margin-bottom: var(--gap); }
.reel { position: relative; overflow: hidden; }
/* The soft edges are two gradients painted OVER the flyers, not a mask on the row.
   A mask forces the browser to rasterise the whole moving strip (thousands of pixels wide) into one
   masked surface every frame, and that is what occasionally came back mis-tiled: the same flyer
   repeated in narrow slices, butted together with no gap. Painting the void colour on top instead
   looks identical, because the page behind is that exact colour, and needs no such surface.
   They sit on .reels, not .reel, so they stay put when reduced motion turns the row into a scroller. */
.reels::before, .reels::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 8%; z-index: 2; pointer-events: none;
}
.reels::before { left: 0; background: linear-gradient(90deg, var(--void), rgba(2, 2, 3, 0)); }
.reels::after { right: 0; background: linear-gradient(270deg, var(--void), rgba(2, 2, 3, 0)); }
.track, .set { display: flex; gap: var(--gap); height: 100%; }
/* Pinned to the row's top and bottom, so the flyers take the row's height however the grid sized it. */
.track { position: absolute; top: 0; bottom: 0; left: 0; width: max-content; }
/* --pad: under a pixel, set by the script so one set plus its gap is a whole number of pixels. */
.set { flex: none; margin-right: var(--pad, 0px); }
/* Width follows each flyer's own ratio (from its width and height attributes), so no tile is cropped. */
.set > img { display: block; flex: none; height: 100%; width: auto; border-radius: 3px; background: #0b0b0e; user-select: none; -webkit-user-drag: none; }

/* Motion starts once the script has measured one set (--set) and its duration at 30px a second (--dur).
   Deliberately no will-change here, and no mask on the row above. Both tell the browser to hold this whole
   strip, several thousand pixels of it, as one drawn surface, and both times it came back wrong: with the
   mask as one flyer repeated in gapless slices, with will-change as flyers that simply stopped partway
   and left black. A plain transform animation lets it draw only the part in front of you. */
.reels-live .track { animation: var(--dur, 60s) linear infinite; }
.reels-live .reel-1 .track { animation-name: reel-ltr; }
.reels-live .reel-2 .track { animation-name: reel-rtl; }
@keyframes reel-ltr { from { transform: translate3d(calc(var(--set, 0px) * -1), 0, 0); } to { transform: translate3d(0, 0, 0); } }
@keyframes reel-rtl { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(calc(var(--set, 0px) * -1), 0, 0); } }
@media (hover: hover) {
  .reel:hover .track { animation-play-state: paused; }
}

/* ---------- Mark, line, links ---------- */

.hero { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 18px 16px 10px; text-align: center; }
.mark-fx { width: var(--mark); height: var(--mark); margin: 0 0 4px; filter: drop-shadow(-3px 0 0 rgba(var(--pink), 0.85)) drop-shadow(3px 0 0 rgba(var(--cyan), 0.85)); }
/* The PNG keeps 4.2% transparent padding around the circle; overscan it so the circle itself is --mark wide. */
.mark { display: block; position: relative; left: -4.26%; top: -4.26%; width: 108.52%; height: 108.52%; max-width: none; animation: turn 30s linear infinite; }
@keyframes turn { to { transform: rotate(360deg); } }

.soon { margin: 0; font-family: var(--serif); font-style: italic; font-weight: 400; font-size: 40px; line-height: 1; letter-spacing: -0.01em; text-shadow: -1.5px 0 rgba(var(--pink), 0.55), 1.5px 0 rgba(var(--cyan), 0.55); }

/* Two rows: the lasting links (Instagram, WhatsApp) side by side, then the current night as a hairline pill below. */
.links { display: flex; flex-direction: column; align-items: center; gap: 8px; }
/* nowrap: the two stay on one line at every width. They shed their icons before they would ever stack (see the
   narrow breakpoints below), because two pills reading as one row is the point of them being pills. */
.social { display: flex; flex-wrap: nowrap; justify-content: center; column-gap: 10px; }
.links a { display: inline-flex; align-items: center; gap: 9px; min-height: 44px; padding: 0 4px; box-sizing: border-box; font-size: 12px; line-height: 1; letter-spacing: 0.16em; text-transform: uppercase; text-decoration: none; color: var(--text-2); cursor: pointer; transition: color 0.2s ease; }
.links a > span { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; text-decoration-color: rgba(201, 205, 211, 0.4); transition: text-decoration-color 0.2s ease; }
.links svg { flex: none; }
.links a:hover { color: var(--text); }
.links a:hover > span { text-decoration-color: rgba(236, 236, 239, 0.85); }
.links a:focus-visible, .foot a:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; border-radius: 3px; }
/* The pill carries the same pink/cyan split as the mark, kept faint so it reads as a clear link, not a loud button. */
/* The two social links are the sign-up's pill, one notch quieter: a dimmer border, the softer text colour, and no
   chromatic edge. That keeps the night itself the one thing on the page with the pink and cyan glow. */
.links a.pill { padding: 0 16px; border: 1px solid rgba(201, 205, 211, 0.18); border-radius: 999px; white-space: nowrap; transition: color 0.2s ease, border-color 0.2s ease; }
.links a.pill > span { text-decoration: none; }
.links a.pill:hover { color: var(--text); border-color: rgba(201, 205, 211, 0.45); }
.links a.pill:focus-visible { border-radius: 999px; outline-offset: 3px; }

.links a.event { padding: 0 20px; border: 1px solid rgba(201, 205, 211, 0.38); border-radius: 999px; color: var(--text); box-shadow: -1.5px 0 0 rgba(var(--pink), 0.45), 1.5px 0 0 rgba(var(--cyan), 0.45); transition: color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; }
.links a.event > span { text-decoration: none; }
.links a.event:hover { border-color: rgba(236, 236, 239, 0.75); box-shadow: -2px 0 0 rgba(var(--pink), 0.7), 2px 0 0 rgba(var(--cyan), 0.7); }
.links a.event:focus-visible { border-radius: 999px; outline-offset: 3px; }

.foot { padding: 0 16px 10px; text-align: center; font-size: 10px; line-height: 14px; letter-spacing: 0.06em; color: var(--muted); }
/* A bigger tap area than the 10px line, without moving anything (the footer's 10px bottom padding holds its overflow). */
.foot a { display: inline-block; margin: -10px -6px; padding: 10px 6px; color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: rgba(154, 158, 166, 0.5); cursor: pointer; }
.foot a:hover { color: var(--text-2); }

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---------- Sizes ---------- */

/* Tablets and desktops (1440x900): rows a shade under 30vh, so the block below keeps real breathing room. */
@media (min-width: 768px) {
  :root { --mark: 110px; }
  .page { padding-top: calc(16px + env(safe-area-inset-top)); }
  .hero { gap: 14px; padding: 20px 24px 8px; }
  .mark-fx { margin-bottom: 6px; }
  .soon { font-size: 56px; }
  .foot { padding-bottom: 14px; }
}

/* Wide but short (1024x768, 1280x720 laptops, the 1200x630 share card): a little less of each. */
@media (min-width: 768px) and (max-height: 820px) {
  :root { --mark: 96px; }
  :root { --reel: calc(27 * var(--u)); }
  .hero { gap: 12px; padding-top: 16px; }
  .mark-fx { margin-bottom: 4px; }
  .soon { font-size: 48px; }
}

/* Wide and very short (the 1200x630 share card): smaller rows and mark, so the footer stays in frame. */
@media (min-width: 768px) and (max-height: 700px) {
  :root { --mark: 84px; --reel: calc(23 * var(--u)); }
  .soon { font-size: 44px; }
}

/* Big screens (2560x1440): the block grows a step so it does not look lost under the rows. */
@media (min-width: 1800px) and (min-height: 1100px) {
  :root { --mark: 150px; }
  .hero { gap: 20px; }
  .mark-fx { margin-bottom: 10px; }
  .soon { font-size: 76px; }
  .social { column-gap: 36px; }
  .links a { font-size: 13px; }
  .foot { font-size: 11px; }
}

/* Very short screens (an iPhone SE in Safari, 375x548 once the bars are shown): everything a step smaller. */
@media (max-height: 600px) {
  :root { --mark: 72px; }
  .page { padding-top: calc(10px + env(safe-area-inset-top)); }
  .hero { gap: 10px; padding: 10px 16px 6px; }
  .mark-fx { margin-bottom: 0; }
  .soon { font-size: 34px; }
}

/* Phones (up to 480px wide): the two social links get a step smaller and closer, so they share one line down to
   360px wide. Below 340px (320px phones) their icons drop out so the words still fit on one line. */
@media (max-width: 480px) {
  .hero { padding-left: 12px; padding-right: 12px; }
  .social { column-gap: 8px; }
  .links a { gap: 7px; padding: 0 2px; font-size: 11px; letter-spacing: 0.08em; }
  .links a.pill { padding: 0 12px; }
  .links a.event { padding: 0 18px; }
}

/* The pills cannot wrap, so they must fit. "Follow us" and "Join the flock" are short enough that both keep their
   logo at every width down to 320px (measured: 250px of pill inside 296px of room), so nothing is dropped and only
   the type tightens. Re-measure before lengthening either label; the icons are the first thing that would have to go. */
@media (max-width: 360px) {
  .links a { font-size: 10px; letter-spacing: 0.06em; }
  .links a.pill { padding: 0 10px; }
  .links a.event { padding: 0 14px; }
}


/* ---------- Reduced motion: no drift, no turn. Each row is a strip to swipe or scroll through, one set only. ---------- */

@media (prefers-reduced-motion: reduce) {
  .track { animation: none !important; transform: none !important; padding-inline: 8vw; }
  .copy { display: none; }
  .reel { overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; scroll-padding-inline: 8vw; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: rgba(201, 205, 211, 0.25) transparent; }
  .set > img { scroll-snap-align: start; }
  .mark { animation: none; }
  .links a, .links a > span, .links a.event { transition: none; }
}

/* ---------- Still frames (?still=1): every animation paused at its first frame. ---------- */

.still *, .still *::before, .still *::after { animation-play-state: paused !important; }
