/*
 * Deliberate deviations from the captured stylesheet.
 *
 * layout.css is live's own CSS, kept byte-for-byte so the rebuild renders as the original does
 * and so it can be re-captured without losing our work. Anything we choose to do differently
 * belongs here instead, with the reason written down — a rule changed in layout.css would look
 * like part of the capture and disappear the next time it is taken.
 *
 * Loaded straight after it, so plain specificity is enough.
 */

/*
 * A validation message needs the room its words take.
 *
 * layout.css caps every message box at 2rem, which is two lines. Under the three dimension
 * fields — Length, Beam and Height, side by side in narrow columns — "Enter length in right
 * format(use a . for decimals)" runs to four, and the overflow printed straight over the WEIGHT
 * row beneath it. Live has the same overlap; this is a deviation on purpose, not a repair of
 * something we broke.
 *
 * The cap stays, so the box still animates open rather than jumping, but it is now high enough
 * for the longest message the form carries.
 */
.form__validation-error.has-error {
  max-height: 8rem;
}

/*
 * A unit selector only has to fit a unit.
 *
 * What makes it wide is the select's own padding: `0 2rem 0 1rem` in layout.css — 48px of gutter
 * around the word "m", a gutter sized for the full-width fields this class also styles. The
 * container then holds a `min-width: 110px` that every field inherits.
 *
 * Two earlier attempts guessed elsewhere and were wrong: the min-width alone changed nothing,
 * and the flex growth was never the cause — layout.css already gives this container
 * `flex: 0 0 auto`. Trimmed to its content instead: enough left padding to sit off the border,
 * enough right to clear the arrow (which is drawn at `right: 16px`, 10px wide), and no floor,
 * so "m" is the width of "m" and "EUR" the width of "EUR".
 */
.form__input-inline .form__input-container--select,
.form__input-container--select {
  min-width: 0;
}

.form__input-container--select .form__select {
  /* A number rather than `auto`: a select sized to its content is at the browser's discretion,
     and this has to be the same everywhere. 5rem holds "EUR" — the longest unit on the form —
     with the arrow beside it. */
  width: 5rem;
  min-width: 0;
  padding: 0 1.9rem 0 0.6rem;
}

/*
 * And a little air under it.
 *
 * With the cap raised, the three-line message under a narrow dimension field ends flush against
 * the WEIGHT row below — no longer printed over it, but close enough to read as one block.
 */
.form__validation-error.has-error {
  margin-bottom: 0.5rem;
}

/*
 * The port search.
 *
 * Live turns these two selects into select2 boxes, and this rebuilds that shape by hand — see
 * lib/port-search.ts. Everything that makes it LOOK like live is already in layout.css: the
 * magnifier in the search field, the 40px rows, the panel border, the bold on a match. What the
 * capture did not bring across is select2's own structural CSS, so only the few rules that
 * position the thing are here. Do not restyle it; extend layout.css's own selectors instead.
 */

/* The panel hangs under the box. layout.css already pins its edges with !important; without a
   position those rules have nothing to work against and the panel lands in the page flow. */
.form__select2 .select2-container--open {
  position: absolute;
}

.form__select2 .select2-search--dropdown {
  display: block;
}

.form__select2 .select2-results__options {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The row the arrow keys are on. layout.css styles :hover and :focus, and neither is true of a
   row reached from the keyboard while the search field keeps the focus. */
.form__select2 .select2-results__option.is-highlighted {
  background: #f1f1f1;
}

.form__select2 .select2-selection {
  cursor: pointer;
}

/*
 * A hero grows to fit its description.
 *
 * The CMS lets an editor put a picture in a page's description — that description is the hero's
 * body (`.header__description`), and on desktop the hero cannot grow to hold one. layout.css
 * pins `.header__container` with `position:absolute; top:50%; transform:translate(-50%,-50%)`
 * from 768px up, so nothing inside it counts towards the hero's height: the hero stays at its
 * `min-height` (450px for `header--image`, 220px otherwise) and `overflow:hidden` cuts whatever
 * sticks out. A 1024x697 picture in a news description was clipped 360px short, and text added
 * around it changed nothing, because out-of-flow content cannot make its parent taller.
 *
 * Put back in flow, with the vertical centring the absolute positioning was there for done by
 * flex instead. Below 768px layout.css already leaves the container `position:relative`, so this
 * only concerns desktop.
 *
 * Measured against the captured layout on the wizard/plain/image hero variants: while the
 * content is shorter than the hero's min-height, flex centring puts the container, heading,
 * content and back link on exactly the same pixels as the absolute centring did. The one hero
 * where the two disagree is the homepage's, whose `header--wizard` carries an asymmetric
 * `padding-bottom:4rem` that absolute centring ignores and flex does not — it would have moved
 * the heading up 32px, so it is left as captured.
 */
@media only screen and (min-width: 768px) {
  .header:not(.header--wizard) {
    display: flex;
    justify-content: center;
  }

  .header:not(.header--wizard) .header__container {
    position: relative;
    top: auto;
    left: auto;
    transform: none;
    /* 90% of a hero that no longer has a fixed height is not a limit worth keeping. */
    max-height: none;
  }

  /*
   * Room around a hero that has actually outgrown its banner — the picture case, and only it.
   * The hero has no vertical padding of its own above 768px, so applying this to every hero
   * would make a whole site's worth of them taller than the capture; scoped here, the only
   * heroes that move are the ones this fix is for. The bottom is the larger of the two because
   * the "Go back" link sits over it, pinned 1rem from the hero's bottom edge.
   */
  .header:has(.header__description img) .header__container {
    padding-block: 1.8rem 3rem;
  }
}

/*
 * And the picture itself is held to the text measure.
 *
 * Nothing in layout.css constrains an image inside a hero description — a picture wider than
 * the 700px column simply ran past it, and past the 1280px container too. Held to that column,
 * with the 1rem of air body copy gives one (`.section__content img:not([class])`).
 *
 * Left inline, unlike that body rule: the hero centres its content with `text-align`, and going
 * block would left-align the two broken PDF-as-image placeholders in the
 * /general-terms-and-conditions description, which this selector also matches. That page is the
 * one hero without a real picture that these two rules reach: its placeholders take the margins
 * and the padding above, so its hero grows from 220px to 334px. Nothing there was clipped
 * before and nothing is now — it simply has the room a description with pictures in it asks for.
 */
.header__description img {
  height: auto;
  margin: 1rem auto;
  max-width: 100%;
}

/*
 * The date a news article was published, under its headline.
 *
 * The listing shows one on every card (`.teaser__date`); the article it opens showed none, so
 * the reader lost the date at the moment they started reading. layout.css has no rule for this
 * — live never put a date in a hero — so the styling is ours.
 *
 * Set in the heading's own face rather than the body's, a quarter its size and widely
 * letter-spaced, so it reads as part of the title block and not as a first line of copy. White
 * rather than the brand gold: the hero photo is different on every article, and gold at 0.9rem
 * disappeared into the bright sail behind this one. The gold is spent on the rule above it
 * instead, where it is decoration and legibility does not depend on it.
 *
 * It sits inside `.header__content`, which layout.css already animates in 0.2s behind the
 * heading — so the date needs no animation of its own, and cannot drift out of step with one.
 */
.header__date {
  color: #fff;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.9rem;
  letter-spacing: 3px;
  margin: 0;
  text-transform: uppercase;
  /* The heading's own shadow, which is what keeps it readable over a photo. */
  text-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
}

.header__date::before {
  background: #c3a572;
  content: "";
  display: block;
  height: 2px;
  margin: 0 auto 0.9rem;
  width: 2.5rem;
}

/* Air between the date and a description, on the articles that have both. Nothing when the
   date is alone: `.header__content` already holds 2rem under itself. */
.header__date:not(:last-child) {
  margin-bottom: 0.9rem;
}

/*
 * The reading time, on the same line as the date.
 *
 * It is the same text as the date in every respect — one meta line, not two facts styled
 * differently — so it inherits everything and only holds the two apart. The separator is
 * dimmed rather than sized down: at 0.9rem with 3px of letter-spacing a smaller dot would
 * read as dirt on the photo.
 */
.header__meta-separator {
  margin: 0 0.6rem 0 0.3rem;
  opacity: 0.6;
}

/* The date and the reading time must break as one unit each, so a narrow phone wraps between
   them rather than leaving "3 min" on one line and "read" on the next. */
.header__date time,
.header__reading-time {
  white-space: nowrap;
}

/*
 * The news overview: one lead story, then a column of rows.
 *
 * layout.css styles listings as a grid of equal cards (`.teasers`), which suits ports and
 * regions — a name and a picture each — but made /news a wall of identical blocks in which
 * the newest article was indistinguishable from one published years ago. The markup for news
 * is now its own (components/listings/NewsListing), so these are new rules rather than a
 * deviation: nothing here overrides the capture, and nothing in the capture reaches them.
 *
 * Colours are the site's own, taken from layout.css: #001d39 and #0c3965 are the header
 * gradient, #c3a572 the accent already used on a news article's date rule, #f3f3f3 the grey
 * the section sits on. Headings keep the Futura face and the wide uppercase letter-spacing
 * that every other heading on the site carries, so the page reads as the same site laid out
 * better, not as a new one.
 */
.news-listing {
  margin: 0 auto;
  max-width: 1180px;
}

/* Both cards share one picture treatment: a fixed 3:2 box the image covers, so a portrait
   upload and a panorama occupy the same space and the rows below never shift while loading. */
.news-card__thumb {
  background: #dfe5ea;
  overflow: hidden;
  position: relative;
}

.news-card__thumb--empty {
  background: #184e83;
}

/* Absolute, not just `height: 100%`: the box gets its height from the row (or from the
   aspect-ratio below), and a picture in the flow would instead impose its own. A portrait
   upload made its row three times the height of its neighbours before this. */
.news-card__thumb img {
  display: block;
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
  transition: transform 550ms cubic-bezier(0.2, 0.6, 0.2, 1);
}

.news-featured__link:hover .news-card__thumb img,
.news-row__link:hover .news-card__thumb img {
  transform: scale(1.045);
}

/* A visitor who has asked for less motion gets none: the zoom is decoration only. */
@media (prefers-reduced-motion: reduce) {
  .news-card__thumb img {
    transition: none;
  }

  .news-featured__link:hover .news-card__thumb img,
  .news-row__link:hover .news-card__thumb img {
    transform: none;
  }
}

/* ---------------------------------------------------------------- the lead story ------- */

/*
 * The one dark panel on the page. It is what carries the emphasis, so the rows beneath it can
 * stay plain white and the page still has an obvious starting point.
 *
 * Stacked on phones, picture over text; side by side from 900px up, where the picture takes
 * the larger share because it is the part that carries at a glance.
 */
.news-featured {
  background: #001d39;
  color: #fff;
  margin-bottom: 1.5rem;
}

.news-featured__link {
  display: block;
  text-decoration: none;
}

.news-featured .news-card__thumb {
  aspect-ratio: 3 / 2;
}

.news-featured__content {
  padding: 1.75rem 1.5rem 2rem;
}

.news-featured__eyebrow {
  color: #c3a572;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 3px;
  margin: 0 0 0.9rem;
  text-transform: uppercase;
}

.news-featured__heading {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 4px;
  line-height: 1.25;
  margin: 0;
  text-transform: uppercase;
}

.news-featured__date {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1rem;
  /* Lighter than the copy beneath it: a timestamp, not a line to read. */
  color: #9fb6cc;
  letter-spacing: 0;
  margin: 0.6rem 0 0.9rem;
  text-transform: uppercase;
}

.news-featured__description {
  /* Held to a measure rather than the column width — a full-bleed 46rem line is tiring. */
  color: #c9d8e6;
  margin: 0 0 1.5rem;
  max-width: 46ch;
}

.news-featured__cta {
  border-bottom: 1px solid currentColor;
  color: #c3a572;
  display: inline-block;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 3px;
  padding-bottom: 3px;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- the rows ------------- */

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

.news-list__item + .news-list__item {
  margin-top: 1.5rem;
}

.news-row {
  background: #fff;
}

.news-row__link {
  display: block;
  text-decoration: none;
}

.news-row .news-card__thumb {
  aspect-ratio: 3 / 2;
}

.news-row__content {
  color: #001d39;
  padding: 1.5rem;
}

.news-row__heading {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: 4px;
  line-height: 1.3;
  margin: 0;
  text-transform: uppercase;
  transition: color 180ms;
}

.news-row__link:hover .news-row__heading {
  color: #0c3965;
}

.news-row__date {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1rem;
  letter-spacing: 0;
  margin: 0.4rem 0 0.7rem;
  opacity: 0.75;
  text-transform: uppercase;
}

.news-row__description {
  margin: 0;
  max-width: 68ch;
  /* Excerpts vary from one line to a paragraph; clamped so a long one cannot make its row
     twice the height of its neighbours. -webkit- prefixed because that is still the only
     form every current browser implements. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---------------------------------------------------------------- wider screens -------- */

@media (min-width: 620px) {
  .news-row__link {
    display: flex;
  }

  .news-row .news-card__thumb {
    aspect-ratio: auto;
    flex: 0 0 260px;
    min-height: 200px;
  }

  .news-row__content {
    align-self: center;
    flex: 1 1 auto;
    padding: 1.5rem 2rem;
  }

  .news-row__description {
    -webkit-line-clamp: 2;
  }
}

@media (min-width: 900px) {
  .news-featured {
    margin-bottom: 2rem;
  }

  .news-featured__link {
    display: flex;
  }

  .news-featured .news-card__thumb {
    aspect-ratio: auto;
    /* 7 : 5 — the picture leads, the text has room for its measure without stretching. */
    flex: 7 1 0;
    min-height: 380px;
  }

  .news-featured__content {
    align-self: center;
    flex: 5 1 0;
    padding: 2.5rem 3rem;
  }

  .news-featured__heading {
    font-size: 1.9rem;
  }

  .news-row .news-card__thumb {
    flex: 0 0 380px;
    min-height: 240px;
  }

  .news-row__content {
    padding: 2rem 2.5rem;
  }

  .news-row__heading {
    font-size: 1.4rem;
  }

  .news-row__description {
    -webkit-line-clamp: 3;
  }
}

/* =========================================================== the event page ============= */

/*
 * An event page is a page somebody plans a trip around. What it has to answer, in this order:
 * when, where, which stand, who, and where are you after this. The body text an editor writes
 * answers none of those reliably, so the template puts them around it.
 *
 * Same palette as the news lead above — #001d39 navy, #c3a572 gold, #c9d8e6 for text on navy —
 * and the site's own Futura for headings, so a dressed-up event page still reads as part of
 * this site rather than as a landing page borrowed from somewhere else.
 */

/* ---------------------------------------------------------------- hero ----------------- */

/*
 * The hero carries the picture and the name of the show, and nothing else. The dates and the
 * place were on it at first, with the same two facts labelled in the band directly below; over
 * a real page that read as the page saying everything twice, so the band keeps them and the
 * hero lets the photograph do its work.
 *
 * The captured mask fades from nothing at the top to navy at the foot. On this template it is
 * deepened a little so the heading holds up over a bright, busy photograph.
 */
.event-hero .header__mask {
  background: linear-gradient(rgba(0, 29, 57, 0.35), rgba(0, 29, 57, 0.8));
}

/* ---------------------------------------------------------------- the facts band -------- */

/*
 * Dates, place and stand number, on the dark band directly under the hero — the three things a
 * visitor came to look up, above the fold and never more than a glance away.
 *
 * Only facts the CMS actually holds are rendered, so the row is two, three or gone. `auto-fit`
 * rather than a fixed column count: with two facts they share the width, with three they sit in
 * thirds, and neither case needs its own rule.
 */
.event-facts {
  background: #001d39;
  color: #fff;
}

/*
 * Held to the same 1000px measure as the body text and centred on it, so the band lines up with
 * the page instead of running out to the full 1440px container while the text beside it does
 * not — which is what made it look pushed to the left.
 *
 * `auto-fit` rather than a fixed column count: with two facts they share the width, with three
 * they sit in thirds, and neither case needs a rule of its own.
 */
.event-facts__list {
  display: grid;
  gap: 1.25rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin: 0 auto;
  max-width: 1000px;
  padding: 1.75rem 0;
  text-align: center;
}

.event-facts__label {
  color: #c3a572;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 2.5px;
  margin: 0 0 0.35rem;
  text-transform: uppercase;
}

.event-facts__value {
  font-size: 1.05rem;
  line-height: 1.4;
  margin: 0;
}

/* ---------------------------------------------------------------- the team -------------- */

/*
 * Who is standing on the stand. Rendered only when the event names people; until then the
 * block is simply absent, which is why there is no empty state here.
 */
.event-team {
  background: #fff;
}

.event-team__head {
  margin: 0 auto 1.75rem;
  max-width: 1000px;
}

.event-team__eyebrow {
  color: #c3a572;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 3px;
  margin: 0 0 0.75rem;
  text-transform: uppercase;
}

.event-team__heading {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 4px;
  margin: 0;
  text-transform: uppercase;
}

.event-team__intro {
  margin: 0.9rem 0 0;
  max-width: 60ch;
}

/*
 * One column on a phone, two from 768px.
 *
 * The hairlines between the cards are drawn by each card's own 1px ring, not by a grey sheet
 * showing through a 1px gap. The sheet was simpler, but with an odd number of colleagues the
 * last row has an empty cell, and that cell showed as a grey block beside the third card.
 * A ring paints only where a card is, so an empty cell is simply the white behind it.
 *
 * The rings of two neighbours each reach 1px into the gap between them, which is what keeps the
 * inner lines exactly one pixel, and the outermost ring draws the border around the whole grid.
 */
.event-team__list {
  background: #fff;
  display: grid;
  gap: 1px;
  grid-template-columns: 1fr;
  list-style: none;
  margin: 0 auto;
  max-width: 1000px;
  padding: 0;
}

.event-person {
  align-items: center;
  background: #fff;
  box-shadow: 0 0 0 1px #e2e2e2;
  display: flex;
  gap: 1.15rem;
  padding: 1.35rem 1.5rem;
}

.event-person__portrait {
  background: #dfe5ea;
  border-radius: 50%;
  flex: 0 0 76px;
  height: 76px;
  overflow: hidden;
  width: 76px;
}

.event-person__portrait img {
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.event-person__name {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 2px;
  margin: 0;
  text-transform: uppercase;
}

.event-person__role {
  font-size: 0.9rem;
  line-height: 1.45;
  margin: 0.2rem 0 0;
}

/* The country, in the same gold as every other label on the page. */
.event-person__area {
  color: #c3a572;
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 2.5px;
  margin: 0.35rem 0 0;
  text-transform: uppercase;
}

.event-person__contact {
  display: flex;
  flex-direction: column;
  font-size: 0.85rem;
  gap: 0.15rem;
  margin: 0.55rem 0 0;
}

.event-person__contact a {
  color: #0c3965;
  text-decoration: none;
  /* An address can be longer than its column; it wraps rather than pushing the card wide. */
  overflow-wrap: anywhere;
}

.event-person__contact a:hover {
  text-decoration: underline;
}

/* ---------------------------------------------------------------- the invitation -------- */

.event-cta {
  background: #0c3965;
  color: #fff;
}

.event-cta__inner {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: space-between;
  margin: 0 auto;
  max-width: 1000px;
}

.event-cta__heading {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 4px;
  margin: 0;
  max-width: 30ch;
  text-transform: uppercase;
}

.event-cta__text {
  color: #c9d8e6;
  margin: 0.75rem 0 0;
  max-width: 46ch;
}

/* ---------------------------------------------------------------- practical -------------- */

/*
 * Where it is, when it opens, how to get in — the questions somebody asks once they have
 * decided to come. Three plain white cards on the grey, held to the same measure as everything
 * else on the page, so it reads as a reference block rather than more prose.
 *
 * Only cards that have been written for this show appear; there is no empty state, because an
 * unchecked opening time on a page a customer plans a trip around is worse than none.
 */
.event-practical {
  background: #f3f3f3;
}

.event-practical__heading {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 4px;
  margin: 0 auto 1.5rem;
  max-width: 1000px;
  text-transform: uppercase;
}

.event-practical__list {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
  list-style: none;
  margin: 0 auto;
  max-width: 1000px;
  padding: 0;
}

.event-practical__item {
  background: #fff;
  padding: 1.5rem;
}

.event-practical__title {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 2px;
  margin: 0 0 0.6rem;
  text-transform: uppercase;
}

.event-practical__text {
  font-size: 0.95rem;
  margin: 0;
}

/*
 * Opening hours that differ per day, as day-and-time rows rather than a sentence. The value
 * sits hard right so the times line up in a column and can be read down.
 */
.event-practical__rows {
  margin: 0;
}

.event-practical__row {
  align-items: baseline;
  border-bottom: 1px solid #ececec;
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
  justify-content: space-between;
  line-height: 1.5;
  padding: 0.45rem 0;
}

.event-practical__row:last-child {
  border-bottom: 0;
}

.event-practical__row dt {
  font-size: 0.95rem;
}

.event-practical__row dd {
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0;
  white-space: nowrap;
}

/*
 * A real button rather than an underlined link: these two are the actions on the card — plan
 * the journey, buy the ticket — and they should look like something to press. The site's own
 * `.button` carries the shape; this only gives it room and lets it wrap on a narrow card.
 */
.event-practical__button {
  height: auto;
  line-height: 1.4;
  margin-top: 1.1rem;
  padding: 0.7rem 1.1rem;
}

/*
 * `.button` in layout.css is built for one short word on a single line: `white-space: nowrap`
 * plus an ellipsis, which cut a two-word label off mid-word. Only those two are lifted, so the
 * label wraps onto a second line.
 *
 * `overflow: hidden` deliberately stays as layout.css has it. The hover effect is two
 * wave-shaped SVGs that slide up from under the button, and the button's own clipping is what
 * keeps them inside it — lifting it too let the wave ride out over the card, which is what made
 * these two buttons behave unlike every other button on the site.
 */
.event-practical__button,
.event-practical__button .button__text {
  text-overflow: clip;
  white-space: normal;
}

/* ---------------------------------------------------------------- the next shows -------- */

/*
 * Rows rather than cards, and for the same reason the news overview uses them: each item
 * carries a date and a place, and a row gives all three one reading line each.
 */
.event-next__heading {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 4px;
  margin: 0 auto 1.5rem;
  max-width: 1000px;
  text-transform: uppercase;
}

.event-next__list {
  list-style: none;
  margin: 0 auto;
  max-width: 1000px;
  padding: 0;
}

.event-next__item + .event-next__item {
  margin-top: 1rem;
}

.event-next__link {
  background: #fff;
  display: block;
  text-decoration: none;
}

.event-next__thumb {
  aspect-ratio: 3 / 2;
  background: #dfe5ea;
  overflow: hidden;
}

.event-next__thumb img {
  display: block;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms;
  width: 100%;
}

.event-next__link:hover .event-next__thumb img {
  transform: scale(1.04);
}

.event-next__content {
  color: #001d39;
  padding: 1.35rem 1.5rem;
}

.event-next__title {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: 4px;
  line-height: 1.3;
  margin: 0;
  text-transform: uppercase;
  transition: color 180ms;
}

.event-next__link:hover .event-next__title {
  color: #0c3965;
}

.event-next__date {
  font-family: "Futura W01", Arial, sans-serif;
  font-size: 1rem;
  letter-spacing: 0;
  margin: 0.4rem 0 0;
  text-transform: uppercase;
}

.event-next__where {
  margin: 0.2rem 0 0;
  opacity: 0.8;
}

/* A visitor who has asked for less motion gets none: the zoom is decoration only. */
@media (prefers-reduced-motion: reduce) {
  .event-next__thumb img,
  .event-next__link:hover .event-next__thumb img {
    transform: none;
    transition: none;
  }
}

@media only screen and (min-width: 768px) {
  .event-facts__list {
    padding: 2rem 0;
  }

  .event-team__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .event-team__heading,
  .event-cta__heading,
  .event-practical__heading,
  .event-next__heading {
    font-size: 1.7rem;
  }

  /* Three cards side by side once there is room; stacked below that. */
  .event-practical__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .event-practical__item {
    padding: 1.75rem;
  }

  /* Picture beside the text, as the news rows do — the same shape, one page later. */
  .event-next__link {
    display: flex;
  }

  .event-next__thumb {
    aspect-ratio: auto;
    flex: 0 0 300px;
    min-height: 200px;
  }

  .event-next__content {
    align-self: center;
    padding: 1.75rem 2.25rem;
  }
}

/*
 * The schedules page: shorter cards, and four of them per row on a wide screen.
 *
 * /schedules renders every published sailing as a card, and there are 67 of them. At the
 * captured sizes a card is ~930px tall and three fit per row, so the page runs to some
 * 22,000px — a visitor looking for one sailing scrolls past twenty. Nothing was wrong with
 * the card; there are simply a lot of them, and the card was built for a page that held a
 * handful.
 *
 * So this trims the card's own padding and leading rather than its content — every line a
 * card showed, it still shows — and lets a fourth column in once the screen is wide enough
 * to carry it. Measured on a 24-card sample at 1440px: 8,026px of page before, and the same
 * cards in a good deal less after. On a phone the card simply gets shorter; it stays one per
 * row, because two would be unreadable.
 *
 * All of it is scoped to `#section-schedules`, the widget's own wrapper (RouteWidget.tsx), so
 * the card styles in layout.css keep working anywhere else they are used and the captured
 * stylesheet stays untouched.
 */

/* The timeline indent, in one place: the vertical line sits at the content edge, the region
   names and the info block are pushed off it by this much, and the port dots are pulled back
   by exactly the same amount. Change it here and the four rules below stay in step — which is
   the whole reason it is a variable and not four numbers. */
#section-schedules {
  --route-indent: 1.5rem;
}

#section-schedules .route-card__route {
  /* Was 2rem 2.5rem. A 2.5rem gutter was generous on a 480px card and is too much on the
     narrower one a four-column row gives. */
  padding: 1.5rem 1.5rem 1.6rem;
}

#section-schedules .route-card__title {
  padding-bottom: 0.4rem;
  padding-left: var(--route-indent);
}

#section-schedules .route-card__stop {
  padding-bottom: 0.55rem;
  padding-left: var(--route-indent);
}

/*
 * The port lines are the reason a long route is a long card: a sailing with five regions and
 * a dozen calls carries a dozen of these, and each one was taking the body's 1.65 leading at
 * 0.8rem — half a line of air per port. At 1.4 they still read as separate calls and a busy
 * card loses the most, which is exactly the card that sets its row's height.
 */
#section-schedules .route-card__port,
#section-schedules .route-card__substop-date {
  line-height: 1.4;
}

#section-schedules .route-card__substop::before {
  left: calc(var(--route-indent) * -1);
}

#section-schedules .route-card__info {
  padding-left: var(--route-indent);
}

#section-schedules .route-card__region {
  /* 1.3rem was set for a card with room to spare. At 1.1rem the region still leads the block
     and still carries the Futura face; it just stops costing a line and a half of height. */
  font-size: 1.1rem;
}

#section-schedules .route-card__info-title {
  /* 1.4rem of air above each of the two info headings, on every one of 67 cards. */
  margin-top: 0.85rem;
}

#section-schedules .route-card__contacts {
  padding: 1rem 0 0.7rem;
}

#section-schedules .route-card__contacts-title {
  margin-bottom: 0.7rem;
}

#section-schedules .route-card__button {
  /* 70px is a full-width call to action for a page with one of them; here it repeats 67
     times. Still comfortably above the 44px a finger needs. */
  font-size: 1rem;
  height: 52px;
  line-height: 51px;
}

/* ---------------------------------------------------------------- four per row ---------- */

/*
 * From 1440px, where three columns leave each card 480px wide — wider than the 360px the
 * card was drawn at. A fourth column uses that width instead of spending it on margins, and
 * takes a quarter of the rows off the page.
 *
 * The gutter drops with it: at four across, 1.5rem on each side of every card eats more than
 * the column it buys.
 */
@media only screen and (min-width: 1440px) {
  #section-schedules .transport-route__item {
    flex: 1 1 25%;
    max-width: 25%;
    padding: 1.25rem 1rem;
  }
}

/*
 * Above 1700px the site's 1440px container is what limits the cards, not the screen. The
 * schedules grid — and only that grid, not the filter above it or any other section — is
 * allowed wider there, so the four columns get their width back instead of staying cramped
 * on a monitor that has room to spare.
 */
@media only screen and (min-width: 1700px) {
  #section-schedules .section--grey .section__container {
    max-width: 1680px;
  }
}

/*
 * The grey "Find your local representative" band, level across a row.
 *
 * The band sits between the white route block and the button, and the card is bottom-anchored,
 * so where its top edge lands is decided by its own height. That height follows the
 * representative: measured against all 53 of them, most give 171px, nine give 186px because
 * their job title runs to two lines ("Trade Manager: USA East to USA West & Asia v.v"), and at
 * the narrowest four-column card three names wrap as well, giving 200 and 216. Four different
 * heights side by side in one row, which is what reads as restless — and four columns put more
 * of them next to each other than three did.
 *
 * Fixed by bounding what the block can contain and then reserving exactly that much, rather
 * than by letting each card find its own height:
 *   - the name is set a notch smaller, so the longest one we have ("Willemijn van Renterghem")
 *     fits on one line even in the narrowest card — no name is ever cut off;
 *   - the job title may take two lines and the area one, which covers every title in the list;
 *   - the block reserves that height for every card, so a one-line title leaves air instead of
 *     pulling the band up.
 *
 * The cost is about 15px on the cards with a short title. Rows are as tall as their tallest
 * card anyway, and most rows already carry a two-line title, so the page barely grows.
 */
/*
 * The carousel reserves 2.5rem on each side of the contact card for its two chevrons, which are
 * ~20px wide and sit 0.4rem in. That was drawn for a 480px card; on the narrowest one — 341px,
 * at the bottom of the three-column range — it costs a quarter of the card's width, and the
 * name and job title wrap for want of room rather than for want of size. Trimmed to what the
 * chevrons actually need.
 */
#section-schedules .carousel--contact {
  padding-left: 1.8rem;
  padding-right: 1.8rem;
}

#section-schedules .contact-card--route .contact-card__name {
  /* 1.1rem is what made three of the 53 names wrap at a 360px card. */
  font-size: 1rem;
  line-height: 1.3;
}

#section-schedules .contact-card--route .contact-card__function {
  /* Two lines is enough for the longest title in the list; the clamp is a guard against a
     future one that is longer still, so it can never push the band out of line again. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

#section-schedules .contact-card--route .contact-card__country {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#section-schedules .contact-card--route .contact-card__info {
  /* Name (1 line) + job title (2) + area (1). Measured, not guessed — see the block above. */
  min-height: 4.6rem;
}
