UI Components Medium
Settings Panel
A slide-in settings panel (sheet/drawer) with tabbed sections for profile, notifications, appearance, and security settings.
Open in Lab
MCP
css vanilla-js
Targets: JS HTML
Code
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #0f172a;
--surface: #1e293b;
--surface-2: #263044;
--border: rgba(255, 255, 255, 0.07);
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #38bdf8;
--panel-width: 420px;
--transition: 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
padding: 0;
}
/* ── Main page ── */
.page-center {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
.page-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2.5rem 2rem;
text-align: center;
max-width: 380px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
.page-icon {
width: 56px;
height: 56px;
background: rgba(56, 189, 248, 0.1);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 14px;
display: flex;
align-items: center;
justify-content: center;
}
.page-title {
font-size: 1.25rem;
font-weight: 700;
color: var(--text);
}
.page-desc {
font-size: 0.875rem;
color: var(--muted);
line-height: 1.6;
}
.open-btn {
margin-top: 0.5rem;
background: var(--accent);
color: #0f172a;
border: none;
border-radius: 8px;
padding: 0.625rem 1.5rem;
font-size: 0.875rem;
font-weight: 600;
cursor: pointer;
transition: background 0.15s, transform 0.1s;
}
.open-btn:hover {
background: #7dd3fc;
}
.open-btn:active {
transform: scale(0.97);
}
/* ── Backdrop ── */
.panel-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0);
z-index: 40;
pointer-events: none;
transition: background var(--transition);
}
.panel-backdrop.active {
background: rgba(0, 0, 0, 0.55);
pointer-events: auto;
}
/* ── Settings Panel ── */
.settings-panel {
position: fixed;
top: 0;
right: 0;
width: var(--panel-width);
height: 100vh;
background: var(--surface);
border-left: 1px solid var(--border);
z-index: 50;
display: flex;
flex-direction: column;
transform: translateX(100%);
transition: transform var(--transition);
box-shadow: -8px 0 40px rgba(0, 0, 0, 0.3);
}
.settings-panel.open {
transform: translateX(0);
}
/* Panel header */
.panel-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.25rem;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.panel-title {
font-size: 1rem;
font-weight: 700;
color: var(--text);
}
.panel-close {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--border);
border-radius: 7px;
color: var(--muted);
cursor: pointer;
transition: color 0.15s, background 0.15s;
}
.panel-close:hover {
background: rgba(239, 68, 68, 0.12);
color: #f87171;
border-color: rgba(239, 68, 68, 0.2);
}
/* Tabs */
.panel-tabs {
display: flex;
border-bottom: 1px solid var(--border);
padding: 0 0.75rem;
gap: 0;
flex-shrink: 0;
overflow-x: auto;
}
.panel-tabs::-webkit-scrollbar {
display: none;
}
.tab-btn {
background: transparent;
border: none;
border-bottom: 2px solid transparent;
padding: 0.75rem 0.875rem;
font-size: 0.8125rem;
font-weight: 500;
color: var(--muted);
cursor: pointer;
white-space: nowrap;
transition: color 0.15s, border-color 0.15s;
margin-bottom: -1px;
}
.tab-btn:hover {
color: var(--text);
}
.tab-btn.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
/* Panel content */
.panel-content {
flex: 1;
overflow-y: auto;
padding: 1.25rem;
}
.panel-content::-webkit-scrollbar {
width: 5px;
}
.panel-content::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.08);
border-radius: 3px;
}
.tab-panel {
display: none;
flex-direction: column;
gap: 1.125rem;
}
.tab-panel.active {
display: flex;
}
/* ── Avatar ── */
.avatar-section {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.02);
border: 1px solid var(--border);
border-radius: 10px;
}
.avatar-circle {
width: 56px;
height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: #fff;
font-size: 1rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.avatar-info {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.avatar-upload-btn {
background: rgba(56, 189, 248, 0.1);
border: 1px solid rgba(56, 189, 248, 0.2);
color: var(--accent);
border-radius: 6px;
padding: 0.3rem 0.75rem;
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: background 0.15s;
display: inline-block;
width: fit-content;
}
.avatar-upload-btn:hover {
background: rgba(56, 189, 248, 0.18);
}
.avatar-hint {
font-size: 0.7rem;
color: #475569;
}
/* ── Forms ── */
.form-group {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.form-label {
font-size: 0.8rem;
font-weight: 500;
color: #cbd5e1;
}
.form-input {
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 0.5625rem 0.75rem;
color: var(--text);
font-size: 0.875rem;
font-family: inherit;
outline: none;
transition: border-color 0.15s, background 0.15s;
width: 100%;
}
.form-input:focus {
border-color: rgba(56, 189, 248, 0.4);
background: rgba(255, 255, 255, 0.06);
}
.form-textarea {
resize: vertical;
min-height: 80px;
}
.form-actions {
display: flex;
align-items: center;
gap: 0.875rem;
flex-wrap: wrap;
}
.btn-primary {
background: var(--accent);
color: #0f172a;
border: none;
border-radius: 8px;
padding: 0.5625rem 1.25rem;
font-size: 0.875rem;
font-weight: 600;
cursor: pointer;
transition: background 0.15s;
}
.btn-primary:hover {
background: #7dd3fc;
}
.btn-sm {
padding: 0.4375rem 1rem;
font-size: 0.8125rem;
}
.save-success {
display: none;
align-items: center;
gap: 0.375rem;
font-size: 0.8125rem;
color: #34d399;
font-weight: 500;
}
.save-success.visible {
display: flex;
}
/* ── Toggle switches ── */
.section-desc {
font-size: 0.8125rem;
color: var(--muted);
line-height: 1.5;
}
.toggle-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 0;
}
.toggle-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.875rem 0;
border-bottom: 1px solid var(--border);
}
.toggle-row:last-child {
border-bottom: none;
}
.toggle-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.toggle-label {
font-size: 0.875rem;
font-weight: 500;
color: var(--text);
}
.toggle-desc {
font-size: 0.75rem;
color: var(--muted);
}
.toggle-switch {
flex-shrink: 0;
cursor: pointer;
}
.toggle-switch input {
display: none;
}
.toggle-track {
display: block;
width: 40px;
height: 22px;
background: #334155;
border-radius: 11px;
position: relative;
transition: background 0.25s;
}
.toggle-switch input:checked + .toggle-track {
background: var(--accent);
}
.toggle-thumb {
position: absolute;
top: 3px;
left: 3px;
width: 16px;
height: 16px;
background: #fff;
border-radius: 50%;
transition: transform 0.25s cubic-bezier(0.34, 1.2, 0.64, 1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.toggle-switch input:checked + .toggle-track .toggle-thumb {
transform: translateX(18px);
}
/* ── Appearance ── */
.radio-group {
display: flex;
gap: 0.625rem;
flex-wrap: wrap;
}
.radio-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.875rem;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 8px;
cursor: pointer;
transition: border-color 0.15s, background 0.15s;
}
.radio-item:has(input:checked) {
border-color: rgba(56, 189, 248, 0.4);
background: rgba(56, 189, 248, 0.06);
}
.radio-item input {
display: none;
}
.radio-box {
width: 14px;
height: 14px;
border: 2px solid #475569;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: border-color 0.15s;
flex-shrink: 0;
}
.radio-item:has(input:checked) .radio-box {
border-color: var(--accent);
}
.radio-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
opacity: 0;
transform: scale(0);
transition: opacity 0.15s, transform 0.2s;
}
.radio-item:has(input:checked) .radio-dot {
opacity: 1;
transform: scale(1);
}
.radio-text {
font-size: 0.8125rem;
color: #cbd5e1;
}
.swatch-group {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.swatch {
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
transition: transform 0.15s, box-shadow 0.15s;
}
.swatch:hover {
transform: scale(1.15);
}
.swatch.active {
border-color: #fff;
box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
}
.font-size-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.font-size-val {
font-size: 0.8rem;
font-weight: 600;
color: var(--accent);
}
.range-input {
width: 100%;
-webkit-appearance: none;
appearance: none;
height: 4px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
outline: none;
cursor: pointer;
accent-color: var(--accent);
}
.range-input::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
border-radius: 50%;
background: var(--accent);
cursor: pointer;
box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.2);
}
.range-ticks {
display: flex;
justify-content: space-between;
font-size: 0.65rem;
color: #475569;
margin-top: 0.25rem;
}
/* ── Security ── */
.security-section {
display: flex;
flex-direction: column;
gap: 0.875rem;
}
.security-section-title {
font-size: 0.875rem;
font-weight: 600;
color: var(--text);
}
.security-divider {
height: 1px;
background: var(--border);
}
.security-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
}
.security-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
}
.security-2fa-right {
display: flex;
align-items: center;
gap: 0.625rem;
flex-shrink: 0;
}
.badge-2fa {
font-size: 0.65rem;
font-weight: 700;
padding: 2px 8px;
border-radius: 20px;
background: rgba(148, 163, 184, 0.1);
color: #64748b;
transition: background 0.2s, color 0.2s;
}
.badge-2fa.enabled {
background: rgba(52, 211, 153, 0.12);
color: #34d399;
}
.session-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.session-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.02);
border: 1px solid var(--border);
border-radius: 8px;
}
.session-icon {
width: 32px;
height: 32px;
background: rgba(255, 255, 255, 0.05);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: var(--muted);
flex-shrink: 0;
}
.session-details {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.session-device {
font-size: 0.8rem;
font-weight: 500;
color: #e2e8f0;
}
.session-meta {
font-size: 0.7rem;
color: #64748b;
}
.session-current {
font-size: 0.65rem;
font-weight: 600;
background: rgba(56, 189, 248, 0.12);
color: var(--accent);
padding: 2px 8px;
border-radius: 20px;
}
.session-revoke {
background: transparent;
border: 1px solid rgba(239, 68, 68, 0.2);
color: #f87171;
border-radius: 6px;
padding: 0.25rem 0.625rem;
font-size: 0.72rem;
font-weight: 500;
cursor: pointer;
transition: background 0.15s;
}
.session-revoke:hover {
background: rgba(239, 68, 68, 0.1);
}
@media (max-width: 480px) {
:root {
--panel-width: 100vw;
}
}
@media (prefers-reduced-motion: reduce) {
.settings-panel,
.panel-backdrop,
.toggle-track,
.toggle-thumb,
.swatch,
.radio-dot {
transition: none !important;
}
}(() => {
const panel = document.getElementById("settingsPanel");
const backdrop = document.getElementById("panelBackdrop");
const openBtn = document.getElementById("openBtn");
const closeBtn = document.getElementById("closeBtn");
// ── Open / Close ──
function openPanel() {
panel.classList.add("open");
backdrop.classList.add("active");
document.body.style.overflow = "hidden";
}
function closePanel() {
panel.classList.remove("open");
backdrop.classList.remove("active");
document.body.style.overflow = "";
}
openBtn.addEventListener("click", openPanel);
closeBtn.addEventListener("click", closePanel);
backdrop.addEventListener("click", closePanel);
// Trap Escape key
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && panel.classList.contains("open")) closePanel();
});
// ── Tab switching ──
const tabBtns = document.querySelectorAll(".tab-btn");
const tabPanels = document.querySelectorAll(".tab-panel");
tabBtns.forEach((btn) => {
btn.addEventListener("click", () => {
tabBtns.forEach((b) => b.classList.remove("active"));
tabPanels.forEach((p) => p.classList.remove("active"));
btn.classList.add("active");
const target = document.getElementById(`tab-${btn.dataset.tab}`);
if (target) target.classList.add("active");
});
});
// ── Profile: save ──
const saveProfileBtn = document.getElementById("saveProfileBtn");
const saveSuccess = document.getElementById("saveSuccess");
let saveTimer = null;
saveProfileBtn.addEventListener("click", () => {
clearTimeout(saveTimer);
saveSuccess.classList.add("visible");
saveProfileBtn.disabled = true;
saveProfileBtn.textContent = "Saving…";
saveTimer = setTimeout(() => {
saveSuccess.classList.remove("visible");
saveProfileBtn.disabled = false;
saveProfileBtn.textContent = "Save Changes";
}, 3000);
});
// ── Appearance: accent color swatches ──
const swatches = document.querySelectorAll(".swatch");
swatches.forEach((swatch) => {
swatch.addEventListener("click", () => {
swatches.forEach((s) => s.classList.remove("active"));
swatch.classList.add("active");
const color = swatch.dataset.color;
document.documentElement.style.setProperty("--accent", color);
});
});
// ── Appearance: font size slider ──
const fontSizeRange = document.getElementById("fontSizeRange");
const fontSizeVal = document.getElementById("fontSizeVal");
if (fontSizeRange) {
fontSizeRange.addEventListener("input", () => {
fontSizeVal.textContent = `${fontSizeRange.value}px`;
});
}
// ── Security: 2FA toggle ──
const toggle2fa = document.getElementById("toggle2fa");
const badge2fa = document.getElementById("badge2fa");
if (toggle2fa) {
toggle2fa.addEventListener("change", () => {
if (toggle2fa.checked) {
badge2fa.textContent = "Enabled";
badge2fa.classList.add("enabled");
} else {
badge2fa.textContent = "Disabled";
badge2fa.classList.remove("enabled");
}
});
}
// ── Security: session revoke ──
document.querySelectorAll(".session-revoke").forEach((btn) => {
btn.addEventListener("click", () => {
const item = btn.closest(".session-item");
if (item) {
item.style.transition = "opacity 0.3s, transform 0.3s";
item.style.opacity = "0";
item.style.transform = "translateX(12px)";
setTimeout(() => item.remove(), 320);
}
});
});
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Settings Panel</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- Main page -->
<div class="page-center">
<div class="page-card">
<div class="page-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#38bdf8" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
</svg>
</div>
<h2 class="page-title">Account Settings</h2>
<p class="page-desc">Manage your profile, notifications, appearance preferences, and security options.</p>
<button class="open-btn" id="openBtn">Open Settings</button>
</div>
</div>
<!-- Backdrop -->
<div class="panel-backdrop" id="panelBackdrop"></div>
<!-- Settings Panel -->
<div class="settings-panel" id="settingsPanel" role="dialog" aria-modal="true" aria-label="Settings">
<div class="panel-header">
<h2 class="panel-title">Settings</h2>
<button class="panel-close" id="closeBtn" aria-label="Close settings">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
<!-- Tabs -->
<div class="panel-tabs" role="tablist">
<button class="tab-btn active" data-tab="profile" role="tab">Profile</button>
<button class="tab-btn" data-tab="notifications" role="tab">Notifications</button>
<button class="tab-btn" data-tab="appearance" role="tab">Appearance</button>
<button class="tab-btn" data-tab="security" role="tab">Security</button>
</div>
<div class="panel-content">
<!-- ── Profile Tab ── -->
<div class="tab-panel active" id="tab-profile">
<div class="avatar-section">
<div class="avatar-circle" id="avatarCircle">AC</div>
<div class="avatar-info">
<button class="avatar-upload-btn">Change Avatar</button>
<span class="avatar-hint">JPG, PNG or GIF — max 2MB</span>
</div>
</div>
<div class="form-group">
<label class="form-label" for="nameInput">Full Name</label>
<input class="form-input" id="nameInput" type="text" value="Alex Chen" />
</div>
<div class="form-group">
<label class="form-label" for="emailInput">Email</label>
<input class="form-input" id="emailInput" type="email" value="alex.chen@company.io" />
</div>
<div class="form-group">
<label class="form-label" for="bioInput">Bio</label>
<textarea class="form-input form-textarea" id="bioInput" rows="3" placeholder="Write a short bio…">Product designer and developer. Building things at the intersection of design and code.</textarea>
</div>
<div class="form-actions">
<button class="btn-primary" id="saveProfileBtn">Save Changes</button>
<div class="save-success" id="saveSuccess">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#34d399" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
Profile saved successfully
</div>
</div>
</div>
<!-- ── Notifications Tab ── -->
<div class="tab-panel" id="tab-notifications">
<p class="section-desc">Choose which events you want to be notified about.</p>
<ul class="toggle-list">
<li class="toggle-row">
<div class="toggle-info">
<span class="toggle-label">Email Alerts</span>
<span class="toggle-desc">Receive important account alerts via email</span>
</div>
<label class="toggle-switch">
<input type="checkbox" checked />
<span class="toggle-track"><span class="toggle-thumb"></span></span>
</label>
</li>
<li class="toggle-row">
<div class="toggle-info">
<span class="toggle-label">Push Notifications</span>
<span class="toggle-desc">Browser push notifications for real-time events</span>
</div>
<label class="toggle-switch">
<input type="checkbox" checked />
<span class="toggle-track"><span class="toggle-thumb"></span></span>
</label>
</li>
<li class="toggle-row">
<div class="toggle-info">
<span class="toggle-label">Weekly Report</span>
<span class="toggle-desc">Summary of your activity every Monday</span>
</div>
<label class="toggle-switch">
<input type="checkbox" />
<span class="toggle-track"><span class="toggle-thumb"></span></span>
</label>
</li>
<li class="toggle-row">
<div class="toggle-info">
<span class="toggle-label">Marketing Emails</span>
<span class="toggle-desc">Product updates, tips, and special offers</span>
</div>
<label class="toggle-switch">
<input type="checkbox" />
<span class="toggle-track"><span class="toggle-thumb"></span></span>
</label>
</li>
</ul>
</div>
<!-- ── Appearance Tab ── -->
<div class="tab-panel" id="tab-appearance">
<div class="form-group">
<label class="form-label">Theme</label>
<div class="radio-group">
<label class="radio-item">
<input type="radio" name="theme" value="dark" checked />
<span class="radio-box">
<span class="radio-dot"></span>
</span>
<span class="radio-text">Dark</span>
</label>
<label class="radio-item">
<input type="radio" name="theme" value="light" />
<span class="radio-box"><span class="radio-dot"></span></span>
<span class="radio-text">Light</span>
</label>
<label class="radio-item">
<input type="radio" name="theme" value="system" />
<span class="radio-box"><span class="radio-dot"></span></span>
<span class="radio-text">System</span>
</label>
</div>
</div>
<div class="form-group">
<label class="form-label">Accent Color</label>
<div class="swatch-group">
<button class="swatch active" data-color="#38bdf8" style="background:#38bdf8" title="Sky Blue"></button>
<button class="swatch" data-color="#a78bfa" style="background:#a78bfa" title="Violet"></button>
<button class="swatch" data-color="#34d399" style="background:#34d399" title="Emerald"></button>
<button class="swatch" data-color="#f472b6" style="background:#f472b6" title="Pink"></button>
<button class="swatch" data-color="#fb923c" style="background:#fb923c" title="Orange"></button>
<button class="swatch" data-color="#facc15" style="background:#facc15" title="Yellow"></button>
</div>
</div>
<div class="form-group">
<div class="font-size-header">
<label class="form-label" for="fontSizeRange">Font Size</label>
<span class="font-size-val" id="fontSizeVal">14px</span>
</div>
<input class="range-input" id="fontSizeRange" type="range" min="12" max="18" value="14" step="1" />
<div class="range-ticks">
<span>12</span><span>14</span><span>16</span><span>18</span>
</div>
</div>
</div>
<!-- ── Security Tab ── -->
<div class="tab-panel" id="tab-security">
<div class="security-section">
<h3 class="security-section-title">Change Password</h3>
<div class="form-group">
<label class="form-label" for="currentPass">Current Password</label>
<input class="form-input" id="currentPass" type="password" placeholder="••••••••" />
</div>
<div class="form-group">
<label class="form-label" for="newPass">New Password</label>
<input class="form-input" id="newPass" type="password" placeholder="Min. 8 characters" />
</div>
<div class="form-group">
<label class="form-label" for="confirmPass">Confirm New Password</label>
<input class="form-input" id="confirmPass" type="password" placeholder="Repeat new password" />
</div>
<button class="btn-primary btn-sm">Update Password</button>
</div>
<div class="security-divider"></div>
<div class="security-section">
<div class="security-row">
<div class="security-info">
<h3 class="security-section-title">Two-Factor Authentication</h3>
<p class="toggle-desc">Add an extra layer of security to your account</p>
</div>
<div class="security-2fa-right">
<span class="badge-2fa" id="badge2fa">Disabled</span>
<label class="toggle-switch">
<input type="checkbox" id="toggle2fa" />
<span class="toggle-track"><span class="toggle-thumb"></span></span>
</label>
</div>
</div>
</div>
<div class="security-divider"></div>
<div class="security-section">
<h3 class="security-section-title">Active Sessions</h3>
<ul class="session-list">
<li class="session-item">
<div class="session-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>
</svg>
</div>
<div class="session-details">
<span class="session-device">MacBook Pro — Chrome 122</span>
<span class="session-meta">San Francisco, CA · Active now</span>
</div>
<span class="session-current">Current</span>
</li>
<li class="session-item">
<div class="session-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="5" y="2" width="14" height="20" rx="2"/><line x1="12" y1="18" x2="12.01" y2="18"/>
</svg>
</div>
<div class="session-details">
<span class="session-device">iPhone 15 — Safari</span>
<span class="session-meta">New York, NY · 2 hours ago</span>
</div>
<button class="session-revoke">Revoke</button>
</li>
</ul>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>Settings Panel
A polished slide-in drawer panel with four tabbed sections: Profile, Notifications, Appearance, and Security. Opens from the right with a smooth slide transition and a dimming backdrop. Each section contains realistic form controls tailored to its context.
Features
- Smooth slide-in from right (400px) with backdrop overlay
- Four tabs: Profile (avatar + form fields), Notifications (toggle switches), Appearance (theme + accent + font), Security (password + 2FA + sessions)
- Toggle switches with smooth CSS animation
- Profile save shows an inline success confirmation
- Accent color swatch selection updates a CSS variable accent preview