UNPKG

homebridge-eufy-security

Version:
776 lines (656 loc) 14.5 kB
/* ===== Eufy Security Plugin - Custom UI Styles ===== */ /* Bootstrap 5 is auto-injected by Homebridge UI */ :root { --eufy-primary: #2d6ff7; --eufy-primary-hover: #1a5ae0; --eufy-success: #28a745; --eufy-danger: #dc3545; --eufy-warning: #ffc107; --eufy-muted: #6c757d; --eufy-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); --eufy-card-hover-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); --eufy-border-radius: 12px; --eufy-transition: all 0.2s ease; } /* ===== Instant Tooltip ===== */ .eufy-tooltip { position: relative; } .eufy-tooltip::after { content: attr(data-tooltip); position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); padding: 4px 8px; background: rgba(0, 0, 0, 0.8); color: #fff; font-size: 0.75rem; white-space: nowrap; border-radius: 4px; pointer-events: none; opacity: 0; transition: opacity 0.1s ease; z-index: 10; } .eufy-tooltip:hover::after { opacity: 1; } .d-flex > .eufy-tooltip:last-child::after { left: auto; right: 0; transform: none; } /* ===== Layout ===== */ #app { max-width: 960px; margin: 0 auto; padding: 0 12px; } /* ===== Header ===== */ .eufy-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 0; margin-bottom: 8px; border-bottom: 1px solid rgba(0, 0, 0, 0.08); } .eufy-header h4 { margin: 0; font-weight: 600; font-size: 1.25rem; } .eufy-header__right { display: flex; align-items: center; gap: 12px; } .eufy-cache-date { font-size: 0.75rem; color: #888; white-space: nowrap; } .eufy-header .btn-group .btn { padding: 6px 10px; font-size: 0.85rem; } /* ===== Device Cards ===== */ .device-card { border: 1px solid rgba(0, 0, 0, 0.1); border-radius: var(--eufy-border-radius); box-shadow: var(--eufy-card-shadow); transition: var(--eufy-transition); cursor: pointer; overflow: hidden; height: 100%; background: var(--bs-body-bg, #fff); } .device-card:hover:not(.device-card--disabled) { box-shadow: var(--eufy-card-hover-shadow); transform: translateY(-2px); } .device-card--unsupported { opacity: 0.65; cursor: pointer; } .device-card__hint { font-size: 0.7rem; color: var(--eufy-primary); margin-top: 4px; font-style: italic; } /* ===== Unsupported Detail View ===== */ .unsupported-detail { padding: 16px 0; } .unsupported-detail__table { width: 100%; font-size: 0.85rem; margin: 16px 0; border-collapse: collapse; } .unsupported-detail__table td { padding: 8px 12px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .unsupported-detail__table td:first-child { font-weight: 600; width: 40%; color: var(--eufy-muted); } .unsupported-detail__steps { margin-top: 20px; } .unsupported-stepper { display: flex; align-items: center; justify-content: center; gap: 0; margin-bottom: 14px; } .unsupported-stepper__step { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 0 0 auto; } .unsupported-stepper__circle { width: 28px; height: 28px; border-radius: 50%; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 0.78rem; font-weight: 700; background: var(--eufy-primary); } .unsupported-stepper__circle--success { background: var(--bs-success, #198754); } .unsupported-stepper__circle--primary { background: var(--bs-primary, #0d6efd); } .unsupported-stepper__circle--warning { background: var(--bs-warning, #ffc107); } .unsupported-stepper__circle--danger { background: var(--bs-danger, #dc3545); } .unsupported-stepper__label { font-size: 0.72rem; font-weight: 600; color: var(--eufy-muted); text-transform: uppercase; letter-spacing: 0.03em; } .unsupported-stepper__line { flex: 1; height: 2px; background: var(--eufy-border, #dee2e6); margin: 0 8px; align-self: flex-start; margin-top: 13px; } .unsupported-detail__actions { display: flex; gap: 12px; } .unsupported-detail__actions .btn { flex: 1; text-align: center; } .unsupported-detail__paste-note { font-size: 0.8rem; color: var(--eufy-muted); margin-top: 12px; padding: 8px 12px; background: rgba(255, 193, 7, 0.1); border-left: 3px solid var(--bs-warning, #ffc107); border-radius: 4px; } .unsupported-detail__info { font-size: 0.82rem; padding: 12px 14px; margin: 16px 0; background: rgba(45, 111, 247, 0.06); border-left: 3px solid var(--eufy-primary); border-radius: 4px; line-height: 1.6; } .unsupported-detail__info a { color: var(--eufy-primary); } .unsupported-detail__dump-wrap { position: relative; } .unsupported-detail__copy-btn { position: absolute; top: 8px; right: 8px; padding: 3px 10px; font-size: 0.72rem; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 6px; background: var(--bs-body-bg, #fff); color: var(--eufy-muted); cursor: pointer; transition: var(--eufy-transition); z-index: 1; } .unsupported-detail__copy-btn:hover { border-color: var(--eufy-primary); color: var(--eufy-primary); } .unsupported-detail__dump { background: rgba(0, 0, 0, 0.04); border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 8px; padding: 12px 16px; font-size: 0.78rem; max-height: 100px; overflow-y: auto; white-space: pre-wrap; word-break: break-word; margin-bottom: 8px; } .device-card--ignored { opacity: 0.6; } .device-card__image-wrap { display: flex; align-items: center; justify-content: center; padding: 16px 16px 8px; height: 120px; } .device-card__image-wrap img { max-height: 100%; max-width: 100%; object-fit: contain; } .device-card__body { padding: 8px 16px 14px; } .device-card__name { font-weight: 600; font-size: 0.9rem; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .device-card__meta-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .device-card__meta { font-size: 0.75rem; color: var(--eufy-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; } .device-card__footer { display: flex; align-items: center; justify-content: space-between; padding: 0 16px 12px; } /* ===== Badges ===== */ .badge-unsupported { font-size: 0.7rem; background-color: var(--eufy-warning) !important; color: #000; } /* ===== Toggle Switch ===== */ .eufy-toggle { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .eufy-toggle:last-child { border-bottom: none; } .eufy-toggle__label { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; font-weight: 500; } .eufy-toggle__help { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: rgba(0, 0, 0, 0.08); color: var(--eufy-muted); font-size: 0.65rem; cursor: help; font-weight: 700; flex-shrink: 0; } /* ===== Discovery / Loading ===== */ .discovery-screen { text-align: center; padding: 60px 20px; } .discovery-screen__icon { font-size: 3rem; margin-bottom: 16px; animation: pulse 2s ease-in-out infinite; } .discovery-screen__title { font-size: 1.2rem; font-weight: 600; margin-bottom: 8px; } .discovery-screen__subtitle { color: var(--eufy-muted); font-size: 0.9rem; margin-bottom: 24px; } @keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.6; transform: scale(1.05); } } /* ===== Login ===== */ .login-card { margin: 0px auto; } .login-section-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 16px; padding-bottom: 12px; border-bottom: 1px solid rgba(0, 0, 0, 0.08); } /* ===== Detail View ===== */ .detail-header { display: flex; align-items: center; gap: 16px; padding: 16px 0; margin-bottom: 8px; border-bottom: 1px solid rgba(0, 0, 0, 0.08); } .detail-header__image { width: 64px; height: 64px; object-fit: contain; } .detail-header__info h5 { margin: 0 0 4px; font-weight: 600; } .detail-header__info small { color: var(--eufy-muted); } .detail-section { margin-bottom: 16px; } .detail-section__title { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--eufy-muted); font-weight: 600; margin-bottom: 4px; padding: 8px 0; } /* ===== Advanced Toggle ===== */ .advanced-toggle { display: flex; align-items: center; gap: 6px; color: var(--eufy-muted); cursor: pointer; font-size: 0.85rem; padding: 12px 0; border: none; background: none; width: 100%; text-align: left; } .advanced-toggle:hover { color: var(--eufy-primary); } .advanced-toggle__chevron { transition: transform 0.2s; font-size: 0.7rem; } .advanced-toggle__chevron--open { transform: rotate(90deg); } /* ===== Settings ===== */ .settings-section { padding: 16px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .settings-section:last-child { border-bottom: none; } .settings-btn-row { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 0; } /* ===== Guard Modes ===== */ .guard-mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .guard-mode-grid .form-group label { font-size: 0.85rem; font-weight: 500; margin-bottom: 4px; } .guard-mode-grid .form-control, .guard-mode-grid .form-select { font-size: 0.85rem; } /* ===== Welcome Banner ===== */ .welcome-banner { text-align: center; padding: 24px 20px 16px; } .welcome-banner__title { font-size: 1.1rem; font-weight: 600; margin-bottom: 8px; } .welcome-banner__text { color: var(--eufy-muted); font-size: 0.85rem; line-height: 1.5; max-width: 360px; margin: 0 auto; } /* ===== Alert overrides ===== */ .alert-admin { border-radius: var(--eufy-border-radius); } /* ===== Node.js Version Warning Banner ===== */ .node-version-banner { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; margin-bottom: 16px; background: #fff3cd; border: 1px solid #ffc107; border-radius: var(--eufy-border-radius); font-size: 0.85rem; line-height: 1.5; } .node-version-banner__icon { font-size: 1.3rem; flex-shrink: 0; margin-top: 1px; } .node-version-banner__content > strong { display: block; margin-bottom: 4px; color: #664d03; } .node-version-banner__text { color: #664d03; } .node-version-banner__text code { background: rgba(0, 0, 0, 0.08); padding: 1px 4px; border-radius: 3px; font-size: 0.8rem; } .node-version-banner__text a { color: #664d03; font-weight: 500; } /* ===== Number Input ===== */ .number-input-group { display: flex; align-items: center; gap: 4px; } .number-input-group .btn { padding: 4px 10px; font-size: 0.85rem; line-height: 1; } .number-input-group input { width: 70px; text-align: center; font-size: 0.85rem; } /* ===== Progress bar for log download ===== */ .log-progress { margin-top: 12px; } .log-progress .progress { height: 8px; border-radius: 4px; } /* ===== Responsive ===== */ @media (max-width: 576px) { .welcome-actions { flex-direction: column; } .guard-mode-grid { grid-template-columns: 1fr; } .device-card__image-wrap { height: 90px; padding: 12px 12px 4px; } } /* ===== Dark mode support ===== */ /* Homebridge UI applies .dark-mode on the body inside the plugin iframe */ body.dark-mode { --eufy-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.35); --eufy-card-hover-shadow: 0 4px 16px rgba(0, 0, 0, 0.5); --eufy-muted: #9ea7b3; } body.dark-mode .device-card { border-color: rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.05); } body.dark-mode .device-card:hover:not(.device-card--disabled) { box-shadow: var(--eufy-card-hover-shadow); } body.dark-mode .eufy-header { border-bottom-color: rgba(255, 255, 255, 0.1); } body.dark-mode .eufy-toggle { border-bottom-color: rgba(255, 255, 255, 0.08); } body.dark-mode .eufy-toggle__help { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.5); } body.dark-mode .detail-header { border-bottom-color: rgba(255, 255, 255, 0.1); } body.dark-mode .login-section-title { border-bottom-color: rgba(255, 255, 255, 0.1); } body.dark-mode .settings-section { border-bottom-color: rgba(255, 255, 255, 0.08); } /* ===== Diagnostics Steps ===== */ .diag-step { padding: 16px; margin-bottom: 12px; border-left: 3px solid var(--eufy-primary); background: rgba(0, 0, 0, 0.02); border-radius: 0 var(--eufy-border-radius) var(--eufy-border-radius) 0; } .diag-step__header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; } .diag-step__badge { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--eufy-primary); color: #fff; font-size: 0.8rem; font-weight: 700; flex-shrink: 0; } body.dark-mode .diag-step { background: rgba(255, 255, 255, 0.04); border-left-color: var(--eufy-primary); } body.dark-mode .advanced-toggle { color: rgba(255, 255, 255, 0.5); } body.dark-mode .advanced-toggle:hover { color: var(--eufy-primary); } body.dark-mode .device-card__meta { color: var(--eufy-muted); } body.dark-mode .detail-header__info small { color: var(--eufy-muted); } body.dark-mode .detail-section__title { color: var(--eufy-muted); } body.dark-mode .welcome-banner__text { color: var(--eufy-muted); } body.dark-mode .discovery-screen__subtitle { color: var(--eufy-muted); } body.dark-mode .discovery-screen__title { color: rgba(255, 255, 255, 0.9); } body.dark-mode .discovery-screen .text-muted { color: var(--eufy-muted) !important; } body.dark-mode .text-muted { color: rgba(255, 255, 255, 0.55) !important; } body.dark-mode .diag-step strong { color: rgba(255, 255, 255, 0.9); } body.dark-mode .node-version-banner { background: rgba(255, 193, 7, 0.12); border-color: rgba(255, 193, 7, 0.3); } body.dark-mode .node-version-banner__content strong { color: #ffda6a; } body.dark-mode .node-version-banner__text { color: #ffe69c; } body.dark-mode .node-version-banner__text code { background: rgba(255, 255, 255, 0.1); color: #ffe69c; } body.dark-mode .node-version-banner__text a { color: #ffda6a; } /* Invert dark-filled SVG icons so they render white on dark backgrounds */ body.dark-mode img[src*="assets/icons/"] { filter: brightness(0) invert(1); }