/* ============================================================
   ihint.css — EIN Infozeichen, Sprechblase beim Ueberfahren
   ------------------------------------------------------------
   Vorgabe, 07.09.2026: „Bei allen Infozeichen soll nichts danebenstehen, nur
   das Zeichen; wenn man mit der Maus rueber geht, ohne zu klicken, wird
   eingeblendet, was da gerade steht." Der GANZE Hinweisblock liegt hinter dem
   Zeichen, auf allen Seiten dasselbe Muster.

   Warum nicht NUR :hover: Telefone koennen nicht hovern und Tastaturnutzer
   auch nicht. Deshalb drei Wege in EINE Sprechblase:
     1. Maus      — :hover, ohne Klick
     2. Tastatur  — Fokus auf dem Knopf
     3. Tippen    — ein <button> bekommt auf iOS/Android beim Tippen den Fokus;
                    zusaetzlich schaltet ein Klick den Zustand fest um.

   ZWEI FASSUNGEN, und das ist Absicht:
   a) OHNE JavaScript (html ohne .ihint-js): die Blase steht als
      position:absolute im Zeichen und wird von :hover / :focus-within
      eingeblendet. Reines CSS — Maus, Tastatur und Fingertipp funktionieren
      also auch dann, der Text ist nie unerreichbar.
   b) MIT JavaScript (html.ihint-js): der Block js/page-*.js haengt die Blase
      beim Oeffnen an <body> um und setzt sie auf position:fixed.
      Grund, gemessen und nicht vermutet: .cal-consent (Kontakt) und
      .roi-panel (Rechner) tragen overflow:hidden, die Blase wurde dort oben
      abgeschnitten; ausserdem legen die Reveal-Animationen (will-change,
      opacity) zeitweise eigene Stapelkontexte an, aus denen kein z-index
      herausfuehrt. Am <body> gibt es beides nicht.

   Vorlesbarkeit: die Blase wird NICHT per display/visibility versteckt,
   sondern per opacity + pointer-events. Sie bleibt damit im
   Barrierefreiheits-Baum; der Knopf zeigt mit aria-describedby darauf, der
   Screenreader liest den Hinweis also beim Fokussieren mit — unabhaengig
   davon, ob er gerade sichtbar ist. aria-expanded/aria-controls fuehrt das
   Skript nach.

   Zielgroesse (WCAG 2.5.8): der Knopf misst echte 48x48 px. Ein negativer
   Rand von -12px holt das Layoutmass auf 24x24 px zurueck, damit die Zeile
   nicht auseinandergezogen wird.
   ============================================================ */

.ihint{
  position:relative;
  z-index:5;
  display:inline-flex;
  align-items:center;
  vertical-align:middle;
}
/* Solange offen, steigt das ganze Zeichen im eigenen Stapelkontext nach oben.
   (Greift fuer die JavaScript-lose Fassung; mit Skript haengt die Blase
   ohnehin am <body>.) */
.ihint:hover, .ihint:focus-within, .ihint.ihint-auf{ z-index:95; }

/* ---------- Der Knopf: nur das Zeichen, sonst nichts ---------- */
.ihint-btn{
  -webkit-appearance:none; appearance:none;
  background:none; border:0; padding:0;
  inline-size:48px; block-size:48px;
  margin:-12px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:50%;
  cursor:pointer; -webkit-tap-highlight-color:transparent;
  color:var(--ice, #7DD3FC);
  transition:color .3s var(--ease-out, ease), background-color .3s var(--ease-out, ease);
}
.ihint-btn > .ik{ inline-size:22px; block-size:22px; flex:none; }
.ihint-btn:hover{ color:var(--text, #F2F5FC); background:rgba(125,211,252,.12); }
.ihint-btn[aria-expanded="true"]{ color:var(--text, #F2F5FC); background:rgba(125,211,252,.14); }
.ihint-btn:focus-visible{ outline:2px solid var(--blue, #4F7DF9); outline-offset:0; }

/* ---------- Die Sprechblase ---------- */
.ihint-bubble{
  position:absolute;
  z-index:90;
  left:50%;
  bottom:100%;
  margin-bottom:12px;
  transform:translateX(-50%) translateY(5px);
  box-sizing:border-box;
  inline-size:max-content;
  max-inline-size:min(300px, calc(100vw - 32px));
  padding:12px 14px;
  border:1px solid var(--line-strong, rgba(242,245,252,.14));
  border-radius:12px;
  background:#111A2E;                 /* deckend, nicht durchscheinend */
  box-shadow:0 12px 34px -10px rgba(5,8,15,.85), 0 0 0 1px rgba(5,8,15,.55);
  text-align:left;
  font-family:var(--font-b, sans-serif);
  font-size:.8rem; line-height:1.55; font-weight:400; letter-spacing:0;
  color:var(--text, #F2F5FC);         /* #F2F5FC auf #111A2E */
  white-space:normal;
  opacity:0; pointer-events:none;
  transition:opacity .2s var(--ease-out, ease), transform .2s var(--ease-out, ease);
}
/* Jede Zeile des urspruenglichen Blocks steht untereinander. */
.ihint-bubble > span{ display:block; }
.ihint-bubble > span + span{ margin-top:8px; }
.ihint-bubble a{
  color:var(--ice, #7DD3FC);
  text-decoration:underline; text-underline-offset:3px;
}
.ihint-bubble a:hover{ color:var(--text, #F2F5FC); }
.ihint-bubble a:focus-visible{ outline:2px solid var(--blue, #4F7DF9); outline-offset:2px; border-radius:3px; }

/* Zeiger auf das Zeichen. --ihint-pfeil setzt das Skript, sonst mittig. */
.ihint-bubble::before{
  content:""; position:absolute; top:100%; left:var(--ihint-pfeil, 50%);
  margin-left:-6px; width:0; height:0;
  border:6px solid transparent; border-top-color:#111A2E;
}
/* Bruecke ueber den Spalt: sonst faellt der Zeiger auf dem Weg vom Zeichen in
   die Blase kurz ins Nichts und die Blase klappt zu. */
.ihint-bubble::after{
  content:""; position:absolute; left:0; right:0; top:100%; height:14px;
}
.ihint-bubble[data-ihint-pos="unten"]::before{
  top:auto; bottom:100%; border-top-color:transparent; border-bottom-color:#111A2E;
}
.ihint-bubble[data-ihint-pos="unten"]::after{ top:auto; bottom:100%; }

/* ---------- a) OHNE JavaScript: reines CSS, an Ort und Stelle ---------- */
@media (hover:hover) and (pointer:fine){
  html:not(.ihint-js) .ihint:hover > .ihint-bubble{
    opacity:1; pointer-events:auto; transform:translateX(-50%) translateY(0);
  }
}
html:not(.ihint-js) .ihint:focus-within > .ihint-bubble{
  opacity:1; pointer-events:auto; transform:translateX(-50%) translateY(0);
}

/* Sonderfall fuer die JavaScript-lose Fassung: steht das Zeichen in einem
   Kasten mit overflow:hidden, wird die Blase dort oben abgeschnitten
   (gemessen an .cal-consent auf /kontakt: die ersten zwei Zeilen fehlten).
   Ohne Skript laesst diese eine Stelle den Text deshalb einfach offen stehen —
   lesbar schlaegt huebsch, und das ist hier zulaessig. Mit Skript haengt
   die Blase am <body> und das Problem gibt es nicht.
   Ausgeloest ueber data-ihint-fallback="offen" am Zeichen. */
html:not(.ihint-js) .ihint[data-ihint-fallback="offen"]{ display:block; }
html:not(.ihint-js) .ihint[data-ihint-fallback="offen"] > .ihint-bubble{
  position:static; opacity:1; pointer-events:auto; transform:none;
  margin:12px 0 0; inline-size:auto; max-inline-size:34em;
  box-shadow:none;
}
html:not(.ihint-js) .ihint[data-ihint-fallback="offen"] > .ihint-bubble::before,
html:not(.ihint-js) .ihint[data-ihint-fallback="offen"] > .ihint-bubble::after{ display:none; }

/* ---------- b) MIT JavaScript: frei am <body>, ueber allem ---------- */
.ihint-bubble.ihint-frei{
  position:fixed;
  /* bottom:auto und right:auto sind PFLICHT, nicht Kosmetik: die Grundregel
     setzt bottom:100%. Bliebe das stehen, haette der fixierte Kasten top:0 UND
     bottom:100% der Bildhoehe — die Hoehe rechnet sich dann auf 0, der Text
     liefe unten heraus und die Blase saesse falsch. Genau so gemessen. */
  left:0; top:0; right:auto; bottom:auto; margin:0;
  z-index:2147483000;                 /* ueber Kopfleiste, Balken, Overlay */
  transform:translate(var(--ihint-x, 0px), calc(var(--ihint-y, 0px) + 5px));
}
.ihint-bubble.ihint-frei[data-ihint-pos="unten"]{
  transform:translate(var(--ihint-x, 0px), calc(var(--ihint-y, 0px) - 5px));
}
.ihint-bubble.ihint-frei.ihint-sicht,
.ihint-bubble.ihint-frei.ihint-sicht[data-ihint-pos="unten"]{
  opacity:1; pointer-events:auto;
  transform:translate(var(--ihint-x, 0px), var(--ihint-y, 0px));
}

@media (prefers-reduced-motion:reduce){
  .ihint-bubble{ transition:opacity .01ms linear; }
}

/* ---------- Die Zeile, in der das Zeichen allein steht ---------- */
.ihint-zeile{
  margin-top:16px;
  display:flex; align-items:center; gap:9px;
  min-height:24px;
}
.ihint-zeile.ihint-mitte{ justify-content:center; }
