/* Self-hosted Source Sans Pro (GDPR: avoids the Google Fonts CDN request main.css's
   vendored copy originally made — see main.css's own comment for the removed line).
   Only latin + latin-ext subsets: covers de/fr/lb/en. */
@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-300-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-300-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0300-0304, U+0308, U+0329, U+1E00-1EFF, U+2020;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-300-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-300-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0300-0304, U+0308, U+0329, U+1E00-1EFF, U+2020;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-600-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-600-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0300-0304, U+0308, U+0329, U+1E00-1EFF, U+2020;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-600-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-600-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0300-0304, U+0308, U+0329, U+1E00-1EFF, U+2020;
}

@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-400-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans Pro";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/SourceSansPro/source-sans-pro-400-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0300-0304, U+0308, U+0329, U+1E00-1EFF, U+2020;
}

/* Forty's 300-weight white-on-dark-green body text is hard to read for older
   visitors; 400 for running text, headings keep Forty's 600. */
body, input, select, textarea {
  font-weight: 400;
}

/* --- Site-specific additions Forty has no component for --- */

/* Primary links inline in the header on laptops and up. Forty only ever offers the
   hamburger; it stays at every width because the two CMS pages live only there. */
#header nav .header-link {
  display: none;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
@media screen and (min-width: 981px) {
  #header nav .header-link {
    display: block;
  }
}

/* Public POC disclaimers: footer line on every page, boxed callout on Anmeldung. */
.demo-notice {
  font-size: 0.8em;
  opacity: 0.7;
}
.demo-callout {
  border-radius: 4px;
  padding: 1em 1.25em;
  margin: 0 0 1.5em 0;
  background: rgba(236, 141, 129, 0.15);
  border: 1px solid rgba(236, 141, 129, 0.4);
}

/* Course schedule line — derived from the Timetable singleton (see timetable.js's
   formatSlotSchedule), never hand-written, so it can't drift from the actual slots. */
.tiles article header.major > p.tile-schedule {
  opacity: 0.75;
  font-size: 0.75em;
  margin-top: 0.35em;
}
.course-sessions {
  list-style: none;
  padding-left: 0;
}

/* Home page hero — overrides main.css's #banner rule, which otherwise points at
   Forty's own (uncommitted) demo image. The dark scrim (#banner:after in main.css)
   still applies on top of this for text legibility. */
#banner {
  background-image: url("/media/hero.jpg");
}

/* Embedded OpenStreetMap for a venue (course page, event page, timetable page) — a
   Google Maps link is kept alongside since Google's own embeddable map needs an API
   key/billing account and OSM's export/embed.html doesn't. */
.venue-embed-wrap {
  margin: 0.75em 0;
}
.venue-embed {
  display: block;
  width: 100%;
  max-width: 100%;
  height: 260px;
  border: 0;
  border-radius: 4px;
}
.venue-map-link {
  margin: 0 0 1.5em 0;
  font-size: 0.85em;
}
.venue-list .venue-embed-wrap {
  margin: 0;
}

/* Course detail: a hero (image, or a band in the course colour), the optional description,
   one "facts" card and one card per venue (the same .venue-card as on the timetable page),
   stacked. Every block is optional, so nothing depends on a long description being present. */
.course-page > * + * { margin-top: 1.5em; }
.course-hero {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.course-hero img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.course-hero-colour { height: 5em; }
@media screen and (min-width: 981px) {
  .course-hero img { aspect-ratio: 21 / 9; }
}
.course-body > :last-child { margin-bottom: 0; }
.course-facts {
  padding: 1.25em 1.5em;
  border: 1px solid rgba(128, 128, 128, 0.35);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.course-facts > :first-child { margin-top: 0; }
.course-facts > :last-child { margin-bottom: 0; }
.course-facts h3 { margin-top: 1.25em; }
.course-facts .course-level { font-weight: 600; }
.course-info .course-venues { margin: 1.5em 0 0 0; }
@media screen and (min-width: 981px) {
  .course-info.has-venues {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5em;
    align-items: stretch;
  }
  .course-info .course-venues { margin: 0; }
  /* The venue card(s) stretch to the facts card's height; the map takes the free space. */
  .course-venues { grid-template-columns: 1fr; grid-auto-rows: 1fr; }
  .course-venues .venue-card { display: flex; flex-direction: column; }
  .course-venues .venue-embed-wrap { flex: 1; display: flex; }
  .course-venues .venue-embed { height: auto; min-height: 200px; flex: 1; aspect-ratio: auto; }
}

/* Forty's header.major sizes itself to its content's *unwrapped* width (max-content)
   so a short title's underline hugs the text exactly — but #two's intro is a full
   sentence, which then doesn't wrap and overflows the viewport on mobile (the
   site-wide horizontal-scroll bug this was causing). Let it wrap like normal text. */
#two header.major {
  width: 100%;
}

/* Forty's .actions row is a non-wrapping flex row; with 3 buttons (added once we
   introduced Events/flyer links) it can be wider than the viewport on mobile instead
   of wrapping — the same class of horizontal-overflow bug as #two's heading above. */
ul.actions {
  flex-wrap: wrap;
  row-gap: 1em;
}

/* Course tiles (courses index) use the course's own colour instead of Forty's
   default nth-child accent rotation. */
.tiles article.course-tile:before {
  background-color: var(--tile-colour) !important;
}

/* Touch screens have no hover, so Forty's "flat colour overlay that fades out on hover"
   would leave every course photo washed out for good. There the photo stays visible and the
   course colour becomes a gradient rising from the bottom, behind the text. */
@media (hover: none) {
  .tiles article.course-tile:before,
  .tiles article.course-tile:hover:before {
    opacity: 1;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.55) 45%, rgba(0, 0, 0, 0.15) 100%) !important;
    background: linear-gradient(to top, var(--tile-colour) 0%, color-mix(in srgb, var(--tile-colour) 65%, transparent) 45%, color-mix(in srgb, var(--tile-colour) 20%, transparent) 100%) !important;
  }
  .tiles article.course-tile header {
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
  }
}

/* Tile subtitles carry the "Für wen" sentence and timeline teasers are prose —
   Forty's uppercase 0.25em-tracked header.major > p is meant for two-word labels. */
.tiles article header.major > p,
.timeline-item header.major > p {
  text-transform: none;
  letter-spacing: 0.025em;
  font-size: 0.85em;
  font-weight: 400;
}

/* Course colour swatch (course page, timetable grid). */
.swatch {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  border-radius: 3px;
  vertical-align: middle;
  margin-right: 0.5em;
}

/* Closure banner (timetable page) — reuses the site's "box" look with a warning tint. */
.closure-banner {
  border-radius: 4px;
  padding: 1em 1.25em;
  margin: 0 0 1.5em 0;
  background: rgba(236, 141, 129, 0.15);
  border: 1px solid rgba(236, 141, 129, 0.4);
}

/* "Cancelled" badge next to a timetable slot. */
.badge-cancelled {
  display: inline-block;
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.2em 0.6em;
  border-radius: 3px;
  background: #ec8d81;
  color: #242943;
  margin-left: 0.5em;
}
/* The badge always renders in the markup now (timetable.11ty.js) so
   timetable-freshness.js can toggle `hidden` on it; without this, the
   `display: inline-block` above (an author-origin rule) would otherwise beat the
   browser's own `[hidden] { display: none }` default. Same reasoning would apply to
   .closure-banner-active-label/-upcoming-label, but those stay plain <strong>s with
   no display override, so the browser default already hides them correctly. */
.badge-cancelled[hidden] {
  display: none;
}

/* Timetable grid cells: one line per slot, swatch + badge inline. */
.timetable-slots {
  list-style: none;
  margin: 0;
}
.timetable-slots li {
  padding: 0.25em 0;
}
.slot-time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.slot-note,
.slot-room {
  opacity: 0.75;
}
.slot-room {
  font-size: 0.85em;
}
.closure-list,
.venue-list {
  list-style: none;
  padding-left: 0;
}

/* Timetable page: venues as cards in a responsive grid (4:3 maps), not full-width banners. */
.venue-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.5em;
  margin: 0 0 2em 0;
}
.venue-card {
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 1px solid rgba(128, 128, 128, 0.35);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.venue-card .venue-embed {
  height: auto;
  aspect-ratio: 4 / 3;
  border-radius: 0;
}
.venue-card-body {
  padding: 0.75em 1em 1em;
}
.venue-card-body .venue-name {
  margin: 0 0 0.25em 0;
}

/* Untranslated-content notice on fallback pages. */
.notice-fallback {
  font-style: italic;
  opacity: 0.75;
}

/* Language switcher — lives in #header so it's reachable on every page without
   opening the hamburger menu (it used to be a section inside #menu). */
.lang-switcher {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.lang-switcher li {
  padding: 0;
}
.lang-switcher a {
  display: block;
  border: 0;
  padding: 0 0.6em;
  text-transform: uppercase;
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.05em;
  opacity: 0.7;
}
.lang-switcher a:hover {
  opacity: 1;
}

/* News timeline (articles index) — a chronological feed instead of the tiled
   photo-grid used for Home/Courses, since news reads better as a single trail. */
.timeline {
  position: relative;
  margin: 2em 0 2em 0.4em;
  padding-left: 2em;
  border-left: 2px solid rgba(212, 255, 228, 0.15);
}
.timeline-item {
  position: relative;
  padding-bottom: 2.5em;
}
.timeline-item:last-child {
  padding-bottom: 0;
}
.timeline-item:before {
  content: "";
  position: absolute;
  left: -2.45em;
  top: 0.3em;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  background: #7be8ae;
  box-shadow: 0 0 0 4px #173226;
}
.timeline-item time {
  display: block;
  margin-bottom: 0.35em;
  text-transform: uppercase;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 0.05em;
  opacity: 0.65;
}
.timeline-item header.major {
  margin: 0;
}
.timeline-item .image {
  float: right;
  width: 9em;
  margin: 0 0 1em 1.5em;
  border-radius: 4px;
  overflow: hidden;
}
.timeline-item .image img {
  display: block;
  width: 100%;
}
.timeline-item.is-past {
  opacity: 0.6;
}
.timeline-divider {
  margin: 0 0 1.5em 0;
  text-transform: uppercase;
  font-size: 0.8em;
  letter-spacing: 0.05em;
  opacity: 0.65;
}
@media screen and (max-width: 480px) {
  .timeline-item .image {
    float: none;
    width: 100%;
    margin: 0 0 1em 0;
  }
}

/* Trainer name: right-aligned directly under the course title. */
.course-trainer {
  text-align: right;
  margin: -0.5em 0 1.5em;
  font-style: italic;
}

/* Home: hero call-to-action. */
.hero-actions {
  justify-content: center;
  margin-top: 1.5em;
}

/* Home: "who is it for" picture cards. */
.category-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.25em;
  margin: 0 0 3em 0;
}
.category-card {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 12em;
  padding: 1em 1.25em;
  border: 0;
  border-radius: 8px;
  overflow: hidden;
  background-color: #1c6b48;
  background-size: cover;
  background-position: center;
  color: #fff;
  text-decoration: none;
}
.category-card:before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.05) 65%);
  transition: background 0.2s;
}
.category-card:hover:before {
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.0) 70%);
}
.category-card-label {
  position: relative;
  font-size: 1.4em;
  font-weight: 600;
}

/* Home: next classes (filled in by assets/js/home-next-classes.js), as cards. */
.week-list {
  list-style: none;
  padding-left: 0;
  margin: 0 0 1.5em 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1em;
}
.week-list li {
  margin: 0;
  padding: 1em 1.25em;
  border: 1px solid rgba(128, 128, 128, 0.35);
  border-radius: 8px;
}
.week-list li.is-cancelled {
  opacity: 0.6;
}
.week-list li.is-cancelled a {
  text-decoration: line-through;
}

/* Courses page: category filter chips. `[hidden]` must win over Forty's tile display. */
.category-filter {
  flex: 0 0 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6em;
  padding: 1.25em 1.5em;
}
.category-filter a,
.category-filter a:hover {
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 999px;
  padding: 0.35em 1.1em;
  text-decoration: none;
  color: #fff;
  background: transparent;
}
.category-filter a:hover {
  background: rgba(255, 255, 255, 0.15);
}
.category-filter a[aria-pressed="true"],
.category-filter a[aria-pressed="true"]:hover {
  background: #fff;
  color: #1c6b48;
  border-color: #fff;
}
/* Explicit 40/60 alternation for course tiles (Forty's :nth-child version breaks with
   the chip bar and filtering). Above 980px only: below, Forty forces 50%/100%. */
.tiles article.course-tile.tile-narrow {
  width: 40%;
}
.tiles article.course-tile.tile-wide {
  width: 60%;
}
.tiles article[hidden] {
  display: none !important;
}

/* Price list page and the compact list on course pages. */
.price-table td { vertical-align: middle; }
.price-table .price-amount { text-align: right; white-space: nowrap; }
.course-prices { margin-bottom: 1em; }

/* Privacy/legal links must stay readable; the theme's copyright colour is too faint for them. */
#footer .legal-links a { color: rgba(255, 255, 255, 0.75); }

/* Enrolment status ("Full" / "Waiting list") next to a course. */
.status-badge {
  display: inline-block;
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.2em 0.6em;
  border-radius: 3px;
  background: #f3c969;
  color: #242943;
  margin-left: 0.3em;
}
.status-badge.status-full { background: #ec8d81; }
.tiles article header.major > p.tile-status { margin-top: 0.5em; }
.tiles article header.major > p.tile-status .status-badge { margin-left: 0; }

/* Club logo (white art, src/assets/img/logo-white.png): header mark, home hero, footer. */
#header .logo .logo-mark {
  height: 2.9em;
  width: 2.9em;
  vertical-align: middle;
  margin-right: 0.6em;
}
.hero-logo {
  display: block;
  width: 120px;
  height: 120px;
  margin: 0 0 1em;
}
.footer-logo {
  display: block;
  width: 48px;
  height: 48px;
  margin: 0 0 1em;
  opacity: 0.8;
}
@media screen and (max-width: 480px) {
  .hero-logo { width: 88px; height: 88px; }
}

/* Grouped course tile: one line per course (colour swatch + who/when), each linking to its own
   course page. */
.tiles article header.major > ul.group-items {
  list-style: none;
  padding: 0;
  margin: 0.4em 0 0 0;
  font-size: 0.85em;
  text-transform: none;
  letter-spacing: 0.025em;
}
.group-items li {
  padding: 0.15em 0;
}
/* The tile's header is a stacking context (z-index 3) below the overlay link (4), so in a
   grouped tile it is lifted above the overlay; clicks on its empty parts fall through to the
   overlay (first course), only the links themselves catch them. */
.tiles article.course-group header {
  z-index: 5;
  pointer-events: none;
}
.tiles article.course-group header a {
  pointer-events: auto;
}
.group-items a {
  color: inherit;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.6);
}
.group-items a:hover {
  border-bottom-color: #fff;
}
.group-items .swatch {
  width: 0.7em;
  height: 0.7em;
  margin-right: 0.5em;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5);
}
