defter 0.3.2

Self-hosted Zotero sync and file storage server, with metadata in SQLite and attachments in S3.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="robots" content="noindex">
  {#- htmx reads its configuration here, so no inline script is needed. Under
      the strict CSP it may not eval code or inject an inline style sheet. -#}
  <meta name="htmx-config" content='{"allowEval": false, "includeIndicatorStyles": false, "historyRestoreAsHxRequest": false}'>
  <title>{% block title %}{% endblock %} — defter</title>
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%230d9488'/%3E%3Cpath d='M10 7h9a5 5 0 0 1 5 5v13H13a3 3 0 0 1-3-3z' fill='white'/%3E%3Cpath d='M14 12h6M14 16h6M14 20h4' stroke='%230d9488' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E">
  <link rel="stylesheet" href="{{ layout.stylesheet }}">
  <script defer src="{{ layout.script }}"></script>
  {#- Before first paint, so a dark page does not flash light. -#}
  <script nonce="{{ layout.nonce }}">
    if (localStorage.getItem('defter-dark') === 'true' || (localStorage.getItem('defter-dark') === null && matchMedia('(prefers-color-scheme: dark)').matches)) document.documentElement.classList.add('dark')
  </script>
</head>
<body>
<div class="min-h-screen flex flex-col">
  <header class="border-b">
    <div class="mx-auto max-w-4xl px-4 h-14 flex items-center justify-between">
      <a href="/" class="flex items-center gap-2 font-semibold tracking-tight">
        <span class="inline-block size-6 rounded-md bg-primary"></span>defter
      </a>
      <div class="flex items-center gap-1">
        <button type="button" data-theme-toggle aria-label="Toggle dark mode"
                class="rounded-md px-3 py-1.5 text-sm text-muted-foreground hover:bg-muted">
          <span class="dark:hidden">Dark</span><span class="hidden dark:inline">Light</span>
        </button>
        {%- if layout.signed_in %}
        <form method="post" action="/ui/logout">
          <button type="submit" class="rounded-md px-3 py-1.5 text-sm text-muted-foreground hover:bg-muted">Sign out</button>
        </form>
        {%- endif %}
      </div>
    </div>
  </header>
  <main class="flex-1 mx-auto w-full max-w-4xl px-4 py-8">
    {% block content %}{% endblock %}
  </main>
  <footer class="border-t">
    <div class="mx-auto max-w-4xl px-4 py-4 text-xs text-muted-foreground">
      Self-hosted Zotero sync and file storage
    </div>
  </footer>
</div>
</body>
</html>