/* ============================================================================
   THE CARD — one screenprinted plate, wherever a card appears.

   Lifted verbatim out of epinoia/index.html's <style> block, which is where it
   was written and where it stayed. news.css has said "the card itself is the
   club plate from the kit" since the day it was written, and it was not true:
   the plate lived on one page, so the news page drew the same markup with none
   of the paint. Measured there before this move — no border, a transparent
   plate instead of #07130d, the registration crosses unpainted, the ink flood
   at full opacity instead of .14, and the caption band laid out as a block
   instead of a row. The card was not a different design; it was the same design
   with the stylesheet missing.

   THE BRIEF WAS AN UNDERGROUND ART-MOVEMENT PIECE, so these are built like a
   riso/screenprint pull rather than a UI component: one ink per card over
   black, a halftone bitten into the plate, deliberate misregistration on a
   second pass, registration crosses at the corners and an edition mark.
   Everything is CSS — no images to load, nothing to go missing, and the
   monogram scales to whatever the thing is called.

   It has to survive being the ONLY thing on screen for a club with no logo,
   because right now none of them have one. So the monogram is the artwork, not
   a placeholder for it.

   --ink-c IS THE ONE INPUT. Every layer here reads it, and each caller sets it
   inline: the club's own colour for a club, a colour derived from the headline
   for an article. Nothing in this file picks a colour.

   What sits ON the plate belongs to whoever is using it — news.css for an
   article's headline and scrim, epinoia/index.html for the aspect-ratio and
   monogram-size variants that make a star or a Team of the Year card.
   ============================================================================ */

.club{position:relative;display:block;text-decoration:none;color:inherit;
  isolation:isolate}
.club-plate{position:relative;aspect-ratio:1;overflow:hidden;
  background:#07130d;border:1px solid var(--rule);
  display:grid;place-items:center;
  transition:transform .18s cubic-bezier(.2,.8,.3,1),border-color .18s ease}
.club:hover .club-plate{border-color:var(--ink-c);transform:translate(-2px,-2px)}

/* the ink block: a hard flood that the halftone eats into */
.club-flood{position:absolute;inset:0;background:var(--ink-c);opacity:.14}
/* halftone, bitten coarse so it reads as print rather than texture */
.club-tone{position:absolute;inset:-20%;
  background-image:radial-gradient(circle,var(--ink-c) 1.1px,transparent 1.4px);
  background-size:7px 7px;opacity:.5;
  transform:rotate(-12deg)}
/* the grain of the paper */
.club-grain{position:absolute;inset:0;pointer-events:none;opacity:.18;
  mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='120' height='120' filter='url(%23n)' opacity='.55'/></svg>")}

/* registration crosses, as a printer would leave them */
.club-reg{position:absolute;width:11px;height:11px;opacity:.5;
  background:
    linear-gradient(var(--ink-c),var(--ink-c)) center/1px 100% no-repeat,
    linear-gradient(var(--ink-c),var(--ink-c)) center/100% 1px no-repeat}
.club-reg.tl{top:8px;left:8px} .club-reg.tr{top:8px;right:8px}
.club-reg.bl{bottom:8px;left:8px} .club-reg.br{bottom:8px;right:8px}

/* the mark. Two passes, the under-pass offset — misregistration is the
   whole visual argument, so it is exaggerated slightly on hover. */
.club-mark{position:relative;display:grid;place-items:center;z-index:1;
  width:100%;height:100%}
.club-mono{font-family:var(--f-score);font-size:clamp(40px,8vw,64px);
  line-height:.8;letter-spacing:-.02em;text-transform:uppercase;
  grid-area:1/1;color:var(--ink)}
.club-mono.ghost{color:var(--ink-c);
  transform:translate(3px,3px);mix-blend-mode:screen;opacity:.85;
  transition:transform .18s cubic-bezier(.2,.8,.3,1)}
.club:hover .club-mono.ghost{transform:translate(6px,5px)}
/* THE CREST, TREATED AS PART OF THE PRINT rather than pasted on top of it.

   The monogram it replaces is two passes of type, the under-pass offset in the
   club's ink — misregistration is the whole visual argument of these cards. A
   crest cannot be printed twice like that (it is somebody's artwork, not our
   type), so it borrows the idea at a fraction of the strength: a soft shadow in
   the club's own ink, close in, which lifts it off the halftone without reading
   as a registration fault.

   SIZED AGAINST THE PLATE, WHICH TOOK A CORRECTION. The obvious rule —
   width:72% on the image — resolves against .club-mark, and .club-mark is
   content-sized, so the percentage was of a box whose size the image itself was
   deciding. Measured: it produced 168px on a 360px plate, not the 259 the
   number implied. So the mark is given the plate's own size and the crest is
   sized against that.

   IN ABSOLUTE UNITS, WHICH TOOK A SECOND CORRECTION. Percentages did not work
   either: the image is a grid item whose track is sized by the image, so a
   percentage max-height is indefinite and the browser drops it. Measured, a
   tall crest capped at "26%" rendered at 78% of the plate — the cap silently
   did nothing.

   So it is sized the way the monogram beside it is sized, with the same
   clamp() against the viewport: up to 160px wide so a wordmark has somewhere
   to go, and at most 64px tall.

   64 RATHER THAN THE MONOGRAM'S 76, and the difference is the stencil band. The
   band crosses the plate at 64% of its height; centred content therefore has
   half the plate's height minus that to play with. Measured on a 360px plate:
   at 76px the square and tall crests ran 7px into the band, while the monogram
   — shorter, and with the type's own internal leading — cleared it by 11. At 64
   a crest of any shape clears it too, which is the point: the card should look
   the same whether a club has a crest or two letters.

   Height is the tighter of the two on purpose. object-fit:contain letterboxes
   inside whatever box it is given, so a round badge, a tall shield and a wide
   wordmark all end up the same optical WEIGHT rather than the same width. */
.club-logo{grid-area:1/1;z-index:1;
  max-width:clamp(96px,20vw,160px);max-height:clamp(46px,7.6vw,64px);
  width:auto;height:auto;object-fit:contain;
  filter:drop-shadow(2px 2px 0 color-mix(in oklch,var(--ink-c) 55%,transparent))
         drop-shadow(0 1px 6px rgba(0,0,0,.28));
  transition:transform .18s cubic-bezier(.2,.8,.3,1)}
/* the plate lifts on hover and the crest goes with it, a shade further — the
   same parallax the ghost monogram has */
.club:hover .club-logo{transform:translate(2px,2px) scale(1.03)}
@media (prefers-reduced-motion:reduce){
  .club-logo{transition:none}
  .club:hover .club-logo{transform:none}
}

.club-band{position:absolute;left:-10%;right:-10%;top:64%;height:15px;
  background:var(--ink-c);opacity:.9;transform:rotate(-4deg);
  display:grid;place-items:center;overflow:hidden}
.club-band span{font-family:var(--f-micro);font-size:7.5px;letter-spacing:.42em;
  text-transform:uppercase;color:#07130d;white-space:nowrap;font-weight:700}

.club-foot{display:flex;align-items:baseline;gap:8px;padding:9px 2px 0}
.club-name{font-family:var(--f-ui);font-weight:800;font-size:12.5px;
  text-transform:uppercase;letter-spacing:.02em;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.club:hover .club-name{color:var(--ink-c)}
.club-ed{margin-left:auto;font-family:var(--f-micro);font-size:8px;
  color:var(--ink-3);letter-spacing:.1em;white-space:nowrap}

@media (prefers-reduced-motion:reduce){
  .club-plate,.club-mono.ghost{transition:none}
  .club:hover .club-plate{transform:none}
  .club:hover .club-mono.ghost{transform:translate(3px,3px)}
}

/* ---------------------------------------------------------------------------
   INSTAGRAM TILES — the same track sizing as the clubs grid above.

   minmax(178px, 1fr) while there is not much room, then a CAPPED track with
   justify-content:start once there is. The cap is the whole point: auto-fit
   collapses the tracks nothing occupies and 1fr then gives the entire row to
   whatever remains, so one spotlit post used to arrive at the full width of the
   page. Four posts stay four tiles; one post is one tile the same size.

   The frame inside is always laid out at 326x470 and scaled by --ig-s, which
   igtile.js keeps equal to tileWidth/326. Instagram's embed does not reflow
   below about 326px — it clips — so narrowing the frame is not an option and
   scaling it is. These two numbers are mirrored from igtile.js's W and H and
   have to move together with them.
   --------------------------------------------------------------------------- */
.ig-grid{display:grid;gap:calc(var(--u)*2);
  grid-template-columns:repeat(auto-fit,minmax(178px,1fr))}
@media (min-width:1100px){
  .ig-grid{grid-template-columns:repeat(auto-fit,minmax(178px,240px));
    justify-content:start}
}
.ig-tile{position:relative;overflow:hidden;aspect-ratio:326/470;
  border:1px solid var(--rule);background:#fff}
.ig-tile iframe{position:absolute;top:0;left:0;width:326px;height:470px;
  border:0;background:#fff;
  transform:scale(var(--ig-s,1));transform-origin:top left}
