*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #f5f5f7; --card-bg: #fff; --border: #d1d5db; --border-light: #e5e7eb; --text: #111827; --text-secondary: #6b7280; --primary: #01a7c4; --primary-hover: #01a7c4; --primary-light: #eff6ff; --error-bg: #fef2f2; --error-border: #fca5a5; --error-text: #991b1b; --warning-bg: #fffbeb; --warning-border: #fcd34d; --warning-text: #92400e; --success-bg: #f0fdf4; --success-border: #86efac; --success-text: #166534; --shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05); } body { font-family: "Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif !important; background: var(--bg); color: var(--text); line-height: 1.6; -webkit-font-smoothing: antialiased; } button { font-family: "Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif !important; } main { max-width: 640px; margin: 0 auto; padding: 2rem 1.5rem 4rem; } /* Hero header */ .hero { margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--border-light); } h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.02em; } #connect-unsupported-hint { margin-top: 20px; color: var(--error-text); } #connect-unsupported-hint a { color: var(--error-text); text-decoration: underline; } .hero-accent { color: var(--primary); font-weight: 600; } .beta-pill { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; background: var(--primary); color: #fff; padding: 0.35rem 0.7rem; border-radius: 10px; vertical-align: middle; position: relative; top: -0.15rem; margin-left: 5px; } .subtitle { color: var(--text-secondary); font-size: 0.95rem; margin-top: 0.25rem; } h2 { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.75rem; color: var(--text); } /* Step navigation */ .step-nav { margin-bottom: 1.5rem; } .step-nav ol { display: flex; list-style: none; gap: 0; counter-reset: step; } .step-nav li { flex: 1; text-align: center; padding: 0.5rem 0; font-size: 0.8rem; font-weight: 500; color: var(--text-secondary); position: relative; counter-increment: step; } .step-nav li::before { content: counter(step); display: block; width: 1.6rem; height: 1.6rem; line-height: 1.6rem; margin: 0 auto 0.3rem; border-radius: 50%; background: var(--border-light); color: var(--text-secondary); font-size: 0.75rem; font-weight: 600; } .step-nav li.active::before { background: var(--primary); color: #fff; } .step-nav li.active { color: var(--primary); font-weight: 600; } .step-nav li.done::before { background: var(--success-text); color: #fff; content: "\2713"; } .step-nav li.done { color: var(--success-text); } /* Connector lines between steps */ .step-nav li + li::after { content: ''; position: absolute; top: 1.3rem; right: 50%; width: 100%; height: 2px; background: var(--border-light); z-index: -1; } .step-nav li.done + li::after, .step-nav li.done + li.active::after { background: var(--success-text); } /* Mode selection cards */ .mode-cards { display: flex; flex-direction: column; gap: 0.75rem; } .mode-card { display: flex; align-items: flex-start; gap: 0.75rem; padding: 1rem 1.25rem; background: var(--card-bg); border: 2px solid var(--border-light); border-radius: 10px; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; box-shadow: var(--shadow); } #mode-patches-hint { margin-top: 15px; } .mode-card:hover { border-color: var(--border); } .mode-card-selected { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary), var(--shadow); } .mode-card-btn { text-align: left; width: 100%; } .mode-card-btn:hover { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary), var(--shadow); } .mode-card-btn:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: var(--shadow); } .mode-card-btn:disabled:hover { border-color: var(--border-light); box-shadow: var(--shadow); } .mode-card input[type="radio"] { margin-top: 0.2rem; flex-shrink: 0; accent-color: var(--primary); } .mode-card-title { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; font-size: 0.93rem; color: var(--text); margin-bottom: 0.25rem; } .mode-card-desc { font-size: 0.83rem; color: var(--text-secondary); line-height: 1.5; } .mode-card-title { position: relative; } .recommended-pill { position: absolute; top: -8px; right: -20px; margin-left: auto; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; background: var(--primary); color: #fff; padding: 0.25rem 0.6rem; border-top-left-radius: 8px; border-bottom-left-radius: 8px; line-height: 1.5; } /* NickelMenu option radio cards */ .nm-options { display: flex; flex-direction: column; gap: 0.6rem; } .nm-option { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.85rem 1rem; background: var(--card-bg); border: 2px solid var(--border-light); border-radius: 10px; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; box-shadow: var(--shadow); } .nm-option:hover { border-color: var(--border); } .nm-option-selected { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary), var(--shadow); } .nm-option-disabled { opacity: 0.45; cursor: not-allowed; } .nm-option-disabled:hover { border-color: var(--border-light); } .nm-option-remove:not(.nm-option-disabled) { border-color: var(--error-border); } .nm-option-remove:not(.nm-option-disabled):hover { border-color: var(--error-text); } .nm-option-remove.nm-option-selected { border-color: var(--error-text); box-shadow: 0 0 0 1px var(--error-text), var(--shadow); } .nm-option-remove input[type="radio"] { accent-color: var(--error-text); } /* NickelMenu config checkboxes */ .nm-config-options { padding: 0 0.25rem; margin-left: 1.5rem; } .nm-config-item { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.5rem 0; font-size: 0.88rem; color: var(--text); cursor: pointer; } .nm-config-item + .nm-config-item { border-top: 1px solid var(--border-light); } .nm-config-item input[type="checkbox"] { flex-shrink: 0; margin-top: 0.15rem; accent-color: var(--primary); } .nm-config-item input[type="checkbox"]:disabled { opacity: 0.6; } .nm-config-text { user-select: none; margin-top: -2px; } .nm-config-desc { display: block; font-size: 0.75rem; color: var(--text-secondary); line-height: 1.4; margin-top: 0.1rem; } .nm-config-link { display: block; margin-top: 0.75rem; padding-top: 0.75rem; padding-bottom: 0.75rem; border-top: 1px solid var(--border-light); font-size: 0.8rem; color: var(--primary); text-decoration: none; } .nm-config-link:hover { text-decoration: underline; } .nm-option input[type="radio"] { margin-top: 0.2rem; flex-shrink: 0; accent-color: var(--primary); } .nm-option-title { font-weight: 500; font-size: 0.88rem; color: var(--text); margin-bottom: 0.15rem; } .nm-option-desc { font-size: 0.78rem; color: var(--text-secondary); line-height: 1.5; } /* Steps */ .step { margin-bottom: 1rem; } .step p { color: var(--text-secondary); margin-bottom: 1rem; font-size: 0.93rem; line-height: 1.6; } /* Step action buttons (back/next) */ .step-actions { display: flex; justify-content: space-between; gap: 0.75rem; margin-top: 1.25rem; } .step-actions .primary:first-child, .step-actions > [hidden] + .primary { margin-left: auto; } .step-actions-right { display: flex; gap: 0.75rem; margin-left: auto; } /* Buttons */ button { font-size: 0.9rem; padding: 0.55rem 1.25rem; border-radius: 8px; border: 1px solid var(--border); cursor: pointer; font-weight: 500; transition: all 0.15s ease; } button.primary { background: var(--primary); color: #fff; border-color: var(--primary); box-shadow: var(--shadow); } button.primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); box-shadow: var(--shadow-md); } button.secondary { background: var(--card-bg); color: var(--text); box-shadow: var(--shadow); } button.secondary:hover { background: #f9fafb; border-color: #9ca3af; } button.danger { background: #fff; color: var(--error-text); border-color: var(--error-border); } button.danger:hover { background: var(--error-bg); border-color: var(--error-text); } button:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; } button.btn-success, button.btn-success:hover { background: var(--success-text); border-color: var(--success-text); color: #fff; cursor: default; opacity: 0.7; } /* Cards */ .info-card { background: var(--card-bg); border: 1px solid var(--border-light); border-radius: 10px; padding: 0.75rem 1.25rem; margin-bottom: 1rem; box-shadow: var(--shadow); } .info-row { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; border-bottom: 1px solid var(--border-light); } .info-row:last-child { border-bottom: none; } .info-row .label { font-weight: 500; color: var(--text-secondary); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em; } .info-row .value { font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace; font-size: 0.88rem; } .device-unknown-ack { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.5rem 0; font-size: 0.83rem; color: var(--text); cursor: pointer; } .device-unknown-ack input[type="checkbox"] { flex-shrink: 0; margin-top: 0.15rem; accent-color: var(--primary); } /* Status banners */ .warning { background: var(--warning-bg); border: 1px solid var(--warning-border); color: var(--warning-text); padding: 0.75rem 1rem; border-radius: 8px; margin-bottom: 1.5rem; font-size: 0.88rem; line-height: 1.5; } .warning a { color: var(--warning-text) !important; text-decoration: underline !important; } .error { background: var(--error-bg); border: 1px solid var(--error-border); color: var(--error-text); padding: 0.75rem 1rem; border-radius: 8px; font-size: 0.88rem; } #error-message { margin-top: 1rem; } .status-supported { background: var(--success-bg); border: 1px solid var(--success-border); color: var(--success-text); padding: 0.65rem 1rem; border-radius: 8px; margin-bottom: 1rem; font-size: 0.88rem; } .status-unsupported { background: var(--warning-bg); border: 1px solid var(--warning-border); color: var(--warning-text); padding: 0.65rem 1rem; border-radius: 8px; margin-bottom: 1rem; font-size: 0.88rem; } /* Scrollable patch container */ .patch-container-scroll { max-height: 50vh; overflow-y: auto; border: 1px solid var(--border); border-radius: 5px; } /* Patch file sections */ .patch-file-section { background: var(--card-bg); border-bottom: 1px solid var(--border-light); } .patch-file-section:last-child { border-bottom: none; } .patch-file-section summary { padding: 0.6rem 0.75rem; cursor: pointer; display: flex; align-items: center; font-weight: 500; font-size: 0.93rem; user-select: none; transition: background 0.1s; list-style: none; } .patch-file-section summary::-webkit-details-marker { display: none; } .patch-file-section summary::before { content: "\203A"; display: inline-block; width: 1rem; margin-right: 0.35rem; flex-shrink: 0; text-align: center; font-size: 1.1rem; font-weight: 600; color: var(--text-secondary); transition: transform 0.15s ease; } .patch-file-section[open] summary::before { transform: rotate(90deg) translateX(0.1rem); } .patch-file-section summary .patch-count { margin-left: auto; } .patch-file-section summary:hover { background: #f9fafb; } .patch-file-section[open] summary { border-bottom: 1px solid var(--border-light); } .patch-count { font-weight: 400; font-size: 0.8rem; background: var(--primary-light); color: var(--primary); padding: 0.15rem 0.6rem; border-radius: 10px; } .patch-list { padding: 0.25rem 0; } .patch-item { padding: 0.4rem 1rem; } .patch-item + .patch-item { border-top: 1px solid var(--border-light); } .patch-header { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; font-size: 0.85rem; } .patch-header input { flex-shrink: 0; accent-color: var(--primary); } .patch-name { font-weight: 500; } .patch-name-none { color: var(--text-secondary); } .patch-desc-toggle { flex-shrink: 0; background: none; border: none; padding: 0 0.3rem; font-size: 0.7rem; color: var(--text-secondary); cursor: pointer; box-shadow: none; opacity: 0.6; transition: opacity 0.1s; } .patch-desc-toggle:hover { opacity: 1; } /* Visual grouping for mutually exclusive patches */ .patch-group { background: #f8fafc; border-left: 3px solid var(--primary); margin: 0.35rem 0.5rem; border-radius: 0 6px 6px 0; } .patch-group .patch-item { padding: 0.4rem 0.75rem; } .patch-group-label { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--primary); padding: 0.45rem 0.75rem 0; } .step .patch-description { margin-top: 0.3rem; margin-left: 1.6rem; margin-bottom: 0; font-size: 0.72rem; color: var(--text-secondary); white-space: pre-line; line-height: 1.4; padding: 0.25rem 0; } .patch-description[hidden] { display: none; } /* Firmware input */ input[type="file"] { display: block; margin-bottom: 1rem; font-size: 0.88rem; } #build-actions { display: flex; justify-content: space-between; gap: 0.75rem; margin-top: 1.25rem; } /* Build header (spinner + progress text) */ .build-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.25rem; } .build-header p { margin-bottom: 0; font-weight: 500; color: var(--text); } /* Spinner */ .spinner { width: 22px; height: 22px; border: 2.5px solid var(--border-light); border-top-color: var(--primary); border-radius: 50%; animation: spin 0.7s linear infinite; flex-shrink: 0; } @keyframes spin { to { transform: rotate(360deg); } } /* Build log terminal */ .build-log { margin-top: 0.75rem; padding: 0.75rem 1rem; background: #0f172a; color: #94a3b8; border-radius: 6px; font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace; font-size: 0.73rem; white-space: pre-wrap; height: calc(10 * 1.5em + 1.5rem); overflow-y: auto; line-height: 1.5; } /* Collapsible log on install step */ .log-details { margin-top: 0.5rem; margin-bottom: 0.25rem; } .log-details summary { font-size: 0.83rem; color: var(--text-secondary); cursor: pointer; padding: 0.25rem 0; } .log-details summary:hover { color: var(--text); } /* Done screen log is shorter */ .done-log { height: calc(7 * 1.5em + 1.5rem); } .step .hint { margin-top: 1rem; padding: 0.65rem 1rem; background: var(--success-bg); border: 1px solid var(--success-border); color: var(--success-text); border-radius: 8px; font-size: 0.88rem; } .restart-hint { margin-top: 1.5rem; font-size: 0.78rem; color: var(--text-muted); } .error-log { margin-top: 0.75rem; padding: 0.75rem 1rem; background: #0f172a; color: #e2e8f0; border-radius: 6px; font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace; font-size: 0.78rem; white-space: pre-wrap; max-height: 300px; overflow-y: auto; } .step a { color: var(--primary); text-decoration: none; } .step a:hover { text-decoration: underline; } .step .fallback-hint { margin-top: 0.5rem; margin-bottom: 1rem; font-size: 0.78rem; color: var(--text-secondary); line-height: 1.5; } select + .fallback-hint { margin-top: -0.5rem; } /* Install summary */ .step .install-summary { font-size: 0.93rem; color: var(--text); line-height: 1.6; margin-bottom: 0.5rem; } /* Install instructions */ .install-instructions { margin-top: 1rem; background: var(--card-bg); border: 1px solid var(--border-light); border-radius: 10px; padding: 1rem 1.25rem; } .install-instructions .warning { margin-bottom: 0.75rem; } .step .install-instructions .hint { margin-top: 0; } .install-steps { margin: 0.25rem 0 0 1.25rem; font-size: 0.88rem; color: var(--text-secondary); line-height: 1.7; } .install-steps li { padding: 0.15rem 0; } .install-steps code { display: inline-block; background: var(--bg); border: 1px solid var(--border-light); border-radius: 4px; padding: 0.15rem 0.4rem; font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace; font-size: 0.82rem; word-break: break-all; } .step .info-banner { background: var(--primary-light); border: 1px solid #bfdbfe; color: #1e40af; padding: 0.6rem 1rem; border-radius: 8px; font-size: 0.83rem; margin-bottom: 1rem; } /* Selected patches summary on build step */ .selected-patches-list { margin: 0 0 0.75rem 1.25rem; font-size: 0.85rem; color: var(--text-secondary); line-height: 1.7; } .selected-patches-list li { padding: 0.05rem 0; } #firmware-download-url { display: inline-block; margin: 0.4rem 0; padding: 0.3rem 0.6rem; font-size: 0.7rem; word-break: break-all; color: #64748b; background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 4px; } #firmware-verify-notice { font-size: 12px; } [hidden] { display: none !important; } select { display: block; width: 100%; padding: 0.5rem 0.75rem; font-size: 0.93rem; border: 1px solid var(--border); border-radius: 8px; background: var(--card-bg); color: var(--text); margin-bottom: 1rem; box-shadow: var(--shadow); appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%236b7280' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.75rem center; padding-right: 2rem; } select:focus, button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; } /* Footer */ .site-footer { max-width: 640px; margin: 0 auto; padding: 1.5rem 1.5rem 2rem; border-top: 1px solid var(--border-light); text-align: center; font-size: 0.8rem; color: var(--text-secondary); } .site-footer a { color: var(--text-secondary); text-decoration: underline; } .site-footer a:hover { color: var(--text); } /* Modal dialog */ .modal { border: none; border-radius: 12px; padding: 0; max-width: 560px; width: calc(100% - 2rem); max-height: 80vh; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05); } .modal::backdrop { background: rgba(0, 0, 0, 0.4); } .modal-content { display: flex; flex-direction: column; max-height: 80vh; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.25rem; border-bottom: 1px solid var(--border-light); flex-shrink: 0; } .modal-header h2 { margin-bottom: 0; font-size: 1rem; } .modal-close { background: none; border: none; font-size: 1.4rem; color: var(--text-secondary); cursor: pointer; padding: 0 0.25rem; line-height: 1; box-shadow: none; } .modal-close:hover { color: var(--text); } .modal-body { padding: 1.25rem; overflow-y: auto; font-size: 0.88rem; color: var(--text-secondary); line-height: 1.7; } .modal-body h3 { font-size: 0.88rem; font-weight: 600; color: var(--text); margin-top: 1.25rem; margin-bottom: 0.5rem; } .modal-body p { margin-bottom: 0.75rem; } .modal-body ol, .modal-body ul { margin: 0 0 0.75rem 1.25rem; } .modal-body li { margin-bottom: 0.5rem; } .modal-body a { color: var(--primary); text-decoration: none; } .modal-body a:hover { text-decoration: underline; } .modal-body code { font-size: 0.8rem; background: #f1f5f9; padding: 0.1rem 0.35rem; border-radius: 3px; }