/* FiveRP — loading screen. Design system: /opt/fivem/server-data/CLAUDE.md This page owns the whole screen (no game behind it), so unlike the in-game panels it is allowed an opaque background and real shadows. */ @font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 300 800; font-display: block; src: url('fonts/unbounded-latin.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 300 800; font-display: block; src: url('fonts/unbounded-latin-ext.woff2') format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; } @font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 300 800; font-display: block; src: url('fonts/unbounded-cyrillic.woff2') format('woff2'); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } :root { --bg: #f5f5f7; --bg-deep: #e8e8ed; --surface: rgba(255, 255, 255, 0.72); --surface-solid: #ffffff; --fg: #1d1d1f; --fg-secondary: #6e6e73; --fg-tertiary: #a1a1a6; --accent: #0071e3; --accent-strong: #0077ed; --accent-soft: rgba(0, 113, 227, 0.08); --line: rgba(0, 0, 0, 0.06); --line-strong: rgba(0, 0, 0, 0.10); --radius-lg: 1.5rem; --radius-md: 1rem; --radius-sm: 0.7rem; --sans: 'Unbounded', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, 'Liberation Mono', 'DejaVu Sans Mono', monospace; --ease: cubic-bezier(0.25, 0.8, 0.25, 1); color-scheme: light; } * { box-sizing: border-box; margin: 0; padding: 0; } html, body { width: 100%; height: 100%; overflow: hidden; background: var(--bg); color: var(--fg); font-family: var(--sans); letter-spacing: -0.005em; -webkit-font-smoothing: antialiased; cursor: none; } /* ---------------------------------------------------------------------- sky */ /* Four wide, heavily blurred washes drifting on long loops. Kept pale so the page still reads as white — colour is a hint, not a gradient poster. */ .sky { position: fixed; inset: -20%; z-index: 0; filter: blur(90px); } .blob { position: absolute; display: block; border-radius: 50%; will-change: transform; } .blob-a { width: 46vw; height: 46vw; top: 4%; left: 8%; background: radial-gradient(circle, rgba(0,113,227,0.30), rgba(0,113,227,0) 70%); animation: driftA 34s var(--ease) infinite alternate; } .blob-b { width: 40vw; height: 40vw; top: 32%; left: 52%; background: radial-gradient(circle, rgba(90,200,250,0.32), rgba(90,200,250,0) 70%); animation: driftB 41s var(--ease) infinite alternate; } .blob-c { width: 34vw; height: 34vw; top: 56%; left: 18%; background: radial-gradient(circle, rgba(201,182,255,0.28), rgba(201,182,255,0) 70%); animation: driftC 47s var(--ease) infinite alternate; } .blob-d { width: 30vw; height: 30vw; top: 6%; left: 68%; background: radial-gradient(circle, rgba(255,214,165,0.30), rgba(255,214,165,0) 70%); animation: driftD 38s var(--ease) infinite alternate; } @keyframes driftA { to { transform: translate3d(9vw, 7vh, 0) scale(1.14); } } @keyframes driftB { to { transform: translate3d(-11vw, -6vh, 0) scale(1.08); } } @keyframes driftC { to { transform: translate3d(7vw, -9vh, 0) scale(1.18); } } @keyframes driftD { to { transform: translate3d(-8vw, 8vh, 0) scale(1.10); } } /* A milky sheet over the colour: this is what turns four blobs into frosted white rather than a lava lamp. */ .veil { position: fixed; inset: 0; z-index: 1; background: radial-gradient(110% 85% at 50% 42%, rgba(255,255,255,0.40) 0%, rgba(255,255,255,0.72) 46%, rgba(255,255,255,0.88) 100%), linear-gradient(180deg, rgba(245,245,247,0.20), rgba(232,232,237,0.42)); } /* -------------------------------------------------------------------- stage */ .stage { position: relative; z-index: 2; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0 32px 96px; text-align: center; } /* App-icon style badge: the one saturated object on an otherwise white page. */ .mark { width: 84px; height: 84px; display: grid; place-items: center; border-radius: 24px; background-image: linear-gradient(160deg, #35a0ff 0%, var(--accent) 52%, #0059b8 100%); margin-bottom: 26px; } .mark-glyph { font-size: 27px; font-weight: 800; letter-spacing: -0.045em; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.22); } .eyebrow { font-size: 10px; font-weight: 600; letter-spacing: 0.20em; text-transform: uppercase; color: var(--fg-tertiary); margin-bottom: 14px; } .wordmark { font-size: clamp(52px, 6.4vw, 84px); font-weight: 800; letter-spacing: -0.045em; line-height: 1; color: var(--fg); margin-bottom: 16px; } .tagline { font-size: 14px; font-weight: 400; color: var(--fg-secondary); margin-bottom: 46px; } /* -------------------------------------------------------------------- meter */ /* Left-aligned: the phase and detail lines change constantly, and centred text that reflows on every update reads as jitter. */ .meter { width: min(560px, 84vw); text-align: left; } .meter-top { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; } .phase { font-size: 11px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--fg-secondary); } .pct { font-size: 34px; font-weight: 700; letter-spacing: -0.045em; color: var(--fg); font-variant-numeric: tabular-nums; } .pct i { font-style: normal; font-size: 15px; font-weight: 600; color: var(--fg-tertiary); margin-left: 3px; } .track { position: relative; height: 8px; border-radius: 999px; /* Inset rather than flat grey: on a near-white page a 7%-black bar reads as a smudge, a hairline-bordered groove reads as a control. */ background: rgba(0, 0, 0, 0.055); overflow: hidden; } .fill { position: absolute; inset: 0 auto 0 0; width: 0%; border-radius: 999px; background-image: linear-gradient(90deg, #5ac8fa, var(--accent)); transition: width 520ms var(--ease); } /* Travelling highlight so a stalled bar still looks alive. */ .fill::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.55) 50%, rgba(255,255,255,0) 100%); transform: translateX(-100%); animation: sweep 1.9s var(--ease) infinite; } @keyframes sweep { to { transform: translateX(100%); } } .detail { margin-top: 14px; height: 14px; font-family: var(--mono); font-size: 11px; letter-spacing: 0; color: var(--fg-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .3s ease; } /* --------------------------------------------------------------------- dock */ .dock { position: fixed; z-index: 2; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 26px 32px; } .tip { display: flex; align-items: center; gap: 12px; max-width: 62vw; padding: 12px 18px 12px 12px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line-strong); } .tip-label { flex: none; padding: 5px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; } .tip-body { font-size: 12.5px; font-weight: 400; line-height: 1.5; color: var(--fg-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: opacity .45s ease, transform .45s var(--ease); } .tip-body.is-swapping { opacity: 0; transform: translateY(-6px); } .badge { flex: none; display: flex; align-items: center; gap: 9px; padding: 11px 18px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line-strong); font-family: var(--mono); font-size: 11.5px; color: var(--fg-secondary); letter-spacing: 0; } .badge i { font-style: normal; color: var(--fg-tertiary); } .badge .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success, #34c759); animation: pulse 2.4s ease-in-out infinite; } @keyframes pulse { 50% { opacity: .45; } } /* ------------------------------------------------------------------- motion */ .fade-up { animation: fadeUp .7s cubic-bezier(.22,1,.36,1) both; } .delay-1 { animation-delay: .07s; } .delay-2 { animation-delay: .14s; } .delay-3 { animation-delay: .21s; } .delay-4 { animation-delay: .30s; } @keyframes fadeUp { from { opacity: 0; transform: translateY(18px) scale(.995); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; } }