/*
 * Technophobia Events — listing styles.
 *
 * Written to survive being dropped into somebody else's theme: everything is
 * scoped under .tpev, no resets, no !important, and no fixed colours beyond
 * what the poster itself brings. Sizes are generous because a good part of the
 * audience for these listings is reading at arm's length on a phone.
 *
 * ── COLOURS AND SIZES ARE VARIABLES ───────────────────────────────────────
 * Every colour and size below comes from a custom property with a sensible
 * fallback, so there are three ways to change the look and none of them mean
 * editing this file:
 *
 *   1. shortcode attributes — [tp_events colour="#222" title_size="1.4rem"]
 *   2. the builder or theme CSS — .tpev { --tpev-colour: #222 }
 *   3. leave them alone and it inherits the theme, which is the default:
 *      `inherit` for colour and rem-based sizes that follow the site's own.
 *
 * Named --tpev-* so they cannot collide with a theme's variables.
 */

:root,
.tpev {
  --tpev-colour: inherit;          /* all body text in a card            */
  --tpev-title-size: 1rem;         /* the event name                     */
  --tpev-text-size: 0.9rem;        /* date line                          */
  --tpev-meta-size: 0.82rem;       /* location and price                 */
  --tpev-heading-size: 1.6rem;     /* the "What's on" heading            */
  --tpev-accent: #2563eb;          /* tickets button                     */
  --tpev-accent-hover: #1d4ed8;
  --tpev-accent-text: #fff;
  /*
   * Near-opaque, NOT a faint tint. It was rgba(127,127,127,0.06) — invisible —
   * which meant the card was really just text sitting on whatever the page had
   * behind it. On the Palladium's home page that is a video of a pantomime, and
   * the listing was unreadable no matter what colour the text was set to. A
   * card has to be a card: something the words sit ON.
   */
  --tpev-card-bg: rgba(255, 255, 255, 0.94);
  --tpev-radius: 10px;
}

.tpev {
  color: var(--tpev-colour);
  /* Belt to the braces above: inside a flex row, take the space rather than
     shrinking to fit whatever the contents happen to ask for. */
  flex: 1 1 auto;
  min-width: 0;
}

/*
 * The heading takes its colour SEPARATELY from the cards, and that separation
 * is the whole point. Cards carry their own background, so their text only has
 * to work against that. The heading sits directly on the page — which on the
 * Palladium is a video — so it needs its own answer, and setting the listing's
 * text colour dark for the cards was leaving the heading unreadable.
 */
.tpev__heading {
  margin: 0 0 1rem;
  font-size: var(--tpev-heading-size);
  color: var(--tpev-heading-colour, var(--tpev-colour));
  text-align: var(--tpev-heading-align, inherit);
}

.tpev__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

/*
 * A chosen number across. The two media queries are not negotiable and
 * deliberately come after: four events side by side on a phone is four
 * unreadable slivers, so a set number is a DESKTOP instruction only.
 *
 * ── WHY minmax AND NOT PLAIN 1fr ──────────────────────────────────────────
 * This is what made the Palladium's listing disappear. Their section is laid
 * out as a FLEX ROW, so the block holding this shortcode is a flex item whose
 * width comes from its content. A grid of plain `1fr` tracks has a min-content
 * width of nothing, and the card no longer contributes any either — the poster
 * image is width:100% inside a ratio box, so it has no intrinsic size to offer.
 * Nothing asking for width, in a container that sizes itself to whatever asks:
 * the whole listing computed to zero and vanished, while sitting there in the
 * HTML the entire time.
 *
 * A track minimum gives it something real to be. It cannot collapse again, in
 * anyone's builder, whatever they have wrapped around it.
 */
.tpev__grid--cols {
  grid-template-columns: repeat(var(--tpev-cols, 3), minmax(150px, 1fr));
}

@media (max-width: 900px) {
  .tpev__grid--cols {
    grid-template-columns: repeat(2, minmax(140px, 1fr));
  }
}

@media (max-width: 580px) {
  .tpev__grid--cols {
    grid-template-columns: 1fr;
  }
}

/* ---- the slider ---------------------------------------------------------
 * One row, showing however many were asked for, with the rest a swipe away.
 *
 * Built on ordinary overflow and scroll-snap rather than a carousel library:
 * it works before any JavaScript loads, it swipes natively on a phone, it can
 * be scrolled with a trackpad, and a keyboard reaches every card because they
 * are still real links in the normal order. The script only adds arrows for a
 * mouse user, who has none of those.
 */
.tpev__rail {
  position: relative;
}

.tpev__grid--slider {
  grid-auto-flow: column;
  grid-template-columns: none;
  /* Same floor as the grid above, and for the same reason. */
  grid-auto-columns: minmax(150px, calc((100% - (var(--tpev-cols, 3) - 1) * 1rem) / var(--tpev-cols, 3)));
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Room for the shadow of a card, which a scroll container would clip. */
  padding-bottom: 0.6rem;
  scrollbar-width: thin;
}

.tpev__grid--slider > .tpev__card {
  scroll-snap-align: start;
}

@media (max-width: 900px) {
  .tpev__grid--slider {
    grid-auto-columns: minmax(140px, calc((100% - 1rem) / 2));
  }
}

@media (max-width: 580px) {
  /* One at a time, but showing a sliver of the next — the only reliable hint
     that there IS a next, now the arrows are gone. */
  .tpev__grid--slider {
    grid-auto-columns: 86%;
  }
}

.tpev__arrow {
  position: absolute;
  top: calc(50% - 22px);
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--tpev-accent);
  color: var(--tpev-accent-text);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

.tpev__arrow--prev {
  left: -10px;
}

.tpev__arrow--next {
  right: -10px;
}

.tpev__arrow:disabled {
  opacity: 0;
  pointer-events: none;
}

/* Touch already swipes, and an arrow that size would sit on top of a poster. */
@media (max-width: 580px) {
  .tpev__arrow {
    display: none;
  }
}

.tpev__card {
  display: flex;
  flex-direction: column;
  border-radius: var(--tpev-radius);
  overflow: hidden;
  background: var(--tpev-card-bg);
}

/*
 * EVERY poster occupies the same box, whatever shape it arrived in.
 *
 * It used to be `height:auto` with a max-height, which meant a portrait A4 scan
 * came out tall, a square social crop came out short, and an event with no
 * poster at all had no image area whatsoever. Three cards in a row, three
 * different heights, one of them starting halfway up — a listing that looks
 * broken rather than busy.
 *
 * A fixed ratio with object-fit:cover fixes the row. Cropping is the right
 * trade here: a poster's own title is nearly always in its top half, so the
 * part that gets trimmed is the small print that nobody could read at this size
 * anyway, and the full thing is one tap away on the event's page.
 */
.tpev__poster {
  display: block;
  line-height: 0;
  aspect-ratio: var(--tpev-poster-ratio, 4 / 3);
  /*
   * And a hard ceiling on top of the ratio. A ratio alone is a TRAP on a wide
   * page: three cards across a 1400px layout are ~440px wide, and at any
   * upright ratio that is a poster taller than most people's screen. The cap
   * wins on a desktop, the ratio governs on a phone, and the row stays level
   * either way because every card is capped identically.
   */
  max-height: var(--tpev-poster-max, 190px);
  /*
   * A floor as well as a ceiling. aspect-ratio needs a definite width to work
   * from, and inside somebody else's builder — a flex row, a slider cell, a
   * section that has been given its own height — that width is not always
   * resolvable. When it is not, the box computes to nothing and the card
   * vanishes: present in the HTML, invisible on the page, which is the worst
   * kind of bug to be told about.
   */
  min-height: 120px;
  overflow: hidden;
  background: rgba(127, 127, 127, 0.12);
}

.tpev__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/*
 * No poster, and no default set for the site: the date fills the space instead.
 *
 * Better than a grey rectangle or a stock photograph of nothing — an event
 * without a poster is usually the regular weekly thing that never had one, and
 * the date is what somebody is looking for anyway. It also keeps the row even,
 * which is the whole point.
 *
 * QUIET, though. The first version filled the whole box with the accent colour
 * and a 4.5rem number, and three of those in a row shouted down the one event
 * that actually had a poster — the opposite of the job. A placeholder's whole
 * purpose is to hold a space, not to compete for it. So: a faint tint of the
 * card it sits in, muted text, and a date at a size that reads as "nothing
 * here yet" rather than as a headline.
 */
.tpev__poster--date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1;
  background: var(--tpev-empty-bg, rgba(127, 127, 127, 0.09));
  color: var(--tpev-colour);
  text-decoration: none;
}

.tpev__poster--date .tpev__poster-day {
  font-size: 1.6rem;
  font-weight: 600;
  opacity: 0.45;
}

.tpev__poster--date .tpev__poster-month {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-top: 0.3rem;
  opacity: 0.35;
}


.tpev__body {
  padding: 0.7rem 0.8rem 0.85rem;
}

.tpev__title {
  margin: 0 0 0.25rem;
  font-size: var(--tpev-title-size);
  line-height: 1.25;
}

.tpev__title a {
  text-decoration: none;
  color: inherit;
}

.tpev__title a:hover,
.tpev__title a:focus {
  text-decoration: underline;
}

/* The date is the thing people scan for, so it is not dimmed into the noise. */
.tpev__when {
  margin: 0 0 0.2rem;
  font-weight: 600;
  font-size: var(--tpev-text-size);
}

.tpev__meta {
  margin: 0;
  opacity: 0.75;
  font-size: var(--tpev-meta-size);
}

.tpev__cta {
  display: inline-block;
  margin-top: 0.6rem;
  padding: 0.4rem 0.85rem;
  border-radius: 6px;
  background: var(--tpev-accent);
  color: var(--tpev-accent-text);
  text-decoration: none;
  font-weight: 600;
}

.tpev__cta:hover,
.tpev__cta:focus {
  background: var(--tpev-accent-hover);
  color: var(--tpev-accent-text);
}

/*
 * "Nothing listed just yet."
 *
 * This used to be dimmed to 0.75 opacity, which is fine on a plain page and
 * useless anywhere interesting. On the Palladium it landed over an autoplaying
 * video of a pantomime and simply could not be read — and it is the one message
 * on the page that MUST be readable, because a visitor who cannot read it is
 * left staring at an empty band wondering whether the site is broken.
 *
 * So this one element is SELF-CONTAINED: it brings its own near-opaque panel
 * and its own dark text, rather than inheriting --tpev-colour like everything
 * else. That is deliberate. Inheriting is right for the cards, which sit on the
 * page's own background — but the whole problem here is that nobody knows what
 * is behind this message, and the theatre's own listing proved it by setting
 * the text to #1a1a1a and then putting it over a video. A panel that carries
 * its own contrast cannot be defeated that way.
 *
 * Both halves are still overridable, from Events → Settings or the shortcode,
 * for a site where a white panel would look wrong.
 */
.tpev__empty {
  margin: 0;
  padding: 0.95rem 1.15rem;
  border-radius: var(--tpev-radius);
  background: var(--tpev-empty-bg, rgba(255, 255, 255, 0.92));
  color: var(--tpev-empty-colour, #1f1f1f);
  border: 1px solid rgba(0, 0, 0, 0.08);
}

/* ---- one event's own page -----------------------------------------------
 * Dropped into whatever hole the builder left, so it assumes nothing about the
 * width or background around it and brings no page furniture of its own.
 */

.tpev-single {
  max-width: 760px;
  margin: 0 auto 1.5rem;
}

.tpev-single__title {
  margin: 0 0 1rem;
  font-size: var(--tpev-heading-size);
  line-height: 1.2;
}

.tpev-single__poster {
  margin: 0 0 1.5rem;
}

/*
 * Capped rather than stretched. These are phone photographs of A4 posters, and
 * blowing one up to 760px wide fills the screen with something unreadable and
 * pushes every actual detail below the fold.
 */
.tpev-single__poster img {
  display: block;
  max-width: 100%;
  max-height: 60vh;
  width: auto;
  height: auto;
  margin: 0 auto;
  border-radius: var(--tpev-radius);
}

.tpev-single__facts {
  margin: 0 0 1.5rem;
  display: grid;
  gap: 0.75rem;
}

/* Label above value, not beside: "Where" against a long venue name in two
   columns leaves a river of white space down the middle on a phone. */
.tpev-single__fact dt {
  font-weight: 700;
  font-size: var(--tpev-meta-size);
  opacity: 0.7;
  margin: 0;
}

.tpev-single__fact dd {
  margin: 0.1rem 0 0;
  font-size: var(--tpev-text-size);
}

.tpev-single__desc {
  font-size: var(--tpev-text-size);
}

.tpev-single__cta {
  margin: 1.5rem 0 0;
}

/* ---- the submission form ------------------------------------------------
 * Big targets and real labels. This is filled in by volunteers, often on a
 * phone, sometimes standing in the foyer — so nothing here is a tiny control
 * or relies on a placeholder to say what a field is.
 */

.tpev-form {
  max-width: 640px;
}

.tpev-f {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0 0 1.1rem;
}

.tpev-f label {
  font-weight: 600;
}

.tpev-f input[type="text"],
.tpev-f input[type="url"],
.tpev-f input[type="datetime-local"],
.tpev-f textarea {
  width: 100%;
  padding: 0.6rem 0.7rem;
  font-size: 1rem;
  border: 1px solid rgba(127, 127, 127, 0.5);
  border-radius: 6px;
  background: #fff;
  color: #111;
}

.tpev-f small {
  opacity: 0.7;
  font-size: 0.85rem;
}

.tpev-req {
  color: #b91c1c;
}

/* Two-up on a desktop, stacked on a phone — never side by side when narrow. */
.tpev-f-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1rem;
}

@media (min-width: 560px) {
  .tpev-f-row {
    grid-template-columns: 1fr 1fr;
  }
}

/*
 * The honeypot. Off-screen rather than display:none — some bots skip hidden
 * fields but happily fill a positioned one.
 */
.tpev-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.tpev-form__ok {
  padding: 1rem 1.1rem;
  border-radius: 8px;
  background: rgba(38, 138, 84, 0.12);
  margin-bottom: 1.2rem;
}

.tpev-form__ok h3 {
  margin: 0 0 0.3rem;
}

.tpev-form__err {
  padding: 0.9rem 1.1rem;
  border-radius: 8px;
  background: rgba(185, 28, 28, 0.1);
  margin-bottom: 1.2rem;
}

.tpev-form__err ul {
  margin: 0;
  padding-left: 1.1rem;
}

.tpev-form__note {
  opacity: 0.75;
}

.tpev-form button.tpev__cta {
  border: 0;
  cursor: pointer;
  font-size: 1rem;
}

/* ---- signing in ---------------------------------------------------------
 * The sign-in screen is a centred card, deliberately narrower than the event
 * form. It only asks for two things, and two short fields stranded at the left
 * edge of a 640px block read as a page that half-loaded rather than as
 * something to fill in. Centring it and drawing an edge round it says "this is
 * the bit", which is the whole job on a page a venue reaches once and then
 * hopefully never thinks about again.
 */

.tpev-form--auth {
  max-width: 26rem;
  margin: 2.5rem auto;
  padding: 1.75rem 1.5rem 1.5rem;
  border-radius: var(--tpev-radius);
  background: var(--tpev-card-bg);
  border: 1px solid rgba(127, 127, 127, 0.18);
  text-align: center;
}

.tpev-form--auth h3 {
  margin: 0 0 0.4rem;
  font-size: var(--tpev-heading-size);
  line-height: 1.25;
}

.tpev-form--auth h3 + p {
  margin: 0 0 1.4rem;
  opacity: 0.75;
}

/*
 * The card is centred; its contents are not. A centred label sitting above a
 * full-width input looks like a mistake, and messages are prose — both read
 * far better ranged left.
 */
.tpev-form--auth .tpev-f,
.tpev-form--auth .tpev-form__err,
.tpev-form--auth .tpev-form__ok {
  text-align: left;
}

.tpev-form--auth .tpev-f:last-of-type {
  margin-bottom: 1.3rem;
}

.tpev-form--auth .tpev__cta {
  width: 100%;
  margin-top: 0;
  padding: 0.65rem 1rem;
}

/* Separated by a rule, because it is the other way in rather than a footnote. */
.tpev-form--auth .tpev-form__note {
  margin: 1.3rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(127, 127, 127, 0.18);
  font-size: 0.95rem;
}

/*
 * Looks like a link because it behaves like one. It stays a real submit button
 * on purpose: the sign-in link is issued by the same POST handler as the form
 * it sits in, and an <a> would mean a second route and a GET request that
 * changes something — which is exactly what link-prefetching breaks.
 */
.tpev-linkbtn {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--tpev-accent);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.tpev-linkbtn:hover,
.tpev-linkbtn:focus {
  color: var(--tpev-accent-hover);
}
