/* TTC München-Neuhausen e.V. — static site
   ==========================================================================
   Rebuilt to match the old jd_newjersey/Helix design, measured off the live
   site and the custom CSS that was stored in the Joomla template style:

     accent  #7db4f4   dark #1f2a30   nav bar #efefef
     body    Open Sans 300, 17px/30px, #333
     titles  25px/600 in the accent colour
     banner  160px, Banner.jpg over #1f2a30, logo 180x145, title 32px/300
             with a 3px 2px #25414e text shadow
     nav     50px, 15px/700, 1px letter-spacing, chevron over the active item
     modules white card, 1px #ddd, 0 3px 6px rgba(0,0,0,.07),
             title 21px/700 #1f2a30 with a 30x4 accent bar above it
     links   3px accent outline + bat icon (not a filled button)
     reveal  slideInLeft / slideInRight / zoomIn, 1s, on scroll

   Improvements over the original: fluid instead of fixed heights, inline SVG
   instead of a 31 kB icon font, real focus states, and prefers-reduced-motion
   honoured throughout. Nothing here is copied from the compromised install.
   ========================================================================== */

/* ---------------------------------------------------------------- fonts */
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/open-sans-v34-latin-300.woff2") format("woff2"),
       url("/assets/fonts/open-sans-v34-latin-300.woff") format("woff");
}
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/open-sans-v34-latin-regular.woff2") format("woff2"),
       url("/assets/fonts/open-sans-v34-latin-regular.woff") format("woff");
}
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/open-sans-v34-latin-600.woff2") format("woff2"),
       url("/assets/fonts/open-sans-v34-latin-600.woff") format("woff");
}
@font-face {
  font-family: "Open Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/open-sans-v34-latin-italic.woff2") format("woff2"),
       url("/assets/fonts/open-sans-v34-latin-italic.woff") format("woff");
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font: 300 17px/30px "Open Sans", -apple-system, BlinkMacSystemFont,
        "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--bg);
  /* Keep the footer on the bottom edge when a page is shorter than the
     viewport: main takes the slack instead of the footer floating mid-screen. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }
.banner, .site-header, .mf-section, .site-footer { flex: none; }

img { max-width: 100%; height: auto; }
svg.ico { flex: none; vertical-align: -.15em; }

a { color: var(--accent-dark); transition: color .4s, background-color .4s; }
a:hover { color: var(--accent); }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

h1, h2, h3, h4 { margin: 0 0 .5em; }
/* the old site rendered page titles at h2 size in the accent colour; the
   semantic level is kept but the look is the same */
h1 { font-size: 25px; line-height: 1.2; font-weight: 600; color: var(--accent-text); }
h2 { font-size: 25px; line-height: 1.2; font-weight: 600; color: var(--accent-text); }
h3 { font-size: 20px; line-height: 1.3; font-weight: 400; color: var(--dark); }
h4 { font-size: 17px; font-weight: 600; color: var(--dark); }
p, ul, ol, dl, table, figure { margin: 0 0 10px; }

.wrap { width: min(100% - 2rem, var(--wrap)); margin-inline: auto; }

.sr, .skip:not(:focus) {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip:focus {
  position: fixed; inset-block-start: .5rem; inset-inline-start: .5rem;
  z-index: 200; padding: .7rem 1.1rem; background: var(--dark); color: #fff;
  text-decoration: none;
}

/* ---------------------------------------------------------------- banner
   160px band: Banner.jpg (table + player silhouette) over the dark colour,
   scaled to the band height and centred, exactly as the old #sp-top-bar. */
.banner {
  background: var(--dark) url("/assets/images/banners/Banner.jpg") no-repeat 50% 0;
  background-size: auto 100%;
}
.banner-inner {
  display: flex; align-items: flex-start; gap: 2rem;
  min-height: 160px;
}
.logo { display: inline-flex; line-height: 0; padding: 7px 0 0; }
.logo img { width: 180px; height: auto; }
.banner-title {
  /* sits in the upper half next to the wappen, as on the old site */
  margin: 22px 0 0;
  font-size: 32px; font-weight: 300; line-height: 1.2;
  color: var(--accent);
  text-shadow: 3px 2px 0 #25414e;
}
@media (min-width: 62rem) { .banner-inner { gap: 7rem; } }

@media (max-width: 47.9375rem) {
  .banner-inner { min-height: 104px; gap: 1.25rem; align-items: center; }
  .logo { padding: 0; }
  .logo img { width: 84px; }
  .banner-title { margin: 0; font-size: 20px; text-shadow: 2px 1px 0 #25414e; }
}

/* ---------------------------------------------------------------- nav bar */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--header-bg);
  box-shadow: 0 3px 3px rgba(0, 0, 0, .05);
}
.header-inner { display: flex; align-items: center; gap: 1rem; }

/* Once the banner has scrolled away the sticky bar carries a small wappen, so the
   club is still identifiable. It fades in at that moment and back out when the
   banner is in view again — which is why this is opacity and visibility rather
   than display: display cannot be transitioned.
   Transitioning visibility alongside opacity is deliberate. Visibility steps
   rather than interpolates, so it flips to visible at the start of a fade-in and
   to hidden only at the end of a fade-out; that keeps the wappen unclickable
   while invisible without needing a separate rule. */
.logo-small {
  display: inline-flex; line-height: 0; margin-right: .25rem;
  opacity: 0; visibility: hidden;
  transition: opacity .35s ease, visibility .35s;
}
.logo-small img { width: 34px; height: auto; }
.site-header.is-stuck .logo-small { opacity: 1; visibility: visible; }

.site-nav { flex: 1; }
.site-nav ul {
  display: flex; flex-wrap: wrap; margin: 0; padding: 0; list-style: none;
}
.site-nav a {
  position: relative; display: block;
  padding: 0 15px; line-height: 50px;
  font-size: 15px; font-weight: 700; letter-spacing: 1px;
  color: var(--accent-dark); text-decoration: none;
}
.site-nav a:hover { color: var(--dark); }
/* the old template put a small chevron PNG at the top centre of the active
   item; drawn here in CSS so it stays crisp and follows the accent colour */
.site-nav a::before {
  content: ""; position: absolute; top: 0; left: 50%; translate: -50% 0;
  width: 0; height: 0;
  border: 6px solid transparent; border-top-color: var(--accent);
  opacity: 0; transition: opacity .4s;
}
.site-nav a:hover::before,
.site-nav a[aria-current="page"]::before { opacity: 1; }
.site-nav a[aria-current="page"] { color: var(--dark); }

.nav-toggle {
  display: none; width: 44px; height: 40px; padding: 0; margin-left: auto;
  background: none; border: 1px solid #d5d5d5; cursor: pointer;
}
.nav-toggle .bars, .nav-toggle .bars::before, .nav-toggle .bars::after {
  display: block; width: 20px; height: 2px; margin-inline: auto;
  background: var(--dark); transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle .bars { position: relative; }
.nav-toggle .bars::before, .nav-toggle .bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle .bars::before { top: -6px; }
.nav-toggle .bars::after { top: 6px; }
.nav-toggle[aria-expanded="true"] .bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .bars::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bars::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 61.9375rem) {
  .nav-toggle { display: block; }
  .header-inner { min-height: 50px; }
  /* The wappen used to sit here unconditionally, so on a phone it was visible
     even while the big banner with the same crest was still on screen — the crest
     twice, once tiny. It now follows the same rule as on a wide screen: it belongs
     to the stuck bar, and appears only once the banner has scrolled away. */
  .logo-small img { width: 30px; }
  .site-nav {
    position: absolute; inset-inline: 0; top: 100%; display: none;
    background: var(--header-bg); box-shadow: 0 8px 12px rgba(0, 0, 0, .1);
  }
  .site-nav.open { display: block; }
  .site-nav ul {
    flex-direction: column;
    width: min(100% - 2rem, var(--wrap)); margin-inline: auto;
  }
  /* The marker turns from a chevron above the label into an arrow beside it, so
     the label needs a gutter to sit in: at padding-left 0 the 12px triangle was
     drawn straight over the first letter of the current item, and over every
     other item on hover. */
  .site-nav a {
    padding: 0 0 0 1.15rem; line-height: 3rem;
    border-bottom: 1px solid #e2e2e2;
  }
  .site-nav li:last-child a { border-bottom: 0; }
  .site-nav a::before { left: 1px; translate: 0; border-top-color: transparent;
                        border-left-color: var(--accent); top: 50%;
                        margin-top: -6px; }
}

/* ---------------------------------------------------------------- layout */
main { display: block; padding: 60px 0; }
.site-footer { margin-top: auto; }
.layout { display: grid; gap: 2.5rem; }
@media (min-width: 62rem) {
  main.with-side .layout { grid-template-columns: minmax(0, 1fr) 283px; }
}
.content { min-width: 0; }
.crumb { margin-bottom: .4rem; font-size: 15px; }
.content > h1:first-child, .crumb + h1 { margin-top: 0; }
.content :is(h2, h3):not(:first-child) { margin-top: 1.6em; }
.content iframe { max-width: 100%; border: 0; }

/* ------------------------------------------------------- outlined CTA link
   The old markup was a stretched invisible <a> over a separate <span>; the
   look is kept (3px accent outline, bat icon, 17px) but it is now one real
   focusable link. */
.cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 14px; margin: 4px 8px 8px 0;
  font-size: 17px; font-weight: 300; line-height: 1.35;
  color: var(--accent-dark); text-decoration: none;
  border: 3px solid var(--accent); background: none;
  transition: color .3s, background-color .3s, border-color .3s;
}
.cta::before {
  content: ""; flex: none; width: 30px; height: 36px;
  background: url("/assets/images/icons/Bat_icon.png") no-repeat 50% / contain;
}
.cta-download::before {
  width: 24px; height: 32px;
  background-image: url("/assets/images/icons/pdf.png");
}
.cta:hover, .cta:focus-visible {
  color: #fff; background: var(--accent); border-color: var(--accent);
}
.cta:hover::before, .cta:focus-visible::before { filter: brightness(0) invert(1); }

/* ------------------------------------------------- player cards (.mitglied)
   Material-ish elevation card, 97px photo, photo zooms 1.15 on hover — the
   original used a fixed 105x160 float; this keeps the look but reflows. */
.mitglied-grid {
  display: grid; gap: 12px; margin: 1.4rem 0;
  grid-template-columns: repeat(auto-fill, minmax(105px, 1fr));
}
.mitglied {
  position: relative; overflow: hidden; padding: 4px 4px 8px;
  background: #fff;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, .2), 0 6px 20px 0 rgba(0, 0, 0, .19);
  transition: box-shadow .3s ease-in-out;
}
.mitglied:hover { box-shadow: 0 5px 12px rgba(0, 0, 0, .55); }
.mitglied-pic { overflow: hidden; aspect-ratio: 1; }
.mitglied-pic img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .6s ease;
}
.mitglied:hover .mitglied-pic img { transform: scale(1.15); }
.mitglied-name {
  margin-top: 6px; text-align: center;
  font-size: 14px; line-height: 1.3;
}
.mitglied-name a { font-size: 13px; text-decoration: none; }
.mitglied-name a:hover { text-decoration: underline; }

/* --------------------------------------------- board cards (.team-member) */
.customcenter { text-align: center; }
.customcenter .introtext { font-size: 17px; color: var(--muted); }
.customcenter .row {
  display: grid; gap: 1.5rem; margin: 1.5rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.verein-align { padding: 0; }
.team-member {
  height: 100%; padding-bottom: 5px;
  background: #fff; border: 1px solid #eee;
  box-shadow: 0 0 25px 0 #ddd;
  text-align: center;
  transition: box-shadow .2s ease-in-out;
}
.team-member:hover { box-shadow: -10px 0 15px 0 rgba(0, 0, 0, .09); }
.team-member img.thumb {
  width: 150px; height: 150px; margin-top: 9px;
  object-fit: cover; border-radius: 50%;
}
.member-name { margin-top: 10px; font-size: 18px; font-weight: 600; color: var(--dark); }
.post { display: block; margin-bottom: 5px; font-size: 15px; color: var(--accent-dark); }
.descrition { padding: 0 10px 15px; font-size: 12px; line-height: 1.7; }

/* ---------------------------------------------------------------- teams */
.team-grid {
  display: grid; gap: 1rem; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.team-grid a {
  display: flex; flex-direction: column; gap: .15rem; height: 100%;
  padding: 1.1rem 1.2rem; text-decoration: none;
  background: #fff; border: 1px solid #ddd;
  border-left: 4px solid var(--accent);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
  transition: box-shadow .25s, transform .25s;
}
.team-grid a:hover { box-shadow: 0 6px 18px rgba(0, 0, 0, .13); transform: translateY(-2px); }
.team-n { font-size: 20px; font-weight: 600; color: var(--dark); }
.team-league { font-size: 15px; color: var(--accent-dark); line-height: 1.35; }
.team-region { font-size: 15px; color: var(--accent-dark); line-height: 1.35; }
.team-count { margin-top: .3rem; font-size: 13px; color: var(--muted); }

/* -------------------------------------------------------- module / sidebar */
.module-title {
  position: relative; display: inline-block;
  margin: 15px 0 20px; padding: 0;
  font-size: 21px; font-weight: 700; line-height: 1.1;
  color: var(--dark); text-transform: capitalize;
}
.module-title::before {
  content: ""; position: absolute; top: -10px; left: 0;
  width: 30px; height: 4px; background: var(--accent);
}

.games {
  padding: 18px 20px 20px;
  background: #fff; border: 1px solid #ddd;
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
}
.games > .module-title { margin-top: 0; }
.games h3 {
  margin: 22px 0 8px; font-size: 13px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.games h3:first-of-type { margin-top: 0; }
.game-list { margin: 0; padding: 0; list-style: none; font-size: 15px; }
.game-list li { padding: 7px 0; }
.g-when {
  display: flex; align-items: baseline; gap: .5rem;
  padding-bottom: 3px; margin-bottom: 4px;
  border-bottom: 1px solid #ddd;
  font-size: 15px; line-height: 1.4; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.g-when abbr { text-decoration: none; }
/* league sits quietly at the right of the date rule (an addition — the old
   widget did not show which league a fixture belonged to) */
.g-league { margin-left: auto; font-size: 11px; letter-spacing: .04em;
            text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.g-teams { display: block; font-size: 80%; line-height: 1.5; }
.g-teams a { color: #333; text-decoration: none; }
.g-teams a:hover { color: grey; text-decoration: underline; }
.g-teams .vs { color: var(--muted); }
.g-teams .own { font-weight: 700; }
.game-list .score {
  margin-left: 10px; padding: 1px 6px;
  font-weight: 700; font-variant-numeric: tabular-nums;
  color: #fff; background: var(--accent);
}
.games-empty { margin: 0; font-size: 15px; color: var(--muted); }
.games-src { margin: 14px 0 0; font-size: 12px; color: var(--muted); }

/* ---------------------------------------------------------------- slideshow */
.slideshow {
  position: relative; overflow: hidden;
  margin: 1.5rem auto; max-width: 700px;
  background: var(--dark);
  box-shadow: 0 3px 12px rgba(0, 0, 0, .18);
}
.slideshow .slides {
  display: flex; margin: 0; padding: 0; list-style: none;
  transition: transform .6s cubic-bezier(.4, 0, .2, 1);
}
.slideshow .slide { position: relative; flex: 0 0 100%; }
.slideshow .slide img { display: block; width: 100%; aspect-ratio: 9 / 5; object-fit: cover; }
.slide-cap {
  position: absolute; inset-inline: 0; inset-block-end: 0;
  padding: 3rem 1.1rem 1.4rem; color: #fff; font-size: 15px; line-height: 1.5;
  background: linear-gradient(to top, rgba(0, 0, 0, .8), transparent);
}
.slide-cap strong { display: block; font-size: 19px; font-weight: 600; }
.slide-cap span { display: block; opacity: .92; }
.slide-nav {
  position: absolute; top: 50%; translate: 0 -50%;
  width: 40px; height: 40px; padding: 0;
  font-size: 24px; line-height: 1; color: #fff;
  background: rgba(0, 0, 0, .35); border: 0; cursor: pointer;
  transition: background-color .3s;
}
.slide-nav:hover { background: var(--accent); }
.slide-nav.prev { left: 0; }
.slide-nav.next { right: 0; }
.slide-dots {
  position: absolute; inset-inline: 0; bottom: .6rem;
  display: flex; gap: .4rem; justify-content: center;
}
.slide-dots button {
  width: 10px; height: 10px; padding: 0; cursor: pointer;
  background: rgba(255, 255, 255, .55); border: 0;
  transition: background-color .3s;
}
.slide-dots button[aria-selected="true"] { background: var(--accent); }
.slideshow:not([data-ready]) :is(.slide-nav, .slide-dots) { display: none; }
.slideshow:not([data-ready]) .slide:not(:first-child) { display: none; }

/* ---------------------------------------------------------------- panorama */
.panorama { position: relative; margin: 0 0 1.2rem; }
.pano-canvas, .pano-flat {
  display: block; width: 100%;
  height: clamp(260px, 42vw, 460px);
  background: #eef1f4;
}
.pano-flat { object-fit: cover; }
.pano-canvas {
  cursor: grab;
  /* the viewer consumes drags and two-finger pinches itself */
  touch-action: none;
}
.pano-canvas:active { cursor: grabbing; }
.panorama figcaption { margin-top: .5rem; font-size: 13px; color: var(--muted); }

.pano-zoom {
  position: absolute; top: 10px; right: 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.pano-zoom button {
  width: 34px; height: 34px; padding: 0;
  font-size: 20px; line-height: 1; font-weight: 600;
  color: #fff; background: rgba(31, 42, 48, .62); border: 0; cursor: pointer;
  transition: background-color .25s;
}
.pano-zoom button:hover { background: var(--accent); }
/* There used to be a dark hint box in the bottom-left corner repeating "Ziehen
   zum Umsehen · Mausrad zum Zoomen". It is gone: the figcaption right below the
   viewer says the same thing, so the overlay only sat on the photo and collided
   with that caption. The instructions still reach screen readers through the
   canvas aria-label in src/js/site.js. */

/* ------------------------------------------------- Mannschaftsführer band
   Full-width band behind the cards using the club's hand-drawn cartoon
   background, as the old #sp-custom-position-8 did. */
/* Its own full-width row between main and the footer, as the template's
   custom-position-8 was — no negative-margin full-bleed trick, so it cannot
   cause horizontal overflow. */
.mf-section {
  padding: 3rem 0;
  /* The club's hand-drawn cartoon, kept as a watermark: a white scrim over it
     kicks the drawing back far enough that the names on top stay readable
     (on the old site they sat directly on the artwork and were hard to read). */
  background:
    linear-gradient(rgba(255, 255, 255, .78), rgba(255, 255, 255, .78)),
    url("/assets/images/banners/funfacts-bg.jpg") no-repeat 50% / cover,
    #eef2f6;
  border-block: 1px solid #e2e7eb;
  text-align: center;
}
.mf-inner { width: min(100% - 2rem, var(--wrap)); margin-inline: auto; }
.mf-section .module-title { margin-top: 0; }
.mf-list {
  display: grid; gap: 1.5rem 1rem; padding: 0; margin: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
}
.mf-card { font-size: 15px; }
.mf-card a { text-decoration: none; color: inherit; }
.mf-card img {
  width: 110px; height: 110px; object-fit: cover;
  border-radius: 50%; border: 4px solid #fff;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .18);
  transition: transform .35s, box-shadow .35s;
}
.mf-card a:hover img { transform: scale(1.06); box-shadow: 0 6px 16px rgba(0, 0, 0, .28); }
.mf-name { display: block; margin-top: .55rem; font-weight: 600; color: var(--dark); }
.mf-team { display: block; font-size: 13px; color: #4a6070; }
.mf-card a:hover .mf-name { text-decoration: underline; }

/* ---------------------------------------------------------------- contacts */
.contact-photo {
  width: 150px; height: 150px; object-fit: cover;
  border-radius: 50%; border: 4px solid #fff; box-shadow: 0 0 25px 0 #ddd;
}
.contact-dl { display: grid; gap: 0; max-width: 30rem; margin-top: 1.4rem; }
.contact-dl > div {
  display: grid; grid-template-columns: 8rem 1fr; gap: .5rem;
  padding: .6rem 0; border-bottom: 1px solid #eee;
}
.contact-dl dt { font-weight: 600; color: var(--muted); font-size: 15px; }
.contact-dl dd { margin: 0; }

/* --------------------------------------------------- contact reveal button
   The details are not in the HTML; this fetches them on request. */
.reveal { margin: 1.2rem 0 0; }
.reveal-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px;
  font: inherit; font-size: 15px; font-weight: 600;
  color: #fff; background: var(--accent-dark);
  border: 0; cursor: pointer;
  transition: background-color .25s, opacity .25s;
}
.reveal-btn:hover { background: var(--dark); }
.reveal-btn:disabled { opacity: .6; cursor: default; }
.reveal-btn .ico { width: 15px; height: 15px; }

.reveal-sm { margin: .4rem 0 .8rem; }
.reveal-sm .reveal-btn {
  padding: 5px 11px; font-size: 13px; font-weight: 400;
  color: var(--accent-dark); background: none;
  border: 1px solid var(--accent);
}
.reveal-sm .reveal-btn:hover { color: #fff; background: var(--accent); }
.reveal-sm .reveal-btn .ico { width: 13px; height: 13px; }

.reveal-foot { margin: 0; }
.reveal-foot .reveal-btn {
  padding: 6px 12px; font-size: 14px; font-weight: 400;
  color: #cbd3d8; background: rgba(255, 255, 255, .08);
}
.reveal-foot .reveal-btn:hover { color: #fff; background: var(--accent-dark); }

.contact-dl.revealed { margin-top: 0; animation: fadeInUp .35s both; }
.reveal-sm .contact-dl.revealed,
.reveal-foot .contact-dl.revealed {
  display: block; max-width: none; font-size: 14px;
}
.reveal-sm .contact-dl.revealed > div,
.reveal-foot .contact-dl.revealed > div {
  display: block; grid-template-columns: none;
  padding: 0 0 .2rem; border: 0;
}
.reveal-sm .contact-dl.revealed dt,
.reveal-foot .contact-dl.revealed dt {
  display: inline; font-size: inherit; font-weight: 400;
}
.reveal-sm .contact-dl.revealed dt::after,
.reveal-foot .contact-dl.revealed dt::after { content: ": "; }
.reveal-sm .contact-dl.revealed dd,
.reveal-foot .contact-dl.revealed dd { display: inline; }
.reveal-foot .contact-dl.revealed dt { color: #8b989f; }

/* Each revealed row carries the icon for its kind, cloned from the page's
   #contact-icons template. Sized and coloured like .foot-line .ico, so a
   revealed line sits flush with the address and training-times lines above. */
.contact-dl.revealed .ico {
  width: 15px; height: 15px; margin-right: .45rem;
  color: var(--accent); vertical-align: -.2em;
}

/* The hall address and the training times, side by side on the homepage and on
   /spiellokal/. Deliberately the same card as the Liga and Mannschaftsführer boxes
   on a team page — a visitor who has seen one of those already knows the address
   is clickable, so it needs no "open in Maps" label; the pin and the pointer
   cursor carry it. The destination is named in a .sr span for anyone who cannot
   see either.
   Only the address card is a link. The times card shares the shell but gets no
   hover lift and no pointer cursor: it would promise a click that does not exist. */
.venue-pair {
  display: grid; gap: 1rem; margin: 1.1rem 0 1.4rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  align-items: stretch;
}
.venue-card, .hours-card {
  display: flex; gap: 1rem; align-items: flex-start;
  padding: 1rem 1.2rem 1.1rem;
  background: var(--bg); border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
  color: inherit; text-decoration: none;
}
.venue-card {
  /* translate, not transform — see the hover rule below for why */
  transition: box-shadow .25s, translate .25s, border-top-color .25s;
}
/* Same lift and shadow as a.info-box on the team pages, to the pixel — the two
   are the same component and should not move by different amounts.

   The lift uses `translate`, not `transform`. While this card was a direct child
   of .content it carried the page-load reveal `animation: fadeInUp .5s both`; that
   keyframe animates transform and `both` keeps its end state applied forever, and
   a filled animation beats normal declarations in the cascade — so a hover
   `transform` was silently discarded (proved live: forcing
   transform: translateY(-2px) inline left the computed value at
   matrix(1,0,0,1,0,0)). The card now sits inside .venue-pair, so the reveal lands
   on the wrapper and transform would work again — but `translate` stays, because
   it composes with transform rather than fighting it and so keeps working wherever
   this card is moved to. */
.venue-card:hover, .venue-card:focus-visible {
  translate: 0 -2px;
  box-shadow: 0 10px 22px rgba(0, 0, 0, .12);
  border-top-color: var(--accent-dark);
}
.venue-card .ico, .hours-card .ico {
  width: 34px; height: 34px; padding: 6px;
  color: var(--accent-dark); background: rgba(125, 180, 244, .16);
  border-radius: 50%; box-sizing: content-box;
}
.hours-when {
  display: inline-block; min-width: 6.5rem;
  font-weight: 600; color: var(--accent-dark);
}
.venue-body { min-width: 0; }
/* block, so the address starts on its own line under the name */
.venue-name { display: block; font-weight: 600; color: var(--accent-text); }
.venue-addr { display: block; font-size: 15px; line-height: 1.65; }

/* The footer address is the other way round: it opens the same map but must not
   look like a link — same colour as the text around it, no underline, nothing on
   hover. The pointer cursor is the only hint, which is what was asked for.
   :focus-visible is deliberately left alone — that ring only appears for keyboard
   users, and without it the link would be impossible to locate when tabbing. */
a.maps,
a.maps:hover,
a.maps:focus,
.site-footer a.maps,
.site-footer a.maps:hover {
  color: inherit; text-decoration: none; cursor: pointer;
}

.reveal-error { margin: .5rem 0 0; font-size: 14px; color: #c0392b; }
.no-contact { margin-top: 1.2rem; font-size: 15px; color: var(--muted); }

/* ----------------------------------------------- team page: league + captain
   Two boxes side by side. `align-items: stretch` on the grid plus a column
   layout inside each box keeps them exactly the same height whatever the text
   length, with the "more" line pinned to the bottom. */
.team-boxes {
  display: grid; gap: 1rem; margin: 1.4rem 0 1.8rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  align-items: stretch;
}
.info-box {
  display: flex; flex-direction: column; gap: .35rem;
  padding: 1rem 1.2rem 1.1rem;
  background: #fff; border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
  color: inherit; text-decoration: none;
  transition: box-shadow .25s, transform .25s, border-top-color .25s;
}
a.info-box:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(0, 0, 0, .12);
  border-top-color: var(--accent-dark);
}
.box-title {
  display: flex; align-items: center; gap: .6rem;
  margin-bottom: .15rem;
  font-size: 13px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
/* The 15px version was almost invisible against the label. These sit on a
   tinted disc so the glyph reads at a glance. */
.box-title .ico {
  flex: none;
  width: 34px; height: 34px; padding: 6px;
  color: var(--accent-dark);
  background: rgba(125, 180, 244, .16);
  border-radius: 50%;
  box-sizing: content-box;
}
a.info-box:hover .box-title .ico {
  color: #fff; background: var(--accent);
}
.box-main { font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--dark); }
.box-sub { font-size: 15px; color: var(--accent-dark); }
/* pinned to the bottom, so both boxes end on the same line */
.box-more {
  display: flex; align-items: center; gap: .3rem;
  margin-top: auto; padding-top: .6rem;
  font-size: 13px; color: var(--accent-dark);
}
.box-more .ico { width: 13px; height: 13px; }
a.info-box:hover .box-more { color: var(--dark); }
.box-person { display: flex; align-items: center; gap: .7rem; }
.box-person img {
  flex: none; width: 48px; height: 48px; object-fit: cover;
  border-radius: 50%; border: 2px solid var(--bg-soft, #f7f9fb);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
}
.info-box-mf { border-top-color: var(--accent-dark); }

/* the captain, highlighted in the squad grid */
.mitglied.is-mf .mitglied-name a { color: var(--accent-dark); text-decoration: none; }
.mitglied.is-mf .mitglied-name a:hover { text-decoration: underline; }
.mf-role {
  margin: -.3rem 0 1rem; font-size: 17px; color: var(--accent-dark);
}

/* ------------------------------------------------------------- info callout
   Uses the club blue as a left rule on a tinted panel, so it reads as a note
   rather than competing with the page heading. */
.note {
  margin: 1.8rem 0;
  padding: 1.3rem 1.5rem;
  background: linear-gradient(180deg, #f2f7fd, #eaf2fb);
  border: 1px solid #d6e5f7;
  border-left: 4px solid var(--accent);
  box-shadow: 0 3px 8px 0 rgba(31, 42, 48, .06);
}
.note > :first-child { margin-top: 0; }
.note > :last-child { margin-bottom: 0; }
.note h2 {
  display: flex; align-items: center; gap: .55rem;
  margin: 0 0 .5rem; font-size: 20px; color: var(--dark);
}
.note h2::before {
  content: ""; flex: none;
  width: 1.5rem; height: 1.5rem;
  background: var(--accent);
  /* a table-tennis bat silhouette, so the box feels like part of the club */
  -webkit-mask: url("/assets/images/icons/Bat_icon.png") no-repeat 50% / contain;
          mask: url("/assets/images/icons/Bat_icon.png") no-repeat 50% / contain;
}
.note p { margin: 0 0 .6rem; }
.note .cta { margin-bottom: 0; }
@media (max-width: 30rem) {
  .note { padding: 1.1rem 1.1rem; }
}

/* ================================================================== calendar
   The two calendars on /training/. Same card shell as .games and .venue-card, so
   they read as part of the site rather than as an embedded widget — which is
   what the Google Calendar iframe they replaced always looked like.

   The week view is a proportional time grid, not a table of hour cells: each day
   is a positioned lane, and every block is placed by its real start and sized by
   its real duration. That is the only way a 19:00-22:00 training slot and a 19:45
   match can both be honest on the same column. */
.cal {
  --cal-lane: 26rem;      /* the height one day column stands for */
  --cal-head: 3.1rem;     /* and the height of the header above it */
  margin: 2rem 0;
  padding: 18px 20px 20px;
  background: #fff; border: 1px solid var(--line);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
}
.cal > .module-title {
  display: flex; align-items: center; gap: .6rem; margin-top: 0;
  text-transform: none;
}
.cal > .module-title .ico {
  flex: none; width: 30px; height: 30px; padding: 5px;
  color: var(--accent-dark); background: rgba(125, 180, 244, .16);
  border-radius: 50%; box-sizing: content-box;
}
.cal-intro { margin: 0 0 1.1rem; font-size: 15px; line-height: 1.6; color: var(--muted); }

/* ---------------------------------------------------------------- toolbar */
.cal-toolbar {
  display: flex; flex-wrap: wrap; gap: .6rem 1rem;
  align-items: center; justify-content: space-between;
  padding-bottom: .8rem; border-bottom: 1px solid var(--line);
}
.cal-nav { display: flex; align-items: center; gap: .35rem; }
.cal-step, .cal-today, .cal-view {
  padding: .35rem .75rem; font: inherit; font-size: 14px; line-height: 1.4;
  color: var(--accent-dark); background: #fff;
  border: 1px solid var(--line); cursor: pointer;
  transition: background-color .2s, color .2s, border-color .2s;
}
.cal-step { min-width: 2.1rem; font-size: 17px; }
.cal-step:hover, .cal-today:hover, .cal-view:hover {
  color: #fff; background: var(--accent-dark); border-color: var(--accent-dark);
}
.cal-view[aria-pressed="true"] {
  color: #fff; background: var(--accent-dark); border-color: var(--accent-dark);
}
.cal-range {
  margin-left: .5rem; font-size: 15px; font-weight: 600; color: var(--dark);
}
.cal-views { display: flex; gap: .3rem; }

/* team chips: accent-dark when on, hollow when off, dashed when the team has no
   published schedule at all — which is information, not an empty state */
.cal-chips {
  display: flex; flex-wrap: wrap; gap: .4rem;
  padding: .8rem 0;
}
.chip {
  padding: .3rem .7rem; font: inherit; font-size: 13px; line-height: 1.4;
  color: var(--muted); background: #fff;
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
  transition: background-color .2s, color .2s, border-color .2s;
}
.chip[aria-pressed="true"] {
  color: #fff; background: var(--accent-dark); border-color: var(--accent-dark);
}
.chip:hover { border-color: var(--accent-dark); }
.chip-train[aria-pressed="true"] { background: var(--accent); border-color: var(--accent);
                                   color: #10222f; }
.chip-off {
  padding: .3rem .7rem; font-size: 13px; line-height: 1.4;
  color: #9aa4ab; border: 1px dashed var(--line); border-radius: 999px;
  cursor: help;
}
.chip-all { border-style: dashed; }

/* ------------------------------------------------------------- week grid */
.cal-grid[data-view="week"] {
  display: grid; grid-template-columns: 3.2rem minmax(0, 1fr);
  gap: 0; margin-top: .4rem;
}
/* The hour labels are placed by percentage, so their containing block has to be
   exactly as tall as a day lane and start at the same line — hence the spacer the
   height of a day header, and --lane shared by both. Position a label against a
   box that also contains the header and every mark drifts downwards. */
.cal-hours { padding-top: var(--cal-head); }
.cal-hourlane { position: relative; height: var(--cal-lane); }
.cal-hour {
  position: absolute; right: .5rem; translate: 0 -50%;
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cal-days {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  border-left: 1px solid var(--line);
}
.cal-day { border-right: 1px solid var(--line); min-width: 0; }
.cal-dayhead {
  display: flex; flex-direction: column; align-items: center; gap: 0;
  height: var(--cal-head); padding: .25rem .2rem;
  border-bottom: 1px solid var(--line);
  font-size: 12px; line-height: 1.25; text-align: center;
}
.cal-dname { font-weight: 700; color: var(--dark); }
.cal-dnum { color: var(--muted); font-variant-numeric: tabular-nums; }
.cal-dholiday {
  overflow: hidden; width: 100%;
  font-size: 10px; color: var(--warn);
  text-overflow: ellipsis; white-space: nowrap;
}
.cal-day[data-today] .cal-dayhead { background: rgba(125, 180, 244, .18); }
.cal-day[data-today] .cal-dname { color: var(--accent-dark); }
.cal-day[data-holiday] .cal-lane { background: rgba(179, 38, 30, .04); }

.cal-lane { position: relative; height: var(--cal-lane); }
.cal-line {
  position: absolute; inset-inline: 0; height: 0;
  border-top: 1px solid #eef1f3;
}

.cal-block {
  position: absolute; inset-inline: 0; overflow: hidden;
  padding: 2px 4px;
  font-size: 11px; line-height: 1.25;
}
.cal-block > * { display: block; }

/* training: a calm tinted band the full width of the day, behind everything */
.cal-train {
  z-index: 1;
  color: var(--accent-dark);
  background: repeating-linear-gradient(135deg,
    rgba(125, 180, 244, .20) 0 8px, rgba(125, 180, 244, .13) 8px 16px);
  border-left: 3px solid var(--accent);
}
.cal-train .cal-bname { font-weight: 600; }

/* a public holiday: the same band, greyed, saying why */
.cal-none {
  z-index: 1;
  color: #5c666d;
  background: repeating-linear-gradient(135deg,
    rgba(0, 0, 0, .07) 0 8px, rgba(0, 0, 0, .04) 8px 16px);
  border-left: 3px solid #b9c0c5;
}
.cal-none strong { color: var(--dark); }

/* a closure: the one red thing on the site */
.cal-closed {
  z-index: 2;
  color: var(--warn); background: var(--warn-tint);
  border-left: 3px solid var(--warn);
}
.cal-closed strong { color: var(--warn); }

/* matches sit on top of the training band, inset from the left so the band stays
   visible behind them — which is the true picture: the hall is open for training
   while 2-3 of the 6 tables are taken */
.cal-match {
  z-index: 3;
  background: #fff; color: var(--text);
  border: 1px solid var(--line); border-left: 3px solid var(--accent-dark);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .14);
}
 /* Heim on the first line, Gast on the second, and .own marks whichever of the two
    is ours — the same convention as the fixture sidebar. Both truncate; the league
    group on the meta line below never does, which is the point of putting it there. */
.cal-match .cal-bteam {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--muted);
}
.cal-match .cal-bteam.own { font-weight: 700; color: var(--dark); }
.cal-bmeta { display: flex; gap: .3rem; align-items: baseline; }
.cal-btime { font-variant-numeric: tabular-nums; color: var(--muted); }
.cal-bleague {
  flex: none; margin-left: auto;
  font-size: 10px; letter-spacing: .03em; text-transform: uppercase;
  color: var(--accent-dark); white-space: nowrap;
}
.cal-bscore {
  display: inline-block; margin-top: 1px; padding: 0 4px;
  font-weight: 700; color: #fff; background: var(--accent);
}
.cal-match[data-conflict] { border-color: var(--warn); border-left-color: var(--warn); }
.cal-match[data-conflict]::after {
  content: "!"; position: absolute; top: 1px; right: 3px;
  font-weight: 700; color: var(--warn);
}

/* ------------------------------------------------------------ month grid */
.cal-mhead, .cal-mgrid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
}
.cal-mhead {
  margin-top: .4rem; padding-bottom: .3rem;
  font-size: 12px; font-weight: 700; text-align: center; color: var(--dark);
}
.cal-mgrid { border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.cal-cell {
  display: flex; flex-direction: column; gap: 2px;
  min-height: 5.4rem; padding: 3px 4px 5px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  font-size: 11px; line-height: 1.25;
}
.cal-cell[data-other] { background: #fafbfc; color: #9aa4ab; }
.cal-cell[data-today] { outline: 2px solid var(--accent); outline-offset: -2px; }
.cal-cell[data-holiday] { background: rgba(179, 38, 30, .05); }
.cal-cell[data-closed] { background: var(--warn-tint); }
.cal-cnum { font-weight: 700; color: var(--dark); font-variant-numeric: tabular-nums; }
.cal-cell[data-other] .cal-cnum { color: #9aa4ab; }
.cal-choliday, .cal-cnone, .cal-cclosed, .cal-ctrain, .cal-cmatch {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-choliday { font-size: 10px; color: var(--warn); }
.cal-ctrain {
  padding: 0 3px; color: var(--accent-dark); background: rgba(125, 180, 244, .18);
  font-variant-numeric: tabular-nums;
}
.cal-cnone { padding: 0 3px; color: #5c666d; background: rgba(0, 0, 0, .06); }
.cal-cclosed { padding: 0 3px; color: #fff; background: var(--warn); cursor: help; }
.cal-cmatch {
  display: flex; gap: .25rem; align-items: baseline;
  padding: 1px 3px;
  background: #fff; border: 1px solid var(--line);
  border-left: 3px solid var(--accent-dark);
}
.cal-cmatch .cal-bname { font-weight: 600; color: var(--dark); }
.cal-cmatch .cal-bleague { margin-left: auto; }

/* ------------------------------------------------------------ export row
   Two unequal columns, and the inequality is the message. Subscribing is the only
   form that follows a Spielverlegung by itself, so it gets the tinted panel, the
   accent rule and the whole left side. The filtered download is a snapshot for the
   one case a subscription cannot cover — an arbitrary pair of teams — so it sits in
   the right-hand corner and stays quiet. */
.cal-export {
  display: grid; gap: 1rem 1.6rem; margin-top: 1.3rem;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  align-items: start;
}

/* Both boxes are closed until asked. The export area is then two quiet lines and
   the calendar above keeps the room, which is what it is there for.

   No tinted fill: the card outline, the accent rule and the icon on its disc carry
   the emphasis on their own, and a filled panel competed with the coloured blocks
   in the grid a few pixels above it. */
.cal-sub-box, .cal-dl-details {
  border: 1px solid var(--line);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .05);
}
.cal-sub-box { border-left: 4px solid var(--accent); }

/* one summary treatment for all three disclosures on the page */
.cal-sub-box > summary,
.cal-dl-details > summary,
.cal-table-wrap > summary {
  display: flex; align-items: center; gap: .55rem;
  cursor: pointer; list-style: none;
}
.cal-sub-box > summary::-webkit-details-marker,
.cal-dl-details > summary::-webkit-details-marker,
.cal-table-wrap > summary::-webkit-details-marker { display: none; }
/* Drawn rather than the native marker, because `display: flex` on a <summary>
   removes that marker in Chrome — so the season table had no affordance at all. */
.cal-sub-box > summary::after,
.cal-dl-details > summary::after,
.cal-table-wrap > summary::after {
  content: ""; flex: none;
  width: .45rem; height: .45rem; margin-left: .1rem;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  rotate: 45deg; translate: 0 -.12rem;
  transition: rotate .2s;
}
.cal-sub-box[open] > summary::after,
.cal-dl-details[open] > summary::after,
.cal-table-wrap[open] > summary::after { rotate: -135deg; translate: 0 .12rem; }

/* Same padding as the download box beside it, so the two closed boxes are exactly
   the same height — they are a pair, and one standing taller read as a mistake. */
.cal-sub-box > summary { padding: .6rem .9rem; }
.cal-sub-box[open] > summary { padding-bottom: .25rem; }
.cal-sub-h {
  display: flex; align-items: center; gap: .55rem;
  margin: 0; font-size: 15px; font-weight: 600; color: var(--dark);
}
/* the calendar's own heading icon, to the pixel: the glyph in the dark accent on a
   light accent disc, never the other way round */
.cal-sub-h .ico {
  flex: none; width: 18px; height: 18px; padding: 6px;
  color: var(--accent-dark); background: rgba(125, 180, 244, .16);
  border-radius: 50%; box-sizing: content-box;
}
.cal-sub-box > summary:hover .ico { color: #fff; background: var(--accent); }
/* indented to the heading text, past the 30px disc and its gap */
.cal-sub-body { padding: 0 .9rem 1rem calc(.9rem + 30px + .55rem); }
.cal-sub-intro { margin: 0 0 .7rem; font-size: 14px; line-height: 1.6; }

/* Which calendar the pills should aim at. The default is sniffed from the user
   agent and remembered, but it stays switchable: no sniff can see that a Windows
   visitor's only calendar is Google Calendar. */
.cal-modes { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: .5rem; }
.cal-mode {
  padding: .25rem .6rem; font: inherit; font-size: 13px; line-height: 1.3;
  color: var(--muted); background: #fff;
  border: 1px solid var(--line); cursor: pointer;
  transition: color .2s, background-color .2s, border-color .2s;
}
.cal-mode:hover { border-color: var(--accent-dark); color: var(--accent-dark); }
.cal-mode[aria-pressed="true"] {
  color: #fff; background: var(--accent-dark); border-color: var(--accent-dark);
}
.cal-mode-hint {
  margin: 0 0 .8rem; font-size: 12.5px; line-height: 1.55; color: var(--muted);
}
/* when the clipboard refuses, the hint line becomes the address itself */
.cal-mode-hint.is-address {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; color: var(--dark); word-break: break-all;
  user-select: all; -webkit-user-select: all;
}
/* in copy mode a pill is still a link to the address, so its look changes but its
   promise does not */
.cal-sub.is-copy { background: var(--dark); border-color: var(--dark); }
.cal-sub.did-copy { background: #2f7a44; border-color: #2f7a44; }

/* one prominent pill per target, wrapping — compact enough that the block stays a
   highlight rather than a wall of eight rows */
.cal-subs {
  display: flex; flex-wrap: wrap; gap: .45rem;
  margin: 0 0 .9rem; padding: 0; list-style: none;
}
.cal-sub {
  display: flex; flex-direction: column; gap: 1px;
  padding: .35rem .8rem;
  font-size: 14px; line-height: 1.25; text-decoration: none;
  color: #fff; background: var(--accent-dark);
  border: 1px solid var(--accent-dark);
  transition: background-color .2s, border-color .2s, translate .2s;
}
.cal-sub:hover, .cal-sub:focus-visible {
  color: #fff; background: var(--dark); border-color: var(--dark);
  translate: 0 -1px;
}
.cal-sub-name { font-weight: 600; }
.cal-sub-n { font-size: 11px; opacity: .78; font-variant-numeric: tabular-nums; }

.cal-dl-box { justify-self: end; width: 100%; max-width: 22rem; }
.cal-dl-details > summary { padding: .6rem .9rem; }
.cal-dl-details[open] > summary { padding-bottom: .2rem; }
.cal-dl-h { flex: 1; font-size: 13px; color: var(--muted); }
/* lighter than the subscribe box's, so the quiet option also looks quieter when
   it is closed — the chevron is the only mark either box shows at that size */
.cal-dl-details > summary::after { border-color: #bcc4c9; }
.cal-dl-details > summary:hover .cal-dl-h { color: var(--accent-dark); }
.cal-dl-body { padding: .4rem .9rem .8rem; }
.cal-dlsel {
  padding: .3rem .7rem; font: inherit; font-size: 13px;
  color: var(--accent-dark); background: none;
  border: 1px solid var(--accent); cursor: pointer;
  transition: color .2s, background-color .2s;
}
.cal-dlsel:hover { color: #fff; background: var(--accent); }
.cal-dlcount {
  margin: .4rem 0 .3rem; font-size: 12px; color: var(--dark);
  font-variant-numeric: tabular-nums;
}

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

.cal-table-wrap { margin-top: 1.1rem; }
.cal-table-wrap > summary {
  display: flex; align-items: center; gap: .45rem;
  padding: .5rem 0; font-size: 15px; color: var(--accent-dark); cursor: pointer;
}

/* -------------------------------------------------- the no-JS season table */
.cal-fallback {
  width: 100%; border-collapse: collapse; font-size: 14px;
}
.cal-fallback caption {
  padding-bottom: .6rem; font-size: 13px; color: var(--muted); text-align: left;
}
.cal-fallback th, .cal-fallback td {
  padding: .35rem .5rem; text-align: left; border-bottom: 1px solid #eee;
}
.cal-fallback th { font-size: 12px; text-transform: uppercase; color: var(--muted); }
.cal-fallback td:first-child { white-space: nowrap; }
/* the Heim and Gast columns are in fixture order; this marks which one is ours */
.cal-fallback .own { font-weight: 700; color: var(--dark); }
.cal-fallback abbr { text-decoration: none; }
.cal-empty { margin: 0; font-size: 15px; color: var(--muted); }
/* the table can be wider than a phone; it scrolls inside its own box rather
   than making the page scroll sideways */
.cal-table-wrap > div, .cal-body > .cal-fallback { overflow-x: auto; }
.cal-table-wrap[open] { overflow-x: auto; }

@media (max-width: 47.9375rem) {
  .cal { padding: 14px 12px 16px; }
  /* Seven columns on a phone would be 45px each. The grid scrolls sideways
     inside the calendar instead of being squeezed to nothing. */
  .cal-grid[data-view="week"] {
    overflow-x: auto; grid-template-columns: 2.6rem minmax(38rem, 1fr);
  }
  .cal { --cal-lane: 22rem; }
  .cal-range { flex: 1 1 100%; margin-left: 0; }
  /* one column, so the quiet option lands under the highlight rather than
     beside it in a 40px-wide gutter */
  .cal-export { grid-template-columns: 1fr; }
  .cal-dl-box { justify-self: stretch; max-width: none; }
  .cal-cell { min-height: 4.2rem; }
  .cal-cmatch .cal-bleague { display: none; }
}

@media print {
  /* the week can be pinned up in the hall */
  .cal-toolbar, .cal-chips, .cal-export { display: none; }
  .cal { border: 0; box-shadow: none; padding: 0; }
  .cal-block { color: #000 !important; }
  .cal-table-wrap { display: none; }
}

/* ---------------------------------------------------------------- weblinks */
.link-grid {
  display: grid; gap: 1.1rem; margin: 1.8rem 0 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
}
.link-card {
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .07);
  transition: box-shadow .3s, transform .3s, border-top-color .3s;
}
.link-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 26px rgba(0, 0, 0, .13);
  border-top-color: var(--accent-dark);
}
.link-hit {
  display: flex; align-items: center; gap: .9rem;
  padding: 1.1rem 1.2rem; text-decoration: none; color: inherit;
}
.link-mono {
  flex: none; display: grid; place-items: center;
  width: 44px; height: 44px;
  font-size: 20px; font-weight: 600; line-height: 1;
  color: #fff; background: var(--accent);
  transition: background-color .3s, transform .3s;
}
.link-card:hover .link-mono { background: var(--accent-dark); transform: rotate(-4deg); }
.link-text { min-width: 0; }
.link-title {
  display: block; font-size: 17px; font-weight: 600; line-height: 1.3;
  color: var(--dark);
}
.link-host {
  display: block; font-size: 13px; color: var(--accent-dark);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.link-card:hover .link-title { text-decoration: underline; }
.link-go {
  flex: none; margin-left: auto; color: var(--muted);
  transition: color .3s, transform .3s;
}
.link-go .ico { width: 18px; height: 18px; }
.link-card:hover .link-go { color: var(--accent-dark); transform: translate(3px, -3px); }
.link-meta {
  padding: 0 1.2rem 1.1rem; margin-left: calc(44px + .9rem);
  font-size: 14px; line-height: 1.6; color: var(--muted);
}
.link-meta p { margin: 0; }
.link-addr + .link-tel { margin-top: .4rem; }
.link-tel { font-variant-numeric: tabular-nums; }
@media (max-width: 30rem) {
  .link-meta { margin-left: 0; }
}

/* staggered reveal, driven by the --d each card carries */
.link-card.wow.is-visible { animation-delay: var(--d, 0ms); }

/* ---------------------------------------------------------------- footer */
.site-footer { margin-top: 0; background: var(--dark); color: #b3bdc3; font-size: 15px; }
.foot-grid {
  display: grid; gap: 1.8rem; padding: 40px 0 24px;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
.site-footer h2 {
  margin: 0 0 .7rem; font-size: 14px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: #fff;
}
.foot-line {
  display: flex; gap: .55rem; align-items: flex-start;
  margin: 0 0 .35rem; line-height: 1.6;
}
.foot-line .ico { margin-top: .35em; color: var(--accent); }
.site-footer a { color: #cbd3d8; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }

.copyright {
  display: flex; flex-wrap: wrap; gap: .25rem 2rem;
  align-items: center; justify-content: space-between;
  padding: 10px 0 20px; font-size: 13px;
  border-top: 1px solid rgba(255, 255, 255, .12);
}
.copyright p { margin: 0; }

/* Legal links, rebuilt from the old footer menu:
     li      float left, 20px apart, 0.3s transition
     a       block, rgba(255,255,255,.9), 15px/300, line-height 36px, 2px 0
     a::before  FontAwesome \f105 (angle-right) with an 8px gap  -> inline SVG
     li:hover   box-shadow 0 2px 0 rgba(255,255,255,.2)  -> the underline bar
   The bar sits under the whole item, chevron included, which is what makes it
   read as an underline rather than a text-decoration. */
.foot-nav {
  display: flex; flex-wrap: wrap; gap: 0 20px;
  margin: 0; padding: 0; list-style: none;
}
.foot-nav li {
  box-shadow: 0 2px 0 rgba(255, 255, 255, 0);
  transition: box-shadow .3s;
}
.foot-nav li:hover, .foot-nav li:focus-within {
  box-shadow: 0 2px 0 rgba(255, 255, 255, .2);
}
.foot-nav a {
  display: flex; align-items: center; gap: 8px;
  padding: 2px 0; line-height: 36px;
  font-size: 15px; font-weight: 300;
  color: rgba(255, 255, 255, .9); text-decoration: none;
  transition: color .3s;
}
.foot-nav a:hover, .foot-nav a:focus-visible { color: #fff; text-decoration: none; }
.foot-nav .ico { width: 11px; height: 11px; color: var(--accent); transition: transform .3s; }
.foot-nav a:hover .ico { transform: translateX(2px); }

@media (max-width: 40rem) {
  .copyright { justify-content: flex-start; }
}

/* ---------------------------------------------------------------- scrollup */
.scrollup {
  position: fixed; z-index: 80; right: 24px; bottom: 24px;
  display: grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  color: #fff; background: var(--accent); border: 0; cursor: pointer;
  opacity: 0; visibility: hidden;
  transition: opacity .3s, visibility .3s, background-color .3s;
}
.scrollup .ico { width: 24px; height: 24px; }
.scrollup:hover { background: var(--dark); }
.scrollup.is-visible { opacity: 1; visibility: visible; }
/* out of the way once the footer is on screen, so it never covers a link */
.scrollup.at-footer { opacity: 0; visibility: hidden; }
@media (min-width: 62rem) { .scrollup { right: 40px; bottom: 40px; } }

/* ---------------------------------------------------------------- popup */
.popup {
  position: fixed; z-index: 90; inset-block-end: 1rem; inset-inline-end: 1rem;
  width: min(25rem, calc(100vw - 2rem));
  padding: 1.2rem 2.2rem 1.3rem 1.4rem;
  font-size: 15px; line-height: 1.6;
  color: #10222f; background: var(--accent);
  box-shadow: 0 10px 32px rgba(0, 0, 0, .3);
  translate: 0 130%; opacity: 0;
  transition: translate .45s cubic-bezier(.2, .8, .2, 1), opacity .45s;
}
.popup[data-open] { translate: 0 0; opacity: .97; }
.popup :is(p, h4) { margin: 0 0 .5rem; }
.popup :last-child { margin-bottom: 0; }
.popup a { color: #10222f; }
.popup-close {
  position: absolute; top: .3rem; right: .4rem;
  display: grid; place-items: center;
  width: 2rem; height: 2rem; padding: 0;
  font-size: 1.4rem; line-height: 1; color: #10222f;
  background: none; border: 0; cursor: pointer;
}
.popup-close:hover { background: rgba(255, 255, 255, .4); }

/* -------------------------------------------------------- scroll reveal
   Replaces wow.js + animate.css. The .wow / .slideInLeft / .slideInRight
   class names come through from the Joomla content, so the original
   authoring intent is preserved; the implementation is ours. */
.wow { opacity: 0; }
.wow.is-visible { animation-duration: 1s; animation-fill-mode: both; opacity: 1; }
.wow.slideInLeft.is-visible  { animation-name: slideInLeft; }
.wow.slideInRight.is-visible { animation-name: slideInRight; }
.wow.zoomIn.is-visible       { animation-name: zoomIn; }
.wow.fadeInUp.is-visible     { animation-name: fadeInUp; }

@keyframes slideInLeft {
  from { transform: translate3d(-100%, 0, 0); visibility: visible; opacity: 0; }
  to   { transform: translate3d(0, 0, 0); opacity: 1; }
}
@keyframes slideInRight {
  from { transform: translate3d(100%, 0, 0); visibility: visible; opacity: 0; }
  to   { transform: translate3d(0, 0, 0); opacity: 1; }
}
@keyframes zoomIn {
  from { transform: scale3d(.3, .3, .3); opacity: 0; }
  50%  { opacity: 1; }
  to   { transform: scale3d(1, 1, 1); opacity: 1; }
}
@keyframes fadeInUp {
  from { transform: translate3d(0, 40px, 0); opacity: 0; }
  to   { transform: translate3d(0, 0, 0); opacity: 1; }
}

/* Content fade-in on first paint, the calm version of the old preloader. */
.content > * { animation: fadeInUp .5s both; }
.content > *:nth-child(1) { animation-delay: .02s; }
.content > *:nth-child(2) { animation-delay: .06s; }
.content > *:nth-child(3) { animation-delay: .1s; }
.content > *:nth-child(4) { animation-delay: .14s; }
.content > *:nth-child(n + 5) { animation-delay: .18s; }
.sidebar > * { animation: fadeInUp .5s .12s both; }

/* -------------------------------------------------- reduced motion
   One place that switches every animation off, including the reveals, the
   slideshow easing and the panorama auto-spin (see site.js). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .wow, .content > *, .sidebar > * { opacity: 1; animation: none !important; }
}

/* ---------------------------------------------------------------- print */
@media print {
  .banner, .site-header, .sidebar, .popup, .scrollup,
  .slide-nav, .slide-dots, .mf-section { display: none; }
  body { color: #000; font-size: 12pt; }
  .content > *, .wow { opacity: 1; animation: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
