/*
Theme Name: UFootball v2
Theme URI: https://ufootball.com.my/
Description: Classic theme for ufootball.com.my. Predictions UI reads the engine API client-side; article bodies always come from the_content().
Author: U Football
Version: 5.17.0
Requires PHP: 8.1
Text Domain: ufootball-v2
*/

/* assets/css/site.css carries the design system (--primary, .hdr, .hero, .sec,
   .ml-*, .st-*, .ps-*, .oc-*, .tn-*). This file only adds what it lacks:
   the league sidebar, date bar, and the WP-side post templates. */

/* ── card surface ──
   Grey page, white cards. Rows live inside a card separated by hairlines rather
   than floating as individual cards, so a competition reads as one object. */

body { background: var(--bg-2) }

.uf-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}

.uf-card-title {
  padding: 16px 18px 10px;
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 15px;
  color: var(--text);
}

/* ── homepage additions ── */

/* The match section rides up over the base of the hero so the cards break the
   banner edge instead of starting cleanly below it. */
#sec-matches { position: relative; z-index: 2; margin-top: -72px }

/* 30 / 70 split. fr units divide what's left AFTER the gap, so unlike percentages
   these two plus the 40px gutter can't overflow the row.
   min-width: 0 on both children is load-bearing: a grid item defaults to
   min-width: auto, which lets long content (a player name in the scorers list)
   push the track wider than its share. */
.uf-split { display: grid; grid-template-columns: 30fr 70fr; gap: 40px; align-items: start }
.uf-split > * { min-width: 0 }
.uf-split-even { grid-template-columns: 1fr 1fr }

.uf-card > .ps-tabs { padding: 0 8px }
.uf-card > .uf-head,
.uf-card > .uf-select,
.uf-card > #standings-body { padding-left: 18px; padding-right: 18px }
.uf-card > .uf-head { padding-top: 18px }
.uf-card > #standings-body { padding-bottom: 6px }

.uf-head { display: flex; align-items: center; justify-content: space-between; gap: 12px }
.uf-head .tn-header { margin-bottom: 20px }

.uf-league-list { list-style: none; margin: 0; padding: 0 0 10px }

.uf-league {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 18px;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  transition: color .18s, background .18s;
}

.uf-league:hover { color: var(--primary-dark); background: var(--bg-2) }
.uf-league.on { color: var(--primary-dark); background: var(--primary-light) }

/* Name takes the slack so the badge and chevron stay pinned right, in that order. */
.uf-league-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* Badges are desaturated at rest so five competing brand palettes don't fight the
   sidebar; colour returns on hover, focus and selection. Purely decorative — the
   league name carries the meaning, so nothing is lost while they're grey. */
.uf-league-badge {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  object-fit: contain;
  filter: grayscale(1);
  /* Greyscale alone leaves the darker marks (Bundesliga red) heavier than the
     rest; dropping opacity evens them out. */
  opacity: .5;
  transition: filter .18s, opacity .18s;
}

.uf-league:hover .uf-league-badge,
.uf-league:focus-visible .uf-league-badge,
.uf-league.on .uf-league-badge { filter: none; opacity: 1 }

@media (prefers-reduced-motion: reduce) {
  .uf-league-badge { transition: none }
}

.uf-toolbar { padding: 12px 14px; margin-bottom: 16px; display: grid; gap: 12px }

.uf-datebar { display: flex; align-items: center; justify-content: center; gap: 16px; font-family: 'Archivo', sans-serif }

.uf-daynav {
  width: 36px; height: 36px;
  border: 0;
  border-radius: 50%;
  background: #EBEBEB;
  color: #222;
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  padding: 0 0 3px; /* the guillemet glyph sits low; lift it to optical centre */
  cursor: pointer;
  transition: background .15s, color .15s;
}

.uf-daynav:hover { background: var(--primary); color: #fff }

/* Pill tabs, matching the reference. site.css styles .ml-tab as an underline tab
   row, which does not belong inside a toolbar card. */
.uf-toolbar .ml-tabs { border-bottom: 0; margin-bottom: 0; gap: 8px; overflow: visible; flex-wrap: wrap }

.uf-toolbar .ml-tab {
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
}

.uf-toolbar .ml-tab.on { border-color: var(--primary-dark); background: var(--primary-light) }

/* Date picker. The trigger reads as text, not a control, until you hover it —
   the day is the label as well as the button. */
.uf-datepick-wrap { position: relative }

.uf-datepick {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 8px; border: 0; border-radius: 8px;
  background: transparent; color: inherit;
  font: inherit; font-weight: 700; cursor: pointer;
}

.uf-datepick:hover { background: var(--bg-2) }

.uf-datepick-caret {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--text-3);
}

.uf-datepick[aria-expanded="true"] .uf-datepick-caret { transform: rotate(180deg) }

.uf-cal {
  position: absolute; z-index: 30; top: calc(100% + 8px); left: 50%;
  transform: translateX(-50%);
  width: 300px; padding: 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .16);
}

.uf-cal[hidden] { display: none }

.uf-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px }
.uf-cal-title { font-family: 'Archivo', sans-serif; font-weight: 700; font-size: 15px }

.uf-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px }

.uf-cal-dow {
  padding-bottom: 6px;
  color: var(--text-3);
  font-size: 11px; font-weight: 600; text-align: center;
}

.uf-cal-day {
  aspect-ratio: 1;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--text-1);
  font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
}

.uf-cal-day:hover { background: var(--bg-2) }
.uf-cal-day.out { color: var(--text-3); font-weight: 400 }

/* Today is outlined, the selected day is filled — two different marks, so the
   two states stay distinguishable when they land on the same cell. */
.uf-cal-day.today { box-shadow: inset 0 0 0 1px var(--border) }
.uf-cal-day.on { background: var(--primary-dark); color: #fff }
.uf-cal-day.on:hover { background: var(--primary-dark) }

@media (max-width: 400px) { .uf-cal { width: 264px } }

.uf-group {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 13px 18px;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: #f5f5f5;
  color: var(--primary-dark);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.uf-group[aria-expanded="false"] { border-bottom: 0 }
.uf-group:hover { background: #E5E7EB }

.uf-group .ml-chevron { transform: rotate(90deg); transition: transform .4s ease }
.uf-group[aria-expanded="false"] .ml-chevron { transform: none }
/* Collapse animates via the 0fr/1fr grid-row trick — display:none can't
   transition. The inner wrapper clips the rows while the track shrinks. */
.uf-group-body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .4s ease }
.uf-group[aria-expanded="false"] + .uf-group-body { grid-template-rows: 0fr }
.uf-group-body-in { overflow: hidden; min-height: 0; display: flex; flex-direction: column }

/* An empty competition is a one-line note, not a full empty state. */
.uf-group-body .uf-empty { padding: 14px 18px; font-size: 13px }

/* ── match rows inside a card ──
   site.css styles .ml-row as a standalone card (border, radius, hover scale).
   Inside a group card that reads as cards-in-cards, so it is flattened here. */
.uf-card .ml-row {
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
}

.uf-card .ml-row:last-child { border-bottom: 0 }
.uf-card .ml-row:hover { transform: none; box-shadow: none; background: var(--bg-2) }

.uf-group-card { overflow: hidden }
.uf-group-card + .uf-group-card { margin-top: 16px }

@media (prefers-reduced-motion: reduce) {
  .uf-group .ml-chevron, .uf-group-body { transition: none }
  .uf-slide-l, .uf-slide-r { animation: none }
}

/* standings pager: new league slides in from the direction of travel */
/* cards rise in when data replaces the skeleton — load only, not re-renders */
@keyframes uf-rise { from { transform: translateY(10px); opacity: 0 } to { transform: none; opacity: 1 } }
.uf-enter > * { animation: uf-rise .35s ease backwards }
.uf-enter > :nth-child(2) { animation-delay: .07s }
.uf-enter > :nth-child(3) { animation-delay: .14s }
.uf-enter > :nth-child(4) { animation-delay: .21s }
.uf-enter > :nth-child(n+5) { animation-delay: .28s }
@media (prefers-reduced-motion: reduce) {
  .uf-enter > * { animation: none }
}

@keyframes uf-slide-r { from { transform: translateX(28px); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes uf-slide-l { from { transform: translateX(-28px); opacity: 0 } to { transform: none; opacity: 1 } }
.uf-slide-r { animation: uf-slide-r .35s ease }
.uf-slide-l { animation: uf-slide-l .35s ease }

.uf-collapse {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  color: var(--text-3);
  padding: 6px 10px;
  cursor: pointer;
}

.uf-collapse:hover { color: var(--primary-dark); border-color: var(--primary-dark) }

.uf-filter {
  flex: 1;
  min-width: 0;
  margin-left: auto;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-2);
  font: inherit;
  font-size: 13px;
}

.uf-select {
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: inherit;
  font: inherit;
  font-size: 13px;
  margin: 12px 0 4px;
}

.uf-select-inline { margin: 0 0 20px; max-width: 220px }

.uf-empty { color: var(--text-3); font-size: 14px; line-height: 1.6; padding: 24px 16px; text-align: center }
.uf-empty strong { color: var(--text-2); font-weight: 600 }

/* Empty fixture list: sad U-Bao with a deflated ball, greyed by CSS so the
   asset stays full-colour and reusable. Decorative only — the one-line
   sentence carries the meaning, the image just softens it. */
.uf-empty--nofix { padding: 32px 16px }
.uf-empty--nofix::before {
  content: ''; display: block; margin: 0 auto 10px;
  width: 180px; height: 180px;
  background: url(assets/img/mascot-empty.webp) center/contain no-repeat;
  filter: grayscale(1); opacity: .55;
}

/* Loading — U-Bao instead of the loading text. A 4KB static still moved
   by CSS: frame animation (WebP/GIF/Lottie) all lost the race with the data —
   by the time the frames downloaded, the content had arrived. The still is
   cached after first paint, so he can never appear late again.
   Hidden for the first .6s so fast fetches never flash a spinner. */
/* font-size:0 hides the wording without hiding the element: the running mascot
   is the whole message on screen, and the sentence stays in the accessibility
   tree for screen readers. JS drops .uf-loading when it swaps in a real
   message, which restores the text. */
.uf-loading { font-size: 0 }
.uf-loading::before {
  content: ''; display: block; margin: 0 auto 4px;
  width: 110px; height: 110px;
  background: url(assets/img/mascot-loading-still.webp) center/contain no-repeat;
  opacity: 0;
  animation:
    uf-loading-in .4s ease .6s forwards,
    uf-loading-run .5s ease-in-out .6s infinite alternate;
}
@keyframes uf-loading-in { to { opacity: 1 } }
/* Run-bob: the stride pose + vertical bounce and a slight lean reads as running. */
@keyframes uf-loading-run {
  from { transform: translateY(0) rotate(-2deg) }
  to   { transform: translateY(-7px) rotate(2deg) }
}
@media (prefers-reduced-motion: reduce) {
  .uf-loading::before { animation: uf-loading-in .4s ease .6s forwards }
}

/* 404 — image already reads "404", so no heading. One line, one way home. */
.uf-404 {
  max-width: 440px; margin: 48px auto 80px;
  padding: 28px 24px 36px; text-align: center;
}
.uf-404 img { display: block; margin: 0 auto; width: 280px; max-width: 100%; height: auto }
.uf-404-line { margin: 4px 0 22px; color: var(--text-2); font-size: 16px }
.uf-404-home {
  display: inline-block; padding: 10px 22px; border-radius: 12px;
  background: var(--primary, #009E4F); color: #fff; font-weight: 600;
  text-decoration: none;
}
.uf-404-home:hover { filter: brightness(1.06) }

/* ── contrast corrections ──
   #009E4F is 3.50:1 on white — fine as a fill or for large display type, short of
   AA for 11-13px labels. Small green text uses the darker brand green (5.45:1).
   Same reason the CTA fill and the W/L badges are darkened: white on #009E4F is
   also 3.50:1. */

.ml-tab.on,
.ps-tab.on,
.st-pos,
.tn-sec-see,
.uf-group { color: var(--primary-dark) }

.ps-tab.on { border-bottom-color: var(--primary-dark) }

.hero-cta { background: var(--primary-dark) }
.hero-cta:hover { background: #00632F }

.ml-odds-col.is-active .ml-odds-lbl,
.ml-odds-col.is-active .ml-odds-val { color: var(--primary-dark) }

/* ── the pick, stated in words ──
   A green ring is invisible to red-green deficiency, so the word carries it. */
.uf-pick-tag {
  margin-left: 5px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--primary-light);
  color: var(--primary-dark);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* ── live status ── */

.uf-live { display: inline-flex; align-items: center; gap: 5px; color: var(--red-dark); font-weight: 600 }

.uf-live-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--red-dark);
  animation: uf-pulse 1.6s ease-in-out infinite;
}

@keyframes uf-pulse { 50% { opacity: .25 } }

/* A goal is the one state change worth animating — the number moved and the
   reader needs to catch it. */
.uf-scored { animation: uf-scored 1.8s ease-out }

@keyframes uf-scored {
  0%   { background: var(--primary-light); border-color: var(--primary) }
  100% { background: #fff; border-color: var(--border) }
}

@media (prefers-reduced-motion: reduce) {
  .uf-live-dot, .uf-scored { animation: none }
  .uf-scored { border-color: var(--primary) }
}

/* Last-5 form badges — the standings table in site.css has no form column. */
.uf-form {
  display: inline-grid;
  place-items: center;
  width: 17px; height: 17px;
  margin-right: 3px;
  border-radius: 50%;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
}

.st-table td:last-child { white-space: nowrap }

.uf-form.f-W { background: var(--primary-dark) }
.uf-form.f-D { background: var(--text-3) }
.uf-form.f-L { background: var(--red-dark) }

.uf-center { align-self: center }

/* Polylang emits .lang-item links; map them onto the .lang-btn look. */
.lang-sw { list-style: none }
.lang-sw .lang-item a { display: block; padding: 4px 11px; font-size: 11px; font-weight: 700; letter-spacing: .05em; color: var(--text-3); text-decoration: none; text-transform: uppercase }
.lang-sw .current-lang a { background: var(--primary-dark); color: #fff }

.uf-social { display: flex; gap: 14px; list-style: none; margin: 0; padding: 0 }
.uf-social a { color: var(--text-2); text-decoration: none }

/* ── posts (index / archive / single) ── */

.uf-post-list { display: grid; gap: 16px }

.uf-post-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}

.uf-post-card h2 { font-size: 19px; margin-bottom: 6px }
.uf-post-card h2 a { color: var(--text); text-decoration: none }
.uf-post-date { color: var(--text-3); font-size: 13px }

.uf-entry { max-width: 720px; margin: 0 auto; padding: 40px 24px }
.uf-entry-title { font-family: 'Archivo', sans-serif; font-weight: 800; font-size: 30px; margin-bottom: 8px }
.uf-entry-content { margin-top: 28px; font-size: 16px; line-height: 1.75; color: var(--text-1) }
/* Body links: brand color + weight instead of the browser's blue underline;
   the underline returns on hover as the affordance. */
.uf-entry-content a { color: var(--primary-dark, #007A3D); font-weight: 600; text-decoration: none }
.uf-entry-content a:hover { text-decoration: underline }

/* reading rhythm: headings get extra air above, lists breathe */
.uf-entry-content h2 { font-size: 24px; line-height: 1.25; margin-top: 36px }
.uf-entry-content h3 { font-size: 19px; line-height: 1.3; margin-top: 28px }
.uf-entry-content li + li { margin-top: 8px }

/* in-article affiliate CTA — markup ships inside post content (.ma-cta) */
.ma-cta { margin-top: 28px }
.ma-cta-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 28px 32px;
  background: linear-gradient(120deg, #07452A, #0B6B3D);
  border-radius: var(--radius-lg);
  color: #fff;
}
.ma-cta-text { flex: 1; font-size: 16px; line-height: 1.6 }
.ma-cta-text strong { display: block; font-size: 19px; margin-bottom: 6px }
.uf-entry-content a.ma-cta-btn {
  flex-shrink: 0;
  padding: 14px 30px;
  background: #E9A62A;
  border-radius: 10px;
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  text-decoration: none;
}
.uf-entry-content a.ma-cta-btn:hover { filter: brightness(1.08); text-decoration: none }
@media (max-width: 560px) {
  .ma-cta-inner { flex-direction: column; align-items: flex-start; gap: 16px }
}
.uf-entry-content > * + * { margin-top: 16px }
/* Article images come from the old editor with no width/height attributes and
   sources up to 1920px, so with only a border-radius here they rendered at
   natural size and blew the column open.
   width/height:auto keeps a small image small rather than stretching it, and
   the two maxima together preserve the aspect ratio. max-height matters as much
   as max-width: a square club crest constrained only by width becomes a full
   screen of logo on the way down the article. */
.uf-entry-content img {
  max-width: 100%;
  max-height: 520px;
  width: auto;
  height: auto;
  border-radius: 8px;
}

@media (max-width: 900px) {
  .uf-split, .uf-split-even { grid-template-columns: minmax(0, 1fr) }
  #sec-matches { margin-top: -32px }
}


/* ── match row: teams centred, no verdict column ── */

.uf-card .ml-row { gap: 12px }

/* The side blocks are pinned to fixed widths, otherwise the "pick" tag widens
   whichever odds column is active and pushes the flexible middle off-centre —
   the VS then lands somewhere different on every row. */
.uf-card .ml-time-block { flex: 0 0 84px; width: 84px }
.uf-card .ml-odds-block { flex: 0 0 228px; width: 228px; display: flex; gap: 6px }

/* Chevron shrinks to the glyph so the prediction block sits flush at the row's
   end instead of floating 68px short of it. */
.uf-card .ml-row > .ml-chevron { flex: 0 0 auto; text-align: right }
.uf-card .ml-odds-col { flex: 1 1 0; min-width: 0; padding: 8px 4px }
.uf-card .ml-odds-lbl { display: flex; align-items: center; justify-content: center; gap: 4px }

/* Equal side columns then park the VS pill on the row's centre line, so it lands
   in the same place regardless of how long the team names are. */
.uf-card .ml-teams-block {
  flex: 1;
  display: grid;
  /* minmax(0, 1fr), not 1fr: a plain fr track floors at min-content, so a long
     name like "Nottingham Forest" widens its own side and shoves the pill off
     the centre line. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
}

.uf-card .ml-team-pair { min-width: 0 }
/* Long names wrap to two lines instead of stretching the row — site.css says
   nowrap; the clamp keeps a runaway name from making a three-line row. */
.uf-card .ml-team-pair span {
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  line-height: 1.25;
}
.uf-card .ml-team-pair:first-child { justify-content: flex-end; text-align: right }
.uf-card .ml-team-pair:last-child { justify-content: flex-start; text-align: left }

/* ── standings rail ──
   Sidebar card matching the reference: league pager on top, compact table below. */

/* Both homepage columns are sticky: sticky is inert on whichever column is
   taller (it defines the row height), so only the shorter side follows the
   scroll — sidebar on busy matchdays, match list on quiet ones. Harmless in
   the stacked mobile layout, where each grid row is its own height. */
/* 80px = 64px sticky header + 16px breathing room, so a pinned column's top
   isn't hidden under the header. */
.uf-side { display: grid; gap: 16px; align-content: start; min-width: 0; position: sticky; top: 80px }

/* ponytail: Top leagues card temporarily hidden — delete this rule to restore. */
.uf-side > .uf-card:not(.uf-standings) { display: none }

/* league badge beside the group header name */
.uf-group-name { display: inline-flex; align-items: center; gap: 9px }
.uf-group-badge { width: 22px; height: 22px; object-fit: contain }
.uf-group .ml-chevron svg { display: block; width: 12px; height: 12px }
/* triangle points down when open, flips up when collapsed (base icon points right) */
.uf-group[aria-expanded="false"] .ml-chevron { transform: rotate(-90deg) }
#sec-matches .uf-main { position: sticky; top: 80px }
.uf-side > * { min-width: 0 }

.uf-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
}

.uf-dots { display: flex; align-items: center; gap: 6px }

.uf-dot {
  width: 7px; height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--bg-3);
  cursor: pointer;
  transition: background .18s;
}

.uf-dot.on { background: var(--primary-dark) }
.uf-dot:hover { background: var(--text-3) }

#standings-head .uf-standings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 18px 14px;
}

.uf-standings-name {
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--text);
}

.uf-standings-country { font-size: 13px; color: var(--text-3) }

.uf-standings-badge {
  width: 32px; height: 32px;
  object-fit: contain;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 50%;
  box-sizing: content-box;
}

.uf-mini-table { font-size: 13px }
.uf-mini-table thead th { padding: 8px 6px; background: transparent }
/* Fixed layout takes column widths from the first row. Sizing the numeric
   columns and leaving the team column auto keeps the total at exactly 100% —
   width:100% on the team column would add to the others, not absorb them. */
.uf-mini-table thead th:nth-child(1) { width: 26px }
.uf-mini-table thead th:nth-child(2) { width: auto }
.uf-mini-table thead th:nth-child(3) { width: 34px }
.uf-mini-table thead th:nth-child(4) { width: 42px }
.uf-mini-table thead th:nth-child(5) { width: 40px }
.uf-mini-table tbody td { padding: 9px 6px; border-bottom: 0 }

/* Full table (match page): ten columns, so every one but the name is a narrow
   number. These tie with the :nth-child rules above on specificity — they have
   to stay below them to win. */
.uf-mini-table.st-table-full thead th { width: 34px }
.uf-mini-table.st-table-full thead th:nth-child(1) { width: 26px }
.uf-mini-table.st-table-full thead th:nth-child(2) { width: auto }
/* Below this the name column would be crushed instead of the table scrolling. */
.uf-mini-table.st-table-full { min-width: 520px }
.st-table-wrap:has(.st-table-full) { overflow-x: auto }
.uf-mini-table tbody tr:hover { background: var(--bg-2) }
.uf-mini-table .st-pos { width: 22px; text-align: center; color: var(--text-3) }
.uf-mini-table .st-team-cell { gap: 8px; text-align: left }
.uf-mini-table .st-name { font-weight: 500; color: var(--text) }
.uf-mini-table .st-pts { color: var(--text) }
.uf-mini-table td:first-child { padding-left: 12px }
.uf-mini-table td:last-child { padding-right: 14px }

/* Qualification zones - supplementary to the position number, never the only cue. */
.st-qualify-bar { width: 3px; height: 20px; border-radius: 2px; flex-shrink: 0 }
.st-qualify-bar.ucl { background: var(--primary) }
.st-qualify-bar.uel { background: #2F6FED }
.st-qualify-bar.grey { background: transparent }

/* Segmented control: a view switcher, not navigation. Three equal segments on a
   grey track keep all three labels visible at 290px. */
.uf-seg {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  margin: 0 14px 14px;
  padding: 3px;
  background: var(--bg-2);
  border-radius: 10px;
}

.uf-seg-btn {
  padding: 7px 4px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--text-3);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .18s, color .18s;
}

.uf-seg-btn:hover { color: var(--text) }

.uf-seg-btn.on {
  background: var(--bg);
  color: var(--primary-dark);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}

@media (prefers-reduced-motion: reduce) {
  .uf-seg-btn { transition: none }
}

.uf-standings .ps-list { margin-top: 0; padding: 0 12px 12px; gap: 6px }
.uf-standings .ps-row { padding: 8px 10px; backdrop-filter: none; background: var(--bg-2); border-color: var(--border) }
.uf-standings .ps-row { min-width: 0 }
.uf-standings .ps-avatar { flex-shrink: 0 }
.uf-standings .ps-name-team { min-width: 0; flex: 1 }
.uf-standings .ps-player-name,
.uf-standings .ps-team-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block }
.uf-standings .ps-value { flex-shrink: 0 }

/* Same reason on the table: a long club name shouldn't stretch the card. */
.uf-mini-table { table-layout: fixed; width: 100% }
.uf-mini-table .st-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.uf-mini-table .st-team-cell { min-width: 0 }
.uf-standings .uf-empty { padding: 8px 18px 20px }

/* ── trending news ── */

/* The design system styles .tn-feat-title / .tn-sec-title, but the titles are
   links here — without this they fall back to browser-default blue underline. */
.tn-feat-title a,
.tn-sec-title a,
.tn-sec-row,
.tn-sec-row:hover { color: inherit; text-decoration: none }

.tn-feat-title a:hover { color: var(--primary-dark) }

.tn-featured, .tn-secondary {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 14px;
}

.tn-featured { gap: 0 }
.tn-feat-img { border-radius: var(--radius); overflow: hidden }
.tn-feat-img img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover }
.tn-feat-content { padding: 16px 4px 8px }
.tn-feat-title { margin-bottom: 10px }
.tn-feat-excerpt { margin-bottom: 20px }
.tn-featured .hero-cta { align-self: center }

.tn-secondary { gap: 0; justify-content: flex-start }
.tn-sec-row { padding: 10px 0; align-items: flex-start; gap: 14px }
.tn-sec-thumb { flex-shrink: 0; width: 150px; border-radius: 10px; overflow: hidden }
.tn-sec-thumb img { width: 100%; aspect-ratio: 16 / 11; object-fit: cover; display: block }
.tn-sec-body { display: flex; flex-direction: column; gap: 4px }
.tn-secondary .hero-cta { align-self: center; margin-top: 14px }

@media (max-width: 560px) {
  .tn-sec-thumb { width: 108px }
}

/* ── trending news v2 — featured story + "Latest News" card grid.
   The .tn- rules above serve the old layout, kept commented out in
   front-page.php for restore. ── */

/* The whole news section as one big card, same surface as the rest of the site. */
.tn2-wrap {
  padding: 24px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.tn2-featured {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 32px;
  align-items: center;
  margin-bottom: 36px;
}
.tn2-feat-img { display: block; border-radius: var(--radius); overflow: hidden }
/* height:auto beats the width/height attrs WP prints, letting aspect-ratio rule */
.tn2-feat-img img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover }

.tn2-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; color: var(--text-3); font-size: 13px }
.tn2-dot { font-size: 10px }

.tn2-feat-title { margin: 10px 0 12px; font-size: clamp(24px, 2.6vw, 34px); line-height: 1.15 }
.tn2-feat-title a, .tn2-card-title a { color: var(--text-1); text-decoration: none }
.tn2-feat-title a:hover, .tn2-card-title a:hover { color: var(--primary-dark) }

.tn2-excerpt { margin: 0 0 14px; color: var(--text-2); font-size: 15px; line-height: 1.6 }
.tn2-card-excerpt {
  font-size: 13px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
}

.tn2-foot { display: flex; align-items: center; gap: 6px; color: var(--text-3); font-size: 13px }
.tn2-cat { color: var(--primary-dark); font-weight: 700; text-decoration: none }
.tn2-cat:hover { text-decoration: underline }

.tn2-latest-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 18px }
.tn2-latest-head .tn-header { margin-bottom: 0 }
.tn2-seeall { color: var(--primary-dark); font-weight: 700; font-size: 14px; text-decoration: none }
.tn2-seeall:hover { text-decoration: underline }

.tn2-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px }
.tn2-card { display: flex; flex-direction: column }
/* Ratio + placeholder live on the wrapper, so a post with no featured image
   still holds the same box and the card text stays aligned across the row. */
.tn2-card-img { display: block; aspect-ratio: 4 / 3; background: var(--bg-2); border-radius: var(--radius); overflow: hidden; margin-bottom: 12px }
.tn2-card-img img { display: block; width: 100%; height: 100%; object-fit: cover }
.tn2-card-title { margin: 6px 0 8px; font-size: 17px; line-height: 1.3 }
.tn2-card .tn2-excerpt { margin-bottom: 10px }
.tn2-card .tn2-foot { margin-top: auto }

@media (max-width: 900px) {
  .tn2-featured { grid-template-columns: 1fr; gap: 16px }
  .tn2-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) }
}
@media (max-width: 520px) {
  .tn2-grid { grid-template-columns: minmax(0, 1fr) }
}

/* ── news page (/news/) — trending banner, league tabs, card grid ── */

.np-banner {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 21 / 9;
  background: var(--text-1, #111);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  color: #fff;
  text-decoration: none;
  margin-bottom: 24px;
}
.np-banner > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover }
/* Frosted-glass strip across the banner's bottom. The solid rgba is the
   fallback; @supports lightens it once backdrop-filter carries the legibility. */
.np-banner-body {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px 28px 18px;
  background: rgba(10, 14, 18, .78);
  border-top: 1px solid rgba(255, 255, 255, .18);
}
@supports (backdrop-filter: blur(1px)) {
  /* Darkness comes from brightness() on the backdrop, not a heavy overlay —
     that keeps the translucency that reads as glass. The white top gradient
     is the gloss highlight. */
  .np-banner-body {
    background: linear-gradient(180deg, rgba(255, 255, 255, .09), rgba(255, 255, 255, 0) 45%), rgba(10, 14, 18, .35);
    backdrop-filter: blur(20px) saturate(.85) brightness(.5);
    -webkit-backdrop-filter: blur(20px) saturate(.85) brightness(.5);
  }
}
.np-banner-title { font-family: var(--font-display, inherit); font-size: clamp(20px, 2.6vw, 32px); font-weight: 800; line-height: 1.2; text-shadow: 0 1px 3px rgba(0, 0, 0, .8) }
.np-banner-sub {
  color: rgba(255, 255, 255, .85);
  font-size: 15px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.np-banner-meta { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: 13px; color: rgba(255, 255, 255, .85) }
.np-banner-meta .avatar { border-radius: 50%; }
.np-pills { display: flex; gap: 8px; margin-left: auto }
.np-pill { padding: 4px 12px; border: 1px solid rgba(255, 255, 255, .7); border-radius: 999px; background: rgba(0, 0, 0, .3); font-size: 12px; font-weight: 600 }

.np-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 22px }
.np-tab {
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text-2);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.np-tab:hover { border-color: var(--primary-dark); color: var(--primary-dark) }
.np-tab.on { background: var(--primary); border-color: var(--primary); color: #fff }
.np-search { margin-left: auto }
.np-search input {
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  font: inherit;
  font-size: 14px;
  min-width: 200px;
}

/* main + sidebar split */
.np-split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start }
/* Same 80px rail offset as .uf-side / .sp-stick — clears the sticky header.
   The stack is ~865px, so it fits a laptop viewport; no bottom-edge trick. */
.np-side { position: sticky; top: 80px }
.np-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) }

/* article cards get card chrome on this page */
.np-main .tn2-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.np-main .tn2-card-img { border-radius: 0; margin-bottom: 0 }
.tn2-card-body { display: flex; flex-direction: column; flex: 1; gap: 8px; padding: 14px 16px 16px }
.tn2-card-body .tn2-card-title, .tn2-card-body .tn2-excerpt { margin: 0 }

/* featured story card */
.np-featured {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 24px;
}
.np-feat-img { position: relative; display: block; aspect-ratio: 16 / 7; background: var(--bg-2) }
.np-feat-img img { display: block; width: 100%; height: 100%; object-fit: cover }
.np-feat-badge {
  position: absolute;
  top: 14px;
  left: 14px;
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.np-feat-body { display: flex; flex-direction: column; gap: 8px; padding: 16px 20px 20px }
.np-feat-title { font-size: 22px; line-height: 1.25; margin: 0 }
.np-feat-title a { color: var(--text-1); text-decoration: none }
.np-feat-title a:hover { color: var(--primary-dark) }
.np-feat-body .tn2-excerpt { margin: 0 }

/* sidebar widgets */
.np-widget {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 16px;
}
.np-widget + .np-widget { margin-top: 20px }
.np-widget-title { font-size: 16px; font-weight: 800; margin-bottom: 12px }

.np-trow { display: flex; gap: 10px; padding: 7px 0; color: inherit; text-decoration: none }
.np-trow-thumb { flex: 0 0 84px; aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden; background: var(--bg-2) }
.np-trow-thumb img { display: block; width: 100%; height: 100%; object-fit: cover }
.np-trow-body { display: flex; flex-direction: column; gap: 4px; min-width: 0 }
.np-trow-title {
  font-size: 13px; font-weight: 700; line-height: 1.35;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.np-trow:hover .np-trow-title { color: var(--primary-dark) }
.np-trow-read { font-size: 12px; color: var(--text-3) }

/* today's top match — green card, engine-fed */
.np-topmatch { background: linear-gradient(160deg, #0B5E34, var(--primary)); border: 0; color: #fff }
.np-topmatch .np-widget-title { color: #fff }
.np-topmatch .uf-empty { color: rgba(255, 255, 255, .8) }
.tm-sub { font-size: 13px; color: rgba(255, 255, 255, .8); margin-bottom: 12px }
.tm-teams { display: flex; align-items: center; gap: 8px }
.tm-team { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; text-align: center; min-width: 0 }
.tm-team img { width: 44px; height: 44px; object-fit: contain }
.tm-vs { font-weight: 800; font-size: 14px }
.tm-btn {
  display: block;
  margin-top: 14px;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, .4);
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}
.tm-btn:hover { background: rgba(255, 255, 255, .24) }

/* newsletter */
.np-sub-text { font-size: 13px; color: var(--text-2); margin-bottom: 12px }
.np-sub input[type="email"] {
  width: 100%;
  padding: 10px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font: inherit;
  font-size: 14px;
  margin-bottom: 10px;
}
.np-sub button {
  width: 100%;
  padding: 10px;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.np-sub button:hover { background: var(--primary-dark, #007A3D) }
.np-sub-note { font-size: 12px; color: var(--text-3); text-align: center; margin-top: 10px }
.np-sub-ok { font-size: 14px; font-weight: 600; color: var(--primary-dark, #007A3D) }

/* skeleton cards shown while the ajax filter loads */
.np-sk { display: flex; flex-direction: column; gap: 10px }
.np-sk-img, .np-sk-line {
  background: linear-gradient(90deg, var(--bg-2) 25%, var(--border) 37%, var(--bg-2) 63%);
  background-size: 400% 100%;
  animation: np-shimmer 1.2s linear infinite;
}
.np-sk-img { aspect-ratio: 4 / 3; border-radius: var(--radius) }
.np-sk-line { height: 14px; border-radius: 6px }
.np-sk-line.w40 { width: 40% }
.np-sk-line.w80 { width: 80% }
@keyframes np-shimmer {
  from { background-position: 100% 0 }
  to   { background-position: 0 0 }
}
@media (prefers-reduced-motion: reduce) {
  .np-sk-img, .np-sk-line { animation: none }
}

.np-pager { display: flex; justify-content: center; gap: 6px; margin-top: 28px }
.np-pager .page-numbers {
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text-2);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.np-pager .page-numbers.current { background: var(--primary); border-color: var(--primary); color: #fff }
.np-pager .page-numbers:hover:not(.current) { border-color: var(--primary-dark); color: var(--primary-dark) }

@media (max-width: 900px) {
  .np-banner { aspect-ratio: 16 / 10 }
  .np-pills { display: none }
  .np-split { grid-template-columns: minmax(0, 1fr) }
  .np-side { position: static }
  .np-search { margin-left: 0; width: 100% }
  .np-search input { width: 100% }
}
@media (max-width: 520px) {
  .np-grid { grid-template-columns: minmax(0, 1fr) }
}

/* ── page texture ──
   Brand texture behind the whole page. A fixed ::before layer instead of
   background-attachment: fixed, which repaints badly on mobile Safari. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--bg-2) url(assets/img/page-texture.webp) center / cover no-repeat;
  pointer-events: none;
}

/* ── footer — brand + stats band, link columns, copyright ── */

.ft { background: #fff; border-top: 1px solid var(--border) }
.ft-top { background-color: #fff; background-size: cover; background-position: center; border-bottom: 1px solid var(--border) }
.ft-top-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 44px 24px;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 40px;
  align-items: center;
}
.ft-brand img { display: block; width: 240px; height: auto }
.ft-desc { margin-top: 14px; max-width: 360px; color: var(--text-2); font-size: 15px; line-height: 1.6 }
.ft-accent { display: block; width: 48px; height: 3px; margin-top: 16px; border-radius: 2px; background: var(--gold, #CFA761) }
.ft-stats { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center }
.ft-stats .stat-col + .stat-col { border-left: 1px solid var(--border) }

.ft-cols {
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 24px 36px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 32px;
}
.ft-col-title { font-size: 14px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase }
.ft-col-title::after { content: ''; display: block; width: 32px; height: 3px; margin-top: 8px; border-radius: 2px; background: var(--gold, #CFA761) }
.ft-col ul { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 12px; justify-items: start }
.ft-col a { color: var(--text-2); font-size: 14px; text-decoration: none }
.ft-col a:hover { color: var(--primary-dark) }
/* Rounded chip per network rather than a bare glyph: the squircle gives the
   three rows one silhouette, and the surface is what carries the hover state —
   colouring a hairline glyph green reads as a rendering fault, filling a tile
   reads as a button. --radius on a 36px box is the same 1:3 curve the cards use. */
.ft-soc { display: inline-flex; align-items: center; gap: 10px }
.ft-soc-ic {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--radius);
  background: var(--bg-2);
  color: var(--text-2);
  transition: background .18s, color .18s, transform .18s;
}
.ft-soc svg { width: 19px; height: 19px }
.ft-soc:hover .ft-soc-ic,
.ft-soc:focus-visible .ft-soc-ic {
  background: var(--primary);
  color: #fff;
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .ft-soc-ic { transition: none }
  .ft-soc:hover .ft-soc-ic { transform: none }
}

.ft .copyright-bar { border-top: 1px solid var(--border) }

@media (max-width: 900px) {
  .ft-top-inner { grid-template-columns: minmax(0, 1fr); gap: 28px }
  .ft-cols { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .ft-brand img { width: 132px } /* matches the header logo's visual weight */
}
@media (max-width: 520px) {
  .ft-cols { grid-template-columns: minmax(0, 1fr) }
}

/* ── match rows on mobile: three stacked rows — time / teams / prediction ── */
@media (max-width: 640px) {
  .uf-card .ml-row { flex-wrap: wrap; gap: 10px }
  .uf-card .ml-time-block { flex: 1 1 100%; width: auto; display: flex; align-items: baseline; gap: 8px }
  .uf-card .ml-teams-block { flex: 1 1 100% }
  .uf-card .ml-odds-block { flex: 1 1 100%; width: 100% }
  .uf-card .ml-row > .ml-chevron { display: none }
}

/* ── mobile bottom nav ── */

.bn { display: none }

@media (max-width: 900px) {
  .bn {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 90;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    background: var(--bg);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, .06);
  }
  .bn-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 9px 0 7px;
    color: var(--text-3);
    font-size: 11px;
    font-weight: 600;
    text-decoration: none;
  }
  .bn-item svg { width: 22px; height: 22px }
  .bn-item.on { color: var(--primary-dark, #007A3D) }
  body { padding-bottom: calc(58px + env(safe-area-inset-bottom)) }

  /* homepage view switch — gated on .uf-bn (set by JS) so no-JS still stacks both */
  body.uf-bn:not(.uf-view-leagues) #sec-matches .uf-side { display: none }
  body.uf-bn.uf-view-leagues #sec-matches .uf-main { display: none }
  /* the News tab covers it — the homepage news section is redundant on mobile */
  body.uf-bn #sec-news { display: none }

  /* toolbar: date row, tab row, then the filter full-width on its own row */
  .ml-tabs { flex-wrap: wrap }
  .ml-tabs .uf-filter { flex: 1 1 100%; order: 9 }

  /* footer columns as accordions — titles only until tapped */
  .ft-col-title { cursor: pointer; position: relative }
  .ft-col-title::before {
    content: '';
    position: absolute;
    right: 0;
    top: 4px;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--text-3);
    border-bottom: 2px solid var(--text-3);
    transform: rotate(45deg);
    transition: transform .18s;
  }
  .ft-col.open .ft-col-title::before { transform: rotate(225deg) }
  .ft-col ul { display: none }
  .ft-col.open ul { display: grid }
  .ft-cols { gap: 20px }
}
@media (prefers-reduced-motion: reduce) {
  .ft-col-title::before { transition: none }
}

/* ── static pages — green hero band + centered content card ── */

.pg-hero { background: linear-gradient(135deg, #07452A, #0B6B3D); color: #fff }
.pg-hero-inner { max-width: 1140px; margin: 0 auto; padding: 40px 20px 36px }
.pg-hero .sp-crumb span:last-child { color: rgba(255, 255, 255, .9) }
.pg-title { font-size: clamp(26px, 3vw, 36px); line-height: 1.15 }

.pg-entry {
  max-width: 900px;
  margin: 0 auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 12px 36px 32px;
}
/* Legacy builder-era pages carry full-size images; cap them so a logo export
   can't fill the viewport. */
.pg-entry img { max-width: 100%; height: auto; max-height: 420px; object-fit: contain }
.pg-entry .uf-entry-content { margin-top: 16px }

/* ── single post — hero, author sidebar, widgets, related ── */

/* The hero band is far wider than a 16:9 featured image, so cover crops top and
   bottom. Anchoring at 25% from the top keeps faces (upper third of most sports
   shots) in frame; the horizontal gradient darkens only the text side. */
.sp-hero {
  position: relative;
  background: #10151a 50% 25% / cover no-repeat;
  background-image: linear-gradient(90deg, rgba(8, 12, 16, .88) 0%, rgba(8, 12, 16, .68) 45%, rgba(8, 12, 16, .28) 100%), var(--sp-bg, none);
  color: #fff;
}
.sp-hero { display: flex; align-items: center; min-height: clamp(340px, 38vw, 480px) }
.sp-hero-inner { width: 100%; max-width: 1140px; margin: 0 auto; padding: 48px 20px }
.sp-crumb { display: flex; gap: 8px; font-size: 13px; color: rgba(255, 255, 255, .7); margin-bottom: 16px }
.sp-crumb a { color: inherit; text-decoration: none }
.sp-crumb a:hover { color: #fff }
.sp-cat-pill {
  display: inline-block;
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  text-decoration: none;
  margin-bottom: 14px;
}
.sp-title { max-width: 720px; font-size: clamp(26px, 3.4vw, 40px); line-height: 1.15; margin-bottom: 14px }
.sp-excerpt { max-width: 620px; color: rgba(255, 255, 255, .85); font-size: 15px; line-height: 1.6; margin-bottom: 16px }
.sp-meta { display: flex; align-items: center; gap: 8px; font-size: 13px; color: rgba(255, 255, 255, .85) }
.sp-meta .avatar { border-radius: 50% }

.sp-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start }
/* margin-top: 0 overrides the shared 28px rule above — that gap belongs to
   static pages (title → text); here the grid already spaces the card. */
.sp-main .uf-entry-content { margin-top: 0; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 20px 32px 28px }

/* Sidebar widgets follow the scroll so the rail isn't blank beside a long
   article. The aside stretches to the row; the inner wrapper does the sticking. */
.sp-right { align-self: stretch }
.sp-stick { position: sticky; top: 80px }

.sp-author { display: flex; gap: 12px }
.sp-author .avatar { border-radius: 50%; flex-shrink: 0 }
.sp-author-name { font-weight: 800; margin-bottom: 4px }
.sp-author-bio { font-size: 13px; color: var(--text-2); line-height: 1.5 }

/* numbered rank badge on popular thumbnails */
.sp-num { position: relative }
.sp-num::before {
  content: attr(data-n);
  position: absolute;
  top: 4px;
  left: 4px;
  z-index: 1;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* tags left, share right, one row */
.sp-foot { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 24px; margin-top: 18px }
.sp-tags, .sp-share { display: flex; align-items: center; flex-wrap: wrap; gap: 8px }
.sp-tags-label { font-size: 13px; font-weight: 700; color: var(--text-2) }
.sp-tag {
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.sp-tag:hover { border-color: var(--primary-dark); color: var(--primary-dark) }

/* ── match-analysis posts (Analysis category) ──
   Markup ships inside post content (.match-analysis). Each section renders as
   its own card, so the article's outer card unwraps for these posts. */
.sp-main .uf-entry-content:has(> .match-analysis) { background: none; border: 0; box-shadow: none; padding: 0 }

.match-analysis > * + * { margin-top: 24px }
/* wpautop wraps the section comments in the post body as stray zero-height <p>s.
   The first one makes .ps-card a "+ *", so its 24px margin lands at the top of
   the column and drops the article below the sidebar. Kill it there only. */
.match-analysis > p:first-child + * { margin-top: 0 }

/* prediction summary — dark green hero card */
.ps-card {
  background: linear-gradient(135deg, #07452A, #0B6B3D);
  border-radius: var(--radius-lg);
  padding: 26px 28px;
  color: #fff;
}
.ps-top-label { font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: #CFA761; margin-bottom: 18px }
/* VS on the true centre line; flags sit at the card's outer edges in ringed
   circles, names read inward in caps. */
.ps-teams { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 20px }
.ps-team { display: flex; align-items: center; gap: 16px; min-width: 0 }
.ps-team-away { flex-direction: row-reverse; justify-content: flex-start; text-align: right }
.ps-card .ps-team-logo {
  width: 64px !important;
  height: 64px !important;
  border-radius: 50%;
  object-fit: cover !important;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .18);
}
/* scoped — site.css owns bare .ps-team-name for the homepage scorers card */
.ps-card .ps-team-name { font-size: 22px; font-weight: 800; color: #fff; text-transform: uppercase; letter-spacing: .02em }
.ps-team-venue { font-size: 12px; color: rgba(255, 255, 255, .65) }
.ps-vs { font-size: 13px; font-weight: 700; letter-spacing: .1em; color: rgba(255, 255, 255, .55) }
.ps-badge {
  display: inline-block;
  margin: 16px 0 4px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  background: rgba(255, 255, 255, .16);
}
/* one color per engine tier; the label text carries the meaning, color reinforces */
.ps-badge--blue { background: #2563EB }   /* HIGH CONFIDENCE */
.ps-badge--cyan { background: #0E7490 }   /* LIKELY WIN */
.ps-badge--purple { background: #7C3AED } /* TIGHT MATCH */
.ps-badge--red { background: #DC2626 }    /* UPSET ALERT */
.ps-outcomes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 16px }
.ps-outcome {
  position: relative;
  padding: 18px 14px 16px;
  text-align: center;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--radius);
}
.ps-outcome.ps-active { border: 2px solid #E9A62A; background: rgba(255, 255, 255, .1) }
.ps-star { position: absolute; top: 8px; left: 12px; color: #E9A62A }
.ps-outcome-name { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em }
.ps-prob-label { margin-top: 10px; font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .6) }
.ps-prob-pct { font-family: Archivo, sans-serif; font-size: 30px; font-weight: 800; line-height: 1.2 }
.ps-prob-bar-track { height: 4px; margin: 10px 0 12px; border-radius: 999px; background: rgba(255, 255, 255, .2); overflow: hidden }
.ps-prob-bar-fill { height: 100%; border-radius: 999px; background: rgba(255, 255, 255, .75) }
.ps-active .ps-prob-bar-fill { background: #E9A62A }
.ps-odds { font-size: 13px; font-weight: 700 }
.ps-return { margin-top: 4px; font-size: 11px; color: rgba(255, 255, 255, .6) }
.ps-analysis {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 18px;
  padding: 16px 20px;
  background: rgba(0, 0, 0, .28);
  border-radius: var(--radius);
}
.ps-analysis-body { flex: 1 }
.ps-analysis-title { font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em }
.ps-analysis-text { margin: 6px 0 0; font-size: 14px; color: rgba(255, 255, 255, .85); line-height: 1.6 }
.uf-entry-content a.ps-bet-btn {
  flex-shrink: 0;
  padding: 12px 26px;
  background: #FDF9EE;
  border-radius: 10px;
  color: #07452A;
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
}
.uf-entry-content a.ps-bet-btn:hover { filter: brightness(.96); text-decoration: none }
.ps-footer { margin-top: 16px; text-align: center; font-size: 11px; letter-spacing: .08em; color: rgba(255, 255, 255, .5) }

/* section cards */
.match-analysis section {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 22px 26px;
}
/* flag + title on one row, green rule underneath */
.match-analysis section h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--primary);
  font-size: 20px;
}
.match-analysis section > p { font-size: 15px }

/* team form stats — bordered table, right column tinted light green */
.ma-stats-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  /* right half tinted edge-to-edge, so an odd row's empty right cell stays green */
  background: linear-gradient(90deg, #fff 50%, #E6F1EB 50%);
}
.ma-stats-list li { display: flex; align-items: center; gap: 10px; padding: 12px 16px; font-size: 14px }
.ma-stats-list li:nth-child(n+3) { border-top: 1px solid var(--border) }
.ma-stats-list li::before { content: ''; flex-shrink: 0; width: 6px; height: 6px; border-radius: 50%; background: var(--primary) }

/* stat tiles — news.js rebuilds the list items; these override the table look.
   12-col grid gives the 4-then-3 rhythm from the reference. */
.ma-stats-list.ma-tiles {
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 14px;
  border: 0;
  border-radius: 0;
  overflow: visible;
  background: none;
}
.ma-tiles li {
  grid-column: span 3;
  gap: 12px;
  padding: 14px 16px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-bottom: 3px solid var(--primary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.ma-tiles li:nth-child(n+3) { border-top: 1px solid var(--border) }
.ma-tiles li::before { display: none }
.ma-tile-ic {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: #E6F1EB;
  color: var(--primary-dark, #007A3D);
}
.ma-tile-ic svg { width: 24px; height: 24px }
.ma-tile-body { display: flex; flex-direction: column; min-width: 0 }
.ma-tile-label { font-size: 12px; font-weight: 600; color: var(--text-2) }
.ma-tile-num { font-family: Archivo, sans-serif; font-size: 22px; font-weight: 800; line-height: 1.2 }
.ma-tile-unit { font-size: 12px; color: var(--text-3) }

@media (max-width: 900px) {
  .ma-tiles li { grid-column: span 6 }
}
@media (max-width: 460px) {
  .ma-tiles li { grid-column: span 12 }
}

/* W/D/L badges — letter + color, never color alone */
.ma-pill-W, .ma-pill-D, .ma-pill-L,
.ma-badge-W, .ma-badge-D, .ma-badge-L {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.ma-pill-W, .ma-badge-W { background: var(--primary) }
.ma-pill-D, .ma-badge-D { background: #E9A62A }
.ma-pill-L, .ma-badge-L { background: #DC2626 }
.ma-pill-W, .ma-pill-D, .ma-pill-L { padding: 5px 14px; border-radius: 999px }
.ma-badge-W, .ma-badge-D, .ma-badge-L { width: 26px; height: 26px; border-radius: 50% }
.ma-form-badges { display: inline-flex; flex-wrap: wrap; gap: 6px; vertical-align: middle }
.ma-results-block, .ma-venue-form { display: flex; align-items: center; gap: 14px; margin-top: 16px; padding: 12px 16px; background: #F4FAF7; border: 1px solid var(--border); border-radius: var(--radius) }
.ma-results-label, .ma-venue-label, .ma-form-label { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3) }

/* head-to-head */
/* the form cards duplicate each team's Form and Insights section — hidden until the post generator stops emitting them */
.ma-h2h-cards { display: none }
.ma-h2h-card { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden }
.ma-h2h-card-header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: var(--primary-dark, #007A3D); color: #fff; font-size: 14px; font-weight: 700; line-height: 1 }
/* flex gap owns the spacing; the inline margin/vertical-align nudge the flag off-centre */
.ma-h2h-card-header img { display: block; margin: 0 !important; vertical-align: unset !important }
/* wpautop inserts a <br> between flag and name (separate lines in the stored
   markup); as a flex item it wrecks the vertical centring */
.ma-h2h-card-header br, .match-analysis section h2 br { display: none }
.ma-form-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px }
.ma-h2h-results-header { margin-top: 16px; padding: 10px 14px; background: #07452A; border-radius: var(--radius) var(--radius) 0 0; color: #fff; font-size: 14px; font-weight: 700 }
.ma-h2h-table { width: 100%; margin: 0; border-collapse: collapse; font-size: 13px }
.ma-h2h-table th { padding: 10px 14px; background: var(--bg-2); font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); text-align: left }
.ma-h2h-table td { padding: 10px 14px; border-bottom: 1px solid var(--border) }
/* site.css sets body img { display: block }, which stacks the flag above the name */
.ma-h2h-team img { display: inline-block }
.ma-h2h-table .ma-score { display: inline-block; min-width: 44px; padding: 3px 10px; background: #E6F1EB; border-radius: 999px; font-family: Archivo, sans-serif; font-weight: 700; text-align: center }

/* our prediction — the verdict card, echoing the prediction hero */
.ma-tip-box {
  margin-top: 16px;
  padding: 20px 24px;
  background: linear-gradient(135deg, #07452A, #0B6B3D);
  border-radius: var(--radius);
  color: #fff;
}
.ma-tip-star { display: none } /* raw asterisk glyph from the stored markup */
.ma-tip-body strong { display: block; margin-bottom: 8px; font-size: 16px; color: #F5CE6E }
.ma-tip-body p { margin: 0; font-size: 14px; line-height: 1.65; color: rgba(255, 255, 255, .88) }

/* match details — three fact tiles */
.ma-match-details ul { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 14px 0 0; padding: 0; list-style: none }
.ma-match-details li { padding: 12px 16px; background: var(--bg-2); border-radius: var(--radius); font-size: 15px }
.ma-match-details li strong { display: block; margin-bottom: 4px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3) }

@media (max-width: 640px) {
  .ps-outcomes { grid-template-columns: minmax(0, 1fr) }
  .ps-analysis { flex-direction: column; align-items: flex-start; gap: 14px }
  .ma-stats-list { grid-template-columns: minmax(0, 1fr) }
  .ma-h2h-cards { grid-template-columns: minmax(0, 1fr) }
  .ma-match-details ul { grid-template-columns: minmax(0, 1fr) }
  .ps-teams { grid-template-columns: minmax(0, 1fr); justify-items: start }
  .ps-team-away { flex-direction: row; justify-content: flex-start; text-align: left }
  .ps-vs { text-align: center }
}

/* circular brand share buttons */
.sp-soc {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: #fff;
}
.sp-soc svg { width: 18px; height: 18px; fill: currentColor }
.sp-soc:hover { filter: brightness(1.12) }
.sp-soc-fb { background: #4267B2 }
.sp-soc-x { background: #000 }
.sp-soc-tg { background: #29A9EA }
.sp-soc-wa { background: #25D366 }

.sp-related { margin-top: 36px }

@media (max-width: 800px) {
  .sp-grid { grid-template-columns: minmax(0, 1fr) }
}

/* ── hero banner ──
   The shipped banner is a 5.3:1 strip, not the 1.6:1 photo site.css was built
   for. Its rules (background-size:auto + scale(1.12), a 560px floor) would crop
   the strip down to the empty middle of the pitch and lose the players at both
   ends, so the sizing is redefined here. */

.hero {
  min-height: clamp(230px, 21vw, 440px);
  padding-bottom: 0;
}

.hero::before {
  background-size: cover;
  background-position: center;
  transform: none;
}

/* The banner's centre is dark green; site.css sets the title to #000000, which
   is unreadable on it. White clears AA comfortably, and the shadow keeps it
   legible if a lighter image is swapped in via the Customizer. */
.hero-title,
.hero-sub {
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .55);
}

.hero-title { margin-bottom: 14px }
.hero-sub { margin-bottom: 0 }

@media (max-width: 700px) {
  /* Narrow viewports crop a wide strip hard, so let it sit shorter still. */
  .hero { min-height: 190px }
  .hero-title { font-size: 24px }
}

/* Rows became links to the match page; site.css styles .ml-row as a div, so the
   default anchor colour and underline have to be cleared. */
a.ml-row { text-decoration: none; color: inherit }
a.ml-row:hover .ml-chevron { color: var(--primary-dark) }

/* ══ match page (/match/{id}/) ══════════════════════════════════
   Shell renders server-side, data fills in from assets/js/match.js. */

/* Stadium plate under a green tint: floodlights top-left and top-right, blurred
   crowd, and a deliberately dark centre the score sits in. */
.mp-hero {
  position: relative;
  overflow: hidden;
  background:
    /* Three layers, first painted on top:
       1. the brand green, now translucent — it tints the photo instead of
          replacing it, so the hero stays green-branded but keeps the stadium;
       2. the photo. 50% 34%, not centre: it is 3:1 but the hero band is far
          wider than tall, so `cover` keeps only a slice, and dead centre lands
          on the empty stands rather than the floodlights;
       3. the same green at full opacity, as the colour underneath — it shows on
          ultra-wide viewports where `cover` runs out, and stands in on a 404. */
    linear-gradient(135deg, rgba(10, 31, 20, .82) 0%, rgba(15, 46, 28, .68) 55%, rgba(7, 26, 16, .86) 100%),
    url(assets/img/match-hero.webp) 50% 34% / cover no-repeat,
    linear-gradient(135deg, #0a1f14 0%, #0f2e1c 55%, #071a10 100%);
  color: #fff;
}

/* Vignette pinned to the middle, so the scoreline keeps its dark pocket while
   the tinted floodlights stay bright at the corners. */
.mp-hero::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 90% at 50% 50%, rgba(4, 20, 12, .55) 0%, rgba(4, 20, 12, 0) 70%);
}

/* Content clears the vignette. */
.mp-hero > * { position: relative; z-index: 1 }

.mp-hero-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 26px 20px 30px;
  text-align: center;
}

.mp-comp {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 14px; margin-bottom: 22px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .12);
  font-size: 12px; font-weight: 600;
}

.mp-comp-badge { width: 20px; height: 20px; object-fit: contain }

.mp-score {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 20px;
}

.mp-team { display: flex; align-items: center; gap: 14px; min-width: 0 }
.mp-team-home { justify-content: flex-end }
.mp-team-away { justify-content: flex-start }
.mp-team img { width: 48px; height: 48px; object-fit: contain }

.mp-team-name {
  font-family: 'Archivo', sans-serif;
  font-size: 22px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.mp-figure {
  font-family: 'Archivo', sans-serif;
  font-size: 34px; font-weight: 800;
  letter-spacing: .02em;
  white-space: nowrap;
}

.mp-status { margin-top: 12px; font-size: 12px; color: rgba(255, 255, 255, .72) }
.mp-status .uf-live { color: #fff }
.mp-hero-empty, .mp-loading { grid-column: 1 / -1; color: rgba(255, 255, 255, .8) }
.mp-hero-empty strong { color: #fff }

/* The band reserves the scoreline's height while it is empty, so the whole page
   below it does not jump down the moment the teams arrive. 48px crest + the
   22px name line, which is what .mp-score resolves to once filled. */
.mp-score[aria-busy="true"] { min-height: 48px }
.mp-score:not([aria-busy="true"]) { animation: uf-rise .4s ease }
.mp-comp:empty { visibility: hidden }
@media (prefers-reduced-motion: reduce) {
  .mp-score:not([aria-busy="true"]) { animation: none }
}

/* ── loading state, match page ──
   Left column: one mascot, no cards. Right column: skeletons in the real row
   geometry. The two differ because the rail's contents are known up front and
   the main column's are not — see the notes in match.php. */
.mp-main.is-loading > .mp-block { display: none }
.mp-main:not(.is-loading) > .mp-main-load { display: none }
.mp-main-load { padding: 40px 0 }

/* Only the values shimmer. The rows around them are the real .mp-info-row and
   .mp-prob-row markup drawn by paintShell(), so the card reserves its true
   height with no measured pixel value to keep in sync — add a row to either
   card and the reservation follows automatically. */
.mp-sk-chip {
  display: inline-block;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--bg-2) 25%, var(--border) 37%, var(--bg-2) 63%);
  background-size: 400% 100%;
  animation: np-shimmer 1.2s linear infinite;
}
.mp-sk-chip.is-val  { width: 92px; height: 15px; vertical-align: -2px }
.mp-sk-chip.is-sub  { width: 60px; height: 10px }
.mp-sk-chip.is-team { width: 76px; height: 13px }
.mp-sk-chip.is-pct  { width: 30px; height: 13px }

/* Stands in for U-Bao's banner. Height matches .mp-mascot as rendered, so the
   card does not grow when the pick lands. */
.mp-sk-mascot {
  height: 102px;
  margin-bottom: 9px;
  border-radius: var(--radius);
  background: linear-gradient(90deg, var(--bg-2) 25%, var(--border) 37%, var(--bg-2) 63%);
  background-size: 400% 100%;
  animation: np-shimmer 1.2s linear infinite;
}

/* The bar track is already drawn by .mp-prob-bar; while loading it simply has no
   fill inside, which reads as an empty track rather than a broken one. */
@media (prefers-reduced-motion: reduce) {
  .mp-sk-chip, .mp-sk-mascot { animation: none }
}

.mp-body { padding-top: 22px }
/* The homepage split is 30/70 with the rail first; here the main column leads,
   so the ratio is redeclared rather than reusing the sidebar proportions. */
.mp-split { margin-top: 16px; grid-template-columns: 70fr 30fr }
.mp-main, .mp-side { display: grid; gap: 16px; align-content: start; min-width: 0 }
/* sticky rides below the 64px fixed header; only engages while the side
   column is shorter than the main one (row height = taller column) */
.mp-split .mp-side { position: sticky; top: 80px }
.mp-main > *, .mp-side > * { min-width: 0 }
.mp-block > div { padding: 0 18px 18px }
.mp-inline-empty { padding: 0 }

/* Match page runs one notch larger than the homepage lists: OneFootball's match
   view sets section titles at 20px and row text at 16px, and beside it our 15/13
   read as fine print. Scoped to .mp-block so the homepage keeps its density. */
.mp-block > .uf-card-title { font-size: 18px }
.mp-block .uf-mini-table { font-size: 14px }

/* who will win */
.mp-prob { display: grid; gap: 10px }
.mp-prob-row { display: grid; grid-template-columns: 1fr 88px 40px; align-items: center; gap: 10px; font-size: 15px }
.mp-prob-label { display: flex; align-items: center; gap: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.mp-prob-bar { height: 6px; border-radius: 999px; background: var(--bg-2); overflow: hidden }
.mp-prob-bar > span { display: block; height: 100%; background: var(--border) }
.mp-prob-row.is-pick .mp-prob-bar > span { background: var(--primary-dark) }
.mp-prob-row.is-pick .mp-prob-val { color: var(--primary-dark); font-weight: 700 }
.mp-prob-val { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums }

.mp-badge {
  display: inline-block; margin: 14px 0 0;
  padding: 4px 10px; border-radius: 6px;
  background: var(--primary-light); color: var(--primary-dark);
  font-size: 12px; font-weight: 700; text-transform: uppercase;
}

.mp-note { margin: 12px 0 0; color: var(--text-3); font-size: 12px; line-height: 1.5 }

/* U-Bao's Pick — the prediction card doubles as the mascot's one on-page
   appearance. The mascot sits in normal flow at the top of the card body, not
   as an absolute sticker: an overlay doesn't add height, so it ended up lying
   across the probability rows and clipping the percentages. */
.mp-pick-card { border-color: var(--primary-light) }

/* The banner carries the tint, not the whole card — a gradient behind the bars
   and the note washed out the one number that matters.
   The band is sized by its TEXT, not by the mascot: the 34px top margin is the
   room U-Bao's head grows into, and the matching -34px on the image keeps that
   head out of the flex line's height. Shrinking the green while the figure
   stays full-size is what makes him stand in front of the band rather than
   inside it. Nothing leaves the card, so no risk to the title or the bars. */
.mp-mascot {
  display: flex; align-items: flex-end; gap: 10px;
  margin: 34px 0 16px;
  padding: 0 12px;
  border-radius: 12px;
  background: linear-gradient(160deg, var(--primary-light) 0%, rgba(0, 158, 79, .06) 100%);
}

/* Bottom-aligned and flush to the band's lower edge, so he stands ON it. The
   shadow is cast down-left onto the green — that contact shadow is most of the
   3D read; without it he looks pasted on. */
.mp-mascot-img {
  display: block;
  flex: 0 0 104px; width: 104px; height: auto;
  margin: -34px 0 -1px;
  filter: drop-shadow(0 6px 9px rgba(0, 0, 0, .2));
}

.mp-mascot-say {
  flex: 1; min-width: 0;
  padding: 12px 0 14px;
  font-size: 13px; line-height: 1.4;
}

.mp-mascot-say span { display: block }

.mp-mascot-label {
  color: var(--text-3);
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}

/* The team is the verdict, so it's the hero. Its probability sits one row down
   in the bars — printing it here too just doubled the same number. */
.mp-mascot-team {
  margin-top: 1px;
  font-family: 'Archivo', sans-serif;
  font-size: 22px; font-weight: 800; line-height: 1.15;
  color: var(--primary-dark);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.mp-mascot-badge {
  display: inline-block; margin-top: 6px;
  padding: 3px 8px; border-radius: 6px;
  background: #fff; color: var(--primary-dark);
  font-size: 11px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
}

.mp-pick-cta {
  display: inline-block; margin-top: 14px;
  color: var(--primary-dark);
  font-size: 13px; font-weight: 700; text-decoration: none;
}

.mp-pick-cta:hover { text-decoration: underline }
.mp-pick-cta::after { content: ' \203A' }

/* Narrow sidebar (tablet) squeezes the banner before the page goes one-column;
   drop the mascot a size rather than let the percentage wrap. */
/* Narrow sidebar: smaller figure means less head above the band, so the top
   margin and the negative margin shrink together — they have to stay equal or
   the head starts eating into the card title. */
@media (max-width: 1080px) and (min-width: 901px) {
  .mp-mascot { margin-top: 26px }
  .mp-mascot-img { flex-basis: 84px; width: 84px; margin-top: -26px }
  .mp-mascot-team { font-size: 19px }
}

/* form guide + head to head — result cards.
   Five per row on desktop; the pill sits on the card's top edge so the outcome
   reads before the scoreline does. Border colour repeats the pill, never
   carries the meaning alone. */
.mp-form-grid { display: grid; gap: 26px }
.mp-form-head {
  display: flex; align-items: center; gap: 8px; margin: 0 0 16px;
  font-family: 'Archivo', sans-serif; font-size: 15px; font-weight: 700;
}
.mp-form-head img { width: 22px; height: 22px; object-fit: contain }
.mp-form-badges { display: flex; gap: 6px }

.mp-rcards {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
}

.mp-rcard-wrap { min-width: 0 }

.mp-rcard {
  position: relative;
  padding: 18px 6px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  text-align: center;
}

.mp-rcard.is-win  { border-color: rgba(0, 122, 61, .45) }
.mp-rcard.is-loss { border-color: rgba(211, 33, 24, .45) }

.mp-rpill {
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -50%);
  padding: 3px 12px; border-radius: 999px;
  color: #fff; font-size: 10px; font-weight: 700; letter-spacing: .04em;
  background: var(--text-3);
}
.mp-rcard.is-win  .mp-rpill { background: var(--primary-dark) }
.mp-rcard.is-loss .mp-rpill { background: var(--red-dark) }

.mp-rscore {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: 'Archivo', sans-serif;
  font-size: 17px; font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.mp-rscore span { color: var(--text-3); font-weight: 600 }

.mp-rcrests { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 9px }
.mp-rcrests img { width: 28px; height: 28px; object-fit: contain }

.mp-rdate { margin-top: 7px; color: var(--text-3); font-size: 12px; text-align: center }

/* head to head — Wins / Draws / Wins circles between the two crests, then one
   row per meeting: date + competition on top, home side left, score centred.
   Circle colour never stands alone: each carries its number, a label below,
   and the crest beside it says whose count it is. */
.mp-h2h-tally {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 4vw, 44px);
  padding: 6px 0 20px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.mp-h2h-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}
.mp-h2h-num {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Archivo', sans-serif;
  font-size: 20px;
  font-weight: 800;
}
.mp-h2h-num.is-home { background: var(--primary-dark, #007A3D); color: #fff }
.mp-h2h-num.is-draw { background: var(--bg); border: 1px solid var(--border); color: var(--text) }
.mp-h2h-num.is-away { background: var(--gold, #CFA761); color: #fff }
/* labels sit under the circles; the crests centre on the circle row, not the column */
.mp-h2h-tally .mp-h2h-tlogo { margin-bottom: 26px }
.mp-h2h-tlogo img { width: 40px; height: 40px; object-fit: contain }

.mp-h2h-row { padding: 12px 2px; border-bottom: 1px solid var(--border) }
.mp-h2h-row:last-child { border-bottom: 0; padding-bottom: 2px }
.mp-h2h-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--text-3);
}
.mp-h2h-league { display: inline-flex; align-items: center; gap: 5px }
.mp-h2h-league img { width: 16px; height: 16px; object-fit: contain }
.mp-h2h-mid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  font-size: 14px;
}
.mp-h2h-team { display: inline-flex; align-items: center; gap: 8px; min-width: 0 }
.mp-h2h-team.is-home { justify-content: flex-end }
.mp-h2h-team img { width: 22px; height: 22px; object-fit: contain; flex: none }
.mp-h2h-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.mp-h2h-score { min-width: 44px; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums }

/* match events — centre spine, home left, away right */

/* Ubao on the pitch behind the timeline. The art is deliberately pale on the
   left where the card text lands, and the event cards are opaque white, so the
   only thing needing protection is the card title — hence the veil, heavier on
   the left than the right so the mascot still reads. */
#mp-events-block {
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, .88) 0%, rgba(255, 255, 255, .72) 45%, rgba(255, 255, 255, .34) 100%),
    linear-gradient(180deg, #fff 0%, rgba(255, 255, 255, 0) 45%),
    url('assets/img/events-bg.webp');
  /* the art is pinned to a fixed height at bottom-right so expanding the
     timeline never rescales U-Bao; the 180deg fade sits over the art strip's
     top edge so the cut-off melts into the card instead of drawing a line */
  background-size: cover, 100% 480px, auto 480px;
  background-position: center, center bottom, right bottom;
  background-repeat: no-repeat;
}

.mp-ev-timeline { position: relative; display: grid; gap: 10px; padding: 4px 0 }

/* The spine is drawn behind the rows so it doesn't shift them. */
.mp-ev-timeline::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: 1px dashed var(--border);
}

.mp-ev-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 46px minmax(0, 1fr);
  align-items: center;
}

/* Cards hug the spine instead of filling their half — on a wide rail a
   full-width card puts its text miles from the minute it belongs to. */
.mp-ev-card { width: 100%; max-width: 330px }

/* grid-row: 1 on both is load-bearing. The card is first in the DOM, and on an
   away row it is placed in column 3; sparse auto-placement will not then step
   back to column 2 for the minute, so it starts a second row and the minute
   drifts below its own card. */
.mp-ev-card, .mp-ev-min { grid-row: 1 }
.mp-ev-home .mp-ev-card { grid-column: 1; justify-self: end; flex-direction: row-reverse; text-align: right }
.mp-ev-away .mp-ev-card { grid-column: 3; justify-self: start }
.mp-ev-min { grid-column: 2 }

.mp-ev-card {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg);
  box-shadow: var(--shadow);
  min-width: 0;
}

/* Opaque so it breaks the dashed spine rather than being crossed out by it. */
.mp-ev-min {
  position: relative;
  padding: 5px 0;
  background: var(--bg);
  text-align: center;
  font-size: 12px; font-weight: 700;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.mp-ev-text { display: grid; min-width: 0 }
.mp-ev-name { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.mp-ev-sub { color: var(--text-3); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* Icons are inline SVG; the span is just a non-shrinking slot for them. */
.mp-ev-icon { flex: 0 0 18px; width: 18px; height: 18px; display: block }
.mp-ev-svg { display: block; width: 18px; height: 18px }

.mp-ev-more {
  display: block; margin: 18px auto 0;
  padding: 9px 20px;
  border: 1px solid var(--primary-dark); border-radius: 999px;
  background: var(--primary-dark);
  color: #fff;
  font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer;
}
.mp-ev-more:hover { background: var(--primary); border-color: var(--primary) }

/* line-ups
   The pitch is one grid of two halves; each half lays its position groups out
   as columns, so 4-4-2 and 3-5-2 both space themselves without per-formation
   rules. Away half renders its groups reversed — both sides attack the centre. */
.mp-lu-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; font-size: 15px }
.mp-lu-team { display: flex; align-items: center; gap: 8px; min-width: 0 }
.mp-lu-team-away { flex-direction: row-reverse }
.mp-lu-team img { width: 22px; height: 22px; object-fit: contain }
.mp-lu-form { color: var(--text-3); font-weight: 600; font-variant-numeric: tabular-nums }

.mp-pitch {
  position: relative;
  display: grid; grid-template-columns: 1fr 1fr;
  min-height: 430px;
  padding: 16px 10px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* Pitch art in assets/img/pitch.webp (18 KB): generated, then recoloured
     pixel-wise to the brand hue (150deg) with the mown-stripe contrast preserved.
     Stretched to 100% 100%
     rather than cover: cover would crop the penalty boxes off the ends, and the
     halfway line has to stay on the container's centre because the two team
     halves butt up against it. */
  background: #0a6537 url(assets/img/pitch.webp) center / 100% 100% no-repeat;
}

/* Light wash only. The turf was recoloured to brand green (see the note on
   .mp-pitch), and white on its lightest stripe already measures ~5.6:1 — the
   heavier scrim the darker art needed would now just mute the brand colour. */
.mp-pitch::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: rgba(4, 40, 22, .12);
}

.mp-lu-half { position: relative; z-index: 1; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr }
.mp-lu-line { display: flex; flex-direction: column; justify-content: space-around; align-items: center; gap: 10px; min-width: 0 }

/* grid col 1 is the team's left flank. Home attacks right, so col 1 is the top
   of the screen; the away side attacks left, where its left flank is the
   bottom — hence the reversed stacking, not a cosmetic choice. */
.mp-lu-half:last-child .mp-lu-line { flex-direction: column-reverse }

.mp-lu-p { position: relative; display: grid; justify-items: center; gap: 5px; width: 100%; min-width: 0 }

.mp-lu-avatar {
  display: grid; place-items: center;
  width: var(--lu-size, 38px); height: var(--lu-size, 38px);
  flex: 0 0 var(--lu-size, 38px);
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  color: var(--primary-dark);
  font-family: 'Archivo', sans-serif; font-size: 13px; font-weight: 800;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
}

/* Headshots arrive on a light background, so they sit on the white circle
   without a ring; object-fit keeps a non-square crop from stretching a face. */
.mp-lu-avatar img { width: 100%; height: 100%; object-fit: cover; display: block }

.mp-lu-name {
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: #fff; font-size: 12px; font-weight: 600; text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .4);
}

.mp-lu-marks { position: absolute; top: -5px; left: calc(50% + 10px); display: flex; gap: 2px }
.mp-lu-mark { display: grid; place-items: center; width: 17px; height: 17px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .3) }
.mp-lu-mark .mp-ev-svg { width: 12px; height: 12px }

.mp-lu-coach { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 2px 0; font-size: 14px; font-weight: 600 }
.mp-lu-coach-label { color: var(--text-3); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .04em }

.mp-lu-subs { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; margin-top: 20px }
.mp-lu-subs-title { margin: 0 0 6px; font-family: 'Archivo', sans-serif; font-size: 13px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em }
.mp-lu-sub-list { list-style: none; margin: 0; padding: 0 }
.mp-lu-sub { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px }
.mp-lu-sub:last-child { border-bottom: 0 }
.mp-lu-sub .mp-lu-avatar { box-shadow: none; background: var(--bg-2); font-size: 11px }
.mp-lu-sub-num { flex: 0 0 auto; min-width: 16px; color: var(--text-3); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums }
.mp-lu-sub-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.mp-lu-sub-pos { margin-left: auto; flex: 0 0 auto; color: var(--text-3); font-size: 12px }
.mp-lu-sub-marks { display: flex; align-items: center; gap: 4px; flex: 0 0 auto }
.mp-lu-sub-marks .mp-lu-marks { position: static; display: flex }
.mp-lu-sub-marks .mp-lu-mark { background: transparent; box-shadow: none }
.mp-lu-min { color: var(--primary-dark); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums }

/* Narrow: the pitch turns vertical, home defending the top edge. */
@media (max-width: 700px) {
  .mp-pitch { grid-template-columns: 1fr; min-height: 0; gap: 18px }
  .mp-lu-half { grid-auto-flow: row }
  .mp-lu-half:first-child { border-right: 0; border-bottom: 2px solid rgba(255, 255, 255, .3); padding-bottom: 14px }
  .mp-lu-line { flex-direction: row; justify-content: space-around; gap: 6px }
  .mp-lu-p { width: auto; max-width: 76px }
  .mp-pitch::after { width: 84px; height: 84px; margin: -42px 0 0 -42px }
  .mp-lu-subs { grid-template-columns: 1fr; gap: 18px }
}

/* match info */
.mp-info-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 15px }
.mp-info-row:last-child { border-bottom: 0 }
.mp-info-k { color: var(--text-3); flex: 0 0 auto }
.mp-info-ico { width: 15px; height: 15px; margin-right: 7px; vertical-align: -2.5px; color: var(--primary) }
.mp-info-v { font-weight: 600; text-align: right }
.mp-info-sub { display: block; color: var(--text-3); font-weight: 400; font-size: 12px }
.mp-info-missing { color: var(--text-3); font-weight: 400; font-style: italic }

/* match statistics — opposed bars meeting on a centre line */
.mp-ms-legend { display: flex; justify-content: space-between; margin-bottom: 14px; color: var(--text-3); font-size: 12px; font-weight: 600 }
.mp-ms + .mp-ms { margin-top: 16px }

.mp-ms-label {
  margin-bottom: 4px;
  color: var(--text-3);
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
  text-align: center; text-transform: uppercase;
}

.mp-ms-vals {
  display: flex; justify-content: space-between;
  font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Two halves with a 4px gap, so the centre line stays visible even when both
   sides are full. Each fill is anchored to its inner edge and grows outward. */
.mp-ms-bar { display: flex; gap: 4px; margin-top: 5px }
.mp-ms-half { flex: 1; height: 6px; border-radius: 999px; background: var(--bg-2); display: flex }
.mp-ms-l { justify-content: flex-end }
.mp-ms-r { justify-content: flex-start }
.mp-ms-half i { display: block; height: 100%; border-radius: 999px; background: var(--text) }
.mp-ms-r i { background: var(--text-2) }

/* league table — highlight the two sides in this match */
.uf-mini-table tbody tr.mp-table-on:hover { background: var(--primary-light) }
.mp-table-on .st-name { font-weight: 700; color: var(--primary-dark) }
.mp-table-gap td { padding: 6px 0; text-align: center; color: var(--text-3); letter-spacing: 3px; background: var(--bg-2) }

/* related news */
/* Full-bleed image card: the thumbnail fills the card and the title sits on a
   black bottom gradient, so the headline stays legible on any photo. */
/* upcoming matches — three fixture cards for this competition */
.mp-upnext { margin-top: 28px }
.mp-up-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px }
.mp-up-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 20px 18px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  color: inherit;
  text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease;
}
.mp-up-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(17, 17, 17, .1) }
.mp-up-league {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-2);
}
.mp-up-league img { width: 20px; height: 20px; object-fit: contain }
.mp-up-teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  width: 100%;
}
.mp-up-team {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}
.mp-up-team img { width: 52px; height: 52px; object-fit: contain }
.mp-up-vs { font-family: 'Archivo', sans-serif; font-size: 18px; font-weight: 800; color: var(--text) }
.mp-up-when {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
}
.mp-up-sep { color: var(--border) }
.mp-up-btn {
  width: 100%;
  padding: 10px;
  border: 1px solid var(--primary);
  border-radius: 10px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
  transition: background .15s, color .15s;
}
.mp-up-card:hover .mp-up-btn { background: var(--primary); color: #fff }
@media (max-width: 900px) {
  .mp-up-grid { grid-template-columns: minmax(0, 1fr) }
}

.mp-news { margin-top: 28px }
.mp-news-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px }
.mp-news-card {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--text-1, #111); /* dark fallback when a post has no thumbnail */
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: #fff;
  transition: box-shadow .18s, transform .18s;
}

.mp-news-card:hover {
  box-shadow: 0 8px 20px rgba(0, 0, 0, .25);
  transform: translateY(-2px);
}

.mp-news-img,
.mp-news-img img { position: absolute; inset: 0; width: 100%; height: 100%; }
.mp-news-img img { display: block; object-fit: cover }
.mp-news-card:hover .mp-news-img img { transform: scale(1.04) }
.mp-news-img img { transition: transform .3s }

.mp-news-body {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  padding: 56px 14px 12px;
  background: linear-gradient(to top, rgba(0, 0, 0, .92) 0%, rgba(0, 0, 0, .72) 45%, rgba(0, 0, 0, 0) 100%);
}
.mp-news-card .tn-sec-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; color: #fff; font-size: 16px; font-weight: 700; line-height: 1.35; text-shadow: 0 1px 3px rgba(0, 0, 0, .8) }

/* outlined category pill, top-left over the image */
.mp-news-tag {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 4px 12px;
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: 999px;
  background: rgba(0, 0, 0, .3);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
}

@media (prefers-reduced-motion: reduce) {
  .mp-news-card, .mp-news-img img { transition: none }
  .mp-news-card:hover { transform: none }
  .mp-news-card:hover .mp-news-img img { transform: none }
}

@media (max-width: 900px) {
  .mp-split { grid-template-columns: minmax(0, 1fr) }
  .mp-news-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) }
}

@media (max-width: 520px) {
  .mp-news-grid { grid-template-columns: minmax(0, 1fr) }
}

@media (max-width: 560px) {
  /* Cover on a narrow, tall card crops to the mascot's midriff and reads as a
     smudge — drop to the flat white card instead. */
  #mp-events-block { background-image: none }
  .mp-rcards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px }
  .mp-ev-row { grid-template-columns: minmax(0, 1fr) 38px minmax(0, 1fr) }
}

@media (max-width: 640px) {
  .mp-team img { width: 34px; height: 34px }
  .mp-team-name { font-size: 15px }
  .mp-figure { font-size: 26px }
  .mp-score { gap: 10px }
  .mp-rscore { font-size: 15px }
  .mp-rcrests img { width: 22px; height: 22px }
}

/* ── about page — hero, mission/vision, timeline, partners, ambassadors ──
   Hardcoded template (page-about-us.php); the stored builder content is a flat
   run of <p> tags no stylesheet can lay out. */

.ab-hero { position: relative; display: flex; align-items: flex-end; min-height: clamp(360px, 40vw, 520px); overflow: hidden; background: #07452A }
.ab-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover }
/* Scrim is brand green rather than neutral black — the office shot is cool-lit
   and goes grey under a black wash. */
.ab-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(5, 42, 26, .94) 0%, rgba(5, 42, 26, .82) 46%, rgba(5, 42, 26, .34) 100%),
    linear-gradient(0deg, rgba(5, 42, 26, .7), rgba(5, 42, 26, 0) 55%);
}
.ab-hero-inner { position: relative; z-index: 1; width: 100%; max-width: 1200px; margin: 0 auto; padding: 44px 24px 48px; color: #fff }
.ab-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--gold) }
.ab-title { font-family: 'Archivo', sans-serif; font-weight: 900; font-size: clamp(30px, 4.4vw, 52px); line-height: 1.08; margin: 10px 0 14px }
.ab-lede { max-width: 620px; font-size: clamp(15px, 1.4vw, 18px); line-height: 1.6; color: rgba(255, 255, 255, .9) }

.ab-sec { padding-top: 40px; padding-bottom: 8px }
.ab-sub { font-family: 'Archivo', sans-serif; font-size: 18px; font-weight: 800; margin: 32px 0 16px }
.ab-sub::after { content: ''; display: block; width: 32px; height: 3px; margin-top: 8px; border-radius: 2px; background: var(--gold) }

.ab-who { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 32px; align-items: start }
/* top: 80px matches the other sticky rails (.uf-side, .sp-stick) — clears the
   sticky header. Dropped below 900px, where the column stacks. */
.ab-who-copy { position: sticky; top: 80px; font-size: 17px; line-height: 1.75; color: var(--text-2) }
.ab-who-copy p + p { margin-top: 16px }
.ab-mv { display: grid; gap: 16px }
.ab-mv-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 20px 24px 22px;
}
.ab-mv-card img { width: 40px; height: 40px }
.ab-mv-card h3 { font-family: 'Archivo', sans-serif; font-size: 17px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; margin: 12px 0 8px }
.ab-mv-card p { font-size: 15px; line-height: 1.65; color: var(--text-2) }

.ab-tl { list-style: none; display: grid; gap: 36px; margin: 0; padding: 0 }
.ab-tl-item { position: relative; padding-left: 34px }
.ab-tl-item::before { content: ''; position: absolute; left: 7px; top: 12px; bottom: -40px; width: 2px; background: var(--border-2) }
.ab-tl-item:last-child::before { display: none }
.ab-tl-item::after { content: ''; position: absolute; left: 0; top: 4px; width: 16px; height: 16px; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 4px var(--primary-light) }
.ab-tl-date { font-family: 'Archivo', sans-serif; font-size: 15px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 14px }
/* Fixed 3-up, not auto-fit: a milestone with one clip keeps the same card width
   as the three-up rows instead of stretching across the section. */
.ab-tl-media { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px }

.ab-media { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 10px 10px 14px }
.ab-frame { position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; background: #0b0f14 }
.ab-frame iframe, .ab-frame img { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: cover }
.ab-media figcaption { padding: 12px 6px 0; font-size: 14px; line-height: 1.5; color: var(--text-2) }

.ab-brands { display: flex; flex-wrap: wrap; gap: 16px }
.ab-brand { width: 200px; padding: 16px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow) }
.ab-brand img { width: 100%; height: auto; object-fit: contain }

.ab-baes { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin: 0; padding: 0 }
/* Cutout PNGs on transparent backgrounds — the green tile is what makes them
   read as portraits instead of floating heads. */
.ab-bae {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(165deg, #0B6B3D, #009E4F 55%, #05341F);
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease;
}
.ab-bae:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); text-decoration: none }
/* height:auto beats the width/height attrs, letting aspect-ratio rule */
.ab-bae img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover }
.ab-bae-tag {
  position: absolute;
  inset: auto 0 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 18px 10px 8px;
  background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .68));
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ab-bae-tag svg { flex-shrink: 0; width: 14px; height: 14px; fill: currentColor }

.ab-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  margin: 24px 0 8px;
  padding: 30px 34px;
  background: linear-gradient(120deg, #07452A, #0B6B3D);
  border-radius: var(--radius-lg);
  color: #fff;
}
.ab-cta h2 { font-family: 'Archivo', sans-serif; font-size: clamp(20px, 2.4vw, 26px); font-weight: 900; letter-spacing: .02em }
.ab-cta p { margin-top: 8px; font-size: 15px; line-height: 1.6; color: rgba(255, 255, 255, .88) }
.ab-cta-btn { flex-shrink: 0; padding: 14px 28px; background: #E9A62A; border-radius: 10px; color: #fff; font-size: 15px; font-weight: 700; text-decoration: none }
.ab-cta-btn:hover { filter: brightness(1.08) }

@media (max-width: 900px) {
  .ab-who { grid-template-columns: minmax(0, 1fr) }
  .ab-who-copy { position: static }
  .ab-tl-media { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .ab-cta { flex-direction: column; align-items: flex-start }
}
@media (max-width: 600px) {
  /* 3-up, not auto-fill: two columns turn 32 portraits into 16 rows of scroll. */
  .ab-baes { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px }
  .ab-bae-tag { padding: 14px 7px 6px; font-size: 11px; gap: 4px }
  .ab-tl-media { grid-template-columns: minmax(0, 1fr) }
  .ab-hero-inner { padding: 32px 20px 36px }
  .ab-sec { padding-top: 28px }
}
@media (prefers-reduced-motion: reduce) {
  .ab-bae { transition: none }
  .ab-bae:hover { transform: none }
}

/* ── category archive ──
   Reuses the news page's rail, cards and pills; only the identity header, the
   hero split and the list rows are new. Classes are ct-* so nothing here can
   change how /news/ renders. */
/* .sp-crumb is written for the dark post hero; on this light page it needs the
   text colours inverted. */
.ct-crumb { color: var(--text-3); margin-bottom: 4px; padding: 4px 4px 0; flex-wrap: wrap }
.ct-crumb a { color: var(--text-2) }
.ct-crumb a:hover { color: var(--primary-dark) }
.ct-crumb span:last-child { color: var(--text) }

.ct-head {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 8px 4px 22px;
}
.ct-logo { width: 72px; height: 72px; object-fit: contain; flex-shrink: 0 }
.ct-title {
  font-family: 'Archivo', sans-serif;
  font-size: clamp(26px, 3.2vw, 36px);
  line-height: 1.1;
  margin: 0 0 6px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}
/* The English name sits beside a Chinese one; on the en archive it is absent. */
.ct-title-alt { font-size: 15px; font-weight: 500; color: var(--text-3) }
.ct-desc { max-width: 640px; color: var(--text-2); font-size: 14px; line-height: 1.6; margin: 0 }

.ct-pills { margin-bottom: 18px }

/* Lead card left, four stacked rows right, both columns the same height:
   `stretch` squares the row off and 4x1fr splits the right column evenly, so
   the lead grows or shrinks to whatever the four rows come to. Row count is set
   by the hero query in category.php - keep the two in step. */
.ct-hero { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; margin-bottom: 28px; align-items: stretch }
.ct-hero-side { display: grid; gap: 12px; grid-template-rows: repeat(4, 1fr) }

.ct-lead { position: relative; border-radius: var(--radius-lg); overflow: hidden; height: 100% }
.ct-lead-img { display: block; position: relative; text-decoration: none; height: 100% }
/* min-height covers the case where the four rows are shorter than the image
   wants to be - a category with only one or two posts. */
.ct-lead-img img { display: block; width: 100%; height: 100%; min-height: 320px; object-fit: cover }
/* Scrim rather than a flat tint: the title sits on photography, and a gradient
   keeps the top of the image readable while still passing contrast at the base. */
.ct-lead-body {
  position: absolute;
  inset: auto 0 0 0;
  padding: 56px 22px 20px;
  background: linear-gradient(to top, rgba(0, 0, 0, .88) 30%, rgba(0, 0, 0, 0));
  color: #fff;
  display: block;
}
.ct-lead-title { display: block; font-family: 'Archivo', sans-serif; font-weight: 700; font-size: 20px; line-height: 1.3 }
.ct-lead-excerpt { display: block; margin-top: 8px; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, .82) }
.ct-lead .np-feat-badge { position: absolute; top: 14px; left: 14px; z-index: 1 }

.ct-srow {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 12px;
  align-items: center;
  padding: 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
}
.ct-srow:hover { border-color: var(--primary) }
.ct-srow-thumb { align-self: stretch; display: block }
.ct-srow-thumb img { display: block; width: 100%; height: 100%; min-height: 66px; object-fit: cover; border-radius: 8px }
.ct-srow-title { display: block; font-weight: 600; font-size: 14px; line-height: 1.4; color: var(--text) }

/* Hard cap on excerpt height. The PHP trim keeps whole articles off the wire;
   this is what guarantees the shape of the row, and it holds whatever the
   editor pastes in either language. */
.tn2-excerpt,
.ct-lead-excerpt,
.np-banner-sub {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tn2-excerpt      { -webkit-line-clamp: 4; line-clamp: 4 }
/* Over the lead photo there is room for two before the scrim runs out. */
.ct-lead-excerpt  { -webkit-line-clamp: 2; line-clamp: 2 }
.np-banner-sub    { -webkit-line-clamp: 2; line-clamp: 2 }

.ct-section-title { font-family: 'Archivo', sans-serif; font-size: 20px; margin: 0 0 16px }

.ct-row { display: grid; grid-template-columns: 180px 1fr; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--border) }
.ct-row:first-of-type { padding-top: 0 }
.ct-row:last-of-type { border-bottom: 0 }
.ct-row-img img { display: block; width: 100%; height: 112px; object-fit: cover; border-radius: 10px }
.ct-row-title { font-size: 16px; line-height: 1.35; margin: 0 0 6px }
.ct-row-title a { color: var(--text); text-decoration: none }
.ct-row-title a:hover { color: var(--primary-dark) }
.ct-row .tn2-excerpt { margin: 0 0 8px; font-size: 13px }

@media (max-width: 860px) {
  .ct-hero { grid-template-columns: minmax(0, 1fr) }
  .ct-hero-side { grid-template-rows: auto }
  .ct-lead-img img { min-height: 220px }
  .ct-head { gap: 14px; padding-bottom: 16px }
  .ct-logo { width: 52px; height: 52px }
  .ct-row { grid-template-columns: 116px 1fr; gap: 12px }
  .ct-row-img img { height: 78px }
}
