@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;600&family=Lora:wght@400;600&display=swap");

:root {
  --color-yellow:    #FFFF5D;
  --color-yellow-dk: #e2e231;
  --color-white:     #FFFFFF;
  --color-grey-lt:   #f3f2f2;
  --color-grey:      #eae9e9;
  --color-grey-dk:   #9f9d9d;
  --color-black:     #201f1d;
  --color-brown-lt2: #fff3e4;
  --color-brown-lt:  #facb8d;
  --color-brown:     #b68235;
  --color-brown-dk:  #7d5411;

  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201f1d;
  --color-accent: #b68235;
  --color-divider: #201f1d;

  --color-accent-100: #fff3e4;
  --color-accent-300: #facb8d;
  --color-accent-600: #a06f24;
  --color-accent-700: #7d5411;

  --font-heading: "Cormorant Garamond", Georgia, serif;
  --font-heading-weight: 600;
  --font-body: "Lora", Georgia, serif;

  --space-1: 5px;
  --space-2: 10px;
  --space-3: 14px;
  --space-4: 18px;
  --space-6: 28px;
  --space-8: 36px;

  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 8px;

  --shadow-sm: 0 1px 2px color-mix(in srgb, #2d2b2b 14%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #2d2b2b 16%, transparent);

  /* compatibility aliases so every existing rule still sources its color
     from a Classical token, not a hardcoded value */
  --bg: var(--color-bg);
  --text: var(--color-text);
  --muted: color-mix(in srgb, var(--color-text) 55%, transparent);
  --border: var(--color-divider);
  --win: #4a6b3d;
}

* {
  box-sizing: border-box;
}

@media (max-width: 720px) {
  .layout {
    flex-direction: column;
  }

  #site-sidebar {
    flex: 0 0 auto;
  }

  .site-nav {
    flex-direction: row;
    flex-wrap: wrap;
  }
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--text);
  background: var(--color-white);
  line-height: 1.55;
}

div#page-content {
  padding: 1rem;
}

a {
  color: var(--color-accent-700);
}

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.layout {
  display: flex;
  min-height: 100vh;
  align-items: stretch;
  /* Matches the real max width of its children (#site-sidebar's fixed
     220px + .central-column's own 900px cap) - a wider value here just
     leaves unfilled space on the right since neither child can grow to
     use it. */
  max-width: 1120px;
  margin: 0 auto;
  background: var(--bg);
}

#site-sidebar {
  flex: 0 0 220px;
  background: var(--color-surface);
  padding: var(--space-4) 0;
}

.central-column {
  flex: 1;
  min-width: 0;
  max-width: 900px;
  display: flex;
  flex-direction: column;
}

/* Sits above .layout and spans over the sidebar too (not just the central
   column), capped/centered to the same 1120px as .layout (#site-sidebar's
   fixed 220px + .central-column's own 900px max-width) so it starts at
   the sidebar's left edge and ends at the central column's right edge. */
.site-header {
  max-width: 1120px;
  margin: 0 auto;
}

.site-header-inner {
  padding:     var(--space-3) var(--space-4);
  display:     flex;
  align-items: center;
  gap:         var(--space-3);
  background:  var(--color-black);
  color:       var(--color-yellow-dk);
  border-bottom: 1px solid var(--color-brown-lt2);
}

.site-title {
  font-size: 1.3rem;
  font-weight: var(--font-heading-weight);
  color: var(--text);
  text-decoration: none;
}

/* Now rendered inside the header bar (see .site-header-inner) rather than
   at the top of the sidebar, so no divider/spacing of its own is needed -
   the header's own border-bottom and .site-header-inner's padding already
   provide that. */
.brand-block {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  color: var(--color-brown-lt);
}

.brand-logo {
  width: 52px;
  height: 58px;
  object-fit: cover;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
}

/* Shield-shaped monogram badge shown when the Logo Content Block has no
   image set - falls back to the first letter of each word in the site
   name (e.g. "Newbury Park" -> "NP"). */
.brand-logo-fallback {
  width:          52px;
  height:         58px;
  flex:           0 0 auto;
  background:     var(--color-yellow-dk);
  border:         1px solid var(--color-yellow-dk);
  border-radius:  3px 3px 22px 22px;
  display:        flex;
  align-items:    center;
  justify-content: center;
  font-family:    var(--font-heading);
  font-weight:    900;
  font-size:      28px;
  letter-spacing: 0.02em;
  color:          var(--color-black);
}

.brand-name {
  font-family:    var(--font-heading);
  font-size:      2.25rem;
  font-weight:    900;
  line-height:    1.1;
}

/* index.html wraps the brand name in a real <h1> - reset it back to
   .brand-name's own styling instead of the global h1 rule (2.6rem/400)
   and the browser's default heading margin, which was pushing the text
   down and throwing off the logo's vertical centering in the header. */
.brand-name h1 {
  margin: 0;
  font: inherit;
}

.brand-tagline {
  font-size:      1rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color:          #E5E559;
  margin-top:     0.2rem;
}

.record-box-label {
  margin: 0 1.5rem 0.35rem;
  text-align: center;
}

.record-box {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin: 0 1.5rem 0.5rem;
  overflow: hidden;
}

.record-col {
  flex: 1;
  text-align: center;
  padding: 0.6rem 0.5rem;
}

.record-col + .record-col {
  border-left: 1px solid var(--border);
}

.record-value {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  line-height: 1;
}

.record-col .eyebrow {
  margin: 0.3rem 0 0;
}

/* Sits below .layout (see any page's HTML), not inside #site-sidebar -
   .layout's flex row stretches #site-sidebar and .central-column to equal
   heights by default (align-items: stretch), and .layout itself has
   min-height: 100vh, so simple document order already places this at
   whichever is lower: the bottom of the sidebar/main content (always
   equal to each other) or the page's 100vh floor on short pages. Capped
   to the same 1120px as .site-header so it lines up with the columns
   above it. */
.site-footer {
  max-width: 1120px;
  margin: 0 auto;
  padding: 1.25rem var(--space-4);
  border-top: 1px solid var(--border);
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.5;
}

.standings-row-us td {
  background: var(--color-accent-100);
  font-weight: 600;
}

.site-nav {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.site-nav a {
  color: var(--text);
  text-decoration: none;
  font-size: 1.15rem;
  padding: 0.3rem 0.75rem;
  display: block;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--color-grey-dk);
}

.site-nav a:hover {
  color: var(--color-brown-dk);
}

.site-nav a.active {
  color:             var(--color-brown);
  border-left-color: var(--color-brown);
  font-weight:       600;
}

.site-nav a.sub-link {
  padding-left: 1.5rem;
  font-size:    1rem;
}

.site-nav a.sub-link:hover {
  color: var(--color-brown);
}

.site-nav a.sub-link.active {
  color: var(--color-brown);
}

/* Rosters' per-team links nest one level deeper than a group's regular
   sub-links (Group > Rosters > Team), so they get extra indent on top of
   .sub-link's own. */
.site-nav a.sub-link--team {
  padding-left: 2rem;
}

.nav-group-label {
  padding: 0.25rem 0.75rem 0.25rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Auto left/right margins here used to make main a flex item with
   auto cross-axis margins inside .central-column's column-flex layout -
   per the flexbox spec, that disables stretch-to-fill and makes main
   shrink-to-fit its own content instead. On pages with wide content
   (e.g. Coaches, with several cards) that shrink-to-fit width happened
   to reach the container's full width anyway, hiding the bug; on pages
   with little content (e.g. Sponsors, with just one or two cards) main
   shrank to a narrow, centered column instead of filling the page -
   collapsing any CSS grid inside it to a single column and leaving the
   text looking centered rather than left-aligned. width:100% removes
   the shrink-to-fit ambiguity entirely - .central-column (max-width:
   900px) is already what caps the real column width, so main doesn't
   need its own max-width/centering on top of that. */
main {
  width: 100%;
}

/* Home page only (see the .home-page class on index.html's <body>) -
   #page-title is shared markup across every page, so this can't just be
   an #page-title rule without affecting every other page's header too. */
#page-title {
  padding-left: 1rem;
}

.page-intro {
  color: var(--muted);
  margin-bottom: 2rem;
  text-align: justify;
  /* Every "body" field across the CMS (Content Blocks, News, Coach
     profiles, etc.) is plain text rendered via textContent, not HTML -
     so blank lines/line breaks the admin types are the only formatting
     available. Browsers collapse consecutive whitespace by default;
     pre-line preserves those newlines as real line/paragraph breaks
     while still wrapping long lines normally. */
  white-space: pre-line;
}

/* Same plain-text-formatting fix as .page-intro, for the handful of body
   paragraphs that don't use that class (News body, Coach profile, Mission
   Statement's own body, news excerpts). */
.rich-text {
  white-space: pre-line;
}

/* Modifier for .rich-text containers whose body is rendered as real HTML
   (innerHTML) rather than plain text - see initMissionPage/
   initHtmlBlockPage in site.js. .rich-text's own pre-line is meant to
   preserve line breaks typed into a plain textarea; applied to actual
   HTML source it would also preserve incidental whitespace between tags
   as visible gaps, so this resets it back to normal and lets the markup
   itself (headings, <ul>/<li>, etc.) dictate spacing instead. */
.rich-text-html {
  white-space: normal;
}

.rich-text-html h2,
.rich-text-html h3 {
  margin: 1.25rem 0 0.5rem;
}

.rich-text-html h2:first-child,
.rich-text-html h3:first-child {
  margin-top: 0;
}

.rich-text-html ul,
.rich-text-html ol {
  margin: 0 0 1rem;
  padding-left: 1.4rem;
}

.rich-text-html li {
  margin: 0.2rem 0;
}

/* Mission Statement page - three "pillar" columns (Coaches/Players/Us)
   instead of the plain stacked h2/ul list .rich-text-html gives every
   other HTML block by default. Scoped under .rich-text-html so it only
   ever applies to markup that opts in with the mission-* classes below,
   not to Store/Sponsorships/Donate's own arbitrary HTML. */
.rich-text-html .mission-intro {
  font-size: 1.2rem;
  max-width: 640px;
  margin: 0 0 2rem;
  text-align: justify;
}

.rich-text-html .mission-standard-label {
  display: block;
  margin-bottom: 0.75rem;
}

.rich-text-html .mission-pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 2rem 2.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rich-text-html .mission-pillar {
  border-top: 2px solid var(--color-accent);
  padding-top: 1rem;
}

.rich-text-html .mission-pillar h2 {
  margin: 0 0 0.85rem;
  font-size: 1.6rem;
}

.rich-text-html .mission-pillar ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rich-text-html .mission-pillar li {
  position: relative;
  padding-left: 1.15rem;
  margin: 0.55rem 0;
  font-size: 0.95rem;
}

.rich-text-html .mission-pillar li::before {
  content: "\2014";
  position: absolute;
  left: 0;
  color: var(--color-accent);
}

.rich-text-html .mission-closing {
  margin: 2.5rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  font-family: var(--font-heading);
  font-size: 1.4rem;
  font-weight: 500;
  text-align: center;
  letter-spacing: 0.02em;
  color: var(--color-accent-700);
}

@media (max-width: 640px) {
  .rich-text-html .mission-pillars {
    grid-template-columns: 1fr;
    gap: 1.75rem;
  }
}

/* Sponsorships page - a letterhead/letter, a mailed-check address card, a
   row of payment-method options, and a grid of sponsorship tier cards.
   Scoped under .rich-text-html like the mission-* classes above, so it
   only applies to markup that opts in. */
.rich-text-html .sponsor-masthead {
  margin: 0 0 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}

.rich-text-html .sponsor-tagline {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.3rem;
  letter-spacing: 0.03em;
  color: var(--color-accent-700);
  margin-bottom: 0.25rem;
}

.rich-text-html .sponsor-masthead h2 {
  margin: 0;
  font-size: 1.9rem;
}

.rich-text-html .sponsor-letter p {
  max-width: 680px;
  text-align: justify;
  margin: 0 0 1rem;
}

.rich-text-html .sponsor-mail {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  max-width: 420px;
}

.rich-text-html .sponsor-mail p {
  margin: 0 0 0.35rem;
}

.rich-text-html .sponsor-mail p:last-child {
  margin-bottom: 0;
}

.rich-text-html .sponsor-payment-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0 2.5rem;
}

.rich-text-html .sponsor-payment-option {
  border-top: 2px solid var(--color-accent);
  padding-top: 0.6rem;
}

.rich-text-html .sponsor-payment-option h3 {
  margin: 0 0 0.35rem;
  font-size: 1.1rem;
}

.rich-text-html .sponsor-payment-option p {
  margin: 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.rich-text-html .sponsor-tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.75rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}

.rich-text-html .sponsor-tier {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 1.5rem;
}

.rich-text-html .sponsor-tier h3 {
  margin: 0 0 0.25rem;
  font-size: 1.3rem;
}

.rich-text-html .sponsor-tier-price {
  display: block;
  font-family: var(--font-heading);
  color: var(--color-accent-700);
  font-size: 1.4rem;
  margin-bottom: 0.85rem;
}

.rich-text-html .sponsor-tier ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rich-text-html .sponsor-tier li {
  position: relative;
  padding-left: 1.15rem;
  margin: 0.5rem 0;
  font-size: 0.92rem;
}

.rich-text-html .sponsor-tier li::before {
  content: "\2014";
  position: absolute;
  left: 0;
  color: var(--color-accent);
}

h1, h2, h3, .site-title {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  line-height: 1.12;
  letter-spacing: -0.015em;
}

h1 {
  font-size:     2.25rem;
  font-weight:   600;
  margin-bottom: 0.25rem;
}

h2 {
  font-size: 2rem;
  font-weight: 500;
  margin: 2rem 0 1rem;
}

h3 {
  font-size: 1.5rem;
  font-weight: 400;
  margin: 0 0 0.5rem;
}

h4 {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0 0 0.3rem;
}

.news-lead {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
  margin-top: 1rem;
}

.news-lead-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.5rem;
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

/* Fixed-height excerpt boxes - if the body text overflows, a "Full
   Article" link (addFullArticleLink in site.js) opens the complete text
   in openNewsModal() instead of growing the card or the page. */
.news-excerpt {
  max-height: 11rem;
  overflow: hidden;
}

.news-excerpt-card {
  max-height: 4.5rem;
  overflow: hidden;
}

@media (max-width: 720px) {
  .news-lead {
    grid-template-columns: 1fr;
  }
}

p {
  text-align: justify;
}

p.sponsors > a {
  text-decoration: none;
  padding: 0.5rem;
  font-size: 1.1rem;
  letter-spacing: -0.01rem;
}

p.sponsors > a:hover {
  font-weight: 800;
}


.eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  margin-bottom: 0.35rem;
}

div#page-content > span.eyebrow {
  font-size: 0.8rem;
}

.section-heading {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 2rem 0 1rem;
}

.section-heading h2 {
  margin: 0;
}

.section-divider {
  border-top: 1px solid var(--border);
  padding-top: 1.5rem;
  margin-top: 2.5rem;
}

.section-divider .section-heading {
  margin-top: 0;
}

.nums {
  font-variant-numeric: tabular-nums;
}

.result-win {
  color: var(--win);
  font-weight: 600;
}

.result-loss {
  color: var(--muted);
}

.plate {
  filter: sepia(0.22) saturate(0.82) contrast(1.05);
  box-sizing: border-box;
  border: 6px solid var(--color-surface);
  outline: 1px solid var(--color-divider);
  display: block;
  margin: 0;
}

img.plate {
  cursor: zoom-in;
}

/* Player-row thumbnails skip .plate (the sepia mat would overwhelm a
   40px image) but still open the same lightbox on click. */
img.thumb-clickable {
  cursor: zoom-in;
}

/* Click-to-enlarge overlay for every real photo (img.plate) - see
   initImageLightbox() in site.js. */
.lightbox-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--color-black, #000) 85%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  z-index: 100;
}

/* site.css has no blanket `[hidden] { display: none !important }` guard
   (unlike admin/style.css - see CLAUDE.md's gotcha about this), so this
   element's own `display: flex` above would otherwise beat the browser's
   default [hidden] rule at equal specificity and stay visible even with
   the hidden attribute set. */
.lightbox-backdrop[hidden] {
  display: none;
}

.lightbox-img {
  /* Capped in absolute px, not just vw/vh - a viewport-only cap lets an
     image with no real intrinsic size (e.g. an SVG placeholder) stretch
     to fill nearly the whole screen instead of displaying at a sane
     "larger, but still a photo" size. */
  max-width: min(90vw, 900px);
  max-height: min(90vh, 700px);
  object-fit: contain;
  /* The full-size view intentionally skips the sepia .plate filter - it's
     meant to show the real photo, not the matted thumbnail treatment. */
  filter: none;
  border: none;
  outline: none;
  box-shadow: var(--shadow-md);
}

.lightbox-close {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  background: transparent;
  border: none;
  color: #fff;
  font-size: 2.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

/* Coaches page: click a card to highlight it and open its full detail
   in coach-modal-backdrop (see openCoachModal() in site.js). Profile and
   email are deliberately left off the card itself - only the modal
   shows them. */
.coach-card {
  cursor: pointer;
}

.coach-card.is-active {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

.coach-modal-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--color-black, #000) 55%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  z-index: 100;
}

.coach-modal {
  position: relative;
  background: var(--bg);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 2rem;
  max-width: 44rem;
  width: 100%;
  /* Deliberately no max-height/overflow here - the photo, name, title and
     email must stay on screen. Only .coach-modal-profile (the free-text
     part, which can run long) scrolls internally. */
  display: flex;
  gap: 1.5rem;
  align-items: flex-start;
}

.coach-modal-photo {
  width: 220px;
  height: 220px;
  object-fit: cover;
  flex-shrink: 0;
}

.coach-modal-body {
  flex: 1;
  min-width: 0;
}

/* Contact info (email) sits above this, always visible - only the
   profile text itself scrolls once it exceeds this fixed height. */
.coach-modal-profile {
  max-height: 220px;
  overflow-y: auto;
  margin-top: 0.75rem;
  padding-right: 0.5rem;
}

.coach-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

@media (max-width: 480px) {
  .coach-modal-profile {
    max-height: 150px;
  }

  .coach-modal {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

/* News/Event "Full Article" popup (openNewsModal in site.js) - same fixed-
   height-modal-with-scrolling-content layout as the coach modal above. */
.news-modal-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--color-black, #000) 55%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  z-index: 100;
}

.news-modal {
  position: relative;
  background: var(--bg);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 2rem;
  max-width: 44rem;
  width: 100%;
  display: flex;
  gap: 1.5rem;
  align-items: flex-start;
}

.news-modal-photo {
  width: 220px;
  height: 220px;
  object-fit: cover;
  flex-shrink: 0;
}

.news-modal-body {
  flex: 1;
  min-width: 0;
}

.news-modal-content {
  max-height: 22rem;
  overflow-y: auto;
  margin-top: 0.75rem;
  padding-right: 0.5rem;
}

.news-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

@media (max-width: 480px) {
  .news-modal-content {
    max-height: 150px;
  }

  .news-modal {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

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

.card {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  display: block;
  transition: border-color 0.15s ease;
}

.card:hover {
  border-color: var(--color-accent);
}

.card-photo {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: var(--color-surface);
  display: block;
}

/* Team photo | coaching staff + description, side by side, instead of a
   full-width photo eating all the horizontal space (see
   initRosterDetailPage in site.js) - the photo is still an img.plate, so
   clicking it opens the full-size lightbox. */
.roster-detail-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
  margin-bottom: 1.5rem;
}

@media (max-width: 720px) {
  .roster-detail-header {
    grid-template-columns: 1fr;
  }
}

.card-body {
  padding: 0.9rem 1rem;
}

.card-title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.1rem;
  margin: 0 0 0.15rem;
}

.card-subtitle {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0;
  padding: 0.5rem 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: transparent;
}

th, td {
  text-align: left;
  padding: var(--space-2);
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
}

th {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

tbody tr:hover {
  background: color-mix(in srgb, var(--text) 4%, transparent);
}

.standings-table {
  table-layout: fixed;
}

.standings-table th,
.standings-table td {
  text-align: center;
}

.standings-table .col-school {
  text-align: left;
  white-space: nowrap;
}

.filter-row {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.filter-row button {
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--color-accent);
  background: transparent;
  color: var(--color-accent-700);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: 0.9rem;
  font-family: var(--font-heading);
}

.filter-row button:hover {
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}

.filter-row button.active {
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  font-weight: 600;
}

.calendar-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-bottom: 0.75rem;
}

.calendar-header h2 {
  font-size: 1.2rem;
  margin: 0;
  min-width: 12rem;
  text-align: center;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.calendar-dow {
  background: var(--bg);
  padding: 0.5rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
}

.calendar-cell {
  background: #fff;
  min-height: 6rem;
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.calendar-cell-empty {
  background: var(--bg);
}

.calendar-day-number {
  font-size: 0.8rem;
  color: var(--muted);
}

.calendar-event {
  font-size: 0.72rem;
  background: var(--color-accent-100);
  color: var(--color-accent-700);
  border-radius: var(--radius-sm);
  padding: 0.2rem 0.35rem;
  line-height: 1.3;
}

.news-post,
.coach-row,
.team-header {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
  display: flex;
  gap: 1.25rem;
  align-items: flex-start;
}

.btn {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  color: var(--color-accent-700);
  text-decoration: none;
  font-family: var(--font-heading);
  font-size: 0.95rem;
  margin-top: 0.5rem;
}

.btn:hover {
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}

/* List-style modifier on the shared .card/.card-grid component (see above)
   — same grid, but each item is a hairline-underlined row instead of a
   bordered box, for contexts like the Contact page that want a list feel
   rather than a card feel. */
.card-grid--list {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem 1.5rem;
  border-top: 1px solid var(--border);
  padding-top: 1rem;
  margin-top: 1rem;
}

.card--list {
  border: none;
  border-radius: 0;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--border);
}

.card--list h3 {
  margin: 0 0 0.15rem;
  padding-left: -1rem;
}

.gym-section {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 1.5rem;
  align-items: start;
  margin-top: 1.5rem;
  border-top: 1px solid var(--border);
  padding-top: 1rem;
}

.gym-section h2 {
  margin-top: 0;
}

.gym-address {
  color: var(--muted);
  margin-bottom: 0.75rem;
}

.gym-photo-placeholder {
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

@media (max-width: 640px) {
  .gym-section {
    grid-template-columns: 1fr;
  }
}

.news-post img,
.coach-row img,
.team-header img {
  width: 96px;
  height: 96px;
  object-fit: cover;
  flex-shrink: 0;
}

.news-post-date {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 0.1rem 0 0.5rem;
}

/* Photo carousel shown at the end of a News/Event article when it has an
   Album linked via `linked.ref === "news:<post_id>"` (see
   fetchNewsPhotoIndex in site.js) - a horizontally-scrolling strip of
   small thumbnails, not one image stretched to the article's width.
   Selectors are compound (two classes) so they beat ".news-post img"/
   ".coach-modal img"-style descendant rules already in this file at
   equal-or-lower specificity, regardless of source order, wherever the
   carousel happens to be nested. */
.photo-carousel {
  display: flex;
  gap: 0.6rem;
  overflow-x: auto;
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.photo-carousel .photo-carousel-thumb {
  width: 96px;
  height: 96px;
  object-fit: cover;
  flex-shrink: 0;
  cursor: zoom-in;
}

/* Full-size photo popup (openPhotoModal in site.js) - same modal chrome
   as .news-modal/.coach-modal, but the caption is the modal's own <h2>
   title rather than a generic label. */
.photo-modal-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--color-black, #000) 55%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  z-index: 110;
}

.photo-modal {
  position: relative;
  background: var(--bg);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 2rem;
  max-width: 44rem;
  width: 100%;
}

.photo-modal .photo-modal-img {
  display: block;
  width: 100%;
  max-height: 65vh;
  object-fit: contain;
}

.photo-modal-caption {
  margin: 1rem 0 0;
  text-align: center;
}

.photo-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

.teaser-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  margin-top: 1rem;
}

.teaser-card {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 1.25rem;
}

.teaser-card h3 {
  margin: 0 0 0.5rem;
  font-size: 1.1rem;
}

.teaser-card a {
  display: inline-block;
  margin-top: 0.75rem;
  font-size: 0.9rem;
}

.stat-row {
  display: flex;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.stat-row > span.eyebrow {
  font-size: 0.7rem;
}

.stat-col {
  flex: 1 1 200px;
  padding: 1.1rem 1.25rem;
  border-right: 1px solid var(--border);
}

/* Wider weighting for the Upcoming column (a short list, not one stat) -
   flex-grow (not a fixed grid column) so it still gets the extra share
   of the row's width even when Last Result/Next Game aren't rendered
   (e.g. a team with no games played yet) and there are only 1-2 columns
   instead of the usual 3. */
.stat-col--wide {
  flex-grow: 1.75;
}

.stat-col > a.stat-list-link {
  padding: 1rem 0 0;
}

.stat-col:last-child {
  border-right: none;
}

.stat-value {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  line-height: 1.2;
  text-decoration: none;
}

a.stat-value:hover {
  text-decoration: underline;
}

.stat-meta {
  margin: 0.35rem 0 0;
}

.stat-list-row {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.85rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
}

.stat-list-link {
  display: block;
  padding-top: 0.6rem;
}

@media (max-width: 720px) {
  .stat-col {
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
}

.maps-link {
  white-space: nowrap;
}

.empty-state {
  color: var(--muted);
  font-style: italic;
}

.site-footer {
  text-align: center;
  padding: 2rem 1rem;
  background: var(--color-black);
  color: var(--color-yellow-dk);
  font-size: 1rem;
}
