/* ────────────────────────────────────────────────────────────────────── Setup Wizard — multi-step slide-right Reuses the shared .aurora-bg + .aurora-stars from aurora-background.css so it shares the loading screen's visual identity. The wizard itself is a translucent shell over that background, with a horizontal track of step panels that slides as the user advances. ────────────────────────────────────────────────────────────────────── */ body.setup-wizard-open { overflow: hidden; } .setup-wizard { position: fixed; inset: 0; z-index: 9999; color: var(--text-primary); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; display: flex; align-items: center; justify-content: center; overflow-y: auto; padding: 2rem 1.5rem; opacity: 0; animation: setupFadeIn 0.6s ease forwards; box-sizing: border-box; } .setup-wizard.hiding { animation: setupFadeOut 0.5s ease forwards; } .setup-wizard.setup-launched .setup-card { transform: scale(0.96); opacity: 0.5; filter: blur(2px); transition: all 0.5s ease; } @keyframes setupFadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes setupFadeOut { from { opacity: 1; } to { opacity: 0; } } /* Vertical stack: logo header on top, card below — same shape as `.login-content` in the login overlay so the two surfaces share a visual identity. The aurora-header / aurora-logo / aurora-subtitle classes themselves are inherited from aurora-background.css so the logo treatment is byte-identical to login + loading. */ .setup-content { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 620px; margin: 1rem; } /* Header inherits .aurora-header / .aurora-logo sizing from aurora-background.css so it matches the loading screen byte-for-byte — single source of truth. The only wizard-specific tweak is a slightly tighter bottom margin since a card sits below it. */ .setup-content .aurora-header { margin-bottom: 1.5rem; } /* Card — translucent panel matching .login-card / loading screen style */ .setup-card { width: 100%; background: rgba(var(--text-rgb), 0.06); border: 1px solid rgba(var(--text-rgb), 0.12); border-radius: 14px; padding: 24px 28px 20px; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); animation: setupCardRise 0.4s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both; display: flex; flex-direction: column; gap: 20px; } @keyframes setupCardRise { from { transform: translateY(16px) scale(0.97); opacity: 0; } to { transform: translateY(0) scale(1); opacity: 1; } } /* Progress bar — same look as loading screen's progress section */ .setup-progress { display: flex; flex-direction: column; gap: 8px; } .setup-progress-bar { background: rgba(var(--text-rgb), 0.10); border-radius: 8px; padding: 2px; border: 1px solid rgba(var(--text-rgb), 0.08); height: 12px; box-sizing: border-box; overflow: hidden; } .setup-progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-hover)); border-radius: 6px; width: 0%; transition: width 0.45s cubic-bezier(0.16, 1, 0.3, 1); position: relative; overflow: hidden; } .setup-progress-fill::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(var(--text-rgb),0.3), transparent); animation: setupShimmer 2s infinite; } @keyframes setupShimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } .setup-progress-text { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: rgba(var(--text-rgb), 0.78); font-family: 'SF Mono', Menlo, monospace; letter-spacing: 0.5px; } .setup-progress-text > #sw-progress-step { display: inline-flex; align-items: center; gap: 6px; } .setup-progress-sep { color: rgba(var(--text-rgb), 0.20); margin: 0 2px; } .setup-progress-icon { display: inline-flex; align-items: center; color: var(--accent); } .setup-progress-name { color: var(--text-primary); font-weight: 600; letter-spacing: 0.3px; } /* Step transitions — fade in / fade out. The previous slide-track approach fought browser flex-basis math whenever step content height varied (e.g. step 2 reveals the domain field when Public is toggled). Fade is simpler: only the active step is in the layout, the card naturally heights to its content, and the swap feels like the wizard "settles into the next thought" rather than swinging horizontally. */ .setup-track-wrap { position: relative; width: 100%; } .setup-track { display: block; width: 100%; } .setup-step { display: none; flex-direction: column; gap: 16px; } .setup-step.active { display: flex; animation: stepFadeIn 0.32s cubic-bezier(0.16, 1, 0.3, 1); } @keyframes stepFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } .setup-form { display: flex; flex-direction: column; gap: 18px; } /* Multi-domain editor — list of removable rows + an "Add domain" button. */ .setup-domain-list { display: flex; flex-direction: column; gap: 10px; } .setup-domain-row { display: flex; flex-direction: column; gap: 8px; } /* Empty status pill collapses so blank-domain rows don't claim vertical space */ .setup-domain-row .setup-dns-status:empty { display: none; } .setup-domain-row .setup-input-row { align-items: stretch; } .setup-domain-remove { flex: 0 0 auto; width: 36px; background: rgba(var(--text-rgb), 0.04); border: 1px solid rgba(var(--text-rgb), 0.10); border-radius: 8px; color: rgba(var(--text-rgb), 0.65); font-size: 18px; font-weight: 500; cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease; } .setup-domain-remove:hover { background: rgba(var(--status-danger-rgb), 0.18); border-color: rgba(var(--status-danger-rgb), 0.45); color: var(--status-danger); } .setup-domain-add { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; background: rgba(var(--accent-rgb), 0.10); border: 1px dashed rgba(var(--accent-rgb), 0.40); border-radius: 10px; padding: 8px 14px; color: var(--accent); font-size: 13px; font-weight: 600; cursor: pointer; margin-top: 8px; transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease; } .setup-domain-add:hover { background: rgba(var(--accent-rgb), 0.20); border-color: rgba(var(--accent-rgb), 0.65); border-style: solid; transform: translateY(-1px); } .setup-domain-add span { font-size: 16px; line-height: 1; } .setup-step-note { font-size: 12px; color: rgba(var(--text-rgb), 0.65); margin: 12px 0 0; font-style: italic; } .setup-section-hint { font-size: 12px; color: rgba(var(--text-rgb), 0.62); margin: 0 0 10px; } /* Field styling — matches the login form's compact subtle look: small lowercase labels, translucent inputs with cyan focus glow. */ .setup-field { display: flex; flex-direction: column; gap: 0.35rem; } .setup-field label { font-size: 0.75rem; font-weight: 500; color: var(--text-secondary); letter-spacing: 0.02em; text-transform: none; margin: 0; } .setup-field input[type=text], .setup-field input[type=email], .setup-field select { width: 100%; background: rgba(var(--text-rgb), 0.06); border: 1px solid rgba(var(--text-rgb), 0.12); border-radius: 8px; padding: 0.6rem 0.875rem; color: var(--text-primary); font-size: 0.95rem; font-family: inherit; box-sizing: border-box; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } .setup-field input[type=text]:focus, .setup-field input[type=email]:focus, .setup-field select:focus { outline: none; background: rgba(var(--text-rgb), 0.10); border-color: rgba(var(--accent-rgb), 0.55); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18); } .setup-field input::placeholder { color: var(--text-secondary); } /* Live validation — green border + glow when valid, red when invalid. The error message is held on data-error and surfaced via a tooltip that floats ABOVE the input on focus/hover (like the ? badge does). Uses a bright mint #86efac (134,239,172) so the border reads against the dark wizard backdrop — the theme's #28a745 is too muddy here. */ .setup-field input.is-valid, .setup-field select.is-valid { border-color: #86efac; box-shadow: 0 0 0 3px rgba(134, 239, 172, 0.22); } .setup-field input.is-invalid, .setup-field select.is-invalid { border-color: rgba(var(--status-danger-rgb), 0.85); box-shadow: 0 0 0 3px rgba(var(--status-danger-rgb), 0.22); } /* Mirror the valid/invalid state onto the custom-select button when the native — the browser's native chevron occupies the right edge, so right:14px collides with it. */ .setup-input-row:has(select.is-valid)::after, .setup-input-row:has(select.is-invalid)::after { right: 32px; } .setup-input-row:has(select.is-valid) .setup-input-with-icon, .setup-input-row:has(select.is-invalid) .setup-input-with-icon { padding-right: 3.5rem !important; } /* Error message floating above the input — same visual language as the ? tooltip but anchored to the input row. We read the message from data-error which the JS mirrors from the input onto the row (pseudo elements can only read attrs from their own host element). */ .setup-input-row[data-error]::before { content: attr(data-error); position: absolute; bottom: calc(100% + 8px); left: 14px; background: rgba(var(--bg-rgb), 0.45); color: var(--status-danger); font-size: 0.72rem; font-weight: 500; letter-spacing: 0; padding: 7px 10px; border-radius: 8px; border: 1px solid rgba(var(--status-danger-rgb), 0.45); white-space: nowrap; pointer-events: none; opacity: 0; z-index: 11; transition: opacity 0.18s ease, transform 0.18s ease; transform: translateY(4px); } .setup-input-row[data-error]:hover::before, .setup-input-row[data-error]:focus-within::before { opacity: 1; transform: translateY(0); } /* Input with leading icon — icon sits absolutely positioned over the left padding zone of the input. Reroll button (when present) sits to the right of the input via the row's flex layout. */ .setup-input-row { position: relative; display: flex; gap: 8px; align-items: stretch; } .setup-field-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; color: var(--accent); pointer-events: none; z-index: 1; transition: color 0.2s ease, filter 0.2s ease; } .setup-input-row .setup-input-with-icon:focus ~ .setup-field-icon, .setup-input-row:focus-within .setup-field-icon { color: var(--accent); } .setup-input-with-icon { flex: 1; padding-left: 2.25rem !important; } .setup-field-icon svg { display: block; } .setup-field-icon-emoji { font-size: 16px; line-height: 1; } .setup-input-row:focus-within .setup-field-icon-emoji { } #sw-name.setup-input-with-icon { font-family: 'SF Mono', Menlo, monospace; letter-spacing: 0.3px; color: var(--accent); padding-right: 7.75rem !important; } .setup-input-row:has(#sw-name.is-valid) #sw-name, .setup-input-row:has(#sw-name.is-invalid) #sw-name { padding-right: 7.75rem !important; } .setup-input-row:has(#sw-name)::after { display: none; } /* Tooltip "?" badge after the label. Hover or keyboard-focus reveals a small floating tip with the description text. */ .setup-tooltip { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background: rgba(var(--accent-rgb), 0.15); color: var(--accent); font-size: 0.65rem; font-weight: 700; margin-left: 6px; cursor: help; position: relative; user-select: none; vertical-align: middle; border: 1px solid rgba(var(--accent-rgb), 0.35); transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease; } .setup-tooltip:hover, .setup-tooltip:focus { outline: none; background: rgba(var(--accent-rgb), 0.30); color: var(--text-primary); } .setup-tooltip::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px); background: rgba(var(--bg-rgb), 0.45); color: var(--text-primary); font-size: 0.72rem; font-weight: 400; letter-spacing: 0; text-transform: none; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(var(--accent-rgb), 0.40); width: max-content; max-width: 240px; white-space: normal; text-align: left; line-height: 1.35; pointer-events: none; opacity: 0; transition: opacity 0.15s ease, transform 0.15s ease; z-index: 10; } .setup-tooltip::before { content: ''; position: absolute; bottom: calc(100% + 2px); left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: rgba(var(--accent-rgb), 0.55); pointer-events: none; opacity: 0; transition: opacity 0.15s ease; } .setup-tooltip:hover::after, .setup-tooltip:focus::after { opacity: 1; transform: translateX(-50%) translateY(0); } .setup-tooltip:hover::before, .setup-tooltip:focus::before { opacity: 1; } .setup-name-pulse { animation: setupNamePulse 0.6s ease; } @keyframes setupNamePulse { 0% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.55); } 60% { box-shadow: 0 0 0 12px rgba(var(--accent-rgb), 0); } 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0); } } .setup-manifest { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); height: calc(100% - 12px); z-index: 2; background: rgba(var(--accent-rgb), 0.12); color: var(--accent); border: 1px solid rgba(var(--accent-rgb), 0.32); border-radius: 8px; padding: 0 12px; font-size: 13px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease, box-shadow 0.18s ease, color 0.18s ease; white-space: nowrap; } .setup-manifest .setup-manifest-icon { color: var(--accent); transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), color 0.2s ease, filter 0.2s ease; } .setup-manifest:hover { background: rgba(var(--accent-rgb), 0.22); border-color: rgba(var(--accent-rgb), 0.55); color: var(--text-primary); transform: translateY(calc(-50% - 1px)); } .setup-manifest:hover .setup-manifest-icon { color: var(--accent); } /* Click animation: full-spin icon + cosmic burst halo around the button */ .setup-manifest.manifesting { animation: manifestBurst 0.7s ease; } .setup-manifest.manifesting .setup-manifest-icon { transform: rotate(360deg); } @keyframes manifestBurst { 0% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.75), 0 0 0 0 rgba(var(--accent-rgb), 0.55); } 60% { box-shadow: 0 0 0 14px rgba(var(--accent-rgb), 0), 0 0 0 28px rgba(var(--accent-rgb), 0); } 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0), 0 0 0 0 rgba(var(--accent-rgb), 0); } } /* DNS check status */ .setup-dns-status { font-size: 12px; margin-top: 8px; padding: 6px 10px; border-radius: 6px; font-family: 'SF Mono', Menlo, monospace; min-height: 14px; } .setup-dns-status.checking { background: rgba(var(--text-rgb), 0.05); color: rgba(var(--text-rgb), 0.6); } .setup-dns-status.ok { background: rgba(var(--status-success-rgb), 0.12); color: var(--status-success); border: 1px solid rgba(var(--status-success-rgb), 0.3); } .setup-dns-status.warn { background: rgba(var(--status-warning-rgb), 0.10); color: var(--status-warning); border: 1px solid rgba(var(--status-warning-rgb), 0.3); } /* App selection sections */ .setup-section { border-top: 1px solid rgba(var(--text-rgb), 0.06); padding-top: 14px; } .setup-section:first-child { border-top: none; padding-top: 0; } .setup-section-title { font-size: 12px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: rgba(var(--accent-rgb), 1); margin-bottom: 10px; } .setup-app { display: flex; align-items: center; gap: 14px; padding: 12px 14px; background: rgba(var(--text-rgb), 0.03); border: 1px solid rgba(var(--text-rgb), 0.08); border-radius: 12px; cursor: pointer; margin-bottom: 8px; transition: all 0.15s ease; } .setup-app:hover { background: rgba(var(--text-rgb), 0.06); border-color: rgba(var(--accent-rgb), 0.25); } .setup-app input[type=checkbox] { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; flex-shrink: 0; cursor: pointer; border-radius: 6px; background: rgba(var(--text-rgb), 0.04); border: 1.5px solid rgba(var(--text-rgb), 0.18); box-shadow: inset 0 0 0 1px rgba(var(--text-rgb), 0.02); position: relative; transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, transform 0.12s ease; } .setup-app:hover input[type=checkbox] { border-color: rgba(var(--accent-rgb), 0.55); box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.08); } .setup-app input[type=checkbox]:focus-visible { outline: none; border-color: rgba(var(--accent-rgb), 0.85); box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.20); } .setup-app input[type=checkbox]:checked { background: linear-gradient(135deg, var(--accent), var(--accent)); border-color: rgba(var(--accent-rgb), 0.9); box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.35); } .setup-app input[type=checkbox]:checked::after { content: ''; position: absolute; inset: 0; background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: center; background-size: 14px 14px; animation: setupCheckPop 0.22s cubic-bezier(0.34, 1.56, 0.64, 1); } @keyframes setupCheckPop { 0% { transform: scale(0.4); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } .setup-app:has(input:checked) { background: rgba(var(--accent-rgb), 0.10); border-color: rgba(var(--accent-rgb), 0.45); } .setup-app-icon-wrap { width: 36px; height: 36px; border-radius: 9px; background: rgba(var(--text-rgb), 0.06); border: 1px solid rgba(var(--text-rgb), 0.08); display: flex; align-items: center; justify-content: center; flex-shrink: 0; overflow: hidden; } .setup-app-icon-wrap .setup-app-icon { width: 24px; height: 24px; object-fit: contain; } .setup-app:has(input:checked) .setup-app-icon-wrap { background: rgba(var(--accent-rgb), 0.20); border-color: rgba(var(--accent-rgb), 0.45); } .setup-app-info { flex: 1; min-width: 0; } .setup-app-name { font-size: 14px; font-weight: 600; color: var(--text-primary); } .setup-app-desc { font-size: 12px; color: rgba(var(--text-rgb), 0.82); margin-top: 2px; } /* Parent tile + sub-option as one merged card. Parent loses its bottom radius; sub-option is a flush drawer below with only the bottom corners rounded. Shared horizontal bounds so the two pieces read as one. */ .setup-app-group { margin-bottom: 8px; } .setup-app-group .setup-app { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: rgba(var(--text-rgb), 0.04); } .setup-app-suboption { display: flex; align-items: center; gap: 10px; /* Left padding lines the sub-checkbox up under the parent's checkbox (parent: 14px padding + ~3px to centre the smaller 14px box). */ padding: 7px 14px 8px 17px; margin: 0; background: rgba(var(--text-rgb), 0.035); border: 1px solid rgba(var(--text-rgb), 0.08); border-top: none; border-radius: 0 0 12px 12px; font-size: 12px; color: rgba(var(--text-rgb), 0.82); cursor: pointer; transition: all 0.15s ease; } /* When the parent is selected, the drawer picks up the same blue tint so the merged card reads as one selected unit. */ .setup-app-group:has(.setup-app input[type=checkbox]:checked) .setup-app { border-bottom-color: rgba(var(--accent-rgb), 0.30); } .setup-app-group:has(.setup-app input[type=checkbox]:checked) .setup-app-suboption { background: rgba(var(--accent-rgb), 0.08); border-color: rgba(var(--accent-rgb), 0.40); border-top: none; } .setup-app-suboption:hover { background: rgba(var(--accent-rgb), 0.12); } .setup-app-suboption.disabled { opacity: 0.35; pointer-events: none; } .setup-app-suboption input[type=checkbox] { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; flex-shrink: 0; cursor: pointer; border-radius: 4px; background: rgba(var(--text-rgb), 0.04); border: 1.4px solid rgba(var(--text-rgb), 0.20); position: relative; transition: background 0.15s ease, border-color 0.15s ease; } .setup-app-suboption:hover input[type=checkbox] { border-color: rgba(var(--accent-rgb), 0.55); } .setup-app-suboption input[type=checkbox]:checked { background: linear-gradient(135deg, var(--accent), var(--accent)); border-color: rgba(var(--accent-rgb), 0.9); } .setup-app-suboption input[type=checkbox]:checked::after { content: ''; position: absolute; inset: 0; background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: center; background-size: 10px 10px; } .setup-app-suboption-label { font-weight: 500; } /* Navigation */ .setup-nav { display: flex; gap: 10px; margin-top: 6px; } .setup-btn-back, .setup-btn-next { background: rgba(var(--text-rgb), 0.06); color: var(--text-primary); border: 1px solid rgba(var(--text-rgb), 0.12); border-radius: 12px; padding: 14px 18px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s ease; } .setup-btn-back { flex: 0 0 auto; } .setup-btn-next { flex: 1; } .setup-btn-back:hover:not(:disabled), .setup-btn-next:hover:not(:disabled) { background: rgba(var(--accent-rgb), 0.14); border-color: rgba(var(--accent-rgb), 0.40); transform: translateY(-1px); } .setup-btn-back:disabled { opacity: 0.35; cursor: not-allowed; } .setup-launch { flex: 1; background: linear-gradient(135deg, var(--accent), var(--accent-hover)); border: none; border-radius: 12px; padding: 14px 18px; color: var(--text-primary); font-size: 15px; font-weight: 700; letter-spacing: 0.5px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 10px; transition: all 0.2s ease; } .setup-launch:hover:not(:disabled) { transform: translateY(-2px); filter: brightness(1.05); } .setup-launch:active:not(:disabled) { transform: translateY(0); } .setup-launch:disabled { opacity: 0.6; cursor: not-allowed; } .setup-launch-arrow { transition: transform 0.2s ease; } .setup-launch:hover:not(:disabled) .setup-launch-arrow { transform: translateX(4px); } /* Error */ .setup-error { background: rgba(var(--status-danger-rgb), 0.10); border: 1px solid rgba(var(--status-danger-rgb), 0.3); color: var(--status-danger); padding: 10px 14px; border-radius: 10px; font-size: 13px; } /* Top-nav disabled state — applied while setup isn't complete. */ .topbar-nav.setup-needed .nav-item { opacity: 0.35; pointer-events: none; filter: grayscale(60%); } /* Setup-in-progress banner — pinned to top of viewport while the wizard's tasks are still running (any page). Auto-removed when finalize completes. */ .setup-progress-banner { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 9000; background: rgba(var(--bg-rgb), 0.45); border: 1px solid rgba(var(--accent-rgb), 0.40); border-radius: 12px; padding: 10px 16px; color: var(--text-primary); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 13px; min-width: 320px; max-width: min(520px, 92vw); animation: setupBannerIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) both; } .setup-progress-banner.leaving { animation: setupBannerOut 0.35s ease both; } .setup-progress-banner.failed { border-color: rgba(var(--status-danger-rgb), 0.5); } .setup-progress-banner-inner { display: grid; grid-template-columns: 18px 1fr; grid-template-rows: auto auto; column-gap: 12px; align-items: center; } .setup-progress-banner-icon { grid-row: 1 / span 2; color: var(--accent); display: flex; align-items: center; justify-content: center; } .setup-progress-banner.failed .setup-progress-banner-icon { color: var(--status-danger); } .setup-progress-banner-text { grid-column: 2; grid-row: 1; letter-spacing: 0.2px; } .setup-progress-banner-text strong { font-weight: 600; color: var(--text-primary); } .setup-progress-banner-count { color: rgba(var(--text-rgb), 0.78); font-family: 'SF Mono', Menlo, monospace; font-size: 12px; margin-left: 4px; } .setup-progress-banner-bar { grid-column: 2; grid-row: 2; height: 4px; background: rgba(var(--text-rgb), 0.08); border-radius: 999px; overflow: hidden; margin-top: 6px; } .setup-progress-banner-fill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--accent), var(--accent-hover)); border-radius: 999px; transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1); } .setup-progress-banner.failed .setup-progress-banner-fill { background: linear-gradient(90deg, var(--status-danger), var(--status-danger-hover)); } @keyframes setupBannerIn { from { opacity: 0; transform: translate(-50%, -16px); } to { opacity: 1; transform: translate(-50%, 0); } } @keyframes setupBannerOut { from { opacity: 1; transform: translate(-50%, 0); } to { opacity: 0; transform: translate(-50%, -16px); } } @media (max-width: 600px) { .setup-shell { padding: 22px 18px 18px; border-radius: 14px; } .setup-logo h1 { font-size: 20px; } .setup-input-row { flex-direction: column; } .setup-input-row .setup-field-icon { top: 22px; transform: none; } .setup-input-row .setup-input-with-icon { padding-left: 2.25rem !important; } .setup-reroll { padding: 10px; } .setup-nav { flex-direction: column; } .setup-btn-back { order: 2; } .setup-btn-next, .setup-launch { order: 1; } }