/* ── Reset & base ────────────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #0a0a0a; --bg-widget: #0f0f0f; --bg-header: #111111; --border: #1a2a1a; --green: #00ff41; --green-dim: #00aa2a; --green-dark:#003310; --red: #ff0033; --red-dim: #aa0022; --orange: #ff7700; --yellow: #ffcc00; --text: #c8ffc8; --text-dim: #5a7a5a; --font: 'Courier New', Courier, monospace; } html, body { height: 100%; background: var(--bg); color: var(--text); font-family: var(--font); font-size: 13px; overflow: hidden; } /* ── Header ──────────────────────────────────────────────────────────────── */ header { display: flex; justify-content: space-between; align-items: center; padding: 0 16px; height: 40px; background: var(--bg-header); border-bottom: 1px solid var(--border); } .logo { color: var(--green); font-size: 14px; font-weight: bold; letter-spacing: 3px; text-shadow: 0 0 8px var(--green); } #header-clock { color: var(--green-dim); font-size: 13px; letter-spacing: 1px; } /* ── Grid ────────────────────────────────────────────────────────────────── */ main.grid { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 8px; padding: 8px; height: calc(100vh - 40px); } /* ── Widget ──────────────────────────────────────────────────────────────── */ .widget { display: flex; flex-direction: column; background: var(--bg-widget); border: 1px solid var(--border); border-radius: 4px; overflow: hidden; } .widget-header { display: flex; justify-content: space-between; align-items: center; padding: 6px 12px; background: var(--bg-header); border-bottom: 1px solid var(--border); flex-shrink: 0; } .widget-title { color: var(--green); font-size: 11px; letter-spacing: 2px; font-weight: bold; } .widget-status { font-size: 10px; letter-spacing: 1px; color: var(--green-dim); } .widget-status.ok { color: var(--green); } .widget-status.err { color: var(--red); } .widget-body { flex: 1; overflow: hidden; padding: 8px; } /* ── Iframe widget ───────────────────────────────────────────────────────── */ .iframe-container { padding: 0; } .iframe-container iframe { width: 100%; height: 100%; border: none; display: block; } /* ── Feed list ───────────────────────────────────────────────────────────── */ .feed-list { list-style: none; height: 100%; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; } .feed-list::-webkit-scrollbar { width: 4px; } .feed-list::-webkit-scrollbar-track { background: transparent; } .feed-list::-webkit-scrollbar-thumb { background: var(--green-dark); border-radius: 2px; } .feed-loading { color: var(--text-dim); font-style: italic; padding: 8px 0; } /* ANSSI items */ .anssi-item { border-bottom: 1px solid var(--border); padding: 6px 4px; } .anssi-item a { color: var(--green); text-decoration: none; font-size: 12px; display: block; margin-bottom: 2px; line-height: 1.4; } .anssi-item a:hover { text-decoration: underline; } .anssi-date { color: var(--text-dim); font-size: 10px; } /* CVE items */ .cve-item { display: flex; align-items: flex-start; gap: 8px; border-bottom: 1px solid var(--border); padding: 6px 4px; } .cve-badge { flex-shrink: 0; font-size: 9px; font-weight: bold; letter-spacing: 1px; padding: 2px 6px; border-radius: 2px; text-transform: uppercase; min-width: 60px; text-align: center; } .badge-critical { background: var(--red); color: #fff; } .badge-high { background: var(--orange); color: #000; } .badge-medium { background: var(--yellow); color: #000; } .badge-low { background: var(--green-dim); color: #000; } .badge-unknown { background: #333; color: var(--text-dim); } .cve-info { flex: 1; min-width: 0; } .cve-id { color: var(--green); font-size: 12px; font-weight: bold; } .cve-desc { color: var(--text-dim); font-size: 11px; margin-top: 2px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ── Clock widget ────────────────────────────────────────────────────────── */ .clock-widget { display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 16px; height: 100%; } #clock-time { font-size: 48px; color: var(--green); text-shadow: 0 0 16px var(--green); letter-spacing: 4px; } #clock-date { font-size: 14px; color: var(--green-dim); letter-spacing: 2px; } .server-info { width: 100%; max-width: 280px; border: 1px solid var(--border); border-radius: 2px; overflow: hidden; } .info-row { display: flex; border-bottom: 1px solid var(--border); } .info-row:last-child { border-bottom: none; } .info-label { width: 100px; padding: 5px 8px; background: var(--bg-header); color: var(--text-dim); font-size: 10px; letter-spacing: 1px; flex-shrink: 0; } .info-value { padding: 5px 8px; color: var(--green-dim); font-size: 10px; letter-spacing: 1px; } /* ── Alert overlay ───────────────────────────────────────────────────────── */ #alert-overlay { position: fixed; inset: 0; z-index: 9999; background: rgba(180, 0, 0, 0.92); display: flex; align-items: center; justify-content: center; animation: flash-bg 1s ease-in-out infinite; } #alert-overlay.hidden { display: none; } @keyframes flash-bg { 0% { background: rgba(200, 0, 0, 0.92); } 50% { background: rgba(80, 0, 0, 0.98); } 100% { background: rgba(200, 0, 0, 0.92); } } #alert-content { text-align: center; max-width: 80vw; padding: 48px; } #alert-icon { font-size: 80px; color: #fff; animation: pulse 1s ease-in-out infinite alternate; margin-bottom: 24px; } #alert-image { margin-bottom: 24px; } #alert-image img { max-width: min(600px, 80vw); max-height: 40vh; object-fit: contain; border: 3px solid rgba(255,255,255,0.3); border-radius: 4px; box-shadow: 0 0 40px rgba(255,0,0,0.6); } @keyframes pulse { from { opacity: 1; transform: scale(1); } to { opacity: 0.6; transform: scale(1.05); } } #alert-message { font-size: 36px; color: #fff; font-weight: bold; letter-spacing: 4px; text-shadow: 0 0 20px rgba(255,255,255,0.5); text-transform: uppercase; line-height: 1.3; } #alert-html { margin-top: 24px; color: #ffcccc; font-size: 16px; line-height: 1.6; } /* ── Utility ──────────────────────────────────────────────────────────────── */ .hidden { display: none !important; }