/*
  Happening This Week — the standalone /events page.
  ==================================================

  Loaded AFTER /style.css, and that order is load-bearing rather than tidy.
  Several rules here override bare element selectors in that file (`body`, `a`,
  `button`, `footer`) at equal specificity, so source order is what decides.
  If these two ever swap places in events.html the page keeps the reader's 14.5px
  body text and this whole file silently does half its job.

  What this file does NOT do is define a palette. Every colour below comes from
  the newzpaper block in style.css — one definition of newsprint, checked by
  test-contrast.mjs, rather than a second copy here drifting away from it.

  ---- the design, stated once so the rules below can be checked against it ----

  COLOUR   The newzpaper palette untouched: --bg #e9e2d0 aged newsprint,
           --fg #14110b ink, --line for rules, --accent-2 sepia for the
           secondary marks, and --hot (an aged red) as the ONE spot colour.
           A letterpress paper printed exactly one extra plate and spent it on
           what was urgent; here that is today, the weather warnings, and where
           the reader's focus is. Nothing decorative gets the red.

  TYPE     Three faces, all already in the palette and none of them a webfont:
           --nameplate (blackletter) for the masthead only; --woodtype (heavy
           condensed) for the banner and the day headings, which is where a
           real listings page shouts; Times for every listing, because a whole
           page of condensed type is a poster, not something you read.

  LAYOUT   One column, centred on a measure, at a size that starts LARGE.
           Today is the hero and runs full width as a single ordered list —
           deliberately not multi-column, because a reader who needs the big
           setting should never have to find the top of a second column. The
           rest of the week is a grid of day cards, which is an index rather
           than a read.

  ---- legibility, which is the actual brief ----

  This page was built for a reader with aged eyes, so a few of the choices below
  are the opposite of the ones the dense reader makes, and they are marked where
  they occur. The three that matter:

    - **Nothing important is dimmed.** The reader dims events that have already
      started; here they keep full contrast and are separated by a labelled rule
      instead. Low contrast is the first thing to fail an ageing eye, and
      "greyed out" is a convention that assumes you can still read the grey.
    - **Size is a control, not a zoom.** Browser zoom reflows the whole page
      including the chrome; this scales the type and lets the layout re-fit
      around it, so the largest setting still shows a whole listing per line.
    - **Hit targets are generous** — every control is at least 2.2em tall, and
      every listing title is a link with padding rather than a bare line of
      text, because a slightly unsteady tap should still land.
*/

/* ---------------------------------------------------------------------------
   Size: three steps, stamped on <html> before paint by events-boot.js.

   The DEFAULT IS ALREADY LARGE. `m` is the middle of this page's own range, not
   a step down from the rest of the site — `s` here is roughly what the reader
   calls normal. That framing is the point: the largest setting should not feel
   like asking for an accommodation.

   Everything downstream is in `em`, so a step changes the page rather than just
   the paragraphs — the time gutter, the card widths and the gaps all move with
   it, and the grid re-fits by itself with no breakpoint involved.
   --------------------------------------------------------------------------- */
:root {
  /* The fallback matters: if events-boot.js is blocked or fails, the page must
     still come up large rather than at the UA default. */
  --ev-base: 20px;
  --ev-pad: 20px;
  --ev-measure: 64em;
  --ev-hair: color-mix(in srgb, var(--line) 24%, transparent);
  --ev-hair-firm: color-mix(in srgb, var(--line) 45%, transparent);
}
html[data-size="s"] { --ev-base: 16px; }
html[data-size="m"] { --ev-base: 20px; }
html[data-size="l"] { --ev-base: 25px; }

/* Beats `[data-theme="newzpaper"] body` on source order — see the file header. */
body.ev-body {
  font-size: var(--ev-base);
  line-height: 1.5;
  /* The reader's paper stock and vignette come from style.css and are wanted
     here unchanged; only the scale is this page's business. */
}

/* The page's one shared measure, applied with the reader's idiom: above the
   measure the padding becomes the leftover margin, below it collapses to the
   gutter and the block goes fluid. No breakpoint, no resize listener. */
.ev-mast,
.ev-weather,
.ev-controls,
.ev-found,
#ev-main,
.ev-foot {
  padding-inline: max(var(--ev-pad), calc((100% - var(--ev-measure)) / 2));
}

/* ---------------------------------------------------------------------------
   Skip link. A page with a masthead, a weather line and two controls in front
   of the content needs one, and it is the cheapest accessibility win there is.
   --------------------------------------------------------------------------- */
.ev-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--fg);
  color: var(--bg);
  padding: 0.7em 1.2em;
  font-size: 1em;
}
.ev-skip:focus {
  left: 0;
  color: var(--bg);
  text-decoration: none;
}

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

/* ---------------------------------------------------------------------------
   The masthead.

   Nameplate, folio rule, banner, standfirst — the stack a listings page
   actually prints. It is NOT sticky. The reader's masthead is, and pays for it
   with --head-h measurement, a scroll sentinel and a documented feedback loop
   between the bar's height and the document's; none of that buys anything on a
   page you scroll once and read.
   --------------------------------------------------------------------------- */
.ev-mast {
  padding-top: 1.4em;
  padding-bottom: 0.4em;
  text-align: center;
}

.ev-nameplate {
  display: block;
  font-family: var(--nameplate);
  /* Mixed case, never uppercased. Blackletter capitals are the fully decorated
     forms, drawn to be used once at the head of a word — a run of them is close
     to unreadable, which is why every real blackletter nameplate is mixed case.
     The source string is already natural case, so this only has to not undo it. */
  text-transform: none;
  font-weight: 400;
  line-height: 1.02;
  /* Scales with the viewport, not with --ev-base: the nameplate is the one
     thing here that is a picture rather than something to read, and it should
     not double in height because a reader wanted bigger listings. */
  font-size: clamp(2rem, 7vw, 4.2rem);
  color: var(--fg);
  letter-spacing: 0.01em;
}
.ev-nameplate:hover,
.ev-nameplate:focus-visible {
  color: var(--fg);
  text-decoration: none;
}

/* The folio line: a date between two rules, which is how a paper dates a page.
   Grid rather than flex so the two rules genuinely share the leftover width —
   with flex they would each need a grow factor and the date would drift off
   centre as its own length changed through the week. */
.ev-folio {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.9em;
  margin: 0.5em 0 0.9em;
}
/* A double rule drawn as one 3px box with a border top and bottom, so the
   1px gap between them is the box's own height rather than a second element. */
.ev-rule {
  height: 3px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.ev-folio-date {
  font-size: 0.85em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-dim);
  white-space: nowrap;
}

.ev-banner {
  font-family: var(--woodtype);
  /* Condensed display faces are drawn heavy and have no true bold; asking for
     700 gets a synthesised smear that fills in the counters. */
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  line-height: 0.95;
  font-size: clamp(2.4rem, 9vw, 5.6rem);
  margin: 0 0 0.18em;
  text-wrap: balance;
  color: var(--fg);
}

.ev-standfirst {
  margin: 0 auto;
  max-width: 46ch;
  font-size: 1em;
  line-height: 1.5;
  color: var(--fg-dim);
  font-style: italic;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
   Weather. One line, boxed, because half of these events are outdoors and the
   question "do I need a coat" is the second thing anyone asks after "what time".
   --------------------------------------------------------------------------- */
.ev-weather {
  margin: 1.4em auto 0;
  border-top: 3px double var(--line);
  border-bottom: 3px double var(--line);
  padding-block: 0.7em;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35em 1.1em;
  font-size: 1em;
}
.ev-wx-temp {
  font-size: 1.5em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.ev-wx-cond { text-transform: capitalize; }
.ev-wx-range {
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.ev-wx-place {
  color: var(--fg-dim);
  font-style: italic;
}
.ev-wx-detail {
  flex: 1 0 100%;
  color: var(--fg-dim);
  font-size: 0.92em;
  line-height: 1.45;
  text-wrap: pretty;
}
/* The one spot colour, spent on the one thing that can change whether you go. */
.ev-wx-alert {
  flex: 1 0 100%;
  color: var(--hot);
  font-weight: 700;
}
.ev-wx-alert a { color: var(--hot); text-decoration: underline; }

/* ---------------------------------------------------------------------------
   Controls: find, and text size.
   --------------------------------------------------------------------------- */
.ev-controls {
  margin-top: 1.2em;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1em 2em;
  justify-content: space-between;
}
.ev-label {
  display: block;
  font-size: 0.8em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 0.3em;
}
.ev-find { flex: 1 1 18em; }

/* An id selector so style.css's `#filter` rules cannot reach it, and so this
   one does not need to fight them. */
#ev-filter {
  width: 100%;
  font: inherit;
  font-size: 1.05em;
  padding: 0.55em 0.7em;
  min-height: 2.3em;
  color: var(--fg);
  background: var(--bg-alt);
  border: 2px solid var(--line);
  border-radius: 0;
}
#ev-filter::placeholder { color: var(--fg-faint); font-style: italic; }

.ev-size-buttons { display: flex; gap: 0.4em; }

/* The three buttons show the letter at the size they set, which is the whole
   affordance — a reader does not have to decode "A−/A+", they can see which one
   they want. The label is still there for a screen reader. */
button.ev-size-btn {
  font-family: var(--body-font);
  min-width: 2.4em;
  min-height: 2.4em;
  padding: 0.15em 0.5em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  color: var(--fg);
  background: var(--bg-alt);
  border: 2px solid var(--line);
  border-radius: 0;
  cursor: pointer;
}
button.ev-size-btn[data-size="s"] { font-size: 0.85em; }
button.ev-size-btn[data-size="m"] { font-size: 1.15em; }
button.ev-size-btn[data-size="l"] { font-size: 1.5em; }
button.ev-size-btn:hover:not(:disabled) {
  color: var(--fg);
  border-color: var(--line);
  background: color-mix(in srgb, var(--fg) 8%, var(--bg-alt));
}
/* Current state is reverse type, not a tint: it has to survive a reader who
   cannot pick two beiges apart, and reverse type is how a paper says "this one"
   without a second colour. */
button.ev-size-btn[aria-pressed="true"] {
  background: var(--fg);
  color: var(--bg);
  border-color: var(--fg);
}

.ev-found {
  margin: 0.9em auto 0;
  min-height: 1.5em;
  font-style: italic;
  color: var(--fg-dim);
}
.ev-found:empty { min-height: 0; margin-top: 0; }

/* ---------------------------------------------------------------------------
   The listings.
   --------------------------------------------------------------------------- */
#ev-main {
  display: block;
  padding-block: 1.2em 2em;
}
.ev-loading, .ev-empty {
  padding: 2em 0;
  font-style: italic;
  color: var(--fg-dim);
  font-size: 1.05em;
}
.ev-error {
  padding: 1em 0;
  color: var(--hot);
  font-weight: 700;
}

.ev-day { margin-bottom: 1.8em; }

/* Day heading: wood type, with the count as a plain fact beside it. The rule
   under it is a double for today and a single hairline for the rest — the
   hierarchy is in the rule weight, the way a printed page does it, rather than
   in a colour a reader might not separate. */
.ev-day-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.2em 0.7em;
  border-bottom: 1px solid var(--ev-hair-firm);
  padding-bottom: 0.25em;
  margin-bottom: 0.5em;
}
.ev-day-name {
  font-family: var(--woodtype);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1;
  font-size: 1.6em;
}
.ev-day-date {
  font-size: 0.95em;
  color: var(--fg-dim);
  font-style: italic;
}
.ev-day-count {
  margin-left: auto;
  font-size: 0.85em;
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ev-day--today .ev-day-head {
  border-bottom: 4px double var(--line);
  padding-bottom: 0.3em;
}
.ev-day--today .ev-day-name {
  font-size: 2.1em;
  color: var(--hot);
}

.ev-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A listing. The time is a fixed gutter so the titles form one edge down the
   page — that vertical line is what makes a long list scannable, and it is the
   first thing lost if the time is allowed to size itself. */
.ev-item {
  display: grid;
  grid-template-columns: 5.4em 1fr;
  gap: 0 0.9em;
  align-items: baseline;
  padding: 0.55em 0;
  border-top: 1px solid var(--ev-hair);
}
.ev-list > .ev-item:first-child { border-top: 0; }

.ev-when {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--fg);
  white-space: nowrap;
}
.ev-when--allday {
  font-weight: 400;
  font-style: italic;
  color: var(--fg-dim);
  /* "all day" does not fit the gutter at the large setting, and shrinking the
     gutter to fit it would cost every other row its alignment. */
  font-size: 0.82em;
}

.ev-what { min-width: 0; }

.ev-title {
  color: var(--link);
  font-size: 1.05em;
  line-height: 1.35;
  text-decoration: none;
  /* A generous target: a slightly unsteady tap should still land on the link
     rather than between two of them. */
  display: inline-block;
  padding: 0.1em 0;
  text-wrap: pretty;
}
.ev-title:hover, .ev-title:focus-visible {
  color: var(--link-hover);
  text-decoration: underline;
}
/* Not every listing has somewhere to link to. It must not look like a broken
   link, so it simply isn't one. */
.ev-title--plain { color: var(--fg); }

/* The concert mark is a glyph and not a colour, so it survives a colour-blind
   reader and a black-and-white print. */
.ev-kind {
  color: var(--accent-2);
  font-size: 1.05em;
}

.ev-meta {
  display: block;
  font-size: 0.92em;
  line-height: 1.4;
  color: var(--fg-dim);
  margin-top: 0.05em;
}
.ev-venue { font-style: italic; }
.ev-price {
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.ev-repeats { color: var(--accent-2); }
.ev-note {
  font-size: 0.9em;
  color: var(--fg-dim);
  line-height: 1.4;
  text-wrap: pretty;
}

/* What has already started.

   The dense reader dims these. This page does not: it separates them with a
   labelled rule and leaves the contrast alone. Dimming is a convention that
   quietly assumes the reader can still read the dimmed version, which is the
   assumption this page exists to stop making. */
.ev-earlier {
  margin-top: 1.1em;
  padding-top: 0.4em;
  border-top: 3px double var(--ev-hair-firm);
  font-style: italic;
  color: var(--fg-dim);
  font-size: 0.95em;
}

.ev-nothing {
  padding: 0.6em 0;
  font-style: italic;
  color: var(--fg-dim);
}

/* ---------------------------------------------------------------------------
   The rest of the week: an index, so it may be columns.

   auto-fill rather than a literal count, and `min(100%, 24em)` in the minmax so
   a single card cannot overflow a narrow screen — a bare 24em floor makes the
   track wider than the viewport on a phone and the page scrolls sideways.

   Today is deliberately NOT in this grid. It is the answer to the question the
   page was opened to ask, and it stays one full-width column so that the
   largest text setting never asks a reader to find the top of a second column.
   --------------------------------------------------------------------------- */
/* Multi-column, NOT grid, and the reason is the same one the reader's briefs
   band documents. A grid fills left-to-right, so seven days in two tracks read
   Sat–Sun across, then Mon–Tue underneath; `columns` fills top-to-bottom, so
   column one is Saturday through Monday **in order** and the eye runs down it
   the way it runs down a printed listings column.

   It also packs. A grid gives every row the height of its tallest day, so a
   quiet Sunday beside a loaded Saturday leaves a hole before Monday can start.
   Multi-column has no rows to leave holes in.

   `24em 2` makes the width a target and the count a CEILING — as many columns
   as fit, never more than two. Two is the limit for a page set this large: a
   third column at 25px type puts the first listing of Thursday somewhere below
   the fold and to the right, which is the opposite of scannable. */
.ev-week {
  columns: 24em 2;
  column-gap: 3em;
  column-rule: 1px solid var(--ev-hair-firm);
}
/* Or a day splits across the column break, putting Tuesday's morning at the
   foot of one column and its afternoon at the head of the next under no
   heading at all. */
.ev-week > .ev-day { break-inside: avoid; }

.ev-weekhead {
  margin: 2.2em 0 1em;
  border-top: 4px double var(--line);
  padding-top: 0.5em;
  font-family: var(--woodtype);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 1.5em;
  letter-spacing: 0.01em;
}

/* ---------------------------------------------------------------------------
   Footer, overriding style.css's bare `footer` rule at equal specificity.
   --------------------------------------------------------------------------- */
footer.ev-foot {
  border-top: 3px double var(--line);
  margin-top: 1em;
  padding-block: 1.2em 3em;
  font-size: 0.9em;
  color: var(--fg-dim);
  line-height: 1.5;
  text-align: left;
}
footer.ev-foot p { margin: 0 0 0.5em; max-width: 60ch; }
footer.ev-foot a { color: var(--fg); text-decoration: underline; }
.ev-foot-note { font-style: italic; }

/* ---------------------------------------------------------------------------
   Focus. Thick, in the spot colour, and never `outline: none` anywhere in this
   file — a keyboard reader on a page built for accessibility should not be the
   one person who cannot tell where they are.
   --------------------------------------------------------------------------- */
.ev-body :focus-visible {
  outline: 3px solid var(--hot);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   Narrow screens. One override, because the layout is fluid by construction:
   the measure idiom collapses to the gutter on its own and the week grid falls
   to one column on its own. What does NOT solve itself is the time gutter —
   5.4em of a 20px face is 108px out of a 390px screen, which leaves a title
   about twenty characters wide.
   --------------------------------------------------------------------------- */
@media (max-width: 34em) {
  :root { --ev-pad: 14px; }
  .ev-item {
    grid-template-columns: 1fr;
    gap: 0.1em;
    padding: 0.7em 0;
  }
  .ev-when { font-size: 0.95em; }
  .ev-controls { gap: 0.9em 1em; }
  .ev-find { flex: 1 1 100%; }
}

/* ---------------------------------------------------------------------------
   Print. A page like this genuinely gets printed and carried around, and the
   default would waste a sheet on the masthead art and print every link's
   underline in grey. Drop the furniture, keep the listings, and let the paper
   be paper — the stock and the vignette are screen effects.
   --------------------------------------------------------------------------- */
@media print {
  body.ev-body {
    background: #fff;
    background-image: none;
    color: #000;
    font-size: 11pt;
  }
  .ev-skip, .ev-controls, .ev-found, .ev-weather, .ev-standfirst { display: none; }
  .ev-nameplate { font-size: 28pt; }
  .ev-banner { font-size: 24pt; }
  .ev-week { display: block; }
  .ev-day { break-inside: auto; }
  .ev-item { break-inside: avoid; }
  .ev-title, .ev-title--plain { color: #000; text-decoration: none; }
  footer.ev-foot { border-top: 1pt solid #000; }
}
