@charset "UTF-8";
/* News Feed (Embed) — Template CSS

   Built to render inside a Mustang Express iframe, so unlike the in-site
   templates this one owns its whole document and therefore its own base:
   the Outfit face, a root font-size, and the design tokens the rest of the
   file reads from. Palette and card treatment follow the Academic Calendar so
   the two read as one system — brand purple #42196F, an accent blue for focus,
   white cards on a border-and-shadow, and contrast held at or above 4.5:1
   throughout (the ratio is noted wherever a colour was actually chosen for it).
*/

/* ── Fonts ──
   The two Outfit weights the theme ships, loaded from their canonical home two
   levels up. woff2 only — every browser that matters supports it, and the
   fallback stack below covers the paint before the file lands. */
@font-face {
  font-family: "Outfit";
  src: url("../../assets/fonts/Outfit/static/Outfit-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Outfit";
  src: url("../../assets/fonts/Outfit/static/Outfit-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ── Tokens ── */
:root {
  --news-brand:       #42196F;          /* WNMU purple — 13.1:1 on white */
  --news-brand-deep:  #2d0f52;          /* hover/active purple */
  --news-focus:       #253F8E;          /* accent blue, focus rings only */
  --news-ink:         #2b2630;          /* card body text — 13:1 on white */
  --news-muted:       #56505f;          /* dates / secondary — 7.0:1 on white */
  --news-card:        #ffffff;
  --news-border:      hsl(0 0% 90%);
  --news-tag-bg:      #efe9f5;          /* light purple pill */
  --news-page:        #ffffff;
  --news-font: "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  --news-max: 1080px;
}

/* ── Base ──
   A local box-sizing reset — there is no theme reset under us here. 16px root
   (this template sets its own scale rather than the site's 17px, so the embed
   is predictable at any portal zoom). The body paints an explicit background:
   an iframe with a transparent body would borrow the portal's, and the cards
   are designed against white. */
*, *::before, *::after { box-sizing: border-box; }

html { font-size: 100%; -webkit-text-size-adjust: 100%; }

body.news-embed {
  margin: 0;
  padding: 0;
  background: var(--news-page);
  color: var(--news-ink);
  font-family: var(--news-font);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; }

/* Off-screen but still announced — used for the "(opens in a new tab)" hints
   and the skip link's target description. */
.news__sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link. Off-screen until focused, then pinned top-left over the header so
   a keyboard user can jump the masthead straight to the list. */
.news__skip {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 10;
  padding: 8px 14px;
  border-radius: 6px;
  background: var(--news-brand);
  color: #fff;
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  transition: top 0.15s ease;
}
.news__skip:focus {
  top: 8px;
}

/* ── Header ──
   A slim branded bar, not the full-bleed hero the in-site calendar uses: inside
   a portal panel the context is already established, so the header only needs to
   name the panel. */
.news__header {
  max-width: var(--news-max);
  margin: 0 auto;
  padding: 26px 20px 0;
}

.news__kicker {
  margin: 0 0 2px;
  color: var(--news-muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.news__title {
  margin: 0;
  color: var(--news-brand);
  font-size: 1.85rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0.01em;
}

/* ── Layout ── */
.news {
  max-width: var(--news-max);
  margin: 0 auto;
  padding: 20px 20px 40px;
}

/* Compact row layout. auto-fill still lets the panel decide its column count:
   a single column of rows in a narrow portal rail, two (or more) side by side
   when there is room. The wider minmax floor suits horizontal rows (thumbnail +
   text) rather than the taller floor a stacked card needed. */
.news__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 480px), 1fr));
  gap: 14px;
}

/* ── Card ──
   White on a border and a soft double shadow, the calendar's card treatment.
   The <li> is the grid cell; the inner <article> is the visual card, so list
   semantics and card styling do not fight over the same box. */
.news__card { display: flex; }

.news__card-inner {
  display: flex;
  flex-direction: row;          /* thumbnail left, text right */
  align-items: stretch;         /* thumbnail matches the row's height */
  min-height: 104px;            /* keeps a sensible thumb size on short rows */
  width: 100%;
  background: var(--news-card);
  border: 1px solid var(--news-border);
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 3px 10px rgba(0, 0, 0, 0.045);
  overflow: hidden;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

/* Lift on hover as an affordance for the linked title inside. Guarded by
   :focus-within so it also holds while the title link is keyboard-focused. */
.news__card-inner:hover,
.news__card-inner:focus-within {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06), 0 8px 22px rgba(0, 0, 0, 0.09);
}

/* Thumbnail column — a fixed-width band on the left of the row that stretches to
   the row's height (set by the text beside it), so the image is always flush with
   no gap regardless of excerpt length. max/min-width keep it proportionate as the
   panel widens or narrows. A missing image leaves a neutral panel, not a collapse. */
.news__thumb {
  position: relative;
  flex: 0 0 40%;
  max-width: 190px;
  min-width: 120px;
  align-self: stretch;
  background: #efedf1;
  overflow: hidden;
}
/* The image fills the thumb via absolute inset. Here the thumb's height is
   definite (it comes from the flex row, not from aspect-ratio), so height:100%
   resolves and the photo covers the band cleanly.

   !important on width/height is deliberate: production runs an image/lazy-load
   optimizer that rewrites the final HTML (via output buffering, so it happens even
   though this template skips wp_head) and injects an inline
   style="width:100%; height:66.68%; max-width:…" onto each <img>. That inline
   height (the image's intrinsic ratio as a percentage) would otherwise beat our
   stylesheet and shrink the image to ~66% of the band — a gap seen on production
   only. !important lets the stylesheet win. aspect-ratio:auto clears the intrinsic
   ratio from the width/height attributes so it can't fight the fill.
   (Cleaner long-term: exclude these images from the optimizer — see the deploy note.) */
.news__thumb img {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: auto !important;
  object-fit: cover !important;
  /* Bias slightly above centre so that when a portrait/very-wide source does get
     cropped, it keeps faces (usually upper-middle) rather than trimming them. */
  object-position: center 40%;
}

.news__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;               /* let long titles/excerpts truncate, not overflow */
  padding: 11px 15px;
}

/* Category pill. Brand-tinted rather than grey so it reads as a WNMU element;
   purple on the light-purple fill stays ~11:1. */
.news__tag {
  align-self: flex-start;
  margin-bottom: 7px;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--news-tag-bg);
  color: var(--news-brand);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* Clamp to two lines so rows stay compact and even. */
.news__card-title {
  margin: 0 0 5px;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The title is the card's only link. Purple by default (13.1:1), underlined on
   interaction rather than at rest so a grid of cards is not a wall of rules. */
.news__card-title a {
  color: var(--news-brand);
  text-decoration: none;
}
.news__card-title a:hover {
  color: var(--news-brand-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.news__card-title a:focus-visible {
  outline: 2px solid var(--news-focus);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Clamp to two lines to keep rows short and even. margin-top:auto is on
   .news__meta below, so the date sits at the row foot regardless of excerpt length. */
.news__excerpt {
  margin: 0 0 8px;
  color: var(--news-ink);
  font-size: 0.85rem;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.news__meta {
  margin: auto 0 0;
  color: var(--news-muted);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}

/* ── Empty / error state ── */
.news__empty {
  margin: 8px 0;
  padding: 28px 22px;
  border: 1px dashed var(--news-border);
  border-radius: 10px;
  color: var(--news-muted);
  font-size: 0.98rem;
}
.news__empty a {
  color: var(--news-brand);
  font-weight: 700;
}
.news__empty a:focus-visible {
  outline: 2px solid var(--news-focus);
  outline-offset: 2px;
}

/* ── View all ── */
.news__more {
  margin: 26px 0 0;
  text-align: center;
}
.news__more-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 22px;
  border: 2px solid var(--news-brand);
  border-radius: 999px;
  color: var(--news-brand);
  font-weight: 700;
  font-size: 0.95rem;
  text-decoration: none;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.news__more-link:hover {
  background: var(--news-brand);
  color: #fff;
}
.news__more-link:focus-visible {
  outline: 2px solid var(--news-focus);
  outline-offset: 3px;
}
.news__more-arrow {
  display: inline-flex;
  transition: transform 0.18s ease;
}
.news__more-link:hover .news__more-arrow {
  transform: translateX(3px);
}

/* ── Narrow panels ── */
@media (max-width: 480px) {
  .news__header { padding-top: 20px; }
  .news__title { font-size: 1.55rem; }
  .news { padding: 16px 14px 32px; }
  .news__grid { gap: 16px; }
}

/* ── Reduced motion ──
   Everything animated here is a nicety — the lift, the arrow nudge, the skip
   link's slide. Honour the OS setting and drop them. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .news__card-inner:hover,
  .news__card-inner:focus-within { transform: none; }
  .news__more-link:hover .news__more-arrow { transform: none; }
}

/* ── Print ──
   Rare for an embedded panel, but if a page that frames it is printed, drop the
   card chrome to ink-light outlines and let images through in case a story is
   the reason for printing. */
@media print {
  body.news-embed { background: #fff; }
  .news__skip, .news__more { display: none; }
  .news__card-inner {
    border: 1px solid #999;
    box-shadow: none;
    break-inside: avoid;
  }
  .news__card-title a { color: #000; text-decoration: underline; }
}
