/* ---------------------------------------------------------------------------
   News cards, listing grid and article layout.

   Extracted from the per-card <style> block that used to be duplicated once
   per rendered card.
   --------------------------------------------------------------------------- */

/* --- grid ---------------------------------------------------------------- */

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: 1.75rem 1.5rem;
  align-items: stretch;
  /* Belt and braces: the listing is wrapped in a .container, but the plugin can
     be dropped into a full-bleed placeholder too. Without a ceiling that gave
     eight cards to a row on a wide display. This matches the container width,
     so inside one it changes nothing. */
  max-width: 82rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.news-grid > li { display: flex; }

/* --- card ---------------------------------------------------------------- */

.news-card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  width: 100%;
  background-color: var(--c-white);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-decoration: none;
  box-shadow: var(--shadow-1);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
  color: var(--on-light);
}

.news-card:hover,
.news-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--shadow-2);
}

.news-card__media {
  /* A ratio rather than a percentage of a fixed-height parent, so the image
     scales with the column instead of overflowing it. */
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background-color: var(--c-violet-pale);
}

.news-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .4s var(--ease);
}

.news-card__media img.news-card__placeholder {
  object-fit: contain;
  padding: 1.5rem;
}

.news-card:hover .news-card__media img {
  transform: scale(1.04);
}

.news-card__body {
  padding: 1rem 1.1rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.news-date {
  font-size: var(--fs-small);
  color: var(--muted-on-light);
  margin: 0;
}

.news-title {
  font-size: 1.05rem;
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  color: var(--c-violet);
  margin: 0;

  /* Clamp rather than clip: the old card cut headlines off mid-word because
     the text box overflowed a fixed-height parent. */
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.news-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1.1rem 1.1rem;
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--c-violet);
}

.news-card:hover .news-card__cta svg,
.news-card:focus-visible .news-card__cta svg {
  transform: translateX(3px);
}

.news-card__cta svg { transition: transform .2s var(--ease); }

/* --- carousel ------------------------------------------------------------ */

/* Scroll-snap rather than a JS-driven track: the row is natively swipeable and
   trackpad-scrollable, and it still works with the script disabled. The old
   version had a fixed 350px height that showed one card inside 256px of dead
   vertical space on a phone. */
.news-carousel {
  position: relative;
  --news-per-view: 3;
  --news-gap: 1.5rem;
}

.news-carousel__viewport {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Room for the cards' hover lift and focus ring, which a plain overflow
     container would clip. The negative margin pulls the box back out so the
     cards still line up with the container edges at rest. */
  padding: 0.5rem 0.25rem 1.25rem;
  margin: -0.5rem -0.25rem -1.25rem;
  /* Must match padding-inline. `scroll-snap-align: start` snaps an item to the
     scrollport edge, which does not account for the padding above, so without
     this every card landed a quarter rem left of the container once the
     carousel had been scrolled: aligned before you touched it, visibly off
     afterwards. */
  scroll-padding-inline: 0.25rem;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* Keep native touch, trackpad and keyboard scrolling while suppressing the
   visual scrollbar below the cards in Chromium and Safari. */
.news-carousel__viewport::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

.news-carousel__viewport:focus-visible {
  outline: 3px solid var(--c-violet-light);
  outline-offset: 4px;
  border-radius: var(--radius-md);
}

.news-carousel__track {
  display: flex;
  gap: var(--news-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  /* Centre the cards when there are too few to fill a view, rather than
     leaving them hugging the left edge under a centred heading. `safe` keeps
     the overflowing case scrollable: plain `center` would push the first cards
     out of reach above the scroll origin. */
  justify-content: safe center;
}

.news-carousel__slide {
  scroll-snap-align: start;
  display: flex;
  /* one card per view by default; wider viewports show more */
  flex: 0 0 100%;
}

@media (min-width: 576px) {
  .news-carousel__slide { flex-basis: calc((100% - var(--news-gap)) / 2); }
}

@media (min-width: 992px) {
  .news-carousel__slide {
    flex-basis: calc(
      (100% - (var(--news-per-view) - 1) * var(--news-gap)) / var(--news-per-view)
    );
  }
}

.news-carousel__arrow {
  position: absolute;
  top: calc(50% - 1.5rem);
  transform: translateY(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: 50%;
  background-color: var(--c-white);
  color: var(--c-violet);
  box-shadow: var(--shadow-2);
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease),
              opacity .2s var(--ease);
}

.news-carousel__arrow:hover,
.news-carousel__arrow:focus-visible {
  background-color: var(--c-violet);
  color: var(--c-white);
}

.news-carousel__arrow[disabled] {
  opacity: 0.35;
  cursor: default;
}

.news-carousel__arrow--prev { left: -0.75rem; }
.news-carousel__arrow--next { right: -0.75rem; }

@media (min-width: 1200px) {
  .news-carousel__arrow--prev { left: -1.5rem; }
  .news-carousel__arrow--next { right: -1.5rem; }
}

/* Arrows overlap the cards on narrow screens, where the swipe gesture is the
   natural control anyway. */
@media (max-width: 575.98px) {
  .news-carousel__arrow { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .news-carousel__viewport { scroll-behavior: auto; }
}

.news-actions {
  display: flex;
  justify-content: center;
  margin-top: 2rem;
}

.btn-6gem {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background-color: var(--c-white);
  color: var(--c-violet);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0.7rem 1.5rem;
  font-weight: var(--fw-medium);
  text-decoration: none;
  transition: background-color .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease);
}

.btn-6gem:hover,
.btn-6gem:focus-visible {
  background-color: var(--c-violet-deep);
  border-color: var(--c-white);
  color: var(--c-white);
}

.bg-color1 .btn-6gem {
  background-color: var(--c-violet);
  color: var(--on-violet);
}

.bg-color1 .btn-6gem:hover,
.bg-color1 .btn-6gem:focus-visible {
  background-color: var(--c-violet-deep);
  color: var(--c-white);
}

/* --- article ------------------------------------------------------------- */

/* An article headline is running text at the top of a page, not a hero title.
   It was inheriting the global h1 size, which tops out at 3.75rem because that
   value is tuned for a headline sitting over a full-screen image. */
.news-article__title {
  font-size: clamp(1.6rem, 1.15rem + 1.6vw, 2.5rem);
  margin-bottom: 0.5rem;
}

.news-article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: center;
  justify-content: center;
  color: var(--muted-on-light);
  font-size: var(--fs-small);
  margin: 0 0 2rem;
}

.news-article__body {
  max-width: var(--measure);
  margin-inline: auto;
  text-align: left;
}

.news-article__body img {
  border-radius: var(--radius-md);
}

.news-article__nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--rule-on-light);
}

.news-article__nav a {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.1rem;
  border-radius: var(--radius-sm);
  background: var(--c-violet-pale);
  text-decoration: none;
  color: var(--c-violet);
}

.news-article__nav a:hover,
.news-article__nav a:focus-visible {
  background: var(--c-violet);
  color: var(--on-violet);
}

.news-article__nav .label {
  font-size: var(--fs-small);
  opacity: .85;
}

.news-article__nav .headline {
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
}

.news-article__nav a.is-next {
  text-align: right;
  align-items: flex-end;
}

.news-back {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1.5rem;
  font-weight: var(--fw-medium);
  text-decoration: none;
}

.news-back:hover,
.news-back:focus-visible { text-decoration: underline; }
