HTML
<div class="tg-perm">
<label class="tg-perm-item">
<input class="tg-perm-input" type="checkbox" checked>
<svg class="tg-perm-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/>
<circle cx="12" cy="10" r="3"/>
</svg>
<span class="tg-perm-info">
<span class="tg-perm-name">Location</span>
<span class="tg-perm-desc">While using the app</span>
</span>
<span class="tg-perm-pill" aria-hidden="true">
<span class="tg-perm-thumb"></span>
</span>
</label>
<label class="tg-perm-item">
<input class="tg-perm-input" type="checkbox">
<svg class="tg-perm-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M23 7l-7 5 7 5V7z"/>
<rect x="1" y="5" width="15" height="14" rx="2"/>
</svg>
<span class="tg-perm-info">
<span class="tg-perm-name">Camera</span>
<span class="tg-perm-desc">Photos and video</span>
</span>
<span class="tg-perm-pill" aria-hidden="true">
<span class="tg-perm-thumb"></span>
</span>
</label>
<label class="tg-perm-item">
<input class="tg-perm-input" type="checkbox" checked>
<svg class="tg-perm-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<rect x="9" y="2" width="6" height="12" rx="3"/>
<path d="M19 10a7 7 0 0 1-14 0"/>
<path d="M12 18v3"/>
</svg>
<span class="tg-perm-info">
<span class="tg-perm-name">Microphone</span>
<span class="tg-perm-desc">Voice input</span>
</span>
<span class="tg-perm-pill" aria-hidden="true">
<span class="tg-perm-thumb"></span>
</span>
</label>
<label class="tg-perm-item">
<input class="tg-perm-input" type="checkbox">
<svg class="tg-perm-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
<circle cx="9" cy="7" r="4"/>
<path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
</svg>
<span class="tg-perm-info">
<span class="tg-perm-name">Contacts</span>
<span class="tg-perm-desc">Read access only</span>
</span>
<span class="tg-perm-pill" aria-hidden="true">
<span class="tg-perm-thumb"></span>
</span>
</label>
</div> CSS
.tg-perm {
--tg-perm-bg: #08080f;
--tg-perm-rim: #14141e;
--tg-perm-wire: #1e1e2e;
--tg-perm-fog: #3a3a52;
--tg-perm-ash: #7a7a98;
--tg-perm-snow: #f0f0fa;
--tg-perm-volt: #e0ff00;
--tg-perm-void: #04040a;
display: flex;
flex-direction: column;
gap: 0;
width: 280px;
font-family: "Inter", "Segoe UI", system-ui, sans-serif;
}
.tg-perm-item {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 16px;
border: 1px solid var(--tg-perm-wire);
margin-top: -1px;
background: var(--tg-perm-bg);
cursor: pointer;
transition: background 0.2s ease;
}
.tg-perm-item:first-child { border-radius: 12px 12px 0 0; }
.tg-perm-item:last-child { border-radius: 0 0 12px 12px; }
.tg-perm-item:hover { background: var(--tg-perm-rim); }
.tg-perm-input {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden; clip: rect(0,0,0,0);
white-space: nowrap; border: 0;
}
.tg-perm-icon {
width: 18px;
height: 18px;
flex-shrink: 0;
color: var(--tg-perm-ash);
opacity: 0.4;
transition: opacity 0.3s ease, color 0.3s ease;
}
.tg-perm-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.tg-perm-name {
font-size: 13px;
letter-spacing: 0.02em;
color: var(--tg-perm-snow);
opacity: 0.5;
transition: opacity 0.3s ease;
}
.tg-perm-desc {
font-size: 11px;
color: var(--tg-perm-ash);
}
/* Mini pill toggle on the right of each row. */
.tg-perm-pill {
position: relative;
width: 38px;
height: 20px;
flex-shrink: 0;
border-radius: 10px;
background: var(--tg-perm-wire);
border: 1px solid var(--tg-perm-fog);
transition: background 0.3s ease, border-color 0.3s ease;
}
.tg-perm-thumb {
position: absolute;
top: 2px;
left: 2px;
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--tg-perm-fog);
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1), background 0.3s ease;
}
.tg-perm-input:checked ~ .tg-perm-icon { opacity: 1; color: var(--tg-perm-volt); }
.tg-perm-input:checked ~ .tg-perm-info .tg-perm-name { opacity: 1; }
.tg-perm-input:checked ~ .tg-perm-pill {
background: var(--tg-perm-volt);
border-color: var(--tg-perm-volt);
}
.tg-perm-input:checked ~ .tg-perm-pill .tg-perm-thumb {
transform: translateX(18px);
background: var(--tg-perm-void);
}
.tg-perm-input:focus-visible ~ .tg-perm-pill {
outline: 2px solid var(--tg-perm-volt);
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.tg-perm-item,
.tg-perm-icon,
.tg-perm-name,
.tg-perm-pill,
.tg-perm-thumb { transition: none; }
}