
/* Oben und unten BÜNDIG (User 2026-08-18: «oben und unten keine margin
   bitte», später «rechteck ecke soll ecke von profilfoto berühren»): die
   Sektion legt kein Polster mehr um den Stapel. Die Luft über der ersten und
   unter der letzten Zeile füllt bereits das Akzent-Polster von
   `.practice-title` (padding-top/-bottom, siehe unten und practice.js
   padRow) — ein zusätzlicher Randabzug ist darum NICHT nötig und zog den
   Stapel früher über die Sektionsgrenze hinaus. */
.practice{ padding-block: 0; }

/* Die Liste ist der RECHTE BLOCK: von der Kante des Porträtstreifens bis an
   den rechten Fensterrand. Die beiden Ränder setzt practice.js (gemessen) —
   im CSS liesse sich weder die Streifenkante noch die Fensterkante ausdrücken,
   beide hängen am Raster bzw. am Fenster. Unter dem Porträt bleibt links
   bewusst Leerraum. */
.practice-list{
  grid-column: 1 / -1;
}

.practice-row{
  position: relative;
  isolation: isolate;
  display: block;
  /* KEIN Abstand: die Zeilen stossen aneinander, damit das Band von Wort zu
     Wort durchläuft. Luft macht die Zeilenhöhe des Wortes, nicht ein Rand. */
  padding: 0;
  color: inherit;
  text-decoration: none;
}

/* --- Das Band ------------------------------------------------------------
   Lage kommt aus practice.js (gemessen): --band-left = Wortanfang,
   --band-right = negativ, damit es bis an den Fensterrand reicht.
   Aufgezogen wird mit clip-path, NICHT mit scaleX — das würde das Bild
   darin in die Breite ziehen. */
.practice-band{
  position: absolute;
  z-index: 0;
  /* Das Rechteck ist die GANZE Zeile — und die Zeile ist über --ink-top /
     --ink-bottom genau so hoch wie die Schrift samt Ring auf dem Å und
     Punkten auf Ä/Ö (practice.js, padRow). Zwei Folgen: die Buchstaben
     liegen IM Rechteck, und zwei Rechtecke übereinander stossen bündig
     aneinander — jedes andere Mass liesse eine Lücke oder Überlappung. */
  top: 0;
  bottom: 0;
  left: var(--band-left, 0);
  right: var(--band-right, 0);
  overflow: hidden;
  background: var(--ink);
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.62s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}
.practice-row.is-on .practice-band{ clip-path: inset(0 0 0 0); }

/* Angeschnitten — das Band ist flach und breit, das Projekt füllt es.
   Das Bild wird dabei etwas dunkler und kontrastreicher gefahren: die
   Schrift darüber ist INVERTIERT (difference), und genau bei mittleren
   Grautönen läge die Umkehrung sonst wieder beim Grundton — das Wort
   verschwände für ein paar Bilder im Video. So bleibt es bei jeder
   Abspielung klar erkennbar (User 2026-08-18). */
.practice-band img,
.practice-band video{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.72) contrast(1.14) saturate(1.05);
}

/* --- Das Wort ------------------------------------------------------------ */
.practice-title{
  position: relative;
  z-index: 1;
  margin: 0;
  /* Polster für die Oberlängen der skandinavischen Zeichen (practice.js
     misst es, in em — skaliert also mit der Schriftgrösse mit). */
  padding-top: var(--ink-top, 0);
  padding-bottom: var(--ink-bottom, 0);
  font-family: var(--display-font);
  font-weight: var(--title-weight);   /* siehe styles/base.css, Rolle TITEL */
  /* --fit ist die GEMESSENE Grösse, bei der das Wort den Block genau füllt
     (practice.js, initBlock). Der clamp() ist nur das Netz, falls JS nicht
     läuft. */
  font-size: var(--fit, clamp(2.6rem, 11.5vw, 9rem));
  line-height: 0.94;
  letter-spacing: -0.04em;
  text-transform: uppercase;
}

/* Das Wort ist ein eigenes Element, weil practice.js seine BREITE misst —
   die Überschrift läuft über die ganze Zeile, das Wort nicht. */
.practice-word{
  display: inline-block;
  /* Die Laufweite ist NEGATIV (-0.04em) — sie wird auch hinter dem letzten
     Buchstaben abgezogen, das Kästchen ist also schmaler als die Schrift.
     Ohne diesen Ausgleich stünde die letzte Letter über den Blockrand hinaus
     und würde am Fensterrand abgeschnitten (gemessen bei 1600px: 13px). */
  padding-right: 0.04em;
  /* IMMER invertiert (User 2026-08-19: «füllfarbe der schriften invertieren
     und mit dem hintergrund reagieren») — weiss + `difference` heisst über
     hellen Stellen dunkel und über dunklen hell. Vorher galt das nur bei
     Hover/aktiv (der Ruhezustand war flaches --ink); jetzt reagiert das Wort
     durchgehend auf das, was hinter ihm liegt: in Ruhe das (transparente)
     Band gegen den Sektionsgrund, sobald das Band ein Projekt zeigt gegen
     dessen Bild oder Video — auf jedem Untergrund lesbar, ohne Umschalten.
     `isolation: isolate` an .practice-row (siehe oben) grenzt die Mischung
     auf die Zeile selbst ein. */
  color: #fff;
  mix-blend-mode: difference;
}

/* --- Anzahl + Stichworte ------------------------------------------------
   Sie stehen LINKS NEBEN dem Rechteck, nicht darin (User 2026-08-18: «die
   bezeichnungen bei sound visual und code sollen links neben den rechteck
   anzeigen und nicht im rechteck») — also in dem Feld, das unter dem Porträt
   ohnehin leer bleibt. `right: 100% + Luft` heisst: rechtsbündig an der linken
   Kante der Zeile, und die ist zugleich die linke Kante des Bandes.

   Sie stehen ausserhalb des Textflusses. Läge die Zeile sie mit, wäre sie
   höher als das Wort und das Band nicht mehr mittig zur Schrift; ausserdem
   entstünden Lücken zwischen den Wörtern. --band-shift zieht sie auf dieselbe
   Mitte wie das Band.

   Sichtbar sind sie IMMER — sie sind die kürzeste Antwort darauf, was hinter
   der Rubrik steckt. Vorher lagen sie im aufklappenden Teil und waren im
   Ruhezustand 0px hoch; wer nicht zufällig mit der Maus darüberfuhr (und auf
   dem Handy: niemand fährt), sah sie nie. */
.practice-meta{
  position: absolute;
  z-index: 1;
  /* auf halber Zeilenhöhe — das Band ist die ganze Zeile */
  top: 50%;
  right: calc(100% + clamp(12px, 1.6vw, 28px));
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  margin: 0;
  width: max-content;
  /* --meta-max misst practice.js: das freie Feld links, ohne Seitenrand */
  max-width: var(--meta-max, 24vw);
  text-align: right;
  color: var(--dim);
  transition: color 0.3s ease;
  pointer-events: none;
}
.practice-row:hover .practice-meta,
.practice-row:focus-visible .practice-meta,
.practice-row.is-on .practice-meta{ color: var(--ink); }

.practice-count{
  font-size: var(--t-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.practice-keys{
  margin: 0;
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Schmal: links ist kein Platz mehr für eine zweite Spalte — dann liegen sie
   wieder IM Band, rechts, und erscheinen mit ihm (invertiert wie das Wort). */
@media (max-width: 900px){
  .practice-meta{
    right: calc(var(--band-right, 0px) + clamp(12px, 3vw, 28px));
    align-items: flex-end;
    max-width: 46vw;
    opacity: 0;
    transition: opacity 0.35s ease;
  }
  .practice-row:hover .practice-meta,
  .practice-row:focus-visible .practice-meta,
  .practice-row.is-on .practice-meta{
    opacity: 1;
    color: #fff;
    mix-blend-mode: difference;
  }
}

/* Ohne Zeiger (Touch): kein Band. Wort, Anzahl und Stichworte stehen dort
   ohnehin dauerhaft da — mehr gibt es an dieser Stelle nicht mehr zu sehen. */
@media (hover: none){
  .practice-band{ display: none; }
  /* zurück in den Fluss unter das Wort: ohne Band und ohne Zeiger gibt es
     weder ein Rechteck noch ein «daneben». */
  .practice-meta{
    position: static;
    transform: none;
    align-items: flex-start;
    text-align: left;
    /* width: max-content bleibt sonst von der Grundregel stehen — ungekürzt
       lief die Stichwortzeile («Web Development · Unity / C# · …») über den
       Fensterrand hinaus, weil max-content nie umbricht, egal wie schmal
       der verfügbare Platz ist. */
    width: auto;
    max-width: 100%;
    margin: 6px 0 clamp(10px, 2vh, 20px);
    opacity: 1;
    color: var(--dim);
    mix-blend-mode: normal;
  }
}

@media (prefers-reduced-motion: reduce){
  .practice-band{ display: none; }
}
