/* R2 storage page (design/storage-manager.pen). The whole point is the 未使用
   count: soft-deleted pages, replaced photos and unsaved generated videos all
   leave files that nothing references, and they were invisible until this
   page existed. Orphans carry the gold accent; deleting something still in
   use gets danger red and a typed confirmation. */
.stor-page {
  max-width: 900px;
  margin: 0 auto;
  padding: 2rem 1.25rem 6rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.stor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.stor-head h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
}

.stor-ghost {
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 0.82rem;
  cursor: pointer;
}

.stor-ghost:hover { background: var(--color-surface-strong); color: var(--color-text); }
.stor-ghost:disabled { opacity: 0.5; }

.stor-primary {
  padding: 0.65rem 1rem;
  border-radius: var(--radius-md);
  background: var(--color-accent);
  color: #1a1408;
  font-weight: 600;
  font-size: 0.88rem;
  cursor: pointer;
}

.stor-primary:disabled { opacity: 0.55; }

.stor-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 720px) {
  .stor-summary { grid-template-columns: 1fr; }
}

.stor-cap {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.1rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.stor-cap__head { display: flex; align-items: baseline; gap: 0.5rem; }
.stor-cap__used { font-size: 1.6rem; font-family: var(--font-display); }
.stor-cap__of { font-size: 0.8rem; color: var(--color-text-muted); }

/* min-width so a category that is a rounding error of 10GB still shows as a
   sliver instead of disappearing entirely. */
.stor-bar {
  display: flex;
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-surface-strong);
}

.stor-bar__seg { min-width: 3px; height: 100%; }
.stor-bar__seg--video { background: var(--color-accent); }
.stor-bar__seg--photo { background: #5bc8d6; }
.stor-bar__seg--thumb { background: #7e8ba3; }
.stor-bar__seg--font  { background: #c58ae0; }
.stor-bar__seg--other { background: #6b6b78; }

.stor-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; font-size: 0.74rem; color: var(--color-text-muted); }
.stor-legend__item { display: inline-flex; align-items: center; gap: 0.35rem; }

.stor-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.stor-dot--video { background: var(--color-accent); }
.stor-dot--photo { background: #5bc8d6; }
.stor-dot--thumb { background: #7e8ba3; }
.stor-dot--font  { background: #c58ae0; }
.stor-dot--other { background: #6b6b78; }

.stor-callout {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.1rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  border: 1px solid rgba(232, 179, 77, 0.35);
}

.stor-callout--clean { border-color: var(--color-border); }
.stor-callout__title { font-size: 1.05rem; color: var(--color-accent-strong); }
.stor-callout--clean .stor-callout__title { color: var(--color-text); }
.stor-callout__desc { font-size: 0.78rem; line-height: 1.5; color: var(--color-text-muted); }

.stor-filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.stor-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.stor-chip {
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 0.8rem;
  cursor: pointer;
}

.stor-chip.is-active {
  background: var(--color-surface-strong);
  color: var(--color-text);
  outline: 1px solid var(--color-accent);
}

.stor-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: 0.8rem;
  color: var(--color-text-muted);
  cursor: pointer;
}

.stor-list { display: flex; flex-direction: column; gap: 0.85rem; }

.stor-group { border-radius: var(--radius-lg); background: var(--color-surface); overflow: hidden; }

/* The group's select-all sits BESIDE the header, not inside it: the header is
   a <button> that collapses the group, and a checkbox nested in it would both
   be invalid markup and collapse the group on every tick. */
.stor-group__bar {
  display: flex;
  align-items: center;
}

.stor-group__bar .stor-row__check {
  padding-left: 1rem;
}

.stor-group__bar .stor-group__head {
  flex: 1;
  min-width: 0;
  padding-left: 0.7rem;
}

/* Marks the select-all apart from the 只看未使用 filter next to it — one
   changes what you are looking at, the other changes what is about to be
   deleted, and they must not read as the same kind of switch. */
.stor-toggle--all {
  color: var(--color-text);
  outline: 1px solid var(--color-border);
}

.stor-toggle--all:has(input:checked) {
  outline-color: var(--color-accent);
  color: var(--color-accent-strong);
}

.stor-toggle--all:has(input:disabled) {
  opacity: 0.45;
}

.stor-group__head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.85rem 1rem;
  background: transparent;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

.stor-group__name { flex: 1; font-size: 0.95rem; }
.stor-group__meta { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.74rem; color: var(--color-text-muted); }
.stor-group__orphans { color: var(--color-accent-strong); }
.stor-group__chev { font-size: 0.6rem; color: var(--color-text-muted); }

.stor-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 1rem;
  border-top: 1px solid var(--color-border);
}

.stor-row.is-orphan { background: rgba(232, 179, 77, 0.05); }

.stor-row__check { display: flex; }

.stor-row__thumb {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 8px;
  overflow: hidden;
  background: var(--color-surface-strong);
  display: flex;
  align-items: center;
  justify-content: center;
}

.stor-row__thumb img { width: 100%; height: 100%; object-fit: cover; }
.stor-row__play { font-size: 0.9rem; color: var(--color-text-muted); }

.stor-row__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.stor-row__name { font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stor-row__meta { font-size: 0.72rem; color: var(--color-text-muted); }

.stor-pill { padding: 0.15rem 0.55rem; border-radius: 999px; font-size: 0.7rem; white-space: nowrap; }
.stor-pill--used { background: var(--color-surface-strong); color: var(--color-text-muted); }
.stor-pill--orphan { background: rgba(232, 179, 77, 0.16); color: var(--color-accent-strong); }

.stor-row__del {
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-md);
  background: var(--color-surface-strong);
  color: var(--color-text-muted);
  cursor: pointer;
}

.stor-row__del:hover { color: #f28b82; }

.stor-confirm,
.stor-danger {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.1rem;
  border-radius: var(--radius-lg);
}

.stor-confirm { background: var(--color-surface); }
.stor-danger { background: #140f10; border: 1px solid rgba(242, 139, 130, 0.4); }

/* Two panels here paint their own opaque dark surface rather than using a
   token, so on a light site background they would have kept dark chrome under
   the now-dark text — the delete confirmation and the selection bar, i.e.
   exactly the two places you must be able to read before destroying files. */
:root.is-light-bg .stor-danger {
  background: #fdecea;
  border-color: rgba(179, 38, 30, 0.35);
}

:root.is-light-bg .stor-danger__title {
  color: #b3261e;
}

:root.is-light-bg .stor-actionbar {
  background: #fdf4de;
  border-color: rgba(138, 90, 0, 0.35);
}

:root.is-light-bg .stor-actionbar__warn {
  color: #b3261e;
}

.stor-confirm__title { font-size: 1rem; }
.stor-confirm__desc { font-size: 0.8rem; line-height: 1.55; color: var(--color-text-muted); }
.stor-confirm__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

.stor-danger__title { font-size: 1rem; color: #f28b82; }
.stor-danger__desc { font-size: 0.8rem; line-height: 1.6; color: var(--color-text); }

.stor-danger__input {
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: rgba(255, 255, 255, 0.04);
  color: var(--color-text);
}

.stor-danger__btn {
  padding: 0.65rem 1rem;
  border-radius: var(--radius-md);
  background: #f28b82;
  color: #2a0f0d;
  font-weight: 600;
  font-size: 0.88rem;
  cursor: pointer;
}

.stor-danger__btn:disabled { opacity: 0.4; }

/* Fixed, not sticky. As the last child of .stor-page it had almost no sticky
   range to travel in, so on any list longer than a screen it simply sat at the
   bottom of the DOCUMENT — measured at y=1003 in an 812px viewport. The bar
   that tells you what you are about to delete was never on screen. .stor-page
   already reserves 6rem of bottom padding for it. */
.stor-actionbar {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  width: min(calc(100% - 2rem), 900px);
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.9rem 1.1rem;
  border-radius: var(--radius-lg);
  background: #1b1710;
  border: 1px solid rgba(232, 179, 77, 0.3);
}

.stor-actionbar__count { font-size: 0.9rem; color: var(--color-accent-strong); }
.stor-actionbar__warn { color: #f28b82; margin-left: 0.4rem; font-size: 0.8rem; }
.stor-actionbar__actions { display: flex; gap: 0.5rem; }

/* Preview lightbox. The row thumbnail and name are buttons that open it —
   two versioned uploads of the same photo are indistinguishable in a list,
   so being able to actually look at a file is what makes deleting safe. */
.stor-row__thumb {
  border: 0;
  padding: 0;
  cursor: zoom-in;
}

.stor-row__name {
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: zoom-in;
}

.stor-row__name:hover { color: var(--color-accent-strong); }

.stor-preview {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.82);
  animation: backdrop-fade-in 160ms ease-out;
}

.stor-preview__box {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: min(100%, 900px);
  max-height: 92vh;
  padding: 1rem;
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
}

.stor-preview__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.stor-preview__name {
  font-size: 0.95rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The stage takes the leftover height so a tall photo is not cropped by the
   metadata below it. */
.stor-preview__stage {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.stor-preview__stage img,
.stor-preview__stage video {
  max-width: 100%;
  max-height: 68vh;
  object-fit: contain;
}

.stor-preview__font {
  padding: 1.5rem;
  text-align: center;
  font-size: 1.6rem;
  line-height: 1.8;
}

.stor-preview__font p { margin: 0; }

.stor-preview__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-size: 0.76rem;
  color: var(--color-text-muted);
}

.stor-preview__key {
  width: 100%;
  font-size: 0.68rem;
  word-break: break-all;
  opacity: 0.7;
}

.stor-preview__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.stor-preview__count {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.stor-preview__actions a.stor-ghost { text-decoration: none; }
.stor-preview__actions .stor-danger__btn { margin-left: auto; }

/* 分享/瀏覽統計 (StatsPage.js) — reuses the storage page's shell, so only the
   day-bar is new. */
.stats-day {
  flex: 0 0 auto;
  width: 5.5rem;
  font-variant-numeric: tabular-nums;
}

.stats-bar {
  flex: 1;
  min-width: 0;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-strong);
  overflow: hidden;
}

.stats-bar__fill {
  display: block;
  height: 100%;
  min-width: 3px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}
