/* =========================================================================
   projects.css — Projekteite: Filterleiste, Karten, Detailfenster
   ========================================================================= */

/* =========================================================================
   Seitenkopf
   ========================================================================= */

.page-head {
   position: relative;
   padding-block: clamp(3rem, 2rem + 5vw, 5.5rem) clamp(2rem, 1.5rem + 3vw, 3.5rem);
   border-bottom: 1px solid var(--edge);
   overflow: hidden;
}

.page-head__grid {
   position: absolute;
   inset: 0;
   pointer-events: none;
   background-image: linear-gradient(to right, var(--grid-line) 1px, transparent 1px);
   background-size: calc(100% / 12) 100%;
   mask-image: radial-gradient(ellipse 110% 100% at 30% 0%, #000 10%, transparent 75%);
   -webkit-mask-image: radial-gradient(ellipse 110% 100% at 30% 0%, #000 10%, transparent 75%);
}

.page-head__inner {
   position: relative;
}

.page-head__title {
   font-size: var(--fs-display);
   line-height: var(--lh-tight);
   letter-spacing: var(--track-display);
   margin-bottom: clamp(0.9rem, 0.6rem + 1.2vw, 1.4rem);
}

.page-head__title em {
   font-style: italic;
   color: var(--accent);
}

.page-head__lead {
   font-size: var(--fs-lead);
   line-height: var(--lh-loose);
   color: var(--ink-2);
   max-width: 52ch;
}

.page-head__stats {
   display: flex;
   flex-wrap: wrap;
   gap: clamp(1.25rem, 0.8rem + 2vw, 2.5rem);
   margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem);
   padding-top: 1.5rem;
   border-top: 1px solid var(--edge);
}

.page-head__stat {
   display: flex;
   flex-direction: column;
   gap: 0.25rem;
}

.page-head__stat-num {
   font-family: var(--font-display);
   font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.5rem);
   line-height: 1;
   color: var(--accent);
   font-variant-numeric: tabular-nums;
}

.page-head__stat-label {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--ink-3);
}

/* =========================================================================
   Externer Link (Discord und ähnliches)
   ========================================================================= */

.srv-discord {
   display: inline-flex;
   align-items: center;
   gap: 0.5rem;
   min-height: 36px;
   padding: 0.4rem 0.85rem;
   font-family: var(--font-mono);
   font-size: var(--fs-xs);
   letter-spacing: var(--track-wide);
   color: var(--ink-2);
   background: var(--surface-2);
   border: 1px solid var(--edge);
   border-radius: var(--r-xs);
   white-space: nowrap;
   transition: color var(--t-xs) var(--ease-out), border-color var(--t-xs) var(--ease-out),
      background-color var(--t-xs) var(--ease-out), transform var(--t-xs) var(--ease-out);
}

.srv-discord svg {
   width: 15px;
   height: 15px;
   flex: none;
}

.srv-discord svg:first-child {
   fill: currentColor;
   stroke: none;
}

.srv-discord svg:last-child {
   width: 12px;
   height: 12px;
   fill: none;
   stroke: currentColor;
   stroke-width: 1.8;
   stroke-linecap: round;
   stroke-linejoin: round;
   opacity: 0.65;
}

.srv-discord:hover,
.srv-discord:focus-visible {
   color: var(--ink);
   background: var(--surface);
   border-color: var(--edge-strong);
   transform: translateY(-2px);
}

@media (max-width: 420px) {
   .detail__foot .srv-discord {
      margin-left: 0;
   }
}

/* =========================================================================
   Einstieg zu den Server-Changelogs
   ========================================================================= */

.srv-entry {
   display: grid;
   grid-template-columns: auto minmax(0, 1fr) auto;
   gap: clamp(1rem, 0.7rem + 1.5vw, 1.75rem);
   align-items: center;
   margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem);
   padding: clamp(1.1rem, 0.9rem + 0.8vw, 1.5rem);
   background: var(--surface);
   border: 1px solid var(--edge);
   border-radius: var(--r-md);
   transition: border-color var(--t-sm) var(--ease-out), background-color var(--t-sm) var(--ease-out),
      box-shadow var(--t-sm) var(--ease-out), transform var(--t-sm) var(--ease-out);
}

.srv-entry:hover,
.srv-entry:focus-visible {
   border-color: var(--accent-line);
   background: var(--surface-hover);
   transform: translateY(-2px);
   box-shadow: var(--shadow-md);
}

.srv-entry__glyph {
   display: grid;
   place-items: center;
   width: 52px;
   height: 52px;
   font-size: 1.6rem;
   line-height: 1;
   background: var(--bg-sunken);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
}

.srv-entry__text {
   display: grid;
   gap: 0.2rem;
   min-width: 0;
}

.srv-entry__kicker {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--accent);
}

.srv-entry__title {
   font-family: var(--font-display);
   font-size: var(--fs-h3);
   line-height: var(--lh-snug);
}

.srv-entry__desc {
   font-size: var(--fs-sm);
   line-height: var(--lh-base);
   color: var(--ink-2);
}

@media (max-width: 700px) {
   .srv-entry {
      grid-template-columns: auto minmax(0, 1fr);
   }

   .srv-entry .btn {
      grid-column: 1 / -1;
   }
}

/* =========================================================================
   Filterleiste
   ========================================================================= */

.toolbar {
   position: sticky;
   top: var(--header-total);
   z-index: var(--z-sticky);
   margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem);
   padding: 0.75rem;
   background: var(--header-bg);
   border: 1px solid var(--edge);
     border-radius: var(--r-md);

/* Kein backdrop-filter: die Leiste ist sticky und wuerde beim
          Scrollen jeden Frame neu weichzeichnen. Stattdessen fast
          deckend, optisch dasselbe. Die erste Zeile ist der Rueckfall
          fuer aeltere Browser ohne color-mix. */
       background: var(--header-bg);
       background: color-mix(in srgb, var(--surface) 94%, transparent);
     display: grid;
   grid-template-columns: minmax(0, 1fr) auto auto;
   gap: 0.6rem;
   align-items: center;
}

@media (max-width: 860px) {
   .toolbar {
      grid-template-columns: minmax(0, 1fr) auto;
      row-gap: 0.6rem;
   }

   .toolbar__scope {
      grid-column: 1 / -1;
   }
}

/* ---------- Suche ---------- */
.search {
   position: relative;
   display: flex;
   align-items: center;
   min-width: 0;
}

/* Auf Touch-Geraeten durchscheint der Inhalt sonst durch die Leiste,
   weil dort kein Weichzeichner im Spiel ist. */
@media (hover: none), (pointer: coarse) {
   .toolbar {
      background: var(--surface);
   }
}

.search__icon {
   position: absolute;
   left: 0.85rem;
   width: 16px;
   height: 16px;
   color: var(--ink-3);
   pointer-events: none;
   transition: color var(--t-xs) var(--ease-out);
}

.search__icon svg {
   width: 100%;
   height: 100%;
   stroke: currentColor;
   fill: none;
   stroke-width: 1.7;
   stroke-linecap: round;
   stroke-linejoin: round;
}

.search:focus-within .search__icon {
   color: var(--accent);
}

.search__input {
   width: 100%;
   height: 44px;
   padding: 0 2.5rem 0 2.6rem;
   font-size: var(--fs-sm);
   color: var(--ink);
   background: var(--surface);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
   transition: border-color var(--t-xs) var(--ease-out), box-shadow var(--t-xs) var(--ease-out);
}

.search__input::placeholder {
   color: var(--ink-3);
}

.search__input:focus {
   outline: none;
   border-color: var(--accent);
   box-shadow: 0 0 0 3px var(--accent-tint);
}

.search__clear {
   position: absolute;
   right: 0.5rem;
   display: grid;
   place-items: center;
   width: 26px;
   height: 26px;
   color: var(--ink-3);
   border-radius: var(--r-xs);
   opacity: 0;
   pointer-events: none;
   transition: opacity var(--t-xs) var(--ease-out), color var(--t-xs) var(--ease-out);
}

.search__clear svg {
   width: 13px;
   height: 13px;
   stroke: currentColor;
   stroke-width: 2;
   stroke-linecap: round;
}

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

.search__clear.is-visible {
   opacity: 1;
   pointer-events: auto;
}

/* ---------- Segment-Schalter (Haupt/Nebenprojekte) ---------- */
.scope {
   position: relative;
   display: flex;
   padding: 3px;
   background: var(--surface);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
}

.scope__btn {
   position: relative;
   z-index: 1;
   display: inline-flex;
   align-items: center;
   gap: 0.4rem;
   height: 36px;
   padding: 0 0.85rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   text-transform: uppercase;
   color: var(--ink-3);
   border-radius: var(--r-xs);
   white-space: nowrap;
   transition: color var(--t-sm) var(--ease-out);
}

.scope__btn[aria-pressed="true"] {
   color: var(--accent);
}

.scope__thumb {
   position: absolute;
   z-index: 0;
   top: 3px;
   bottom: 3px;
   left: 3px;
   background: var(--accent-tint);
   border: 1px solid var(--accent-line);
   border-radius: var(--r-xs);
   transition: transform var(--t-md) var(--ease-out), width var(--t-md) var(--ease-out);
}

@media (max-width: 560px) {
   .scope {
      width: 100%;
   }

   .scope__btn {
      flex: 1;
      justify-content: center;
      padding-inline: 0.4rem;
   }
}

/* ---------- Filter-Trigger ---------- */
.filter-trigger {
   position: relative;
   display: inline-flex;
   align-items: center;
   gap: 0.5rem;
   height: 44px;
   padding: 0 0.9rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   text-transform: uppercase;
   color: var(--ink-2);
   background: var(--surface);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
   white-space: nowrap;
   transition: color var(--t-xs) var(--ease-out), border-color var(--t-xs) var(--ease-out);
}

.filter-trigger:hover,
.filter-trigger[aria-expanded="true"] {
   color: var(--ink);
   border-color: var(--edge-strong);
}

.filter-trigger svg {
   width: 15px;
   height: 15px;
   stroke: currentColor;
   fill: none;
   stroke-width: 1.7;
   stroke-linecap: round;
   stroke-linejoin: round;
}

.filter-trigger__badge {
   display: none;
   align-items: center;
   justify-content: center;
   min-width: 17px;
   height: 17px;
   padding: 0 4px;
   font-size: 0.625rem;
   font-weight: 700;
   color: var(--accent-ink);
   background: var(--accent);
   border-radius: var(--r-pill);
}

.filter-trigger.has-filters .filter-trigger__badge {
   display: inline-flex;
}

/* Telefon: Die Leiste klebt direkt unter dem Kopf und friss sonst fast
   ein Fuenftel des Bildschirms. Suchfeld und Filter-Knopf teilen sich
   eine Zeile, die Textmarken liegen darunter.

   Diese Regeln stehen bewusst hinter allen Grundregeln oben. Eine
   Media-Abfrage gewinnt gegen spaetere Regeln mit gleicher
   Staerke nicht, sonst blieben Suchfeld und Knopf bei 44px. */
@media (max-width: 560px) {
   .toolbar {
      row-gap: 0.4rem;
      padding: 0.5rem;
      margin-top: 1rem;
      border-radius: var(--r-sm);
   }

   /* Ohne feste Platzierung landet der Filter-Knopf in einer eigenen
      Zeile, weil der Segment-Schalter die volle Breite belegt. */
   .search {
      grid-column: 1;
      grid-row: 1;
   }

   .toolbar__scope {
      grid-column: 1 / -1;
      grid-row: 2;
   }

   .search__input {
      height: 38px;
      padding-inline: 2.2rem;
   }

   .search__icon {
      left: 0.7rem;
   }

   .search__clear {
      right: 0.4rem;
   }

   /* Nur das Symbol. Die Zahl wandert als Punkt auf das Symbol. */
   .filter-trigger {
      grid-column: 2;
      grid-row: 1;
      width: 38px;
      height: 38px;
      padding: 0;
      justify-content: center;
   }

   /* Die Beschriftung bleibt fuer Vorlesesoftware erhalten. */
   .filter-trigger > span:not(.filter-trigger__badge) {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
   }

   .filter-trigger__badge {
      position: absolute;
      top: -5px;
      right: -5px;
      min-width: 16px;
      height: 16px;
      font-size: 0.5625rem;
   }

   .scope__btn {
      height: 30px;
      font-size: 0.56rem;
   }
}

/* ---------- Kategorie-Reiter ---------- */
.category-bar {
   display: flex;
   align-items: center;
   gap: 0.4rem;
   margin-top: 1.25rem;
   padding-bottom: 0.35rem;
   overflow-x: auto;
   scrollbar-width: none;
   -ms-overflow-style: none;
}

.category-bar::-webkit-scrollbar {
   display: none;
}

.category-btn {
   display: inline-flex;
   align-items: center;
   gap: 0.5rem;
   padding: 0.5rem 0.9rem;
   font-size: var(--fs-sm);
   color: var(--ink-2);
   background: transparent;
   border: 1px solid transparent;
   border-radius: var(--r-pill);
   white-space: nowrap;
   cursor: pointer;
   transition: color var(--t-xs) var(--ease-out), background-color var(--t-xs) var(--ease-out),
      border-color var(--t-xs) var(--ease-out);
}

.category-btn:hover {
   color: var(--ink);
   background: var(--surface-2);
}

.category-btn.is-active {
   color: var(--accent);
   background: var(--accent-tint);
   border-color: var(--accent-line);
}

.category-btn__count {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   color: var(--ink-3);
}

.category-btn.is-active .category-btn__count {
   color: var(--accent);
}

/* ---------- Ergebniszeile ---------- */
.results-bar {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   justify-content: space-between;
   gap: 0.75rem;
   margin-block: 1.5rem 1.25rem;
   padding-bottom: 0.85rem;
   border-bottom: 1px solid var(--edge);
}

.results-bar__count {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   text-transform: uppercase;
   color: var(--ink-3);
}

.results-bar__count strong {
   color: var(--accent);
}

.active-filters {
   display: flex;
   flex-wrap: wrap;
   gap: 0.35rem;
}

.active-filters:empty {
   display: none;
}

.filter-tag {
   display: inline-flex;
   align-items: center;
   gap: 0.4rem;
   padding: 0.22rem 0.4rem 0.22rem 0.6rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--accent);
   background: var(--accent-tint);
   border: 1px solid var(--accent-line);
   border-radius: var(--r-pill);
}

.filter-tag button {
   display: grid;
   place-items: center;
   width: 15px;
   height: 15px;
   color: inherit;
   border-radius: 50%;
   transition: background-color var(--t-xs) var(--ease-out);
}

.filter-tag button:hover {
   background: var(--accent-line);
}

.filter-tag svg {
   width: 9px;
   height: 9px;
   stroke: currentColor;
   stroke-width: 2.4;
   stroke-linecap: round;
}

/* =========================================================================
   Filterfenster
   ========================================================================= */

.modal-overlay {
     position: fixed;
     inset: 0;
     z-index: var(--z-modal);
     display: grid;
     place-items: center;
     padding: var(--gutter);
     /* Kein backdrop-filter. Ueber den ganzen Bildschirm geweicht kostet
        der Browser bei jedem Neuaufbauen des Hintergrunds, und im
        Dialog wird haeufig gescrollt. Das Scrim allein reicht, es ist
        mit 0.62 ohnehin dunkel genug. */
     background: var(--scrim);
     opacity: 0;
     visibility: hidden;
     transition: opacity var(--t-md) var(--ease-out), visibility var(--t-md) var(--ease-out);
   }

.modal-overlay.is-open {
   opacity: 1;
   visibility: visible;
}

  .modal {
     position: relative;
     width: min(100%, 560px);
     max-height: min(86svh, 780px);
     display: flex;
     flex-direction: column;
     background: var(--surface);
     border: 1px solid var(--edge-strong);
     border-radius: var(--r-md);
     box-shadow: var(--shadow-pop);
     overflow: hidden;

     /* Nur eine Verschiebung, keine Skalierung. Eine Skalierung zwingt den
        Browser, den ganzen Dialog in jedem Frame neu zu zeichnen — bei
        langen Versionsverläufen merkt man das deutlich als Ruckeln. */
     transform: translateY(14px);
     transition: transform var(--t-md) var(--ease-out);
  }

  .modal-overlay.is-open .modal {
     transform: translateY(0);
  }

.modal__head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 1rem;
   padding: 1.1rem 1.25rem;
   border-bottom: 1px solid var(--edge);
   flex: none;
}

.modal__title {
   font-size: var(--fs-h3);
}

.modal__close {
   display: grid;
   place-items: center;
   width: 34px;
   height: 34px;
   color: var(--ink-3);
   border-radius: var(--r-sm);
   transition: color var(--t-xs) var(--ease-out), background-color var(--t-xs) var(--ease-out);
}

.modal__close:hover {
   color: var(--ink);
   background: var(--surface-2);
}

.modal__close svg {
   width: 15px;
   height: 15px;
   stroke: currentColor;
   stroke-width: 1.8;
   stroke-linecap: round;
}

.modal__body {
   padding: 1.25rem;
   overflow-y: auto;
   overscroll-behavior: contain;
}

.modal__foot {
   display: flex;
   gap: 0.6rem;
   padding: 1rem 1.25rem;
   border-top: 1px solid var(--edge);
   background: var(--surface-2);
   flex: none;
}

.modal__foot .btn {
   flex: 1;
}

/* ---------- Filtergruppen ---------- */
.filter-group + .filter-group {
   margin-top: 1.5rem;
   padding-top: 1.25rem;
   border-top: 1px solid var(--edge-faint);
}

.filter-group__title {
   margin-bottom: 0.75rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--ink-3);
}

.chip-set {
   display: flex;
   flex-wrap: wrap;
   gap: 0.4rem;
}

.chip {
   padding: 0.45rem 0.85rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--ink-2);
   background: var(--surface-2);
   border: 1px solid var(--edge);
   border-radius: var(--r-pill);
   white-space: nowrap;
   cursor: pointer;
   transition: color var(--t-xs) var(--ease-out), background-color var(--t-xs) var(--ease-out),
      border-color var(--t-xs) var(--ease-out);
}

.chip:hover {
   color: var(--ink);
   border-color: var(--edge-strong);
}

.chip.is-active {
   color: var(--accent);
   background: var(--accent-tint);
   border-color: var(--accent-line);
}

/* =========================================================================
   Projektliste
   ========================================================================= */

.projects-group + .projects-group {
   margin-top: clamp(2.5rem, 1.5rem + 3vw, 4rem);
}

.projects-group__head {
   display: flex;
   align-items: center;
   gap: 1rem;
   margin-bottom: 1.5rem;
}

.projects-group__title {
   font-family: var(--font-mono);
   font-size: var(--fs-xs);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--ink-2);
   white-space: nowrap;
}

.projects-group__rule {
   flex: 1;
   height: 1px;
   background: var(--edge);
}

.projects-group__count {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   color: var(--ink-3);
   white-space: nowrap;
}

.projects-grid {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
   gap: var(--sp-5);
}

/* ---------- Karte ---------- */
.project-card {
   position: relative;
   display: flex;
   flex-direction: column;
   background: var(--surface);
   border: 1px solid var(--edge);
   border-radius: var(--r-md);
   overflow: hidden;
   text-align: left;
   cursor: pointer;
   animation: card-in var(--t-lg) var(--ease-out) both;
   animation-delay: calc(var(--i, 0) * 45ms);
   transition: border-color var(--t-sm) var(--ease-out), transform var(--t-sm) var(--ease-out),
      box-shadow var(--t-sm) var(--ease-out), background-color var(--t-sm) var(--ease-out);
}

@keyframes card-in {
   from {
      opacity: 0;
      transform: translateY(20px);
   }

   to {
      opacity: 1;
      transform: none;
   }
}

.project-card:hover {
   border-color: var(--edge-strong);
   background: var(--surface-hover);
   transform: translateY(-4px);
   box-shadow: var(--shadow-lg);
}

.project-card:focus-visible {
   border-color: var(--accent);
}

/* ---------- Kartenkopf mit Glyphe ---------- */
.card-visual {
   position: relative;
   display: grid;
   place-items: center;
   height: 132px;
   background: var(--bg-sunken);
   border-bottom: 1px solid var(--edge);
   overflow: hidden;
}

/* Feines Raster im Kopf */
.card-visual::before {
   content: "";
   position: absolute;
   inset: 0;
   background-image: linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
      linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
   background-size: 28px 28px;
   mask-image: radial-gradient(circle at 50% 50%, #000 10%, transparent 72%);
   -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 10%, transparent 72%);
}

.card-visual__glyph {
   position: relative;
   font-size: 2.6rem;
   line-height: 1;
   filter: grayscale(0.25);
   transition: transform var(--t-md) var(--ease-spring), filter var(--t-md) var(--ease-out);
}

.project-card:hover .card-visual__glyph {
   transform: scale(1.14) translateY(-2px);
   filter: grayscale(0);
}

/* Ecken-Akzente */
.card-visual__corner {
   position: absolute;
   width: 10px;
   height: 10px;
   border-color: var(--accent);
   opacity: 0;
   transition: opacity var(--t-sm) var(--ease-out), transform var(--t-sm) var(--ease-out);
}

.card-visual__corner--tl {
   top: 10px;
   left: 10px;
   border-top: 1px solid;
   border-left: 1px solid;
   transform: translate(4px, 4px);
}

.card-visual__corner--br {
   bottom: 10px;
   right: 10px;
   border-bottom: 1px solid;
   border-right: 1px solid;
   transform: translate(-4px, -4px);
}

.project-card:hover .card-visual__corner {
   opacity: 0.7;
   transform: translate(0, 0);
}

/* ---------- Statusmarken ---------- */
.card-badges {
   position: absolute;
   top: 0.7rem;
   right: 0.7rem;
   z-index: 2;
   display: flex;
   flex-wrap: wrap;
   justify-content: flex-end;
   gap: 0.3rem;
   max-width: calc(100% - 1.4rem);
}

.badge {
     padding: 0.18rem 0.5rem;
     font-family: var(--font-mono);
     font-size: 0.6rem;
     letter-spacing: var(--track-caps);
     text-transform: uppercase;
     color: var(--ink-2);
     background: var(--surface);
     border: 1px solid var(--edge-strong);
     border-radius: var(--r-pill);
     /* Kein backdrop-filter. Auf jeder Badge eine eigene Ebene, und im
        Detail-Dialog liegen viele ueber dem scrollenden Text. */
     white-space: nowrap;
   }

.badge--main {
   color: var(--accent);
   border-color: var(--accent-line);
   background: var(--accent-tint);
}

.badge--finished {
   color: var(--ok);
   border-color: color-mix(in srgb, var(--ok) 35%, transparent);
   background: color-mix(in srgb, var(--ok) 9%, var(--surface));
}

.badge--beta {
   color: var(--accent);
   border-color: var(--accent-line);
   background: color-mix(in srgb, var(--accent) 7%, var(--surface));
}

.badge--school {
   color: var(--ink-2);
   border-style: dashed;
}

.badge--soon {
   color: var(--warn);
   border-color: color-mix(in srgb, var(--warn) 35%, transparent);
   background: color-mix(in srgb, var(--warn) 9%, var(--surface));
}

.badge--new {
   color: var(--ink-inv);
   background: var(--accent);
   border-color: var(--accent);
   font-weight: 700;
}

/* ---------- Karteninhalt ---------- */
.card-body {
   display: flex;
   flex-direction: column;
   flex: 1;
   padding: 1.15rem 1.25rem 1.25rem;
}

.card-head {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 0.75rem;
   margin-bottom: 0.55rem;
}

.card-title {
   font-family: var(--font-display);
   font-size: 1.2rem;
   line-height: var(--lh-snug);
   letter-spacing: var(--track-tight);
   color: var(--ink);
}

.card-index {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   color: var(--ink-3);
   flex: none;
}

.card-desc {
   font-size: var(--fs-sm);
   line-height: var(--lh-base);
   color: var(--ink-2);
   display: -webkit-box;
   -webkit-line-clamp: 3;
   line-clamp: 3;
   -webkit-box-orient: vertical;
   overflow: hidden;
}

/* ---------- Tags ---------- */
.card-tags {
   display: flex;
   flex-wrap: wrap;
   gap: 0.3rem;
   margin-top: 1rem;
}

.card-tag {
   padding: 0.18rem 0.5rem;
   font-family: var(--font-mono);
   font-size: 0.625rem;
   letter-spacing: var(--track-wide);
   color: var(--ink-3);
   background: var(--surface-2);
   border: 1px solid var(--edge);
   border-radius: var(--r-xs);
}

/* ---------- Kartenfuß ---------- */
.card-foot {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 0.75rem;
   margin-top: auto;
   padding-top: 1rem;
}

.card-dates {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--ink-3);
}

.card-cta {
   display: inline-flex;
   align-items: center;
   gap: 0.35rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   text-transform: uppercase;
   color: var(--ink-3);
   transition: color var(--t-xs) var(--ease-out);
}

.card-cta svg {
   width: 12px;
   height: 12px;
   stroke: currentColor;
   fill: none;
   stroke-width: 2;
   stroke-linecap: round;
   stroke-linejoin: round;
   transition: transform var(--t-sm) var(--ease-out);
}

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

.project-card:hover .card-cta svg {
   transform: translateX(3px);
}

/* ---------- Sprachpunkte ---------- */
.card-langs {
   display: inline-flex;
   gap: 2px;
}

.card-lang {
   width: 14px;
   height: 3px;
   background: var(--edge-strong);
   border-radius: 2px;
}

.card-lang.is-primary {
   background: var(--accent);
}

/* =========================================================================
   Leerzustand
   ========================================================================= */

.empty-state {
   display: grid;
   place-items: center;
   gap: 1rem;
   padding: clamp(3rem, 2rem + 5vw, 5rem) 1.5rem;
   text-align: center;
   border: 1px dashed var(--edge);
   border-radius: var(--r-md);
   background: var(--surface);
}

.empty-state__glyph {
   display: grid;
   place-items: center;
   width: 54px;
   height: 54px;
   color: var(--ink-3);
   background: var(--surface-2);
   border: 1px solid var(--edge);
   border-radius: 50%;
}

.empty-state__glyph svg {
   width: 22px;
   height: 22px;
   stroke: currentColor;
   fill: none;
   stroke-width: 1.5;
   stroke-linecap: round;
   stroke-linejoin: round;
}

.empty-state__title {
   font-family: var(--font-display);
   font-size: 1.25rem;
}

.empty-state__text {
   font-size: var(--fs-sm);
   color: var(--ink-2);
   max-width: 34ch;
}

/* =========================================================================
   Projekt-Detailfenster
   ========================================================================= */

  /* Deutlich groesser als das Filterfenster: das Detail enthaelt Text,
     Tags und den Versionsverlauf und braucht dafuer Platz */
  .modal--detail {
     width: min(100%, 1120px);
     max-height: min(90svh, 920px);
  }

.detail__hero {
   position: relative;
   display: grid;
   grid-template-columns: auto minmax(0, 1fr);
   gap: 1.25rem;
   align-items: center;
   padding: 1.5rem 1.5rem 1.25rem;
   border-bottom: 1px solid var(--edge);
}

.detail__glyph {
   display: grid;
   place-items: center;
   width: 66px;
   height: 66px;
   font-size: 2rem;
   background: var(--bg-sunken);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
}

.detail__badges {
   display: flex;
   flex-wrap: wrap;
   gap: 0.3rem;
   margin-bottom: 0.5rem;
}

.detail__title {
   font-size: var(--fs-h2);
   margin-bottom: 0.4rem;
}

.detail__meta {
   display: flex;
   flex-wrap: wrap;
   gap: 0.35rem 1rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--ink-3);
}

.detail__meta strong {
   font-weight: 400;
   color: var(--ink-2);
}

.detail__section {
   padding-top: 1.5rem;
}

.detail__section + .detail__section {
   margin-top: 1.5rem;
   padding-top: 1.5rem;
   border-top: 1px solid var(--edge-faint);
}

.detail__section-title {
   display: flex;
   align-items: center;
   gap: 0.6rem;
   margin-bottom: 0.85rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--ink-3);
}

.detail__section-title::before {
   content: "";
   width: 1.25rem;
   height: 1px;
   background: var(--accent);
}

.detail__text {
   font-size: var(--fs-sm);
   line-height: var(--lh-loose);
   color: var(--ink-2);
}

.detail__tags {
   display: flex;
   flex-wrap: wrap;
   gap: 0.35rem;
}

.detail__tag {
   padding: 0.28rem 0.65rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--ink-2);
   background: var(--surface-2);
   border: 1px solid var(--edge);
   border-radius: var(--r-xs);
}

.detail__tags--spaced {
   margin-top: 0.9rem;
}

.detail__hint {
   margin-top: 0.7rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   color: var(--ink-3);
}

/* ---------- Eckdaten des Servers im Detailfenster ---------- */
.detail__factgrid {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
   gap: 0.75rem 1.25rem;
}

.detail__fact {
   display: grid;
   gap: 0.2rem;
   min-width: 0;
}

.detail__fact-key {
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--ink-3);
}

.detail__fact-val {
   font-size: var(--fs-sm);
   color: var(--ink);
   overflow-wrap: anywhere;
}

/* ---------- Technische Eckdaten ---------- */
.detail__code {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
   gap: 1px;
   background: var(--edge);
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
   overflow: hidden;
}

.detail__code-cell {
   padding: 0.85rem 0.9rem;
   background: var(--surface);
}

.detail__code-val {
   font-family: var(--font-display);
   font-size: 1.15rem;
   line-height: 1.1;
   color: var(--accent);
   font-variant-numeric: tabular-nums;
}

.detail__code-key {
   margin-top: 0.35rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-wide);
   text-transform: uppercase;
   color: var(--ink-3);
}

/* ---------- Modulgruppen ---------- */
.detail__sublabel {
   margin: 1.1rem 0 0.5rem;
   font-family: var(--font-mono);
   font-size: var(--fs-micro);
   letter-spacing: var(--track-caps);
   text-transform: uppercase;
   color: var(--accent);
}

.detail__subgroup + .detail__subgroup {
   margin-top: 0.2rem;
}

/* ---------- Plugin-Knopf auf der Serverkarte ---------- */
.server-card__actions .btn-accent__name {
   opacity: 0.75;
}

.server-card__actions .btn-accent:hover .btn-accent__name {
   opacity: 1;
}

@media (max-width: 640px) {
   .server-card__actions .btn-accent {
      width: 100%;
      justify-content: center;
   }
}

/* ---------- Versionsverlauf ---------- */
.history {
   border: 1px solid var(--edge);
   border-radius: var(--r-sm);
   overflow: hidden;
}

  .history__row {
     display: grid;
     grid-template-columns: 3.75rem 4.5rem minmax(0, 1fr);
     gap: 0.75rem;
     align-items: baseline;
     padding: 0.8rem 0.95rem;
     font-size: var(--fs-xs);

     /* Versionsverlaeufe koennen lang sein. Zeilen ausserhalb des
        Sichtfensters werden nicht gezeichnet, das Scrollen bleibt damit
        ruhig. "auto" merkt sich die echte Hoehe, sobald sie einmal da war. */
     content-visibility: auto;
     contain-intrinsic-size: auto 64px;
  }

.history__row + .history__row {
   border-top: 1px solid var(--edge-faint);
}

.history__row:nth-child(odd) {
   background: var(--surface-2);
}

.history__v {
   font-family: var(--font-mono);
   color: var(--accent);
   letter-spacing: var(--track-wide);
}

.history__date {
   font-family: var(--font-mono);
   color: var(--ink-3);
   letter-spacing: var(--track-wide);
}

.history__text {
   color: var(--ink-2);
   line-height: 1.5;
}

/* Mehrere Punkte unter einer Version */
.history__list {
   display: grid;
   gap: 0.15rem;
   margin: 0.35rem 0 0;
   padding: 0;
   list-style: none;
}

.history__list li {
   position: relative;
   padding-left: 0.95rem;
}

.history__list li::before {
   content: "";
   position: absolute;
   top: 0.6em;
   left: 0.15rem;
   width: 3px;
   height: 3px;
   border-radius: 50%;
   background: var(--accent);
}

@media (max-width: 560px) {
   .history__row {
      grid-template-columns: 1fr;
      gap: 0.2rem;
   }
}

/* ---------- Aktionen im Detailfenster ---------- */
.modal__body--detail {
   display: flex;
   flex-direction: column;
   padding: 0;
   overflow: hidden;
}

.detail__scroll {
   flex: 1 1 auto;
   min-height: 0;
   padding: 1.25rem;
   overflow-y: auto;
   overscroll-behavior: contain;
}

.detail__foot {
   display: flex;
   flex: none;
   flex-wrap: wrap;
   align-items: center;
   gap: 0.45rem 0.6rem;
   padding: 0.9rem 1.25rem;
   border-top: 1px solid var(--edge);
   background: var(--surface-2);
}

.detail__foot .btn {
   flex: 0 0 auto;
   min-height: 36px;
   padding: 0.42rem 0.85rem;
   font-size: var(--fs-xs);
   letter-spacing: var(--track-wide);
}

/* Sekundäre Aktion bleibt leise und sitzt am rechten Rand */
.detail__foot [data-close-detail] {
   margin-left: auto;
   color: var(--ink-3);
   background: transparent;
   border-color: transparent;
}

.detail__foot [data-close-detail]:hover,
.detail__foot [data-close-detail]:focus-visible {
   color: var(--ink-inv);
   border-color: var(--ink);
}

@media (max-width: 420px) {
   .detail__foot [data-close-detail] {
      margin-left: 0;
   }
}

/* =========================================================================
   Responsive Feinschliff
   ========================================================================= */

@media (max-width: 640px) {
   .projects-grid {
      gap: var(--sp-4);
   }

   .card-visual {
      height: 96px;
   }

   .card-visual__glyph {
      font-size: 2.2rem;
   }

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

   .card-title {
      font-size: 1.1rem;
   }

   .card-tags {
      margin-top: 0.85rem;
   }

   /* Datum und Aufruf standen sonst nebeneinander und brachen beide
      in zwei halbe Zeilen um. */
   .card-foot {
      flex-direction: column;
      align-items: flex-start;
      gap: 0.55rem;
      padding-top: 0.85rem;
   }

   .card-dates,
   .card-cta {
      white-space: nowrap;
   }

   .detail__hero {
      grid-template-columns: 1fr;
      gap: 1rem;
      text-align: left;
   }

   .detail__glyph {
      width: 54px;
      height: 54px;
      font-size: 1.6rem;
   }

   .detail__body {
      padding: 1.15rem;
   }

   .modal__body {
      padding: 1.1rem;
   }
}

/* Ohne Zeiger gibt es kein Wegbewegen: Der Hover-Zustand bliebe an der
   Karte haengen. Dafuer bekommen die Karten eine Druckrueckmeldung. */
@media (hover: none), (pointer: coarse) {
   .project-card:hover {
      transform: none;
      box-shadow: none;
   }

   .project-card:active {
      transform: scale(0.985);
      border-color: var(--accent-line);
      background: var(--surface-hover);
   }

   .project-card:hover .card-visual__glyph {
      transform: none;
      filter: grayscale(0.25);
   }

   .project-card:hover .card-visual__corner {
      opacity: 0;
   }
}