Files
SilverMetal/windows/welcome/src/SilverOS.Welcome.App/wwwroot/css/app.css
sysadmin 30a168e853
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Successful in 4m46s
perf(welcome): cut first-boot cold-start + add loading affordance
The Welcome wizard showed nothing until WebView2 cold-started and Blazor
booted, so the whole startup cost presented as a blank window long enough
that operators thought first boot had failed.

- Native MAUI splash overlay (renders in the first frame, no WebView2/JIT
  dependency) + a visually identical in-page splash inside #app, so the
  native -> webview -> Blazor handoff reads as one continuous loading
  screen. Fades out on first successful WV2 NavigationCompleted.
- PublishReadyToRun=true (publish-only) to remove first-run JIT on the
  one-shot cold-disk path. R2R header verified present after publish.
- Fixed-version WebView2 runtime baked offline next to the exe (build.ps1
  stages it, app points WEBVIEW2_BROWSER_EXECUTABLE_FOLDER at it). Removes
  the Evergreen registry probe and the LTSC "no WebView2 at all" risk flagged
  in welcome-app-spec.md; air-gap friendly. Absent => falls back to Evergreen.
- De-flash launch: drop the `cmd /c` wrapper and add -WindowStyle Hidden in
  autounattend FirstLogonCommands (kills the console flash + one process).

Verified: Release build clean, win-x64 self-contained publish succeeds with
R2R confirmed, 38/38 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 09:06:02 +01:00

967 lines
29 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===================================================================
SilverOS Welcome — Mercury Aesthetic
Theme: precision dark, slate-steel dominant, electric-ice accent.
Typography: "DM Mono" for headings/UI text, fallback to Courier
variant stacks for the "terminal-built" feel of a security OS.
Atmosphere: layered radial + linear gradients, subtle scanline texture.
Motion: staggered CSS entrance on .step reveal — one orchestrated
arrival, not scattered micro-animations.
=================================================================== */
/* ── Web Fonts (bundled locally — offline-safe, no CDN dependency) ──── */
/* DM Mono — latin subset only; weights 300/400/500 + italic 300 */
@font-face {
font-family: 'DM Mono';
font-style: italic;
font-weight: 300;
font-display: swap;
src: url('../fonts/dm-mono-italic-300.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: 'DM Mono';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('../fonts/dm-mono-300.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: 'DM Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/dm-mono-400.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: 'DM Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/dm-mono-500.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;
}
/* Inter — latin subset only; weights 300/400/500 */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('../fonts/inter-300.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: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/inter-400.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: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/inter-500.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;
}
/* ── Design Tokens ──────────────────────────────────────────────────── */
:root {
/* Palette */
--clr-void: #0b0f14; /* near-black background */
--clr-surface: #111720; /* card / panel surface */
--clr-surface-2: #19202e; /* raised surface */
--clr-border: #1e2a3a; /* subtle border */
--clr-border-hi: #2a3d56; /* highlighted border */
--clr-accent: #00d4ff; /* electric ice — primary CTA, progress */
--clr-accent-dim: #0099bb; /* dimmer accent for hover states */
--clr-accent-glow: rgba(0,212,255,0.18);
--clr-success: #00e5a0; /* completion green */
--clr-warn: #f5a623; /* error / warning amber */
--clr-text-hi: #e8edf5; /* high-emphasis text */
--clr-text-mid: #8fa4bc; /* mid-emphasis: labels, subtitles */
--clr-text-lo: #4a5f78; /* low-emphasis: placeholders, hints */
/* Typography */
--font-mono: 'DM Mono', 'Fira Code', 'Consolas', monospace;
--font-ui: 'Inter', system-ui, -apple-system, sans-serif;
/* Geometry */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Motion */
--ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
--ease-in: cubic-bezier(0.64, 0, 0.78, 0);
}
/* ── Reset & Base ───────────────────────────────────────────────────── */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
background-color: var(--clr-void);
color: var(--clr-text-hi);
font-family: var(--font-ui);
font-size: 15px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
/* Atmospheric background — layered radial glow on deep void */
body {
background:
radial-gradient(ellipse 80% 60% at 50% -10%, rgba(0,100,180,0.18) 0%, transparent 70%),
radial-gradient(ellipse 50% 40% at 90% 100%, rgba(0,180,140,0.08) 0%, transparent 60%),
var(--clr-void);
min-height: 100vh;
}
body::after {
content: "SILVERMETAL";
position: fixed;
right: 26px;
bottom: 16px;
font-family: var(--font-ui);
font-weight: 700;
font-size: 13px;
letter-spacing: 4px;
color: rgba(255, 255, 255, 0.16);
pointer-events: none;
}
/* ── Blazor error overlay (keep readable) ──────────────────────────── */
#blazor-error-ui {
background: #1a0a0a;
border-top: 2px solid var(--clr-warn);
color: var(--clr-warn);
bottom: 0;
box-shadow: 0 -2px 12px rgba(245,166,35,0.15);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
font-family: var(--font-mono);
font-size: 0.8rem;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
color: var(--clr-text-mid);
}
.blazor-error-boundary {
background: #1a0a0a;
border: 1px solid var(--clr-warn);
padding: 1rem 1rem 1rem 3.7rem;
color: var(--clr-warn);
border-radius: var(--radius-md);
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
/* ── Validation ─────────────────────────────────────────────────────── */
h1:focus { outline: none; }
.valid.modified:not([type=checkbox]) {
outline: 1px solid var(--clr-success);
}
.invalid {
outline: 1px solid var(--clr-warn);
}
.validation-message {
color: var(--clr-warn);
font-size: 0.75rem;
font-family: var(--font-mono);
}
/* ══════════════════════════════════════════════════════════════════════
WIZARD CHROME
══════════════════════════════════════════════════════════════════════ */
.wizard {
display: grid;
grid-template-rows: auto 1fr auto;
position: fixed;
inset: 5vh 7vw; /* float as a card inset from the wall edges */
max-width: 1040px;
margin: 0 auto; /* center horizontally within the inset box */
background: rgba(16, 22, 31, 0.55);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border: 1px solid rgba(255, 255, 255, 0.14);
border-radius: 18px;
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.12);
overflow: hidden; /* clip header/footer corners to the radius */
animation: sm-rise 0.5s var(--ease-out) both;
}
@keyframes sm-rise {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: none; }
}
/* ── Step indicator ─────────────────────────────────────────────────── */
.wizard-header {
padding: 1.5rem 2rem 1rem;
border-bottom: 1px solid var(--clr-border);
background: linear-gradient(to bottom, rgba(17,23,32,0.95), transparent);
position: sticky;
top: 0;
z-index: 10;
}
.wizard-steps-indicator {
display: flex;
gap: 0;
align-items: center;
}
.wizard-step-dot {
font-family: var(--font-mono);
font-size: 0.7rem;
font-weight: 400;
letter-spacing: 0.05em;
color: var(--clr-text-lo);
padding: 0.25rem 0.75rem;
border-radius: var(--radius-sm);
transition: color 0.25s var(--ease-out), background 0.25s var(--ease-out);
position: relative;
white-space: nowrap;
}
.wizard-step-dot + .wizard-step-dot::before {
content: '';
position: absolute;
left: -2px;
color: var(--clr-border-hi);
font-size: 0.9rem;
top: 50%;
transform: translateY(-50%);
}
.wizard-step-dot.done {
color: var(--clr-success);
}
.wizard-step-dot.done::after {
content: ' ✓';
font-size: 0.6rem;
}
.wizard-step-dot.active {
color: var(--clr-accent);
background: var(--clr-accent-glow);
font-weight: 500;
}
/* ── Wizard body ────────────────────────────────────────────────────── */
.wizard-body {
padding: 2.5rem 2rem;
overflow-y: auto;
}
/* ── Wizard footer ──────────────────────────────────────────────────── */
.wizard-footer {
padding: 1.25rem 2rem;
border-top: 1px solid var(--clr-border);
display: flex;
justify-content: space-between;
align-items: center;
background: linear-gradient(to top, rgba(11,15,20,0.98), transparent);
gap: 1rem;
}
/* ── Boot splash (pre-Blazor; mirrors the native MAUI splash) ───────── */
.sm-boot {
position: fixed;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1.4rem;
background: var(--clr-void);
z-index: 2000;
}
.sm-boot-title {
font-family: var(--font-mono);
font-size: 2.6rem;
font-weight: 300;
letter-spacing: -0.02em;
color: var(--clr-text-hi);
}
.sm-boot-kicker {
font-family: var(--font-mono);
font-size: 0.8rem;
letter-spacing: 0.55em;
text-indent: 0.55em; /* balance the trailing letter-spacing */
color: var(--clr-accent);
}
.sm-boot-spinner {
width: 34px;
height: 34px;
border: 3px solid var(--clr-border-hi);
border-top-color: var(--clr-accent);
border-radius: 50%;
animation: sm-spin 0.8s linear infinite;
}
@keyframes sm-spin {
to { transform: rotate(360deg); }
}
.sm-boot-text {
font-family: var(--font-ui);
font-size: 0.9rem;
color: var(--clr-text-mid);
}
@media (prefers-reduced-motion: reduce) {
.sm-boot-spinner { animation: none; }
}
/* ── Loading / error states ─────────────────────────────────────────── */
.loading {
font-family: var(--font-mono);
color: var(--clr-text-lo);
font-size: 0.85rem;
animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.4; }
50% { opacity: 1; }
}
.error-panel {
border: 1px solid var(--clr-warn);
border-radius: var(--radius-md);
padding: 1.5rem;
background: rgba(245,166,35,0.06);
}
.error {
color: var(--clr-warn);
font-weight: 500;
margin-bottom: 0.4rem;
}
.error-detail {
color: var(--clr-text-lo);
font-family: var(--font-mono);
font-size: 0.75rem;
margin-bottom: 1rem;
}
/* ══════════════════════════════════════════════════════════════════════
BUTTONS
══════════════════════════════════════════════════════════════════════ */
.btn-primary,
.btn-secondary {
font-family: var(--font-mono);
font-size: 0.8rem;
font-weight: 500;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 0.6rem 1.4rem;
border-radius: var(--radius-sm);
border: none;
cursor: pointer;
transition:
background 0.2s var(--ease-out),
box-shadow 0.2s var(--ease-out),
opacity 0.15s;
outline-offset: 3px;
}
.btn-primary {
background: var(--clr-accent);
color: var(--clr-void);
}
.btn-primary:hover:not(:disabled) {
background: #1ae0ff;
box-shadow: 0 0 18px var(--clr-accent-glow);
}
.btn-primary:focus-visible {
outline: 2px solid var(--clr-accent);
}
.btn-primary:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.btn-secondary {
background: transparent;
color: var(--clr-text-mid);
border: 1px solid var(--clr-border-hi);
}
.btn-secondary:hover:not(:disabled) {
background: var(--clr-surface-2);
color: var(--clr-text-hi);
border-color: var(--clr-accent-dim);
}
.btn-secondary:focus-visible {
outline: 2px solid var(--clr-accent);
}
.btn-secondary:disabled {
opacity: 0.3;
cursor: not-allowed;
}
/* ══════════════════════════════════════════════════════════════════════
STEP ENTRANCE ANIMATION (orchestrated stagger)
══════════════════════════════════════════════════════════════════════ */
.step {
animation: step-enter 0.45s var(--ease-out) both;
}
@keyframes step-enter {
from {
opacity: 0;
transform: translateY(16px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* heading and subtitle arrive slightly after the container */
.step h1 {
font-family: var(--font-mono);
font-size: 1.6rem;
font-weight: 300;
letter-spacing: -0.02em;
color: var(--clr-text-hi);
line-height: 1.2;
margin-bottom: 0.4rem;
animation: step-enter 0.5s 0.05s var(--ease-out) both;
}
.step-subtitle {
font-family: var(--font-ui);
font-size: 0.9rem;
color: var(--clr-text-mid);
margin-bottom: 2rem;
animation: step-enter 0.5s 0.1s var(--ease-out) both;
}
/* ══════════════════════════════════════════════════════════════════════
WELCOME STEP
══════════════════════════════════════════════════════════════════════ */
.welcome-step {
display: flex;
flex-direction: column;
justify-content: center;
min-height: 50vh;
}
.welcome-hero {
animation: step-enter 0.55s 0.05s var(--ease-out) both;
}
.welcome-hero h1 {
font-size: 2.2rem;
font-weight: 300;
color: var(--clr-text-hi);
margin-bottom: 0.5rem;
/* Accent underline */
background: linear-gradient(90deg, var(--clr-accent) 0%, var(--clr-success) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: step-enter 0.55s 0.1s var(--ease-out) both;
}
.tagline {
font-size: 1.05rem;
color: var(--clr-text-mid);
font-style: italic;
margin-bottom: 1.5rem;
animation: step-enter 0.5s 0.15s var(--ease-out) both;
}
.time-estimate {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--clr-text-lo);
margin-top: 1.5rem;
animation: step-enter 0.5s 0.2s var(--ease-out) both;
}
/* ══════════════════════════════════════════════════════════════════════
FLAVOUR STEP
══════════════════════════════════════════════════════════════════════ */
.flavour-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 1rem;
margin-top: 0.5rem;
}
.flavour-card {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: var(--radius-lg);
padding: 1.5rem;
cursor: pointer;
transition:
border-color 0.2s var(--ease-out),
box-shadow 0.2s var(--ease-out),
background 0.2s var(--ease-out);
position: relative;
overflow: hidden;
}
.flavour-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, var(--clr-accent-glow) 0%, transparent 60%);
opacity: 0;
transition: opacity 0.25s var(--ease-out);
border-radius: inherit;
}
.flavour-card:hover {
border-color: var(--clr-border-hi);
box-shadow: 0 0 0 1px var(--clr-border-hi), 0 4px 20px rgba(0,0,0,0.4);
}
.flavour-card:hover::before {
opacity: 0.5;
}
.flavour-card.selected {
border-color: var(--clr-accent);
box-shadow: 0 0 0 1px var(--clr-accent), 0 0 28px var(--clr-accent-glow);
background: var(--clr-surface-2);
}
.flavour-card.selected::before {
opacity: 1;
}
.flavour-card h3 {
font-family: var(--font-mono);
font-size: 0.95rem;
font-weight: 500;
color: var(--clr-text-hi);
letter-spacing: 0.03em;
margin-bottom: 0.5rem;
}
.flavour-card.selected h3 {
color: var(--clr-accent);
}
.flavour-card p {
font-size: 0.82rem;
color: var(--clr-text-mid);
line-height: 1.5;
}
/* Staggered card entrance */
.flavour-card:nth-child(1) { animation: step-enter 0.45s 0.1s var(--ease-out) both; }
.flavour-card:nth-child(2) { animation: step-enter 0.45s 0.18s var(--ease-out) both; }
.flavour-card:nth-child(3) { animation: step-enter 0.45s 0.26s var(--ease-out) both; }
.flavour-card:nth-child(4) { animation: step-enter 0.45s 0.34s var(--ease-out) both; }
/* ══════════════════════════════════════════════════════════════════════
ACCOUNT STEP / FORM FIELDS
══════════════════════════════════════════════════════════════════════ */
.field-group {
margin-bottom: 1.4rem;
animation: step-enter 0.4s var(--ease-out) both;
}
.field-group:nth-child(2) { animation-delay: 0.06s; }
.field-group:nth-child(3) { animation-delay: 0.12s; }
.field-group:nth-child(4) { animation-delay: 0.18s; }
.field-group label {
display: block;
font-family: var(--font-mono);
font-size: 0.72rem;
font-weight: 500;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--clr-text-mid);
margin-bottom: 0.4rem;
}
.field-group input[type="text"],
.field-group input[type="password"] {
width: 100%;
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: var(--radius-sm);
padding: 0.65rem 0.9rem;
font-family: var(--font-mono);
font-size: 0.9rem;
color: var(--clr-text-hi);
outline: none;
transition:
border-color 0.2s var(--ease-out),
box-shadow 0.2s var(--ease-out);
}
.field-group input:focus {
border-color: var(--clr-accent);
box-shadow: 0 0 0 3px var(--clr-accent-glow);
}
.field-group input::placeholder {
color: var(--clr-text-lo);
font-style: italic;
}
.field-error {
display: block;
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--clr-warn);
margin-top: 0.3rem;
}
/* ══════════════════════════════════════════════════════════════════════
PREFS STEP
══════════════════════════════════════════════════════════════════════ */
.prefs-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.pref-item {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: var(--radius-md);
padding: 0.9rem 1.1rem;
animation: step-enter 0.4s var(--ease-out) both;
}
.pref-item:nth-child(2) { animation-delay: 0.07s; }
.pref-item:nth-child(3) { animation-delay: 0.14s; }
.pref-item label {
display: flex;
align-items: center;
gap: 0.75rem;
cursor: pointer;
font-size: 0.88rem;
color: var(--clr-text-hi);
}
.pref-item input[type="checkbox"] {
width: 1rem;
height: 1rem;
accent-color: var(--clr-accent);
cursor: pointer;
flex-shrink: 0;
}
.pref-item small {
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--clr-text-lo);
}
/* ══════════════════════════════════════════════════════════════════════
APPLY STEP
══════════════════════════════════════════════════════════════════════ */
.apply-step {
display: flex;
flex-direction: column;
gap: 2rem;
min-height: 40vh;
}
.apply-header h1 {
font-size: 1.7rem;
}
/* Ready state */
.apply-ready {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: var(--radius-lg);
padding: 2rem;
text-align: center;
animation: step-enter 0.4s 0.1s var(--ease-out) both;
}
.apply-ready-text {
color: var(--clr-text-mid);
font-size: 0.9rem;
margin-bottom: 1.5rem;
}
.btn-start {
min-width: 140px;
}
/* Progress state */
.apply-progress-container {
animation: step-enter 0.35s var(--ease-out) both;
}
.apply-stage-label {
font-family: var(--font-mono);
font-size: 0.8rem;
color: var(--clr-accent);
letter-spacing: 0.04em;
margin-bottom: 0.6rem;
}
.apply-progress-track {
width: 100%;
height: 6px;
background: var(--clr-surface-2);
border-radius: 99px;
overflow: hidden;
border: 1px solid var(--clr-border);
}
.apply-progress-bar {
height: 100%;
background: linear-gradient(90deg, var(--clr-accent) 0%, var(--clr-success) 100%);
border-radius: 99px;
transition: width 0.4s var(--ease-out);
box-shadow: 0 0 10px var(--clr-accent-glow);
}
.apply-percent-label {
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--clr-text-lo);
text-align: right;
margin-top: 0.3rem;
}
/* Complete state */
.apply-complete {
display: flex;
align-items: center;
gap: 0.75rem;
background: rgba(0,229,160,0.08);
border: 1px solid var(--clr-success);
border-radius: var(--radius-md);
padding: 1rem 1.25rem;
animation: step-enter 0.4s var(--ease-out) both;
}
.apply-complete-icon {
font-size: 1.4rem;
color: var(--clr-success);
line-height: 1;
}
.apply-complete p {
color: var(--clr-success);
font-family: var(--font-mono);
font-size: 0.85rem;
}
/* Error state */
.apply-error {
background: rgba(245,166,35,0.07);
border: 1px solid var(--clr-warn);
border-radius: var(--radius-md);
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.6rem;
animation: step-enter 0.35s var(--ease-out) both;
}
.apply-error-icon {
font-size: 1.5rem;
color: var(--clr-warn);
line-height: 1;
}
.apply-error-title {
font-family: var(--font-mono);
font-size: 0.85rem;
font-weight: 500;
color: var(--clr-warn);
}
.apply-error-detail {
font-family: var(--font-mono);
font-size: 0.78rem;
color: var(--clr-text-mid);
margin-bottom: 0.5rem;
word-break: break-word;
}
.btn-retry {
align-self: flex-start;
}
/* ══════════════════════════════════════════════════════════════════════
DONE STEP
══════════════════════════════════════════════════════════════════════ */
.done-step {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
justify-content: center;
min-height: 50vh;
gap: 1.5rem;
}
.done-step h1 {
background: linear-gradient(90deg, var(--clr-success) 0%, var(--clr-accent) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 2.2rem;
}
.done-step p {
color: var(--clr-text-mid);
max-width: 440px;
font-size: 0.92rem;
}
.btn-restart {
min-width: 160px;
background: linear-gradient(90deg, var(--clr-accent), var(--clr-success));
color: var(--clr-void);
font-weight: 500;
}
.btn-restart:hover:not(:disabled) {
box-shadow: 0 0 28px rgba(0,229,160,0.25), 0 0 18px var(--clr-accent-glow);
opacity: 0.92;
}
/* ── Accessibility / focus safety ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
.step,
.step h1,
.step-subtitle,
.welcome-hero,
.welcome-hero h1,
.tagline,
.time-estimate,
.flavour-card,
.field-group,
.pref-item,
.apply-progress-container,
.apply-ready,
.apply-complete,
.apply-error {
animation: none !important;
transition: none !important;
}
}
/* ── MAUI layout safety ─────────────────────────────────────────────── */
.status-bar-safe-area {
display: none;
}
@supports (-webkit-touch-callout: none) {
.status-bar-safe-area {
display: flex;
position: sticky;
top: 0;
height: env(safe-area-inset-top);
background-color: var(--clr-void);
width: 100%;
z-index: 1;
}
.flex-column, .navbar-brand {
padding-left: env(safe-area-inset-left);
}
}
/* ── BitLocker recovery key (Done step) ─────────────────────────────── */
.done-step { display: flex; flex-direction: column; align-items: flex-start; }
.recovery-panel {
margin: 0.75rem 0;
padding: 0.85rem 1rem;
border: 1px solid var(--clr-accent);
border-radius: var(--radius-sm, 8px);
background: var(--clr-accent-glow, rgba(0,212,255,0.10));
width: 100%;
}
.recovery-panel h3 { margin: 0 0 0.35rem; color: var(--clr-accent); font-family: var(--font-mono); font-size: 1rem; }
.recovery-lead { margin: 0 0 0.5rem; color: var(--clr-text-lo); font-size: 0.85rem; }
.recovery-row { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
.recovery-qr {
width: 132px; height: 132px;
background: #fff; padding: 6px; border-radius: var(--radius-sm, 8px);
flex: 0 0 auto;
}
.recovery-key {
flex: 1 1 14rem;
font-family: var(--font-mono);
font-size: 1.0rem;
letter-spacing: 0.04em;
color: var(--clr-text-hi);
background: rgba(0,0,0,0.30);
padding: 0.6rem 0.85rem;
border-radius: var(--radius-sm, 8px);
white-space: pre-wrap;
word-break: break-all;
user-select: all;
margin: 0;
}
.recovery-note { color: var(--clr-text-lo); margin: 0.5rem 0 0; }
.done-step .btn-restart { margin-top: 1rem; align-self: flex-start; }