:root {
  --bg: #14161a;
  --surface: #1d2026;
  --border: #2c313a;
  --text: #e8eaed;
  --muted: #9aa3af;
  --accent: #4f8ef7;
  --danger: #f2777a;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 64px; }
main.narrow { max-width: 640px; }

h1 { font-size: 1.4rem; margin: 0 0 16px; }
h2 { font-size: 1.05rem; margin: 32px 0 12px; font-weight: 600; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 20px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 10;
}
.brand { font-weight: 600; color: var(--text); }
.topbar nav { display: flex; align-items: center; gap: 16px; }
.topbar form { margin: 0; }

button { font: inherit; cursor: pointer; }
button.link {
  background: none; border: none; color: var(--accent); padding: 0;
}
button.link:hover { text-decoration: underline; }
button.danger, .danger { color: var(--danger); }

.primary {
  background: var(--accent); color: #fff; border: none;
  padding: 10px 18px; border-radius: var(--radius); font-weight: 500;
}
.primary:hover { filter: brightness(1.1); }

.centered { display: grid; place-items: center; min-height: 100vh; padding: 20px; }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 24px;
}
.centered .card { width: 100%; max-width: 360px; }

.stack { display: grid; gap: 14px; margin: 0; }
.stack label { display: grid; gap: 6px; font-size: 0.9rem; color: var(--muted); }
.stack input[type="text"], .stack input[type="password"], .stack input:not([type]) {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  padding: 10px 12px; border-radius: 8px; font: inherit; width: 100%;
}
.stack input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.checkbox { display: flex !important; flex-direction: row; align-items: center; gap: 8px; }

.flash { padding: 10px 14px; border-radius: 8px; margin: 0 0 16px; font-size: 0.92rem; }
.flash.error { background: #3a2226; border: 1px solid #6b3a3f; color: #ffc9cb; }
.flash.notice { background: #1e3026; border: 1px solid #38614a; color: #b9edcf; }

.uploader { margin-bottom: 28px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.dropzone {
  display: grid; gap: 4px; place-items: center; text-align: center;
  padding: 28px; border: 1.5px dashed var(--border); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; color: var(--muted);
}
.dropzone:hover, .dropzone.dragover { border-color: var(--accent); color: var(--text); }
.dropzone strong { color: var(--text); }
.upload-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-top: 12px;
}

.grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.tile {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
  /* Deliberately NOT overflow:hidden. That clipped the share popup inside the
     tile. The image rounds its own corners below instead, so the tile can let
     an open popup escape its bounds. */
  position: relative;
}
/* A tile with its share popup open must paint above its neighbours in the grid,
   which are later siblings and would otherwise cover it. */
.tile:has(.share[open]) { z-index: 30; }
.tile > a {
  position: relative; display: block; background: #0e1013;
  overflow: hidden;
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}
.tile img { display: block; width: 100%; height: 170px; object-fit: cover; }
.badge {
  position: absolute; right: 8px; bottom: 8px;
  background: rgba(0,0,0,0.7); color: #fff;
  padding: 2px 7px; border-radius: 5px; font-size: 0.72rem;
}
.meta { padding: 10px 12px 4px; display: grid; gap: 2px; min-width: 0; }
.name { font-size: 0.88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sub { color: var(--muted); font-size: 0.78rem; }
.tile-actions {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 12px 12px; font-size: 0.85rem; margin-top: auto;
}
.tile-actions form { margin: 0; }

.empty { color: var(--muted); text-align: center; padding: 48px 0; }

.users { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.users th, .users td {
  text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--border);
}
.users th { color: var(--muted); font-weight: 500; font-size: 0.82rem; }
.users form { margin: 0; }

.recipients {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; margin: 0 0 14px; background: var(--surface);
}
.recipients legend { color: var(--muted); font-size: 0.82rem; padding: 0 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; margin: 0 6px 6px 0; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg); font-size: 0.85rem;
  cursor: pointer;
}
.chip:hover { border-color: var(--accent); }
.hint { color: var(--muted); font-size: 0.8rem; margin: 8px 0 0; }

.shared { color: var(--accent); }
.share summary { cursor: pointer; color: var(--accent); list-style: none; }
.share summary::-webkit-details-marker { display: none; }
/* Positioned against the tile rather than the summary, and spanning its width,
   so it can never run off the left or right edge of the viewport whichever
   column the tile is in. It opens downward: opening upward put it under the
   sticky header for tiles in the first row. */
.share-form {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 31;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px; margin-top: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
}
.primary.small { padding: 6px 12px; font-size: 0.85rem; margin-top: 4px; }

.library-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin: 0 0 16px;
}
.library-bar .primary { text-decoration: none; }
.library-bar .primary:hover { text-decoration: none; }

.pick {
  position: absolute; top: 8px; left: 8px; z-index: 2;
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: rgba(0,0,0,0.55); cursor: pointer;
}
.pick:hover { background: rgba(0,0,0,0.75); }
.pick-box { width: 17px; height: 17px; cursor: pointer; margin: 0; }
/* A selected tile is obvious at a glance, so it is clear what a download holds. */
.tile:has(.pick-box:checked) { outline: 2px solid var(--accent); outline-offset: -1px; }
#download-selected[disabled] { opacity: 0.45; cursor: not-allowed; filter: none; }

.upload-queue { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 6px; }
.upload-queue li {
  display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 12px;
  padding: 8px 12px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 8px; font-size: 0.88rem;
}
.queued-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
