/* app.css — custom styles on top of Pico CSS v2 */

/* --- Pico custom property overrides --- */
/* Slightly denser layout for admin tool with ~5 users */
/* Remove default underline on links — hover shows underline instead */
:root {
  --pico-typography-spacing-vertical: 1.25rem;
  --pico-spacing: 0.75rem;
}

/* Links: no underline by default, underline on hover */
a:not([role=button]) {
  text-decoration: none;
}

a:not([role=button]):hover {
  text-decoration: underline;
}

/* --- Visually hidden (for accessible labels on icon-only or search inputs) --- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link: revealed on focus */
.skip-link:focus {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 300;
  width: auto;
  height: auto;
  padding: 0.5rem 1rem;
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  background: var(--pico-background-color);
  border: 2px solid var(--pico-primary-border, #007bff);
  border-radius: var(--pico-border-radius, 0.25rem);
  color: var(--pico-primary, #007bff);
  text-decoration: underline;
}

/* Ensure scroll target isn't hidden behind sticky nav */
#main {
  scroll-margin-top: 4rem;
}

/* --- Flash messages --- */
.flash-success {
  border-left: 4px solid #20c997;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background: #d1e7dd;
  color: #0f5132;
  border-radius: 0.25rem;
  overflow: hidden;
}

.flash-error {
  border-left: 4px solid #e14646;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background: #f8d7da;
  color: #842029;
  border-radius: 0.25rem;
  overflow: hidden;
}

.flash-dismiss {
  float: right;
  border: none;
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
  padding: 0 0.25rem;
  cursor: pointer;
  color: inherit;
  opacity: 0.6;
}

.flash-dismiss:hover {
  opacity: 1;
}

/* --- Top nav --- */
.top-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--pico-background-color);
  border-bottom: 1px solid var(--pico-muted-border-color, #e9ecef);
  /* Reset Pico's nav { display: flex } — we control layout via .container */
  display: block;
}

.top-nav > .container {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  gap: 0.5rem;
}

/* Brand */
.nav-brand {
  margin-bottom: 0;
  list-style: none;
  flex-shrink: 0;
}
.nav-brand a {
  text-decoration: none;
}

/* Primary + admin link groups */
.nav-links {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Vertical padding so focus rings aren't clipped by overflow-x: auto */
  padding: 0.25rem 0;
}
.nav-links::-webkit-scrollbar {
  display: none;
}
.nav-links > ul {
  margin-bottom: 0;
  list-style: none;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* Admin group: visual separator via structural class, not URL coupling */
.nav-admin-links {
  border-left: 1px solid var(--pico-muted-border-color, #ced4da);
  padding-left: 1rem;
  margin-left: 0.5rem;
}

/* Account dropdown */
.nav-account {
  margin-bottom: 0;
  list-style: none;
  display: flex;
  align-items: center;
  margin-left: auto;
  flex-shrink: 0;
}

/* Email truncation: truncate the span, not the summary (preserves Pico chevron) */
.nav-email {
  display: inline-block;
  max-width: 10rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

/* Ensure dropdown positioning works in custom flex nav.
   `left: auto` is required, not cosmetic: Pico sets `left: 0` with
   `width: 100%` + `min-width: fit-content` on the menu, so adding `right: 0`
   leaves the box over-constrained. In LTR the browser then ignores `right`
   and the menu is anchored by its left edge, which pushes a wide menu past
   the viewport and makes the whole page scroll sideways. Resetting `left`
   lets `right: 0` align the menu to the trigger's right edge as intended. */
.top-nav .dropdown {
  position: relative;
}
.top-nav .dropdown > ul {
  position: absolute;
  left: auto;
  right: 0;
  top: 100%;
  min-width: 12rem;
  z-index: 200;
}

/* Hamburger toggle: hidden by default, shown only when JS collapses nav on mobile */
.nav-toggle {
  display: none;
  margin-bottom: 0;
  padding: 0.3rem 0.6rem;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  width: auto;
  flex-shrink: 0;
}

/* Active nav link: visible, non-color-only treatment */
.top-nav a[aria-current="page"] {
  font-weight: 700;
  border-bottom: 2px solid var(--pico-primary, #007bff);
}

/* --- Mobile nav (≤767px, only when JS has initialized collapse) --- */
@media (max-width: 767.98px) {
  /* Allow wrapping so the expanded menu takes its own row */
  .js-nav-collapse .top-nav > .container {
    flex-wrap: wrap;
  }

  /* JS adds .js-nav-collapse to <html> when nav toggle is initialized */
  .js-nav-collapse .nav-toggle {
    display: inline-flex;
  }

  /* Account stays on the first row via order */
  .js-nav-collapse .nav-account {
    order: 1;
  }
  .js-nav-collapse .nav-toggle {
    order: 2;
  }
  /* Menu takes full width below the header row */
  .js-nav-collapse .nav-links {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 0.5rem 0;
    order: 3;
    overflow: visible;
  }
  .js-nav-collapse .nav-links > ul {
    flex-direction: column;
    align-items: flex-start;
    width: 100%;
    gap: 0;
  }
  .js-nav-collapse .nav-links > ul > li {
    width: 100%;
  }
  /* Pico gives nav links `margin: -0.5rem` (to optically align text with the
     nav box) and pulls the first nav list left by another -0.5rem. In the
     horizontal bar those cancel out against the li padding. In this
     vertical menu they compound to -16px, which pushes the first glyph of
     every link off the left edge of the nav, so labels render clipped
     ("ashboard" instead of "Dashboard"). Reset both axes — the negative
     margins only exist to optically align the horizontal bar, and there is
     no bar here to align. */
  .js-nav-collapse .nav-links {
    margin-left: 0;
  }
  .js-nav-collapse .nav-links > ul {
    margin-left: 0;
  }
  .js-nav-collapse .nav-links > ul > li {
    padding-left: 0;
  }
  .js-nav-collapse .nav-links > ul > li > a {
    display: block;
    margin-left: 0;
    margin-right: 0;
    padding: 0.4rem 0;
  }

  /* Admin separator: no left border in vertical layout */
  .js-nav-collapse .nav-admin-links {
    border-left: none;
    padding-left: 0;
    margin-left: 0;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--pico-muted-border-color, #ced4da);
    width: 100%;
  }

  /* Expanded state */
  .js-nav-collapse .nav-links[data-open] {
    display: flex;
    max-height: calc(100vh - 4rem);
    overflow-y: auto;
  }

  /* Email more aggressive truncation on very small screens */
  .nav-email {
    max-width: 5rem;
  }
}

/* --- Table rows with data-href --- */
table tbody tr[data-href] {
  cursor: pointer;
}

table tbody tr[data-href]:hover {
  background: var(--pico-secondary-background, #f8f9fa);
}

table tbody tr[data-href]:hover td {
  background: transparent;
}

/* --- Dialog forms --- */
dialog article {
  max-width: 32rem;
}

/* --- Session selection checkboxes --- */
.session-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
}

.session-option input[type="checkbox"] {
  margin-bottom: 0;
}

/* --- Utility classes --- */
.inline-form {
  display: inline;
}

.btn-sm {
  display: inline;
  padding: 0.2rem 0.5rem;
}

/* --- Dashboard summary cards --- */
.dashboard-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
}

.dashboard-cards article {
  text-align: center;
  display: flex;
  flex-direction: column;
}

.dashboard-cards article header {
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1.2;
  padding: 1.25rem 1rem 0.5rem;
}

.dashboard-cards article > small {
  display: block;
  padding: 0 1rem 1rem;
  color: var(--pico-muted-color);
  font-size: 0.9rem;
  flex: 1;
}

.dashboard-cards article footer {
  font-size: 0.85rem;
}

.dashboard-cards article footer:empty::before {
  content: "\00a0";
}

/* --- Flex utility --- */
.flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Headings inside a .flex-between row are flex items and default to
   `min-width: auto`, so a long single word (e.g. "Dokumentenbibliothek" at
   2rem) cannot shrink below its min-content width and pushes the whole page
   into horizontal overflow. `min-width: 0` lets the item shrink, but on its
   own it makes the word break mid-syllable because Pico sets
   `overflow-wrap: break-word` on :root. Stepping the font size down on
   narrow screens keeps the heading on a single readable line instead.
   Scoped to headings: `min-width: 0` on every child would also strip the
   intrinsic width protection from buttons and forms in the same row. */
@media (max-width: 575.98px) {
  .flex-between > h1,
  .flex-between > h2 {
    min-width: 0;
    font-size: 1.5rem;
  }
}

/* --- Pagination nav --- */
nav[aria-label="Seiten"] {
  display: flex;
  justify-content: space-between;
  margin-top: 1rem;
}

/* --- Status badges --- */
/* Small inline badge with text label + subtle color. Never color alone. */
.badge {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 1rem;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.badge-success {
  background: #d1e7dd;
  color: #0f5132;
}

.badge-warning {
  background: #fff3cd;
  color: #664d03;
}

.badge-danger {
  background: #f8d7da;
  color: #842029;
}

.badge-info {
  background: #cfe2ff;
  color: #084298;
}

.badge-muted {
  background: #e9ecef;
  color: #495057;
}

/* --- Responsive table wrapper --- */
/* Screen-only: the wrapper exists so a wide table scrolls inside its own
   box instead of dragging the whole page sideways. The overflow container is
   deliberately NOT created during print — Chromium can clip or paginate
   content inside an `overflow: auto` box down to the first page, which would
   silently drop attendance rows. Print keeps the raw table and relies on the
   A4 landscape page setup below. */
@media screen {
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* --- Numeric columns: right-align, tabular figures --- */
td.num,
th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- Badge and compact action cells: prevent wrapping --- */
td.action-cell {
  white-space: nowrap;
}

/* --- Destructive button --- */
/* Use alongside .secondary.outline for visually distinct destructive actions. */
.btn-danger {
  border-color: #e14646;
  color: #e14646;
}

.btn-danger:hover {
  background: #e14646;
  color: #fff;
}

.btn-danger:focus-visible {
  outline: 2px solid #e14646;
  outline-offset: 2px;
}

/* --- Detail page key-value pairs --- */
/* Using <dl> for structured key-value display on detail pages */
dl.key-values {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.3rem 1rem;
  margin: 0;
}

dl.key-values dt {
  font-weight: 600;
  color: var(--pico-muted-color, #6c757d);
}

dl.key-values dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: break-word;
}

@media (max-width: 576px) {
  dl.key-values {
    grid-template-columns: 1fr;
    gap: 0.1rem;
  }
  dl.key-values dt {
    margin-top: 0.5rem;
  }
  dl.key-values dt:first-child {
    margin-top: 0;
  }
}

/* --- Login page --- */
.login-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 70vh;
}

.login-wrapper article {
  max-width: 24rem;
  width: 100%;
}

.login-wrapper hgroup {
  text-align: center;
  margin-bottom: 1.5rem;
}

/* --- Empty state --- */
.empty-state {
  text-align: center;
  padding: 2.5rem 1rem;
  color: var(--pico-muted-color);
}

.empty-state p {
  margin-bottom: 0;
}

/* --- Action group --- */
.action-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

/* Course detail header: the attendance-list link and the management actions
   live in separate groups (different visibility rules) but should flow and
   wrap together as one row instead of stacking vertically.

   Each group is sized to its content (max-content) so the attendance link sits
   on the same row as the actions when there is room, and the row wraps
   cleanly when there is not. Sizing only the groups — rather than the links
   inside them — matters: Pico gives form elements inside a [role=group]
   `flex: 1 1 auto`, and overriding that to content width would stop the
   action buttons from wrapping inside their own group and overflow the
   viewport on narrow screens. */
.course-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.course-actions > .action-group {
  width: max-content;
  max-width: 100%;
}

.action-group form {
  margin-bottom: 0;
}

.action-group button {
  margin-bottom: 0;
}

/* --- Form fieldset sections --- */
fieldset.form-section {
  border: var(--pico-border-width) solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  padding: var(--pico-spacing);
  padding-top: 0;
  margin-bottom: var(--pico-typography-spacing-vertical);
}

fieldset.form-section legend {
  padding: 0 0.5rem;
  font-weight: 600;
}

/* --- Inline field errors (registration form) --- */
small.error {
  display: block;
  color: #842029;
  font-size: 0.85rem;
  margin-top: 0.25rem;
  margin-bottom: 0.5rem;
}

/* --- Footer legal links --- */
.footer-links {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 0.25rem;
}

.footer-links a {
  font-size: 0.85rem;
}

/* --- Filter bar (compact inline filters) --- */
.filter-bar {
  margin-bottom: var(--pico-typography-spacing-vertical);
}

.filter-bar .grid {
  margin-bottom: 0;
}

.filter-bar label {
  margin-bottom: 0;
}

.filter-bar select {
  margin-bottom: 0;
}

/* --- Inline-editable table cells --- */
/* Inputs inside table cells are compact and borderless, blending into the row.
   The form's submit button (✓) provides the save action. */
.cell-input,
table .cell-input {
  width: 100%;
  margin-bottom: 0;
  padding: calc(var(--pico-form-element-spacing-vertical) * 0.35) calc(var(--pico-form-element-spacing-horizontal) * 0.5);
  font-size: 0.95rem;
  border: 1px solid var(--pico-muted-border-color, #ced4da);
  border-radius: calc(var(--pico-border-radius) * 0.5);
  background: transparent;
  color: var(--pico-color);
  transition: border-color var(--pico-transition), background var(--pico-transition);
}

table .cell-input:hover {
  border-color: var(--pico-muted-border-color);
}

table .cell-input:focus {
  border-color: var(--pico-primary-border);
  background: var(--pico-form-element-active-background-color);
  box-shadow: none;
}

.cell-num {
  text-align: right;
  max-width: 6rem;
}

/* --- Section rhythm --- */
main > section + section {
  margin-top: calc(var(--pico-typography-spacing-vertical) * 1.5);
}

/* --- Card sections on detail pages --- */
.detail-card {
  margin-bottom: var(--pico-typography-spacing-vertical);
}

.detail-card > h2 {
  margin-bottom: 0.75rem;
}

/* ===== Dark mode overrides ===== */
/* Pico v2 doesn't define named color variables (green-100, red-100, etc.)
   so our badge/flash CSS uses hardcoded hex values that are light-mode only.
   These overrides ensure readable contrast in dark mode via prefers-color-scheme
   and data-theme="dark". */

@media only screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* Flash messages */
    .flash-success {
      background: #0f3526;
      color: #9be8c6;
      border-left-color: #20c997;
    }
    .flash-error {
      background: #3d1418;
      color: #f4a8ae;
      border-left-color: #e14646;
    }

    /* Badges */
    .badge-success {
      background: #0f3526;
      color: #9be8c6;
    }
    .badge-warning {
      background: #3d2f00;
      color: #ffdf8a;
    }
    .badge-danger {
      background: #3d1418;
      color: #f4a8ae;
    }
    .badge-info {
      background: #0a2440;
      color: #a3c8ff;
    }
    .badge-muted {
      background: #2a2f38;
      color: #b3b9c5;
    }

    /* Destructive button */
    .btn-danger {
      border-color: #e14646;
      color: #f4a8ae;
    }
    .btn-danger:hover {
      background: #e14646;
      color: #fff;
    }

    /* Table hover */
    table tbody tr[data-href]:hover {
      background: #202632;
    }
    table tbody tr[data-href]:hover td {
      background: transparent;
    }

    /* Inline field errors */
    small.error {
      color: #f4a8ae;
    }
  }
}

[data-theme="dark"] {
  /* Flash messages */
  .flash-success {
    background: #0f3526;
    color: #9be8c6;
    border-left-color: #20c997;
  }
  .flash-error {
    background: #3d1418;
    color: #f4a8ae;
    border-left-color: #e14646;
  }

  /* Badges */
  .badge-success {
    background: #0f3526;
    color: #9be8c6;
  }
  .badge-warning {
    background: #3d2f00;
    color: #ffdf8a;
  }
  .badge-danger {
    background: #3d1418;
    color: #f4a8ae;
  }
  .badge-info {
    background: #0a2440;
    color: #a3c8ff;
  }
  .badge-muted {
    background: #2a2f38;
    color: #b3b9c5;
  }

  /* Destructive button */
  .btn-danger {
    border-color: #e14646;
    color: #f4a8ae;
  }
  .btn-danger:hover {
    background: #e14646;
    color: #fff;
  }

  /* Table hover */
  table tbody tr[data-href]:hover {
    background: #202632;
  }
  table tbody tr[data-href]:hover td {
    background: transparent;
  }

  /* Inline field errors */
  small.error {
    color: #f4a8ae;
  }
}

/* --- Print attendance list --- */

/* The attendance sheet carries up to nine columns, which does not fit a
   portrait A4 at a readable size. Landscape gives the columns room without
   shrinking the font. */
@page {
  size: A4 landscape;
  margin: 10mm;
}

.attendance-table {
  width: 100%;
  border-collapse: collapse;
}
.attendance-table th,
.attendance-table td {
  border: 1px solid #ddd;
  padding: 6px 8px;
  text-align: left;
}
.attendance-table th {
  background: #f5f5f5;
}
.checkbox-col {
  width: 3em;
  text-align: center;
}

/* Each session starts its own block so the sheet can be printed and signed
   per date rather than as one long list. */
.attendance-session {
  break-inside: avoid-page;
  page-break-inside: avoid;
  margin-bottom: 1.5rem;
}
.attendance-session-header h2 {
  margin-bottom: 0.15rem;
}
.attendance-session-date {
  font-weight: 400;
  font-size: 0.9em;
  margin-left: 0.5rem;
}
.attendance-session-location {
  margin-bottom: 0.35rem;
  font-size: 0.9em;
  color: var(--pico-muted-color, #6c757d);
}
.attendance-empty {
  font-size: 0.9em;
  color: var(--pico-muted-color, #6c757d);
}
.clear-both {
  clear: both;
}
.signature-line {
  margin-top: 2rem;
  border-top: 1px solid #333;
  width: 30%;
  float: right;
  text-align: center;
  padding-top: 4px;
  font-size: 0.9em;
}

@media print {
  .no-print,
  .top-nav,
  footer,
  .flash-success,
  .flash-error {
    display: none !important;
  }
  body {
    font-size: 10pt;
  }
  .print-header h1 {
    font-size: 14pt;
    margin-bottom: 0.2rem;
  }
  .attendance-table {
    width: 100%;
  }
  .attendance-table th,
  .attendance-table td {
    border: 1px solid #ccc;
    padding: 4px 6px;
  }
  .attendance-table th {
    background: #f0f0f0;
  }
  /* Keep a row's fields on one line; long addresses wrap within the cell. */
  .attendance-table td {
    word-break: break-word;
  }
}
