Ctrl K
ComunidadGuías…

mockups/account_settings.html

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Account settings — Cloudzilla</title>
<link rel="stylesheet" href="/assets/tailwind.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500&family=Geist:wght@400;500;600&display=swap" rel="stylesheet" />
</head>
<body class="min-h-screen flex flex-col antialiased font-sans">

<a href="#main-content" class="skip-link">Skip to main content</a>

<div id="cz-header" data-account-tab="settings"></div>
<script src="shell.js"></script>

<main id="main-content" tabindex="-1" class="max-w-[1400px] mx-auto px-6 pt-6 pb-20 flex-1 w-full">
  <section class="mb-8" aria-labelledby="settings-title">
    <h1 id="settings-title" class="text-2xl font-semibold tracking-tight">Account settings</h1>
    <p class="mt-1 text-[13px] text-muted-foreground">Profile, appearance, security, access tokens, OAuth apps, notifications, and saved replies.</p>
  </section>

  <div class="grid grid-cols-12 gap-8">
    <aside class="col-span-12 lg:col-span-3" aria-label="Settings sections">
      <nav class="lg:sticky lg:top-4 flex flex-col gap-0.5 text-[13px]">
        <a href="#profile" class="block px-3 py-1.5 rounded-sm bg-accent text-foreground font-medium">Profile</a>
        <a href="#appearance" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Appearance</a>
        <a href="#security" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Security</a>
        <a href="#ssh-keys" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">SSH keys</a>
        <a href="#tokens" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Access tokens</a>
        <a href="#oauth-apps" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">OAuth apps</a>
        <a href="#notifications" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Notifications</a>
        <a href="#saved-replies" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Saved replies</a>
        <a href="#sessions" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Sessions</a>
        <a href="#email" class="block px-3 py-1.5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent">Email</a>
        <p class="font-mono text-[10px] uppercase tracking-wider mt-4 mb-1 px-2.5 text-muted-foreground">Danger zone</p>
        <a href="#delete" class="block px-3 py-1.5 rounded-sm text-[13px] text-destructive hover:bg-destructive/10">Delete account</a>
      </nav>
    </aside>

    <div class="col-span-12 lg:col-span-9 space-y-8">

      <section id="profile" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <h2 class="text-base font-semibold tracking-tight mb-1">Profile</h2>
        <p class="mb-1 text-[12.5px] text-muted-foreground">How others see you across Cloudzilla.</p>
        <p id="quota-usage" class="text-[12.5px] text-muted-foreground mb-6">Using 412 MB of your 5 GB storage quota.</p>
        <div class="mb-5">
          <div class="flex items-start gap-4" data-avatar-control>
            <span class="inline-grid place-items-center rounded-full bg-muted border border-border font-medium text-muted-foreground h-16 w-16 text-base" role="img" aria-label="mkappworks">M</span>
            <div class="flex flex-col gap-2 min-w-0">
              <div class="flex flex-wrap items-center gap-2">
                <form onsubmit="return false">
                  <input id="avatar-form-error-file" type="file" name="avatar" accept="image/png,image/jpeg,image/gif,image/webp" class="peer sr-only"/>
                  <label for="avatar-form-error-file" class="inline-flex items-center h-8 px-3 text-[13px] rounded-md border border-border bg-card hover:bg-accent cursor-pointer peer-focus-visible:ring-2 peer-focus-visible:ring-ring">Upload new picture</label>
                </form>
              </div>
              <p class="text-[11.5px] text-muted-foreground">PNG, JPEG, GIF or WebP, max 2 MB.</p>
              <div id="avatar-form-error" data-avatar-error class="empty:hidden"></div>
            </div>
          </div>
        </div>
        <form onsubmit="return false" class="space-y-5" data-toast="Profile saved">
          <div id="profile-form-error" class="empty:hidden"></div>
          <div>
            <label for="acct-name" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Name</label>
            <input id="acct-name" name="name" type="text" value="Malith Kuruppu" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="acct-username" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Username</label>
            <input id="acct-username" type="text" value="mkappworks" readonly class="w-full bg-muted/50 border border-border rounded-md px-3 py-2 text-[13px] font-mono text-muted-foreground focus:outline-hidden"/>
            <p class="mt-1 text-[11.5px] text-muted-foreground">Usernames can't be changed.</p>
          </div>
          <div>
            <label for="acct-email" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Email</label>
            <input id="acct-email" name="email" type="email" value="info.mkappworks@gmail.com" required class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] font-mono text-foreground focus:outline-hidden focus:border-ring"/>
            <p class="mt-1 text-[11.5px] text-muted-foreground">Used for sign-in and notifications. A new address has to be verified again.</p>
            <div id="email-confirm" hidden class="mt-3 flex flex-wrap items-end gap-3">
              <div class="min-w-0">
                <label for="email-change-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
                <input id="email-change-password" name="password" type="password" autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
              </div>
              <p class="basis-full text-[11.5px] text-muted-foreground">Changing your email needs your password.</p>
            </div>
          </div>
          <div>
            <label for="acct-bio" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Bio</label>
            <textarea id="acct-bio" name="bio" rows="3" placeholder="A short description of yourself" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring">Building Cloudzilla, a self-hosted Git forge. Go, HTMX and too much Tailwind.</textarea>
          </div>
          <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
            <div>
              <label for="acct-company" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Company</label>
              <input id="acct-company" name="company" type="text" value="Benchlabs" placeholder="Company or @organization" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            </div>
            <div>
              <label for="acct-location" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Location</label>
              <input id="acct-location" name="location" type="text" value="Colombo, Sri Lanka" placeholder="City, Country" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            </div>
          </div>
          <div class="flex items-center justify-end gap-2">
            <button type="reset" class="h-9 px-4 text-sm rounded-md border border-border hover:bg-muted text-foreground">Cancel</button>
            <button type="submit" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90">Save profile</button>
          </div>
        </form>
      </section>

      <section id="appearance" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <h2 class="text-base font-semibold tracking-tight mb-1">Appearance</h2>
        <p class="text-[12.5px] text-muted-foreground mb-6">Colors for code in files, diffs and Markdown. The preview follows the site theme; toggle it to preview the other mode. Changes save automatically.</p>
        <form onsubmit="return false">
          <div class="flex items-center justify-between gap-4 py-3 border-b border-border last:border-b-0">
            <label for="code_theme_light" class="block text-sm font-medium text-foreground">Light mode code theme</label>
            <div class="w-52 shrink-0">
              <div class="relative">
                <select id="code_theme_light" name="code_theme_light" class="appearance-none flex h-9 w-full rounded-md border border-input bg-transparent pl-3 pr-8 py-1 text-sm shadow-xs">
                  <option value="github-light" selected>GitHub Light</option><option value="solarized-light">Solarized Light</option><option value="catppuccin-latte">Catppuccin Latte</option>
                </select>
                <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M7 10l5 5 5-5"></path></svg>
              </div>
            </div>
          </div>
          <div class="flex items-center justify-between gap-4 py-3 border-b border-border last:border-b-0">
            <label for="code_theme_dark" class="block text-sm font-medium text-foreground">Dark mode code theme</label>
            <div class="w-52 shrink-0">
              <div class="relative">
                <select id="code_theme_dark" name="code_theme_dark" class="appearance-none flex h-9 w-full rounded-md border border-input bg-transparent pl-3 pr-8 py-1 text-sm shadow-xs">
                  <option value="github-dark" selected>GitHub Dark</option><option value="solarized-dark">Solarized Dark</option><option value="catppuccin-mocha">Catppuccin Mocha</option>
                </select>
                <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M7 10l5 5 5-5"></path></svg>
              </div>
            </div>
          </div>
        </form>
        <pre class="hl mt-4 rounded-md border border-border px-4 py-3 font-mono text-[12.5px] leading-[1.6] overflow-x-auto"><code><span class="text-muted-foreground">// Preview</span>
<span class="text-[hsl(270_70%_70%)]">func</span> <span class="text-primary">Greet</span>(name <span class="text-warning">string</span>) <span class="text-warning">string</span> {
    <span class="text-[hsl(270_70%_70%)]">return</span> <span class="text-success">"hello, "</span> + name
}</code></pre>
      </section>

      <section id="security" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <h2 class="text-base font-semibold tracking-tight mb-1">Security</h2>
        <p class="text-[12.5px] text-muted-foreground mb-6">Password, two-factor authentication, and connected accounts.</p>
        <ul class="divide-y divide-border">
          <li id="password" class="py-4 scroll-mt-6">
            <div class="flex items-start justify-between gap-4">
              <div class="min-w-0">
                <p class="text-[13.5px] font-medium">Password</p>
                <p class="mt-0.5 text-[12.5px] text-muted-foreground">Changing it signs out every session, so anyone else who knows the old one is signed out too.</p>
              </div>
              <button type="button" data-open="change-password-dialog" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-foreground shrink-0">Change password</button>
            </div>
          </li>
          <li class="py-4">
            <div class="flex items-start justify-between gap-4">
              <div class="min-w-0">
                <p class="text-[13.5px] font-medium inline-flex items-center gap-2">
                  Two-factor authentication
                  <span id="totp-badge" class="text-[10px] px-1.5 py-0.5 rounded-full border border-border bg-muted text-muted-foreground">Disabled</span>
                </p>
                <p class="mt-0.5 text-[12.5px] text-muted-foreground">TOTP via authenticator app (Google Authenticator, 1Password, Authy).</p>
              </div>
            </div>
            <form id="totp-setup" onsubmit="return false" class="mt-3">
              <button type="button" id="totp-start" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-foreground">Set up 2FA</button>
            </form>
            <div id="totp-pending" hidden class="mt-4 space-y-4">
              <div class="flex gap-6 items-start">
                <div class="shrink-0 border border-border rounded-md w-[160px] h-[160px] grid place-items-center text-[11px] text-muted-foreground">QR code</div>
                <div class="flex-1 min-w-0">
                  <p class="text-[12.5px] font-medium mb-1">Or enter this key manually</p>
                  <code class="block bg-muted border border-border rounded-sm px-3 py-2 text-[12.5px] font-mono tracking-widest break-all text-foreground">JBSWY3DPEHPK3PXP4GRQ7ZKM</code>
                </div>
              </div>
              <form id="totp-enable" onsubmit="return false" class="flex flex-wrap items-end gap-3">
                <div class="min-w-0">
                  <label for="totp-enable-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
                  <input id="totp-enable-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
                </div>
                <div>
                  <label for="totp-enable-code" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Enter the 6-digit code from your app</label>
                  <input id="totp-enable-code" name="code" type="text" inputmode="numeric" pattern="[0-9]*" maxlength="6" required autocomplete="one-time-code" placeholder="000000" class="w-32 font-mono text-center text-base bg-background border border-border rounded-md px-3 py-2 text-foreground focus:outline-hidden focus:border-ring"/>
                </div>
                <button type="submit" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90">Verify &amp; enable</button>
              </form>
            </div>
            <form id="totp-disable" hidden onsubmit="return false" class="mt-4 flex flex-wrap items-end gap-3">
              <div class="min-w-0">
                <label for="totp-disable-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
                <input id="totp-disable-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
              </div>
              <div>
                <label for="totp-disable-code" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Verification code</label>
                <input id="totp-disable-code" name="code" type="text" inputmode="numeric" pattern="[0-9]*" maxlength="6" required autocomplete="one-time-code" placeholder="000000" class="w-32 font-mono text-center text-base bg-background border border-border rounded-md px-3 py-2 text-foreground focus:outline-hidden focus:border-ring"/>
              </div>
              <button type="submit" class="h-9 px-4 text-sm rounded-md border border-destructive/40 text-destructive hover:bg-destructive/10">Disable 2FA</button>
            </form>
          </li>
        </ul>

        <div id="connected-accounts" class="mt-2 pt-6 border-t border-border scroll-mt-6">
          <h3 class="text-[13.5px] font-semibold tracking-tight mb-1">Connected accounts</h3>
          <p class="text-[12.5px] text-muted-foreground mb-4">Sign in with an account you have elsewhere. Connect it here, or sign in with a Google account whose verified address matches this account's verified email.</p>
          <div class="flex items-start gap-3">
            <span class="h-8 w-8 shrink-0 grid place-items-center rounded-md border border-border bg-background">
              <svg class="h-4 w-4" viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.27-4.74 3.27-8.1z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84A11 11 0 0012 23z"/><path fill="#FBBC05" d="M5.84 14.09a6.6 6.6 0 010-4.18V7.07H2.18a11 11 0 000 9.86l3.66-2.84z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1A11 11 0 002.18 7.07l3.66 2.84C6.71 7.31 9.14 5.38 12 5.38z"/></svg>
            </span>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium inline-flex items-center gap-2">
                Google
                <span class="text-[10px] px-1.5 py-0.5 rounded-full border border-border bg-muted text-muted-foreground">Not connected</span>
              </p>
              <p class="mt-0.5 text-[12.5px] text-muted-foreground">Confirm it's you, then choose the Google account to connect.</p>
              <form onsubmit="return false" class="mt-3 flex flex-wrap items-end gap-3">
                <div class="min-w-0">
                  <label for="google-connect-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
                  <input id="google-connect-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
                </div>
                <button type="submit" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90">Connect Google</button>
              </form>
            </div>
          </div>
        </div>
      </section>

      <section id="ssh-keys" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">SSH keys</h2>
            <p class="text-[12.5px] text-muted-foreground">Used for git push/pull over SSH.</p>
          </div>
          <button type="button" data-open="add-ssh-key-dialog" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 shrink-0">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12h14"></path></svg>
            Add SSH key
          </button>
        </div>
        <div id="ssh-keys-list" class="space-y-2 mb-4">
          <div class="flex items-center gap-3 border border-border rounded-md p-3">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground shrink-0" aria-hidden="true"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 11-7.778 7.778 5.5 5.5 0 017.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"></path></svg>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">MacBook Pro</p>
              <p class="text-[11.5px] text-muted-foreground font-mono break-all">SHA256:Zk1p7vQ3nXh0e9LwYb2sAq5cT8uRfJdM4oGiNxVa6Hw</p>
              <p class="text-[11.5px] text-muted-foreground mt-0.5">Added <time datetime="2026-01-14T00:00:00Z">Jan 14, 2026</time></p>
            </div>
            <button type="button" data-remove data-confirm-title="Remove this SSH key?" data-confirm-label="Remove" data-confirm-msg="The MacBook Pro key will immediately lose access. Any system using it for git operations will stop working." data-toast="SSH key removed" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Remove</button>
          </div>
          <div class="flex items-center gap-3 border border-border rounded-md p-3">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground shrink-0" aria-hidden="true"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 11-7.778 7.778 5.5 5.5 0 017.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"></path></svg>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">CI deploy key</p>
              <p class="text-[11.5px] text-muted-foreground font-mono break-all">SHA256:Hq8dLw2mTz9yPb4XvNe1sCk7uRgJfA5oIiVx3MaYt0E</p>
              <p class="text-[11.5px] text-muted-foreground mt-0.5">Added <time datetime="2026-03-02T00:00:00Z">Mar 2, 2026</time></p>
            </div>
            <button type="button" data-remove data-confirm-title="Remove this SSH key?" data-confirm-label="Remove" data-confirm-msg="The CI deploy key key will immediately lose access. Any system using it for git operations will stop working." data-toast="SSH key removed" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Remove</button>
          </div>
        </div>
      </section>

      <section id="tokens" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">Personal access tokens</h2>
            <p class="text-[12.5px] text-muted-foreground">For scripts and integrations that need to act on your behalf.</p>
          </div>
          <button type="button" data-open="generate-token-dialog" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 shrink-0">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12h14"></path></svg>
            Generate token
          </button>
        </div>
        <div id="tokens-list" class="space-y-2 mb-4">
          <div class="flex items-center gap-3 border border-border rounded-md p-3">
            <span role="img" class="h-2 w-2 rounded-full bg-success shrink-0" aria-label="Active"></span>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">CI deploy</p>
              <p class="text-[12px] text-muted-foreground">scopes: <span class="font-mono">repo:read</span>, <span class="font-mono">repo:write</span> · expires <time datetime="2026-12-01T00:00:00Z">Dec 1, 2026</time></p>
            </div>
            <span class="text-[11px] text-muted-foreground font-mono">…a91f03bc</span>
            <button type="button" data-remove data-confirm-title="Revoke this token?" data-confirm-label="Revoke" data-confirm-msg="The CI deploy token will immediately lose access. Any script or integration using it will stop working." data-toast="Token revoked" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Revoke</button>
          </div>
          <div class="flex items-center gap-3 border border-border rounded-md p-3">
            <span role="img" class="h-2 w-2 rounded-full bg-success shrink-0" aria-label="Active"></span>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">cz CLI</p>
              <p class="text-[12px] text-muted-foreground">scopes: <span class="font-mono">repo:read</span>, <span class="font-mono">issues:write</span>, <span class="font-mono">pulls:write</span> · no expiry</p>
            </div>
            <span class="text-[11px] text-muted-foreground font-mono">…47d2e8f0</span>
            <button type="button" data-remove data-confirm-title="Revoke this token?" data-confirm-label="Revoke" data-confirm-msg="The cz CLI token will immediately lose access. Any script or integration using it will stop working." data-toast="Token revoked" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Revoke</button>
          </div>
        </div>
      </section>

      <section id="oauth-apps" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">OAuth applications</h2>
            <p class="text-[12.5px] text-muted-foreground">Applications you've registered to call the Cloudzilla API on behalf of other users.</p>
          </div>
          <button type="button" data-open="register-oauth-app-dialog" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 shrink-0">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12h14"></path></svg>
            Register app
          </button>
        </div>
        <div class="mb-6">
          <div id="oauth-apps-list" class="space-y-2">
            <div class="flex items-center gap-3 border border-border rounded-md p-3">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground shrink-0" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1"></rect><rect x="14" y="3" width="7" height="7" rx="1"></rect><rect x="3" y="14" width="7" height="7" rx="1"></rect><rect x="14" y="14" width="7" height="7" rx="1"></rect></svg>
              <div class="min-w-0 flex-1">
                <p class="text-[13.5px] font-medium">Deploy bot</p>
                <p class="text-[11.5px] text-muted-foreground font-mono break-all">Client ID: czo_5f2c9e1a7b3d4c68</p>
                <p class="text-[11.5px] text-muted-foreground font-mono break-all mt-0.5">Redirect: https://deploy.example.com/callback</p>
              </div>
              <button type="button" data-remove class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Delete</button>
            </div>
          </div>
        </div>
        <h3 class="text-[13.5px] font-medium mb-1">Authorized applications</h3>
        <p class="text-[12.5px] text-muted-foreground mb-3">Applications you've allowed to access your account.</p>
        <div id="oauth-authorizations-list" class="space-y-2">
          <div class="flex items-center gap-3 border border-border rounded-md p-3">
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">App ID <span class="font-mono">3</span></p>
              <p class="text-[12px] text-muted-foreground">scopes: <span class="font-mono">repo:read, issues:write</span></p>
            </div>
            <button type="button" data-remove class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive shrink-0">Revoke</button>
          </div>
        </div>
      </section>

      <section id="notifications" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <h2 class="text-base font-semibold tracking-tight mb-1">Notifications</h2>
        <p class="text-[12.5px] text-muted-foreground mb-6">How and when you hear about activity. Changes save automatically.</p>
        <form onsubmit="return false">
          <label class="flex items-start justify-between gap-4 py-3 border-b border-border last:border-b-0 cursor-pointer">
            <span class="min-w-0">
              <span class="block text-sm font-medium text-foreground">Email notifications</span>
              <span class="block text-xs text-muted-foreground mt-0.5">Send email when something happens that needs your attention.</span>
            </span>
            <span class="relative inline-flex h-5 w-9 shrink-0 items-center mt-0.5">
              <input type="checkbox" name="email_notifications" checked class="peer sr-only"/>
              <span class="absolute inset-0 rounded-full border border-border bg-muted transition-colors peer-checked:bg-success peer-checked:border-success"></span>
              <span class="absolute left-0.5 h-3.5 w-3.5 rounded-full bg-muted-foreground transition-transform peer-checked:bg-background peer-checked:translate-x-4"></span>
            </span>
          </label>
          <div class="flex items-start justify-between gap-4 py-3 border-b border-border last:border-b-0">
            <span class="min-w-0">
              <label for="email_digest" class="block text-sm font-medium text-foreground">Delivery</label>
              <span class="block text-xs text-muted-foreground mt-0.5">Send each email right away, or a digest of your unread notifications, watched repositories included, at 08:00 UTC (weekly on Mondays).</span>
            </span>
            <div class="w-40 shrink-0">
              <div class="relative">
                <select id="email_digest" name="email_digest" class="appearance-none flex h-9 w-full rounded-md border border-input bg-transparent pl-3 pr-8 py-1 text-sm shadow-xs">
                  <option value="immediate" selected>Immediately</option><option value="daily">Daily digest</option><option value="weekly">Weekly digest</option><option value="never">Never</option>
                </select>
                <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false"><path d="M7 10l5 5 5-5"></path></svg>
              </div>
            </div>
          </div>
          <label class="flex items-start justify-between gap-4 py-3 border-b border-border last:border-b-0 cursor-pointer">
            <span class="min-w-0">
              <span class="block text-sm font-medium text-foreground">Reviews on my pull requests</span>
              <span class="block text-xs text-muted-foreground mt-0.5">Email me when someone reviews a pull request I opened.</span>
            </span>
            <span class="relative inline-flex h-5 w-9 shrink-0 items-center mt-0.5">
              <input type="checkbox" name="notify_pr_review" checked class="peer sr-only"/>
              <span class="absolute inset-0 rounded-full border border-border bg-muted transition-colors peer-checked:bg-success peer-checked:border-success"></span>
              <span class="absolute left-0.5 h-3.5 w-3.5 rounded-full bg-muted-foreground transition-transform peer-checked:bg-background peer-checked:translate-x-4"></span>
            </span>
          </label>
          <label class="flex items-start justify-between gap-4 py-3 border-b border-border last:border-b-0 cursor-pointer">
            <span class="min-w-0">
              <span class="block text-sm font-medium text-foreground">Mentions in comments</span>
              <span class="block text-xs text-muted-foreground mt-0.5">Email me when someone @-mentions me in an issue or pull request comment.</span>
            </span>
            <span class="relative inline-flex h-5 w-9 shrink-0 items-center mt-0.5">
              <input type="checkbox" name="notify_mention" checked class="peer sr-only"/>
              <span class="absolute inset-0 rounded-full border border-border bg-muted transition-colors peer-checked:bg-success peer-checked:border-success"></span>
              <span class="absolute left-0.5 h-3.5 w-3.5 rounded-full bg-muted-foreground transition-transform peer-checked:bg-background peer-checked:translate-x-4"></span>
            </span>
          </label>
        </form>
      </section>

      <section id="saved-replies" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">Saved replies</h2>
            <p class="text-[12.5px] text-muted-foreground">Reusable snippets you can insert into issue and pull request comments.</p>
          </div>
          <button type="button" data-open="new-saved-reply-dialog" class="h-9 px-4 text-sm rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 shrink-0">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12h14"></path></svg>
            New reply
          </button>
        </div>
        <div id="saved-replies-list" class="space-y-2">
          <div class="border border-border rounded-md p-3" data-reply-id="1">
            <div class="flex items-start gap-3">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground shrink-0 mt-0.5" aria-hidden="true"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"></path></svg>
              <div class="min-w-0 flex-1">
                <p class="text-[13.5px] font-medium">Thanks for the report</p>
                <p class="mt-0.5 text-[12px] text-muted-foreground whitespace-pre-wrap break-words">Thanks for opening this. I can reproduce it on main and will follow up here once there's a fix.</p>
              </div>
              <div class="flex gap-2 shrink-0">
                <button type="button" data-edit class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-foreground">Edit</button>
                <button type="button" data-remove class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-destructive">Delete</button>
              </div>
            </div>
            <form onsubmit="return false" class="hidden mt-3 pt-3 border-t border-border space-y-3">
              <div>
                <label for="reply-title-1" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Title</label>
                <input id="reply-title-1" name="title" type="text" value="Thanks for the report" required class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
              </div>
              <div>
                <label for="reply-body-1" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Content</label>
                <textarea id="reply-body-1" name="body" rows="4" required class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring">Thanks for opening this. I can reproduce it on main and will follow up here once there's a fix.</textarea>
              </div>
              <div class="flex justify-end gap-2">
                <button type="button" data-cancel-edit class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-foreground">Cancel</button>
                <button type="submit" class="h-8 px-3 text-[13px] rounded-md font-medium bg-primary text-primary-foreground hover:bg-primary/90">Save</button>
              </div>
            </form>
          </div>
        </div>
      </section>

      <section id="sessions" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">Sessions</h2>
            <p class="text-[12.5px] text-muted-foreground">Browsers signed in to your account. Access tokens, SSH keys and authorized apps are revoked in their own sections.</p>
          </div>
          <form onsubmit="return false" class="shrink-0">
            <button type="submit" class="h-8 px-3 text-[13px] rounded-md border border-border hover:bg-muted text-foreground">Sign out other sessions</button>
          </form>
        </div>
        <ul class="divide-y divide-border">
          <li class="py-3 flex items-center gap-3">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground" aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2"></rect><path d="M8 21h8M12 17v4"></path></svg>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium">This browser <span class="ml-2 text-[10px] px-1.5 py-0.5 rounded-full border border-success/30 bg-success/15 text-success">Current</span></p>
              <p class="text-[12px] text-muted-foreground">Sign out to end this session. Other sessions can't be listed, only signed out together.</p>
            </div>
          </li>
        </ul>
      </section>

      <section id="email" class="border border-border rounded-lg bg-card p-6 scroll-mt-6">
        <div class="flex items-start justify-between gap-4 mb-6">
          <div class="min-w-0">
            <h2 class="text-base font-semibold tracking-tight mb-1">Email</h2>
            <p class="text-[12.5px] text-muted-foreground">Your address, and the author email on commits you make in the web UI.</p>
          </div>
          <span class="inline-flex items-center gap-2 shrink-0">
            <span class="text-[10px] font-normal px-1.5 py-0.5 rounded-full border border-border bg-muted text-muted-foreground">Coming soon</span>
            <button type="button" disabled class="h-8 px-3 text-[13px] rounded-md border border-border bg-card text-muted-foreground cursor-not-allowed shrink-0">Add email</button>
          </span>
        </div>
        <ul class="divide-y divide-border mb-4">
          <li class="py-3 flex items-center gap-3">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="text-muted-foreground" aria-hidden="true"><path d="M4 4h16v16H4z"></path><path d="M22 6l-10 7L2 6"></path></svg>
            <div class="min-w-0 flex-1">
              <p class="text-[13.5px] font-medium font-mono">info.mkappworks@gmail.com</p>
              <p class="text-[12px] text-muted-foreground">Used for sign-in and notifications.</p>
            </div>
            <span class="text-[10px] px-1.5 py-0.5 rounded-full border border-success/30 bg-success/15 text-success">Verified</span>
            <span class="text-[10px] px-1.5 py-0.5 rounded-full border border-success/30 bg-success/15 text-success">Primary</span>
          </li>
        </ul>
        <form onsubmit="return false" id="email-settings-form">
          <label class="flex items-start justify-between gap-4 py-3 border-t border-border cursor-pointer">
            <span class="min-w-0">
              <span class="block text-sm font-medium text-foreground">Keep my email address private</span>
              <span id="keep-email-private-help" class="block text-xs text-muted-foreground mt-0.5">
                File edits, wiki changes, merges, applied suggestions, and profile README edits are authored as
                <code class="text-[11px] bg-muted border border-border rounded-sm px-1.5 py-0.5 font-mono break-words">12@users.noreply.cloudzilla.example</code>
                instead of your account email. Commit authors are visible to anyone who can read the repository.
              </span>
            </span>
            <span class="relative inline-flex h-5 w-9 shrink-0 items-center mt-0.5">
              <input id="keep_email_private" type="checkbox" name="keep_email_private" aria-describedby="keep-email-private-help" class="peer sr-only"/>
              <span class="absolute inset-0 rounded-full border border-border bg-muted transition-colors peer-checked:bg-success peer-checked:border-success"></span>
              <span class="absolute left-0.5 h-3.5 w-3.5 rounded-full bg-muted-foreground transition-transform peer-checked:bg-background peer-checked:translate-x-4"></span>
            </span>
          </label>
        </form>
        <p class="text-[12px] text-muted-foreground mt-3">
          Commits you push keep the email your git client sets. To keep those private too, run
          <code class="mt-1.5 block w-fit max-w-full text-[11px] bg-muted border border-border rounded-sm px-1.5 py-0.5 font-mono break-words">git config --global user.email 12@users.noreply.cloudzilla.example</code>
        </p>
      </section>

      <section id="danger" class="border border-destructive/40 rounded-lg bg-card p-6 scroll-mt-6">
        <h2 class="text-base font-semibold tracking-tight mb-1 text-destructive">Danger zone</h2>
        <p class="text-[12.5px] text-muted-foreground mb-6">Irreversible. Clone any repositories you want to keep first.</p>
        <ul class="divide-y divide-border">
          <li id="export" class="py-4 flex items-start justify-between gap-4">
            <div class="min-w-0">
              <p class="text-[13.5px] font-medium inline-flex items-center gap-2">
                Export your data
                <span class="text-[10px] font-normal px-1.5 py-0.5 rounded-full border border-border bg-muted text-muted-foreground">Coming soon</span>
              </p>
              <p class="mt-0.5 text-[12.5px] text-muted-foreground">Download everything you've created on Cloudzilla as a zip.</p>
            </div>
            <button type="button" disabled class="h-8 px-3 text-[13px] rounded-md border border-border bg-card text-muted-foreground cursor-not-allowed shrink-0">Request export</button>
          </li>
          <li id="delete" class="py-4 flex items-start justify-between gap-4">
            <div class="min-w-0">
              <p class="text-[13.5px] font-medium">Delete account</p>
              <p class="mt-0.5 text-[12.5px] text-muted-foreground">Permanently remove your account, your repositories and their wikis, gists, and activity. Issues, comments and reviews you left in other people's repositories stay, credited to ghost. Organization repositories stay with their organization.</p>
            </div>
            <form method="POST" action="#" onsubmit="return confirm('Permanently delete @mkappworks? This cannot be undone.') && false" class="shrink-0 flex flex-wrap items-end gap-2">
              <div class="min-w-0">
                <label for="delete-account-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
                <input id="delete-account-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
              </div>
              <input type="text" name="confirm_username" placeholder="type your username" aria-label="Type your username to confirm" required autocomplete="off" class="h-8 w-44 bg-background border border-border rounded-md px-3 text-[12.5px] font-mono text-foreground focus:outline-hidden focus:border-ring"/>
              <button type="submit" class="h-8 px-3 text-[13px] rounded-md font-medium bg-destructive text-destructive-foreground hover:bg-destructive/90">Delete account</button>
            </form>
          </li>
        </ul>
      </section>

    </div>
  </div>

  <dialog id="change-password-dialog" aria-labelledby="change-password-dialog-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs">
    <form onsubmit="return false">
      <div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
        <h2 id="change-password-dialog-title" class="text-base font-semibold leading-tight">Change password</h2>
        <p class="text-[13px] text-muted-foreground leading-snug">Every session signed in to your account is signed out. This browser stays signed in.</p>
      </div>
      <div class="p-5 text-sm">
        <div class="space-y-4">
          <div class="basis-full min-w-0">
            <label for="password-change-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
            <input id="password-change-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="new-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">New password</label>
            <input id="new-password" name="new_password" type="password" required minlength="8" autocomplete="new-password" aria-describedby="new-password-help" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            <p id="new-password-help" class="mt-1 text-[11.5px] text-muted-foreground">At least 8 characters.</p>
          </div>
          <div>
            <label for="new-password-confirm" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Confirm new password</label>
            <input id="new-password-confirm" name="new_password_confirm" type="password" required minlength="8" autocomplete="new-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
        </div>
      </div>
      <div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
        <button type="button" data-close class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
        <button type="submit" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90">Change password</button>
      </div>
    </form>
  </dialog>

  <dialog id="add-ssh-key-dialog" aria-labelledby="add-ssh-key-dialog-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs">
    <form id="add-ssh-key-form" onsubmit="return false">
      <div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
        <h2 id="add-ssh-key-dialog-title" class="text-base font-semibold leading-tight">Add SSH key</h2>
        <p class="text-[13px] text-muted-foreground leading-snug">A key gives any system holding the private half full git access to your repos.</p>
      </div>
      <div class="p-5 text-sm">
        <div class="space-y-4">
          <div>
            <label for="key-title" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Title</label>
            <input id="key-title" name="title" type="text" required placeholder="e.g. laptop" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="public-key" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Public key</label>
            <textarea id="public-key" name="public_key" rows="5" required placeholder="ssh-ed25519 AAAA…" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[12px] font-mono text-foreground focus:outline-hidden focus:border-ring"></textarea>
          </div>
          <div class="flex flex-wrap items-end gap-3">
            <div class="min-w-0">
              <label for="ssh-key-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
              <input id="ssh-key-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            </div>
          </div>
        </div>
      </div>
      <div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
        <button type="button" data-close class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
        <button type="submit" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90">Add key</button>
      </div>
    </form>
  </dialog>

  <dialog id="generate-token-dialog" aria-labelledby="generate-token-dialog-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs">
    <form id="generate-token-form" onsubmit="return false">
      <div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
        <h2 id="generate-token-dialog-title" class="text-base font-semibold leading-tight">Generate personal access token</h2>
        <p class="text-[13px] text-muted-foreground leading-snug">Treat tokens like passwords — they grant API and git access on your behalf.</p>
      </div>
      <div class="p-5 text-sm">
        <div class="space-y-4">
          <div>
            <label for="token-name" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Name</label>
            <input id="token-name" name="name" type="text" required placeholder="e.g. CI deploy" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <fieldset>
            <legend class="block text-[12px] font-medium text-muted-foreground mb-1.5">Scopes</legend>
            <div class="space-y-1.5 text-[13px]">
              <label class="flex items-center gap-2"><input type="checkbox" name="scopes" value="repo:read"/> <span><strong class="font-mono">repo:read</strong> — Read repositories, issues, pull requests and releases you can access</span></label>
              <label class="flex items-center gap-2"><input type="checkbox" name="scopes" value="repo:write"/> <span><strong class="font-mono">repo:write</strong> — Create and update repository content: issues, pull requests, releases, branches, pushes</span></label>
              <label class="flex items-center gap-2"><input type="checkbox" name="scopes" value="issues:write"/> <span><strong class="font-mono">issues:write</strong> — Create and update issues and issue comments</span></label>
              <label class="flex items-center gap-2"><input type="checkbox" name="scopes" value="pulls:write"/> <span><strong class="font-mono">pulls:write</strong> — Create and update pull requests, reviews and comments</span></label>
              <label class="flex items-start gap-2"><input type="checkbox" name="scopes" value="repo:admin" class="mt-0.5"/> <span><strong class="font-mono">repo:admin</strong> — manage collaborators, deploy keys, webhooks, org owners, transfers and deletion without a password prompt. Needs a signing key and an expiry within 90 days, and applies only to the repositories and organizations you list.</span></label>
            </div>
            <p class="text-[11px] text-muted-foreground mt-1">Choose at least one. Tokens can't manage your account, SSH keys or other tokens, nor repository and organization settings without repo:admin.</p>
          </fieldset>
          <div>
            <label for="token-targets" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Repositories and organizations (required with repo:admin)</label>
            <textarea id="token-targets" name="targets" rows="2" placeholder="acme/app" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[12px] font-mono text-foreground focus:outline-hidden focus:border-ring"></textarea>
            <p class="text-[11px] text-muted-foreground mt-1">One per line: a repository you manage as <span class="font-mono">owner/repo</span>, or an organization you own, which covers its settings and all its repositories. The token can't touch anything else.</p>
          </div>
          <div>
            <label for="token-signing-key" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Signing key (required with repo:admin)</label>
            <textarea id="token-signing-key" name="signing_key" rows="2" placeholder="ssh-ed25519 AAAA…" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[12px] font-mono text-foreground focus:outline-hidden focus:border-ring"></textarea>
            <p class="text-[11px] text-muted-foreground mt-1">An SSH public key, which can live on a hardware key (sk-). Every request with this token must then be signed with its private key (<span class="font-mono">ssh-keygen -Y sign</span>), so the token alone is useless to anyone who copies it.</p>
          </div>
          <div>
            <label for="token-expires" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Expiration (optional)</label>
            <input id="token-expires" name="expires_at" type="date" class="bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            <p class="text-[11px] text-muted-foreground mt-1">Leave blank for a non-expiring token.</p>
          </div>
          <div class="flex flex-wrap items-end gap-3">
            <div class="min-w-0">
              <label for="token-password" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Current password</label>
              <input id="token-password" name="password" type="password" required autocomplete="current-password" class="h-9 w-56 max-w-full bg-background border border-border rounded-md px-3 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
            </div>
          </div>
        </div>
      </div>
      <div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
        <button type="button" data-close class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
        <button type="submit" id="generate-token-submit" disabled class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:pointer-events-none">Generate token</button>
      </div>
    </form>
  </dialog>

  <dialog id="register-oauth-app-dialog" aria-labelledby="register-oauth-app-dialog-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs">
    <form onsubmit="return false">
      <div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
        <h2 id="register-oauth-app-dialog-title" class="text-base font-semibold leading-tight">Register OAuth application</h2>
        <p class="text-[13px] text-muted-foreground leading-snug">You'll get a client ID and a client secret. The secret is shown once.</p>
      </div>
      <div class="p-5 text-sm">
        <div class="space-y-4">
          <div>
            <label for="oauth-app-name" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Application name</label>
            <input id="oauth-app-name" name="name" type="text" required class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="oauth-app-homepage" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Homepage URL</label>
            <input id="oauth-app-homepage" name="homepage_url" type="url" placeholder="https://example.com" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="oauth-app-redirect" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Redirect URI</label>
            <input id="oauth-app-redirect" name="redirect_uri" type="url" placeholder="https://example.com/callback" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] font-mono text-foreground focus:outline-hidden focus:border-ring"/>
            <p class="text-[11px] text-muted-foreground mt-1">Leave blank to accept any redirect URI.</p>
          </div>
          <div>
            <label for="oauth-app-desc" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Description (optional)</label>
            <textarea id="oauth-app-desc" name="description" rows="3" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"></textarea>
          </div>
        </div>
      </div>
      <div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
        <button type="button" data-close class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
        <button type="submit" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90">Register app</button>
      </div>
    </form>
  </dialog>

  <dialog id="new-saved-reply-dialog" aria-labelledby="new-saved-reply-dialog-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[480px] max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto mt-[28vh] mb-auto translate-y-[min(0px,calc(100dvh-28vh-1rem-100%))] backdrop:bg-black/60 backdrop:backdrop-blur-xs">
    <form onsubmit="return false">
      <div class="sticky top-0 z-10 bg-popover flex flex-col gap-1 p-5 border-b border-border">
        <h2 id="new-saved-reply-dialog-title" class="text-base font-semibold leading-tight">New saved reply</h2>
        <p class="text-[13px] text-muted-foreground leading-snug">Pick it from the saved replies menu when writing a comment.</p>
      </div>
      <div class="p-5 text-sm">
        <div class="space-y-4">
          <div>
            <label for="reply-title" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Title</label>
            <input id="reply-title" name="title" type="text" required placeholder="e.g. Thanks for the report" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"/>
          </div>
          <div>
            <label for="reply-body" class="block text-[12px] font-medium text-muted-foreground mb-1.5">Content</label>
            <textarea id="reply-body" name="body" rows="5" required placeholder="Your reusable comment text…" class="w-full bg-background border border-border rounded-md px-3 py-2 text-[13px] text-foreground focus:outline-hidden focus:border-ring"></textarea>
          </div>
        </div>
      </div>
      <div class="sticky bottom-0 z-10 bg-popover flex items-center justify-end gap-2 p-5 border-t border-border">
        <button type="button" data-close class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
        <button type="submit" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90">Add reply</button>
      </div>
    </form>
  </dialog>
</main>

<dialog id="cz-confirm-dialog" aria-labelledby="cz-confirm-title" class="rounded-lg border border-border bg-popover text-popover-foreground p-0 w-[420px] max-w-[calc(100vw-2rem)] mt-[28vh] mb-auto backdrop:bg-black/60 backdrop:backdrop-blur-xs">
  <div class="p-5">
    <h2 id="cz-confirm-title" class="text-base font-semibold tracking-tight mb-1"></h2>
    <p id="cz-confirm-msg" class="text-[13px] text-muted-foreground leading-relaxed mb-5"></p>
    <div class="flex justify-end gap-2">
      <button type="button" id="cz-confirm-cancel" class="inline-flex items-center justify-center rounded-md text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground h-9 px-4">Cancel</button>
      <button type="button" id="cz-confirm-ok" class="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-4 bg-destructive text-destructive-foreground hover:bg-destructive/90">Confirm</button>
    </div>
  </div>
</dialog>
<div id="cz-footer"></div>

<script>
(function () {
  document.addEventListener('click', function (e) {
    var open = e.target.closest('[data-open]');
    if (open) document.getElementById(open.dataset.open).showModal();
    var close = e.target.closest('[data-close]');
    if (close) close.closest('dialog').close();
    var rm = e.target.closest('[data-remove]');
    if (rm && rm.dataset.confirmTitle) {
      document.getElementById('cz-confirm-title').textContent = rm.dataset.confirmTitle;
      document.getElementById('cz-confirm-msg').textContent = rm.dataset.confirmMsg;
      document.getElementById('cz-confirm-ok').textContent = rm.dataset.confirmLabel;
      pending = function () { rm.parentElement.closest('.border.rounded-md').remove(); window.czToast(rm.dataset.toast); };
      confirmDlg.returnValue = '';
      confirmDlg.showModal();
    } else if (rm) rm.parentElement.closest('.border.rounded-md').remove();
    var edit = e.target.closest('[data-edit]');
    if (edit) edit.closest('[data-reply-id]').querySelector('form').classList.toggle('hidden');
    var cancel = e.target.closest('[data-cancel-edit]');
    if (cancel) { cancel.form.reset(); cancel.form.classList.add('hidden'); }
  });
  var confirmDlg = document.getElementById('cz-confirm-dialog'), pending = null;
  document.getElementById('cz-confirm-ok').addEventListener('click', function () { confirmDlg.close('confirm'); });
  document.getElementById('cz-confirm-cancel').addEventListener('click', function () { confirmDlg.close('cancel'); });
  confirmDlg.addEventListener('click', function (e) { if (e.target === confirmDlg) confirmDlg.close('cancel'); });
  confirmDlg.addEventListener('close', function () {
    var f = pending; pending = null;
    if (f && confirmDlg.returnValue === 'confirm') f();
  });
  document.querySelectorAll('dialog form').forEach(function (f) {
    f.addEventListener('submit', function () { f.closest('dialog').close(); });
  });

  var email = document.getElementById('acct-email'), original = email.value;
  email.addEventListener('input', function () { document.getElementById('email-confirm').hidden = email.value === original; });

  var scopes = document.querySelectorAll('#generate-token-form input[name=scopes]'), submit = document.getElementById('generate-token-submit');
  scopes.forEach(function (s) {
    s.addEventListener('change', function () { submit.disabled = !document.querySelector('#generate-token-form input[name=scopes]:checked'); });
  });

  var badge = document.getElementById('totp-badge'), setup = document.getElementById('totp-setup'), pending = document.getElementById('totp-pending'), disable = document.getElementById('totp-disable');
  document.getElementById('totp-start').addEventListener('click', function () { setup.hidden = true; pending.hidden = false; });
  document.getElementById('totp-enable').addEventListener('submit', function () {
    pending.hidden = true; disable.hidden = false;
    badge.textContent = 'Enabled'; badge.className = 'text-[10px] px-1.5 py-0.5 rounded-full border border-success/30 bg-success/15 text-success';
  });
  disable.addEventListener('submit', function () {
    disable.hidden = true; setup.hidden = false;
    badge.textContent = 'Disabled'; badge.className = 'text-[10px] px-1.5 py-0.5 rounded-full border border-border bg-muted text-muted-foreground';
  });

  var links = Array.prototype.slice.call(document.querySelectorAll('aside[aria-label="Settings sections"] a[href^="#"]'));
  var pairs = links.map(function (l) { return { link: l, el: document.getElementById(l.getAttribute('href').slice(1)) }; }).filter(function (p) { return p.el; });
  function spy() {
    var y = window.scrollY + 80, best = pairs[0];
    pairs.forEach(function (p) { if (p.el.offsetTop <= y) best = p; });
    links.forEach(function (l) {
      var on = l === best.link;
      l.classList.toggle('bg-accent', on);
      l.classList.toggle('text-foreground', on);
      l.classList.toggle('font-medium', on);
      l.classList.toggle('text-muted-foreground', !on && !l.classList.contains('text-destructive'));
    });
  }
  spy();
  window.addEventListener('scroll', spy, { passive: true });
})();
</script>

</body>
</html>