/* The Showcase. One page, every precomputed animation, grouped by wallpaper
 * group. The site's own stylesheets do the chrome, the typography and the
 * directory cards; this file is only the grid, the rail and the card. */
.showcase main { max-width: 1600px; }
.showcase-summary { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: baseline; margin: 0 0 18px; font-size: 13px; color: var(--muted); }
.showcase-summary b { font: 600 15px ui-monospace, monospace; color: var(--ink); }

/* The group rail: eighteen anchors, sticky under the header, the reader's way
 * around a page that is longer than any screen. */
.group-rail { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; gap: 5px; padding: 9px 0; margin: 0 0 20px; background: #fbfaf9cc; backdrop-filter: blur(7px); border-bottom: 1px solid var(--rule); }
.group-rail a { display: inline-flex; gap: 6px; align-items: baseline; padding: 4px 9px; border: 1px solid var(--rule); border-radius: 999px; font-size: 12px; text-decoration: none; color: var(--ink); background: #fff; white-space: nowrap; }
.group-rail a:hover { background: #f0edf7; border-color: var(--accent); }
.group-rail a b { font-size: 13px; }
.group-rail a span { color: var(--muted); font: 11px ui-monospace, monospace; }
.group-rail a.pinned { background: #111; color: #fff; border-color: #111; }
.group-rail a.pinned span { color: #cfcbc4; }
.group-rail a[aria-current="true"] { border-color: var(--accent); background: #f0edf7; }

/* The kind filter, and the page's honesty about its own budget. */
.kind-bar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 22px; font-size: 13px; }
.kind-bar button { padding: 5px 11px; border-radius: 999px; font-size: 12px; }
.kind-bar button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.kind-bar .spacer { margin-left: auto; font: 11px ui-monospace, monospace; color: var(--muted); }
.kind-bar label { display: inline-flex; gap: 5px; align-items: center; font-size: 12px; color: var(--muted); }

/* The chip, quoted in the prose above the grid, drawn like the real one. */
.chip-eg { display: inline-block; padding: 1px 8px; border-radius: 999px; background: #1b1626d9; color: #fff; font: 600 10.5px/1.6 -apple-system, BlinkMacSystemFont, sans-serif; vertical-align: 1px; }

/* A section per wallpaper group. */
.showcase-section { margin: 0 0 34px; scroll-margin-top: 64px; }
.showcase-section h2 { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; font-size: 1.35rem; margin: 0 0 4px; padding-top: 6px; border-top: 2px solid var(--ink); }
.showcase-section h2 .hm { font-size: .62em; color: var(--muted); font-weight: 500; }
.showcase-section h2 .n { margin-left: auto; font: 600 12px ui-monospace, monospace; color: var(--muted); }
.showcase-section > p.small { margin: 0 0 12px; max-width: 80ch; }

/* The grid. 148-pixel cards, as many as fit. */
.loop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; }
/* A card is a DIV holding one stretched link and, where the clip has
 * look-alikes behind it, one button. It has to be a div: the chip is a
 * <button>, and a button inside an <a> is invalid and unreachable by keyboard
 * in every engine that tries to render it anyway. `a.open` fills the card, so
 * the whole card is still one click; the chip sits over the art beside it. */
.loop-card { display: block; position: relative; border: 1px solid var(--rule); border-radius: 6px; overflow: hidden; background: #fff; }
.loop-card .open { display: block; text-decoration: none; color: inherit; border-radius: 5px; }
.loop-card:hover, .loop-card:focus-within { border-color: var(--accent); box-shadow: 0 2px 10px #2711371f; }
.loop-card .open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.loop-card .art { position: relative; display: block; width: 100%; aspect-ratio: 1; background: #14110f; line-height: 0; }
.loop-card .art img, .loop-card .art video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }
.loop-card .art video { z-index: 1; }
.loop-card .badge { position: absolute; z-index: 2; top: 5px; left: 5px; padding: 2px 6px; border-radius: 3px; font: 600 9.5px/1.5 -apple-system, BlinkMacSystemFont, sans-serif; letter-spacing: .06em; text-transform: uppercase; color: #fff; background: #1b1626cc; }
.loop-card .badge.mono { background: #111e; }
.loop-card .badge.colour { background: #c9563ee6; }
.loop-card .badge.ember { background: #8a4b1fe6; }
.loop-card .badge.viewer { background: #3b2a72e6; }
.loop-card .sig { position: absolute; z-index: 2; bottom: 4px; right: 4px; padding: 1px 5px; border-radius: 3px; background: #0009; font: 600 11px/1.5 ui-monospace, monospace; color: #fff; letter-spacing: .02em; }
.loop-card .meta { display: block; padding: 6px 7px 7px; }
.loop-card .meta strong { display: block; font-size: 11.5px; font-weight: 600; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loop-card .meta span { display: block; font: 10.5px/1.45 ui-monospace, monospace; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The last line wraps to two, because on a two-colour card it leads with the
 * RULE and a card is only 160 px wide. With both tiers carded a section holds
 * many readings of one wave, agreeing about name, group, equation and
 * parameters; "Glide Mx, slide (23, 24)" alone fills a line, and ellipsed at
 * one it left six neighbours reading "Glide Mx, slide (23, 2…" and saying
 * nothing. Two lines hold the rule and the parameters, which is the pair that
 * tells any two cards in a section apart. */
.loop-card .meta .det {
  white-space: normal; overflow-wrap: anywhere; text-overflow: clip;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2;
}

/* The look-alike chip: "+6 alike" over the bottom-left of the art, opposite the
 * signature, with the kind badge still top-left.
 *
 * It is anchored to the bottom of the ART and not of the card, and the art is a
 * square as wide as the card — so its bottom edge is one card-WIDTH below the
 * top. A percentage `top` would resolve against the card's height, which
 * includes the two or three lines of metadata; a percentage MARGIN resolves
 * against the containing block's width, which is exactly the number wanted. */
.loop-card .alike {
  position: absolute; z-index: 3; left: 5px; top: 0; margin-top: 100%;
  transform: translateY(calc(-100% - 5px));
  min-height: 24px; padding: 2px 8px; border: 0; border-radius: 999px;
  background: #1b1626d9; color: #fff; cursor: pointer;
  font: 600 10.5px/1.6 -apple-system, BlinkMacSystemFont, sans-serif;
  letter-spacing: .02em; white-space: nowrap;
}
.loop-card .alike:hover { background: var(--accent); }
.loop-card .alike:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }
.loop-card .alike[aria-expanded="true"] { background: var(--accent); }
/* With the fold off there is nothing for the chip to do, and a control that
 * does nothing is worse than no control. The count it carried is in the card's
 * own `title` — "… — 6 more cards in this group look like this one", written by
 * `card_title()` and `cardTitle()` alike — so it is still on the card and not
 * only in a control that is gone. */
.showcase[data-unfold="1"] .loop-card .alike { display: none; }

/* A card that was folded behind the card before it, mounted because the reader
 * opened that chip. Dashed, so the eye reads the run as one group, and it says
 * the word as well — a dashed border is not a sentence. */
.loop-card[data-alike-of] { border-style: dashed; background: #fcfbfa; }
.loop-card[data-alike-of] .meta .alike-word { color: var(--accent); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; font-size: 9.5px; }

.load-more { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 14px 0 0; }
.load-more button { padding: 9px 22px; font-size: 14px; }
.load-more[hidden] { display: none; }
.mount-note { text-align: center; font: 11px ui-monospace, monospace; color: var(--muted); margin: 8px 0 0; }
/* Shown only by the <noscript> block in index.html's head, which is also what
 * takes the dead controls away. */
.noscript-note { display: none; }

/* p1's orbifold symbol is a lone ring. At rail and heading size it reads as a
 * bullet beside "2222" and "**" unless it is drawn a little larger. */
/* `.group-rail a span` sets a font SHORTHAND, which resets the size, so this
 * has to out-specify it rather than sit beside it. */
.group-rail a b .orb-small { font-size: 2.2em; line-height: .45; vertical-align: -.1em; }
.showcase-section h2 .orb-small { font-size: 1.6em; line-height: .6; vertical-align: -.06em; }

/* A family the mount budget has taken out of the document. The grid keeps the
 * height it had, so the scrollbar does not jump, and this button is the way
 * back — scrolling to it brings the cards back on its own, but a spacer with
 * nothing in it is indistinguishable from a broken page. */
.remount-note { grid-column: 1 / -1; justify-self: center; margin: 14px 0; padding: 10px 20px; border: 1px dashed var(--rule); border-radius: 999px; background: #fff; font: 12px ui-monospace, monospace; color: var(--muted); cursor: pointer; }
.remount-note:hover, .remount-note:focus-visible { border-color: var(--accent); color: var(--ink); }

/* The standalone viewers: first, and bigger, because they are pages. */
.pinned-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.pinned-grid .loop-card .meta strong { font-size: 13px; }

/* The kind filter hides cards rather than unmounting them: a filter is a way of
 * looking, not a reload, and switching back must be instant. */
.showcase[data-kind="ember"] .loop-card:not([data-kind="ember"]),
.showcase[data-kind="colour"] .loop-card:not([data-kind="colour"]),
.showcase[data-kind="mono"] .loop-card:not([data-kind="mono"]),
.showcase[data-kind="viewer"] .loop-card:not([data-kind="viewer"]) { display: none; }
.showcase-section[hidden] { display: none; }

/* Cards read as pictures alone: no kind badge, no signature, no name/group/
 * parameter caption, no "+N alike" chip. The underlying markup, fold and
 * expand behaviour are unchanged — this is a visual override only. */
.showcase .loop-card .badge,
.showcase .loop-card .sig,
.showcase .loop-card .meta,
.showcase .loop-card .alike {
  display: none !important;
}

@media (max-width: 720px) {
  .loop-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 7px; }
  .pinned-grid { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); }
  .group-rail { gap: 4px; padding: 7px 0; overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  /* A thumb needs 44 px, and a row that scrolls sideways has to look like one:
   * the only hint was a half-cut pill at the right edge. */
  .group-rail a { flex: 0 0 auto; min-height: 44px; align-items: center; }
  .group-rail::after { content: ''; position: sticky; right: 0; flex: 0 0 26px; margin-left: -26px; align-self: stretch; pointer-events: none; background: linear-gradient(to right, #fbfaf900, #fbfaf9f2); }
  .kind-bar button { min-height: 44px; padding-inline: 14px; }
  .kind-bar label { min-height: 44px; }
  .showcase-section h2 { font-size: 1.1rem; }
  .showcase-summary { gap: 4px 12px; font-size: 12px; margin-bottom: 12px; }
  .showcase-summary b { font-size: 13px; }
  .directory > p:not(.showcase-summary) { font-size: 14px; }
  .showcase-section h2 .n { flex-basis: 100%; margin-left: 0; }
  /* A 112 px card cannot hold three lines, but the one line that tells a card
   * from the card beside it has to survive. With both two-colour tiers carded
   * a p1 section holds twenty readings of one wave, every one of them called
   * "Standing wave": on the name alone the phone grid was twenty identical
   * labels over twenty different pictures. `.det` leads with the rule for a
   * two-colour card and with the parameters for a field one, which is exactly
   * what differs; `.where` (the group and the equation) is what they share, so
   * that is the line to drop. The pinned viewers keep theirs — nine cards on a
   * wider track, where the note is the whole point of the card. */
  .loop-card .meta .where { display: none; }
  .pinned-grid .loop-card .meta .where { display: block; }
  /* The chip is bigger here than on a mouse, and it is bigger VISIBLY.
   *
   * It used to be 24 px with a transparent `::after` halo of `inset: -10px`
   * ALL ROUND, on the argument that nothing else on the card was listening
   * there. Something was: `a.open` wraps the whole card, art included, so the
   * halo sat on top of the card's own link and took 27 % of a 115 px picture
   * with it — a tap seven pixels ABOVE the chip, on the picture, folded the
   * look-alikes instead of opening the card, and nothing on screen said why.
   *
   * A thumb still wants 44 px and a 112 px card cannot spare that much ink, so
   * the pill is 38 px of real chip and the last 6 px are a halo that grows only
   * DOWNWARD — away from the middle of the picture, into the strip between the
   * chip and the signature, which is the one part of the art a thumb aiming at
   * the chip overshoots into. Nothing above the pill, and nothing to either
   * side of it, answers to the chip.
   *
   * 38 + 6 and not 36 + 8, for a reason worth a line: the pill's bottom lands
   * on a fractional pixel, and WebKit rounds that boundary outward where
   * Chromium rounds it in — so with an 8 px halo a real tap exactly 8 px below
   * the pill folded the card in one engine and followed the link in the other.
   * At 6 px the two engines agree everywhere a finger can land, and the tap box
   * is still 44 px. */
  .loop-card .alike { min-height: 38px; padding-block: 9px; }
  .loop-card .alike::after { content: ''; position: absolute; inset: 0 0 -6px 0; }
  /* The chip and the signature cannot share the bottom strip of a 117 px card:
   * "+4 alike" is 65 px and "*²2²2²2²2" is 71 px, and the chip — which is above
   * the signature — was drawn over its first two characters, leaving the card
   * showing a signature no group has. So on the phone the chip takes the row
   * ABOVE: still over the art, still left, with the signature alone on the
   * bottom row. 34 px is the signature's own 18 px band, its 4 px inset, the
   * 6 px halo under the chip and 6 px of air — so the tap box stops short of
   * the signature rather than taking the corner of it. */
  .loop-card .alike { transform: translateY(calc(-100% - 34px)); }
  /* Two buttons side by side leave about 80 px each on a 390 px screen, which
   * is a button that says "Show 50" and then stops. */
  .load-more { flex-direction: column; align-items: stretch; }
  .load-more button { min-height: 44px; }
  /* …except where dropping it would make two cards read alike. Twelve of the
     eighteen sections hold more than one film group — p6 holds g247 and g248 —
     and there two cards can agree about the name, the rule, the parameters and
     the size and differ only in the group. `make-manifest.py` marks those grids
     `data-where="keep"`; the other six pay nothing for it. */
  .loop-grid[data-where="keep"] .loop-card .meta .where { display: block; }
  .kind-bar .spacer { margin-left: 0; flex-basis: 100%; }
}
