/* Kein backdrop-filter: bricht nach FiveM-Updates zu einem schwarzen Kasten auf. */ :root { --accent: #38bdf8; --accent-dim: rgba(56, 189, 248, 0.15); --warn: #fbbf24; --danger: #f87171; --text: #e2e8f0; --muted: #94a3b8; --panel: rgba(9, 18, 28, 0.72); --dial-face: #0b1622; --ring: 327; /* 2 * PI * 52, Umfang des Luft-Rings */ } * { margin: 0; padding: 0; box-sizing: border-box; } body { overflow: hidden; background: transparent; font-family: 'Segoe UI', 'Roboto', system-ui, sans-serif; user-select: none; } /* Dreier-Konsole: Finimeter, Luft, Tiefenmesser nebeneinander, Lampe darunter. Grid statt Flex, damit die drei Instrumente auf einer Mittelachse sitzen und die Lampen-Leiste ohne Ausgleichs-Margins in Zeile 2 haengt. */ #hud { position: absolute; left: 50%; bottom: 7vh; /* Skaliert mit der Bildschirmhöhe, sonst wäre das in festen Pixeln entworfene HUD auf 1440p und 4K winzig. --hud-scale setzt script.js. transform-origin unten mittig, damit das Panel beim Skalieren zentriert bleibt und der Abstand zum unteren Rand gleich wirkt. */ transform: translateX(-50%) scale(var(--hud-scale, 1)); transform-origin: bottom center; display: grid; grid-template-columns: auto auto auto; grid-template-rows: auto auto; align-items: center; justify-items: center; column-gap: 20px; row-gap: 6px; padding: 14px 20px; border-radius: 16px; background: var(--panel); border: 1px solid rgba(148, 163, 184, 0.18); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45); color: var(--text); transition: opacity 220ms ease, transform 220ms ease; } #hud.hidden { opacity: 0; transform: translateX(-50%) scale(var(--hud-scale, 1)) translateY(14px); pointer-events: none; } .caption { font-size: 9px; font-weight: 600; letter-spacing: 1.4px; color: var(--muted); text-transform: uppercase; } /* --- Zeigerinstrumente --- */ .dial-face { width: 96px; height: 96px; } /* Werte stehen unter den Uhren, nicht darin: auf 96 px kollidiert eine Zahl in der Skala mit Strichen, Zeiger und rotem Bereich. Zusammen mit der Lampe ergeben sie eine durchgehende zweite Zeile. */ .readout { display: flex; flex-direction: column; align-items: center; gap: 2px; } .dial-face svg { width: 100%; height: 100%; } .face { fill: var(--dial-face); stroke: rgba(148, 163, 184, 0.25); stroke-width: 1.5; } /* Skalenzahlen gibt es bewusst nicht: bei dieser Groesse liest die niemand. Der Zeiger zeigt die Tendenz, die Zahl in der Mitte den genauen Wert. */ .ticks line { stroke: #cbd5e1; stroke-opacity: 0.4; stroke-width: 1; } .ticks line.major { stroke-opacity: 0.85; stroke-width: 1.6; } .zone { fill: none; stroke: var(--danger); stroke-width: 3.5; stroke-opacity: 0.9; } .needle line { stroke: var(--text); stroke-width: 2.6; stroke-linecap: round; transition: stroke 260ms ease; } .needle circle { fill: var(--text); transition: fill 260ms ease; } /* Kein transform-origin hier: das rotate(winkel 50 50) im transform-Attribut bringt den Drehpunkt schon mit. Beides zusammen verschiebt den Zeiger aus der Uhr heraus - CSS rechnet die Origin nochmal obendrauf. */ .needle { transition: transform 260ms ease-out; } .value { display: flex; align-items: baseline; gap: 3px; font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; transition: color 260ms ease; } .unit { font-size: 11px; font-weight: 500; color: var(--muted); } /* Zeiger und Wert faerben sich, sobald der rote Bereich erreicht ist. Die Klassen sitzen am HUD, weil Uhr und Wert in getrennten Grid-Zellen liegen. */ #hud.pressure-alert #pressure-needle line { stroke: var(--danger); } #hud.pressure-alert #pressure-needle circle { fill: var(--danger); } #hud.pressure-alert #pressure-readout .value { color: var(--danger); } #hud.depth-alert #depth-needle line { stroke: var(--danger); } #hud.depth-alert #depth-needle circle { fill: var(--danger); } #hud.depth-alert #depth-readout .value { color: var(--danger); } #hud.depth-deep #depth-needle line { stroke: var(--warn); } #hud.depth-deep #depth-needle circle { fill: var(--warn); } #hud.depth-deep #depth-readout .value { color: var(--warn); } /* --- Luft-Ring --- */ /* Oben ausgerichtet: die 2px gleichen 96 gegen 92 Durchmesser aus, damit alle drei Instrumente auf einer Achse liegen. */ .gauge { position: relative; width: 92px; height: 92px; align-self: start; margin-top: 2px; } .gauge svg { width: 100%; height: 100%; transform: rotate(-90deg); } .gauge circle { fill: none; stroke-width: 8; stroke-linecap: round; } .gauge-track { stroke: rgba(148, 163, 184, 0.16); } .gauge-fill { stroke: var(--accent); stroke-dasharray: var(--ring); stroke-dashoffset: 0; transition: stroke-dashoffset 260ms linear, stroke 260ms ease; } .gauge-inner { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; } #air-value { font-size: 21px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: 0.5px; line-height: 1; } /* --- Lampe --- */ .lamp { display: flex; align-items: center; gap: 6px; padding: 5px 9px; border-radius: 8px; background: rgba(148, 163, 184, 0.1); font-size: 10px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: var(--muted); transition: background 200ms ease, color 200ms ease; } .lamp svg { width: 13px; height: 13px; fill: currentColor; } .lamp.hidden { display: none; } .lamp.on { background: var(--accent-dim); color: var(--accent); } /* --- Warnzustaende der Restluft --- */ #hud.warn .gauge-fill { stroke: var(--warn); } #hud.warn #air-value { color: var(--warn); } #hud.danger .gauge-fill { stroke: var(--danger); } #hud.danger #air-value { color: var(--danger); } #hud.danger .gauge { animation: pulse 1s ease-in-out infinite; } /* Tiefengrenze des Atemgases ueberschritten - Tiefenrausch laeuft. */ #hud.overlimit #depth-face { animation: pulse 1s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }