/* =====================================================================
   EVENT CARDS — the upcoming-events band.

   Loaded on TWO templates: page-events (the full grid) and page-hub (the
   two-up band above Insights). One sheet rather than a rule in each page
   sheet, because the two renderings are one component with one variant —
   and news.css already records what the alternative costs: its own
   .hub-band--alt duplicates components/bands.css's .band-cream pair and
   flags that "if bands.css ever changes which tokens that class pairs,
   this rule will not follow it".

   NO COLOUR VALUE APPEARS HERE. tokens.css was not opened and no new
   token was introduced — LOCK 5, and the director's standing constraint
   for this unit. Everything below is an existing token, the existing type
   scale, and the spacing rhythm news.css already uses on the hub.

   ⚠ EVERY RATIO IN THIS FILE WAS MEASURED, NOT ESTIMATED, AND THE PROBER
   WAS VALIDATED FIRST. It reproduces five figures already published in
   this build — base.css's 4.5994 for --slate on --paper, news.css's
   4.9579 / 3.3306 / 4.6361 / 4.3009 — to four decimal places before any
   number below was trusted. See HANDOFF §35 for the one figure in the
   existing record it does NOT reproduce, which is reported rather than
   corrected here.

   THE "DIFFERENT LOOK" IS THE BOX, AND THE RESTRAINT IS DELIBERATE. The
   hub's own lists are ruled rows; this is a grid of bounded blocks, which
   is the distinction the brief asked for. It is a QUIET card — a tinted
   fill, a hairline, and generous padding — because this site's entire
   visual language is hairlines and type, and there is no elevation,
   shadow or radius token to reach for. Inventing one would be a new
   design primitive smuggled in under a listing page.
   ===================================================================== */

/* ---- the band ----
   64px top and bottom, matching .hub-band exactly, so the events band and
   the three link bands beneath it sit on one rhythm rather than two. */
.ev-band{padding-top:64px;padding-bottom:64px}

/* THE GROUND IS THE PAGE'S, AND THAT IS WHAT KEEPS LOCK 9 INTACT.
   The hub's three link bands alternate alt / plain / alt by POSITION —
   asserted by hub-diff's HB-H2 — and this band is not one of them. It
   takes the page ground, sits outside the sequence, and the counter that
   drives the alternation still starts at 0 on Insights. The --alt class
   exists for a caller that needs it and is unused today; it is the
   semantic PAIR from bands.css, never the raw palette token, so a future
   split of --cream into separate ground and foreground values lands
   correctly. */
.ev-band--alt{background:var(--ground-alt);color:var(--on-alt)}

/* ---- the head: heading left, link right ----
   flex-wrap, not a media query, because the two children are a heading of
   unknown length and a link of unknown length — the point at which they
   stop fitting is a property of the copy, not of the viewport. */
.ev-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:16px;
  flex-wrap:wrap;
}
.ev-band h2{font-size:clamp(24px,2.2vw,32px)}

/* --pill-hover, measured 5.4187 on --paper, clearing the 4.5 small-text
   threshold by 0.9187. It is the ink news.css already gives .hub-title
   and the article back link, so an outbound text link reads the same on
   this band as on the three beneath it.

   MONO 13px AT .1em IS .hub-count's TREATMENT, not .kick's. .kick is
   11px at .26em uppercase and base.css records that 11px is a measured
   WRAP CEILING rather than a preference — nothing here goes near it. */
.ev-all{
  font-family:var(--mono);
  font-size:13px;
  letter-spacing:.1em;
  color:var(--pill-hover);
  text-decoration:underline;
  text-underline-offset:3px;
  text-decoration-thickness:1px;
  text-decoration-color:transparent;
  transition:text-decoration-color .18s ease;
  white-space:nowrap;
}
.ev-all:hover,
.ev-all:focus-visible{text-decoration-color:currentColor}
.ev-all:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

/* ---- the grid ----
   ⚠ `min(260px,100%)` IS THE 1.4.10 FIX AND IT IS NOT DECORATION.
   A bare minmax(260px,1fr) has a HARD MINIMUM of 260px, so in the 252px
   content column a 320px viewport leaves (34px padding a side, 1180px
   cap) every track is 260px wide and the document overflows by 8px. The
   page still looks fine at every width anyone checks by eye, which is
   exactly the failure header.css already documents at 320: a 1.5px
   overflow invisible to a document-level scrollWidth check and found only
   by an element-level scan. min() lets the track collapse to the
   container instead. The 760px branch below is a second line, not the
   only one. */
.ev-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));
  gap:22px;
  margin-top:34px;
}
/* ---- the hub band: THREE COLUMNS FOR TWO CARDS ----
   DIRECTOR'S VERDICT AT THE EVENTS-01 GATE, 2026-09-22.

   The band shows exactly two events. Built first as `repeat(2, 1fr)`, which
   stretched each card to half the 1180px container — about 580px — and read
   sparser than the four-up grid on the listing page.

   Three columns for two cards narrows them and leaves the third cell empty.
   That empty third is the accepted trade-off, chosen deliberately over the two
   alternatives: `repeat(2, 1fr)` (as built, wide) and showing three events
   (which would depart from the brief's "next two").

   ⚠ AND THE NUMBERS ARE MEASURED, NOT THE ONES I PREDICTED. I put "~373px,
   matches the listing page's cards" in front of the director as the rationale
   for this option. MEASURED AT 1440:

       this band, 3 columns    379px
       listing page, 4 columns 279px

   **THEY DO NOT MATCH, AND "matches the listing" WAS WRONG.** The listing runs
   `auto-fill minmax(min(260px,100%), 1fr)` and lands on FOUR tracks in the
   1180px container, not three. R63 — the build disagreed with my number, so the
   build is right and the number was wrong; corrected here rather than left
   standing as the reason for a decision it did not describe.

   THE DECISION ITSELF IS UNAFFECTED AND IS WHAT SHIPPED: cap the columns so two
   cards are not half-width, and accept a visible empty third. 379 delivers that.
   Exact parity with the listing would be `repeat(4, 1fr)` — one character — and
   was NOT chosen, because it leaves two of four cells empty instead of one of
   three. Reported at the gate, 2026-09-22.

   ⚠ IT IS NOT `auto-fill`. At 1180px auto-fill with a 260px minimum yields FOUR
   tracks, so two cards would sit in the left half and the band would read as
   broken rather than as composed. The column count is stated because the ITEM
   COUNT is fixed by the template at two — a grid that derives its width from the
   viewport is wrong for a band whose content count never changes.

   ⚠ AND IT CHANGES NO MARKUP. This is a stylesheet-only decision, so the R147
   enumerated band on /hub is byte-for-byte what it was — hub-diff's excision and
   its eight positive checks are untouched by it. */
.ev-band--compact .ev-grid{grid-template-columns:repeat(3,1fr)}

/* ---- FEWER THAN THREE: COLUMNS FOLLOW THE COUNT, NEVER AN EMPTY TRACK ----
   Director's ruling 2026-09-23, and it is R170's shape: the rule is stated for
   every count the data model permits, not for the count that happens to exist.

   THE BAND IS ONE ROW, AND THAT IS THE WHOLE ARGUMENT. Three tracks holding two
   cards leaves a gap that reads as a card which failed to load, because a single
   row has no established rhythm for an incomplete row to be read against. The
   LISTING page is the contrast that proves it rather than an inconsistency:
   eleven cards in four columns make a last row of three obviously a continuation,
   so the listing needs no modifier and gets none.

   COLUMNS = min(count, 3). Measured against the real data, every one of these
   states arrives on a known date without anyone choosing a fixture — 3 upcoming
   on 2026-10-24, 2 on 2026-11-06, 1 on 2027-01-01, 0 on 2027-01-15.

   ⚠ THE SINGLE CARD IS CAPPED AT THE TWO-UP WIDTH. Left to one 1fr track it would
   span the full 1180px container, and a lone full-bleed card reads as a banner
   rather than as one item in a list. `calc((100% - 22px)/2)` is the two-up track
   width expressed from the gap, so it follows the gap if that ever moves instead
   of freezing a pixel value that would silently stop matching. */
.ev-band--compact .ev-grid--n2{grid-template-columns:repeat(2,1fr)}
.ev-band--compact .ev-grid--n1{grid-template-columns:minmax(0,calc((100% - 22px)/2))}

/* ---- the card ----
   THE WHOLE CARD IS THE LINK, so the box is the <a> and the three lines
   are spans inside it. A card whose title alone is the anchor gives a
   pointing device a small target and a screen reader an anchor named with
   the event name and nothing else.

   display:grid with align-content:start so the three lines sit to the top
   of a card that has been stretched by a taller sibling in its row —
   otherwise a two-line event name in one column pushes the other cards'
   text into vertical centring and the row loses its baseline.

   --ground-alt with --on-alt, the semantic PAIR. The fill sits 1.0694
   against the page ground: this is a quiet surface and the hairline is
   what delineates it, which is the same relationship .hub-list li already
   has with the page. */
.ev-card{
  display:grid;
  align-content:start;
  gap:6px;
  padding:24px;
  background:var(--ground-alt);
  color:var(--on-alt);
  border:1px solid var(--rule-hair);
  transition:border-color .18s ease,transform .18s ease;
}
.ev-card:hover{border-color:var(--pill-hover);transform:translateY(-2px)}

/* 3px, MATCHING THE SITE. join-form.css, accordion.css, header.css,
   why-longitude.css and news.css all ship `outline:3px solid var(--focus)`.
   news.css records authoring 2px here and correcting it: a focus
   indicator thinner on one page than every other reads as intentional to
   a reviewer. */
.ev-card:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

/* ---- the three lines ----
   .ev-when is .hub-date's treatment: mono 13px at .06em in
   --on-page-soft, measured 4.6361 on the cream fill. --on-page-muted was
   not considered — news.css already measured it at 3.1144 on cream and
   3.3306 on paper, short of 4.5 at a size where nothing relaxes the
   requirement, and tokens.css still marks it NO LIVE CONSUMER. */
.ev-when{
  font-family:var(--mono);
  font-size:13px;
  letter-spacing:.06em;
  color:var(--on-page-soft);
}

/* THE NAME CARRIES THE LINKED / UNLINKED DISTINCTION, AND THAT IS R54
   RATHER THAN DECORATION. ev_url is optional — one of the eleven seeded
   events has none — so some cards go somewhere and some do not. Making
   that difference VISIBLE beats leaving it to the cursor: a reader can
   tell at a glance which cards are targets, and an unlinked card is not
   in the tab order and is not announced as a link, so the visual state
   and the semantic state agree.

     linked    --pill-hover  5.0671 on cream
     unlinked  --on-alt      13.0839 on cream

   SERIF, WHERE THE HUB'S ROW TITLES ARE SANS. This is the one type
   decision that makes the band read as cards rather than as a third list,
   and it is the face h1/h2 and .uc h3 already use — not a new one. 18px
   is a fixed size rather than a clamp: a card is a bounded box whose
   width does not track the viewport the way a heading's column does. */
.ev-name{
  font-family:var(--serif);
  font-weight:700;
  font-size:18px;
  line-height:1.3;
  color:var(--pill-hover);
  text-decoration:underline;
  text-underline-offset:3px;
  text-decoration-thickness:1px;
  text-decoration-color:transparent;
  transition:text-decoration-color .18s ease;
}
.ev-card--plain .ev-name{color:var(--on-alt);text-decoration:none}
.ev-card:hover .ev-name,
.ev-card:focus-visible .ev-name{text-decoration-color:currentColor}

/* .hub-outlet's treatment — 15px in --on-page-body, 7.5580 on cream. */
.ev-where{
  font-size:15px;
  color:var(--on-page-body);
}

/* ---- the hero and the empty state, page-events only ----
   .ev-hero is .hub-hero's geometry exactly. The two pages are a parent
   and its child and must not open differently. */
.ev-hero{padding-top:132px;padding-bottom:56px}
.ev-hero h1{max-width:18ch}
.ev-hero .ev-lede{
  margin-top:22px;
  font-size:19px;
  line-height:1.6;
  color:var(--on-page-body);
  max-width:85ch;
}
/* The band with no cards in it. It still carries the band's padding so
   the page's rhythm does not collapse on the one day it has nothing to
   show. 8.0825 on --paper. */
.ev-empty{
  font-size:19px;
  line-height:1.6;
  color:var(--on-page-body);
  max-width:85ch;
}

/* ---- narrow ----
   760px matches news.css's own breakpoint, so the hub does not change
   shape twice on the way down. */
@media(max-width:760px){
  .ev-hero{padding-top:112px;padding-bottom:40px}
  .ev-band{padding-top:48px;padding-bottom:48px}
  /* ⚠ THE COUNT MODIFIERS COLLAPSE HERE TOO. Without them a --n2 grid keeps two
     columns at 320px and the cards overflow the viewport — the 1.4.10 failure the
     min() guard on the listing grid exists to prevent, reintroduced by a modifier
     added later. Named explicitly rather than relying on the base selector, because
     `.ev-band--compact .ev-grid--n2` is (0,3,0) and a bare `.ev-grid` here is
     (0,1,0): a media query adds no specificity, so the lower one would lose. */
  .ev-grid,
  .ev-band--compact .ev-grid,
  .ev-band--compact .ev-grid--n1,
  .ev-band--compact .ev-grid--n2{grid-template-columns:1fr;gap:16px}
  .ev-head{gap:10px}
  .ev-card{padding:20px}
  .ev-name{font-size:17px}
  .ev-empty,
  .ev-hero .ev-lede{font-size:17px}
}

/* ⚠ THE SELECTORS ARE RESTATED IN FULL, AND news.css RECORDS WHY.
   A MEDIA QUERY ADDS NO SPECIFICITY. A step-down written at lower or
   equal specificity than the rule it is stepping down loses on source
   order and silently does nothing — the transition keeps running, the
   preference is ignored, and nothing reports it. `.ev-card:hover` is
   (0,2,0); a bare `.ev-card` here would be (0,1,0) and lose. */
@media(prefers-reduced-motion:reduce){
  .ev-card{transition:none}
  .ev-card:hover{transform:none}
  .ev-name,
  .ev-all{transition:none}
}
