:root {
  color-scheme: light dark;
  --bg: #f7f7fa;
  --card-bg: #ffffff;
  --text: #1a1a1a;
  --muted: #666;
  --accent: #4f46e5;
  --border: #e4e4e9;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #16161d;
    --card-bg: #1f1f29;
    --text: #f0f0f5;
    --muted: #a0a0ad;
    --border: #2c2c38;
  }
}

* {
  box-sizing: border-box;
}

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

.page {
  max-width: 640px;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 3rem;
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.25rem;
}

.header-row h1 {
  margin: 0;
}

.mode-toggle {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
}

.mode-toggle:hover {
  border-color: var(--accent);
}

/* Sidebar mode needs room to show the list and content side by side - not
   viable on a phone-width screen, so the toggle to reach it is hidden there
   (tablets and up keep it). */
@media (max-width: 600px) {
  .mode-toggle {
    display: none;
  }
}

/* Covers the viewport with the active project's iframe instead of
   navigating to it - project pages stay alive underneath (just hidden) so
   switching back and forth doesn't lose their state. Hidden entirely while
   no project is open and the sidebar isn't active, so it doesn't block
   clicks on the list below it. Its `left` offset (sidebar on/off) is not
   transitioned - it snaps instantly while opacity fades over it instead,
   see the scenario-specific transitions below. */
#frames {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--bg);
}

body.project-active #frames,
body.sidebar-mode #frames {
  display: block;
}

body.project-active #hubWidgets {
  display: none;
}

/* ---- normal mode: an open project covers the whole viewport, list hidden ---- */
body.project-active:not(.sidebar-mode) .page {
  display: none;
}

/* Wipe for opening/closing a project in normal mode - see selectSite() in
   script.js, which slides+fades the current pane out to one side, swaps
   display:none/block while invisible, then slides+fades the other in from
   the other side. Reuses the very same .project-switching rules for both
   directions: opening animates .page from 0 to -100% (list exits left)
   then #frames from 100% to 0 (project enters from the right); closing
   animates the reverse, so the "hidden" transform values below apply
   identically either way. */
.page,
#frames {
  transform: translateX(0);
}

.page {
  transition: opacity 0.15s ease, transform 0.15s ease;
}

body.project-switching #frames {
  transition: opacity 0.15s ease, transform 0.15s ease;
}

body.project-switching .page,
body.project-switching #frames {
  opacity: 0;
}

body.project-switching .page {
  transform: translateX(-100%);
}

body.project-switching #frames {
  transform: translateX(100%);
}

/* Content pane slides+fades away to the left over the sidebar toggle (see
   script.js) while the sidebar panel itself slides too - a slower, gentler
   motion (0.5s) than the quicker project crossfade above, since it's
   covering a bigger jump in layout (list+content vs. content-only). */
body.sidebar-entering #frames,
body.sidebar-leaving #frames {
  transition: opacity 0.5s ease, transform 0.5s ease;
  opacity: 0;
  transform: translateX(-100%);
}

/* Entering the sidebar reuses .page's own position/width for the sidebar
   layout, which can't be transitioned directly (static centered block ->
   fixed panel) - without this, the visible list would just hard-cut away
   the instant sidebar-mode is applied. So script.js briefly fades the
   normal view out first (reusing .page's existing opacity transition
   above) before swapping to the off-screen sidebar layout and sliding it
   in - mirroring how leaving never hard-cuts anything visible either.
   The content pane slides away to the left in the same breath (still at
   its full pre-sidebar width here, so it clears the viewport cleanly
   before the narrower sidebar layout applies underneath) - and so does the
   list itself, still at its full centered width here for the same reason. */
body.sidebar-preentering .page {
  opacity: 0;
  transform: translateX(-100%);
}

body.sidebar-preentering #frames {
  transition: transform 0.15s ease;
  transform: translateX(-100%);
}

/* ---- sidebar mode: list stays put on the left, content fills the rest ---- */
body.sidebar-mode .page {
  position: fixed;
  inset: 0 auto 0 0;
  width: 320px;
  max-width: 320px;
  margin: 0;
  padding: 1.75rem 1.25rem;
  overflow-y: auto;
  border-right: 1px solid var(--border);
  background: var(--bg);
  z-index: 45;
  transform: translateX(0);
  transition: transform 0.5s ease;
}

/* Applied for one frame before removing (entering) or right when adding
   (leaving) - see script.js. Slides the sidebar panel fully past the left
   edge instead of just toggling visibility, so it visibly wipes in/out. */
body.sidebar-entering .page,
body.sidebar-leaving .page {
  transform: translateX(-100%);
}

body.sidebar-mode .list {
  max-height: none;
}

body.sidebar-mode #frames {
  left: 320px;
}

#frames .frame-pane,
.placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
}

#frames .frame-pane {
  display: none;
}

#frames .frame-pane.active {
  display: block;
}

/* Impressum is plain static text, not a separate project - it's rendered
   directly into this pane instead of loading its own page in an iframe. */
.impressum-pane {
  overflow-y: auto;
  background: var(--bg);
}

.impressum-pane .back-to-hub {
  position: fixed;
  top: 1.25rem;
  left: 1.25rem;
  z-index: 50;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 0.9rem;
  cursor: pointer;
}

.impressum-pane .back-to-hub:hover {
  border-color: var(--accent);
}

.impressum-body {
  max-width: 560px;
  margin: 0 auto;
  padding: 4.5rem 1.25rem 3rem;
}

.impressum-body h1 {
  margin: 0 0 1.5rem;
}

.impressum-body h2 {
  font-size: 1rem;
  margin: 1.75rem 0 0.5rem;
}

.impressum-body p {
  line-height: 1.6;
  margin: 0 0 0.5rem;
}

.placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  text-align: center;
  padding: 1rem;
}

.placeholder[hidden] {
  display: none;
}

header {
  margin-bottom: 1.5rem;
}

h1 {
  margin: 0 0 0.25rem;
  font-size: 1.75rem;
}

.subtitle {
  margin: 0;
  color: var(--muted);
}

.search {
  width: 100%;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  color: var(--text);
  margin-bottom: 1.25rem;
}

.search:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.list {
  list-style: none;
  margin: 0;
  padding: 3px;
  max-height: 60vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.9rem 1.1rem;
  cursor: pointer;
  transition: transform 0.12s ease, border-color 0.12s ease;
}

.card:hover,
.card:focus-visible {
  border-color: var(--accent);
  transform: translateY(-1px);
  outline: none;
}

.card-title {
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.card-desc {
  color: var(--muted);
  font-size: 0.9rem;
}

.empty {
  text-align: center;
  color: var(--muted);
  margin-top: 2rem;
}

.footer-link {
  display: block;
  text-align: center;
  margin-top: 2.5rem;
  color: var(--muted);
  font-size: 0.8rem;
  text-decoration: none;
}

.footer-link:hover {
  color: var(--accent);
}

.primary-btn {
  display: block;
  width: 100%;
  padding: 0.65rem;
  font-size: 1rem;
  font-weight: 600;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
}

.primary-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---------------- support / admin widgets ---------------- */

.widget-toggle {
  position: fixed;
  bottom: 1.25rem;
  z-index: 50;
  padding: 0.65rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}

.widget-toggle-right {
  right: 1.25rem;
}

.widget-toggle-left {
  left: 1.25rem;
  background: var(--card-bg);
  color: var(--text);
}

.widget-panel {
  position: fixed;
  z-index: 60;
  width: min(340px, calc(100vw - 2.5rem));
  height: min(560px, calc(100vh - 6rem));
  min-width: 260px;
  min-height: 220px;
  max-width: calc(100vw - 0.5rem);
  max-height: calc(100vh - 0.5rem);
  resize: both;
  display: flex;
  flex-direction: column;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

/* display:flex above would otherwise override the browser's default
   [hidden] { display: none }, making the panels impossible to hide */
.widget-panel[hidden] {
  display: none;
}

.support-success {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  min-height: 160px;
}

#supportForm[hidden],
.support-success[hidden] {
  display: none;
}

.success-check {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: #22c55e;
  color: #fff;
  font-size: 2.2rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(34, 197, 94, 0.4);
}

.success-text {
  margin: 0;
  font-weight: 600;
  color: var(--text);
}

.panel-header {
  display: flex;
  align-items: center;
  cursor: move;
  user-select: none;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}

.panel-header h3 {
  margin: 0;
  font-size: 1rem;
}

.panel-close {
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 1.1rem;
  cursor: pointer;
  line-height: 1;
}

.panel-body {
  padding: 1rem;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.category-group {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
}

.support-text {
  width: 100%;
  min-height: 90px;
  padding: 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  resize: vertical;
  margin-bottom: 0.75rem;
}

.support-status {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  min-height: 1.2em;
}

.admin-password-input {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  margin-bottom: 0.6rem;
}

.error-text {
  color: #d33;
  font-size: 0.85rem;
  min-height: 1.2em;
  margin: 0;
}

.report-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.report-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
}

.report-list li:has(.report-row-body:hover) {
  border-color: var(--accent);
}

.ticket-select {
  flex-shrink: 0;
  padding-top: 0.15rem;
}

.report-row-body {
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.report-row-folder {
  cursor: pointer;
}

.report-row-folder:hover {
  border-color: var(--accent);
}

.bulk-actions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.5rem 0;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

.bulk-count {
  font-size: 0.8rem;
  color: var(--muted);
}

.bulk-buttons {
  display: flex;
  gap: 0.5rem;
}

.bulk-btn {
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.5rem;
  font-size: 0.78rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--text);
  cursor: pointer;
}

.bulk-btn-success {
  color: #16a34a;
  border-color: #16a34a;
}

.bulk-btn-danger {
  color: #d33;
  border-color: #d33;
}

.select-all-bar {
  display: flex;
  gap: 0.9rem;
  margin-bottom: 0.5rem;
}

.link-btn {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  padding: 0;
  font-size: 0.8rem;
}

/* .report-list, .bulk-actions and .select-all-bar set display:flex
   unconditionally, which otherwise silently overrides the browser's
   default [hidden]{display:none} */
.report-list[hidden],
.bulk-actions[hidden],
.select-all-bar[hidden] {
  display: none;
}

.report-list a {
  color: var(--accent);
  text-decoration: none;
}

.report-list .report-meta {
  color: var(--muted);
  font-size: 0.75rem;
}

.report-status-badge {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  margin-left: 0.4rem;
}

.report-status-open {
  background: #fee2e2;
  color: #991b1b;
}

.report-status-resolved {
  background: #dcfce7;
  color: #166534;
}

.report-detail {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
}

.report-detail .detail-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.report-detail .detail-actions button {
  flex: 1;
  padding: 0.5rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}

.report-detail .detail-actions button.action-success {
  color: #16a34a;
  border-color: #16a34a;
}

.report-detail .detail-actions button.action-danger {
  color: #d33;
  border-color: #d33;
}

.back-link {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  padding: 0;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
  display: block;
}

.back-link[hidden] {
  display: none;
}
