/* ============================================================
   TourneyFlow – Grundschicht der Gestaltung
   ============================================================

   Diese Datei ist in allen drei Auftritten IDENTISCH und wird beim
   Hochladen einfach in jeden assets/-Ordner kopiert. Sie enthaelt nur, was
   ueberall dasselbe bedeutet: Tiefenstufen, Bewegungskurven, Glas, Rauschen,
   Fokusring und die Mindestgroesse von Bedienelementen.

   Was sie NICHT enthaelt: Regeln auf Klassennamen einzelner Seiten. Die drei
   Auftritte haben je ein eigenes Vokabular –

     tourneyflow.de   .hero  .topbar  .foot  .product  .rg-*
     handball-app     .hero-section  .navbar  .site-foot  .feature-card
     handball-cloud   eigenes Geruest

   – und jeder bekommt dafuer eine eigene, duenne Uebersetzungsdatei
   (tf-design.css / tf-app.css / tf-cloud.css), die NACH dieser hier geladen
   wird. Der urspruengliche Plan, eine einzige Datei ueberall unveraendert
   einzuhaengen, ging genau daran vorbei: Sie haette in zwei von drei
   Auftritten auf Klassen gezielt, die es dort nicht gibt.
   ============================================================ */

/* @property macht Farbwinkel animierbar. Ohne die Typangabe springt ein
   Verlauf von 0 auf 360, statt zu drehen. */
@property --tf-winkel {
  syntax: '<angle>'; inherits: false; initial-value: 0deg;
}

:root{
  /* Tiefenstufen. Statt eines Schattens je Karte eine Leiter, damit
     "weiter vorn" im ganzen Auftritt dasselbe bedeutet. */
  --tf-t1:0 1px 2px rgba(9,14,30,.05), 0 2px 6px rgba(9,14,30,.06);
  --tf-t2:0 2px 4px rgba(9,14,30,.05), 0 8px 20px rgba(9,14,30,.07),
          0 16px 40px rgba(9,14,30,.05);
  --tf-t3:0 4px 8px rgba(9,14,30,.06), 0 16px 36px rgba(9,14,30,.09),
          0 40px 80px rgba(9,14,30,.10);
  --tf-t4:0 8px 16px rgba(9,14,30,.08), 0 30px 60px rgba(9,14,30,.12),
          0 70px 140px rgba(9,14,30,.14);

  /* Lichtkante: die schmale helle Linie an der Oberkante einer Flaeche.
     Sie tut mehr fuer den Eindruck von Material als jeder Schatten. */
  --tf-kante:inset 0 1px 0 rgba(255,255,255,.92);
  --tf-kante-dunkel:inset 0 1px 0 rgba(255,255,255,.10);

  --tf-glas:rgba(255,255,255,.72);
  --tf-glas-dunkel:rgba(255,255,255,.055);

  /* Bewegungskurven. Das lange Ausschwingen laesst Bewegung teuer wirken;
     ein linearer Verlauf wirkt billig, egal wie aufwendig der Rest ist. */
  --tf-weich:cubic-bezier(.22,.61,.36,1);
  --tf-sanft:cubic-bezier(.16,1,.3,1);

  /* Rauschen gegen Streifenbildung. Grosse, weiche Verlaeufe zeigen auf
     8-Bit-Bildschirmen sonst sichtbare Baender. Erzeugt im Browser, kein
     Bild, keine Anfrage. */
  --tf-rauschen:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");

  /* Der dunkle Grund der Kopfbereiche – auf allen drei Auftritten derselbe,
     damit sie als ein Haus wirken. */
  --tf-dunkel:#0a0f1e;
}

/* ------------------------------------------------------------
   Bedienbarkeit: gilt ueberall, unabhaengig vom Klassennamen
   ------------------------------------------------------------ */

/* 44 x 44 fuer Bedienelemente (WCAG 2.5.5). Auf allen drei Auftritten war
   die Regel vorher unvollstaendig – mal traf sie nur .btn, mal nur einen
   einzigen Selektor in der Kopfzeile. */
.btn,.btn-primary,.btn-ghost,.btn-outline-primary,.btn-lg,.btn-sm,
button,input:not([type=hidden]),select,textarea{min-height:44px}

/* Kontakt- und Telefonlinks stehen fast immer allein auf einer Zeile und
   sind das Ziel des ganzen Abschnitts – keine Links im Fliesstext. */
a[href^="mailto:"],a[href^="tel:"]{
  display:inline-flex;align-items:center;min-height:44px;
}

/* Bootstraps Schliessen-Knopf ist von Haus aus 26 Pixel breit. Er sitzt in
   Dialogen und Seitenleisten – also genau dort, wo man ihn im Zweifel schnell
   trifft muessen soll. */
.btn-close{min-width:44px;min-height:44px;background-position:center}

/* Knoepfe, die nur ein Symbol tragen, werden schmal: der Erneuern-Knopf der
   Sicherheitsabfrage mass 40 Pixel Breite. min-height allein genuegt nicht,
   die Flaeche muss in BEIDE Richtungen reichen. */
.btn-sm{min-width:44px}

/* Das Einwilligungsbanner ist auf allen drei Auftritten dasselbe Bauteil
   (vendor/css/consent.css) und wird von JEDEM Besucher als Erstes gesehen.
   Gemessen: die Links darin 16 Pixel hoch, der Text auf 116 Zeichen je
   Zeile. Beides hier gerichtet, ohne die Fremddatei anzufassen – die wird
   beim naechsten Update ueberschrieben. */
.tf-consent-links a,
.tf-consent-inner a{display:inline-flex;align-items:center;min-height:44px}
.tf-consent-inner p{max-width:62ch}

/* Sichtbarer Fokus, auch auf dunklem Grund. Ein Umriss in der Markenfarbe
   geht dort fast unter; Weiss mit dunklem Saum steht auf jedem Untergrund. */
:focus-visible{outline:2.5px solid currentColor;outline-offset:3px;border-radius:6px}
.tf-dunkel :focus-visible,
[data-tf-dunkel] :focus-visible{
  outline:3px solid #fff;outline-offset:3px;
  box-shadow:0 0 0 6px rgba(10,15,30,.65);border-radius:8px;
}

/* Lange deutsche Zusammensetzungen und URLs sprengen sonst die Spalte. */
h1,h2,h3,h4{overflow-wrap:break-word;hyphens:auto;text-wrap:balance}
p,li,dd,dt,td,th,label,figcaption{overflow-wrap:break-word}

/* ------------------------------------------------------------
   Bausteine, die jeder Auftritt benutzen kann
   ------------------------------------------------------------ */

/* Dunkler Kopfbereich aus vier Ebenen: Grundton, wandernder Farbschleier,
   Raster mit weicher Maske, Rauschen. Einzeln unauffaellig, zusammen sieht
   es nach Material aus.

   Die Deckkraft des Schleiers ist nachgerechnet, nicht nach Gefuehl
   gewaehlt: Mit .55/.45/.34 fiel heller Fliesstext dort, wo sich alle drei
   Lichter ueberlagern, auf 3,2:1 – unter die Grenze von 4,5:1. */
.tf-dunkel{
  position:relative;isolation:isolate;overflow:clip;
  background:var(--tf-dunkel);color:#e7ecf7;
}
.tf-dunkel::before{
  content:'';position:absolute;inset:-30% -10%;z-index:-2;
  background:
    radial-gradient(38% 46% at 22% 28%, rgba(99,102,241,.34), transparent 68%),
    radial-gradient(34% 40% at 78% 22%, rgba(124,58,237,.28), transparent 70%),
    radial-gradient(46% 52% at 62% 82%, rgba(37,99,235,.22), transparent 72%);
  filter:blur(14px);
  animation:tf-schleier 34s var(--tf-weich) infinite alternate;
}
@keyframes tf-schleier{
  0%  {transform:translate3d(0,0,0) scale(1)}
  50% {transform:translate3d(-2.5%,1.5%,0) scale(1.06)}
  100%{transform:translate3d(2%,-1%,0) scale(1.02)}
}
.tf-dunkel::after{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px),
    var(--tf-rauschen);
  background-size:64px 64px, 64px 64px, 140px 140px;
  -webkit-mask-image:radial-gradient(78% 68% at 50% 34%, #000 25%, transparent 82%);
  mask-image:radial-gradient(78% 68% at 50% 34%, #000 25%, transparent 82%);
  opacity:.9;
}
.tf-dunkel>*{position:relative;z-index:1}

/* Glasplakette ueber der Ueberschrift. */
.tf-plakette{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.42rem .9rem;border-radius:999px;
  background:var(--tf-glas-dunkel);
  border:1px solid rgba(255,255,255,.13);
  box-shadow:var(--tf-kante-dunkel);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  color:#c9d2ea;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
}

/* Karte mit Tiefe und Lichtkante. */
.tf-karte-flaeche{
  background:linear-gradient(180deg,#fff 0%,#fcfdff 100%);
  box-shadow:var(--tf-t2), var(--tf-kante);
  transition:transform .5s var(--tf-sanft), box-shadow .5s var(--tf-sanft);
}
@media(hover:hover){
  .tf-karte-flaeche:hover{transform:translateY(-6px);box-shadow:var(--tf-t4), var(--tf-kante)}
}
.tf-karte-flaeche:focus-within{transform:translateY(-6px);box-shadow:var(--tf-t4), var(--tf-kante)}

/* Tabellen bekommen ihren EIGENEN Schiebebereich, damit nicht die ganze
   Seite nach rechts zieht – mit Schatten am Rand, damit man sieht, dass
   noch etwas kommt. */
.tf-tabelle{
  display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;
  background:
    linear-gradient(90deg,#fff 30%, rgba(255,255,255,0)),
    linear-gradient(90deg, rgba(255,255,255,0), #fff 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(16,24,40,.14), transparent),
    radial-gradient(farthest-side at 100% 50%, rgba(16,24,40,.14), transparent) 100% 0;
  background-repeat:no-repeat;
  background-size:36px 100%, 36px 100%, 14px 100%, 14px 100%;
  background-attachment:local, local, scroll, scroll;
}

/* ------------------------------------------------------------
   Erscheinen beim Scrollen – ohne JavaScript
   ------------------------------------------------------------
   Ueber scroll-driven animations. Wo der Browser das nicht kennt, passiert
   schlicht nichts und alles steht sofort da; deshalb stehen die Startwerte
   NICHT im Grundzustand. */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    .tf-auftauchen{
      animation:tf-auftauchen linear both;
      animation-timeline:view();
      animation-range:entry 8% cover 26%;
    }
    @keyframes tf-auftauchen{
      from{opacity:0;transform:translateY(26px) scale(.985)}
      to  {opacity:1;transform:none}
    }
  }
}

/* ------------------------------------------------------------
   Bewegung reduzieren
   ------------------------------------------------------------
   Keine Geschmacksfrage: Fuer Menschen mit vestibulaerer Stoerung loesen
   wandernde Flaechen Schwindel aus. Alles Bewegte kommt zum Stehen – und
   zwar im ENDzustand, nicht im Anfangszustand. */
@media (prefers-reduced-motion: reduce){
  .tf-dunkel::before{animation:none !important}
  .tf-auftauchen{opacity:1 !important;transform:none !important;animation:none !important}
  .tf-karte-flaeche,.tf-karte-flaeche:hover{transition:none;transform:none}
}
