/*
 * Styling for the admin area. Everything is scoped under `.admin` so the
 * public pages (home.css / pages.css) stay untouched.
 *
 * House rule: no rounded corners anywhere in here.
 */

.admin {
  --admin-bg: #f4f2f0;
  --admin-surface: #ffffff;
  --admin-border: #ddd7d3;
  --admin-sidebar-bg: #221e1e;
  --admin-sidebar-muted: rgba(255, 255, 255, 0.55);
  --admin-sidebar-width: 250px;
  --admin-muted: #6f6663;

  background-color: var(--admin-bg);
  color: #241f1f;
}

/* Square corners, everywhere ---------------------------------------------- */

.admin,
.admin *,
.admin *::before,
.admin *::after {
  border-radius: 0 !important;
}

/* Sidebar ----------------------------------------------------------------- */

.admin-sidebar {
  width: var(--admin-sidebar-width);
  /* Bootstrap forces a transparent background on `.offcanvas-lg` above the
     breakpoint, so the sidebar colours need to win that fight. */
  background-color: var(--admin-sidebar-bg) !important;
  color: #fff;
}

.admin-sidebar .offcanvas-body {
  background-color: var(--admin-sidebar-bg) !important;
}

@media (min-width: 992px) {
  .admin-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    flex: 0 0 var(--admin-sidebar-width);
  }

  .admin-sidebar .offcanvas-body {
    flex-grow: 1;
    overflow-y: auto;
  }
}

.admin-sidebar-brand {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.admin-sidebar-brand .logo {
  max-width: 44px;
}

.admin-sidebar-label {
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--admin-sidebar-muted);
}

.admin-nav-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1.25rem;
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.admin-nav-link:hover {
  background-color: rgba(255, 255, 255, 0.06);
  color: #fff;
}

.admin-nav-link.active {
  background-color: rgba(255, 255, 255, 0.1);
  border-left-color: var(--intense-color);
  color: #fff;
  font-weight: 600;
}

.admin-nav-link i {
  font-size: 1.05rem;
  width: 1.25rem;
  text-align: center;
}

.admin-sidebar-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.admin-sidebar-footer a {
  color: var(--admin-sidebar-muted);
  text-decoration: none;
}

.admin-sidebar-footer a:hover {
  color: #fff;
}

/* Topbar and page header -------------------------------------------------- */

.admin-topbar {
  background-color: var(--admin-surface);
  border-bottom: 1px solid var(--admin-border);
}

.admin-main {
  min-width: 0;
  max-width: 100%;
}

/* Bootstrap ships no min-width utility; flex children need one to be able to
   shrink below their content width (wide tables, long titles). */
.admin .min-w-0 {
  min-width: 0;
}

.admin-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--admin-muted);
}

.admin-page-title {
  font-size: 1.6rem;
  font-weight: 700;
  margin: 0;
}

/* Panels ------------------------------------------------------------------ */

.admin-panel {
  background-color: var(--admin-surface);
  border: 1px solid var(--admin-border);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.admin-panel-header {
  padding: 0.85rem 1.25rem;
  border-bottom: 1px solid var(--admin-border);
  font-weight: 600;
}

.admin-panel-body {
  padding: 1.25rem;
}

/* Tables ------------------------------------------------------------------ */

.admin-table {
  margin-bottom: 0;
}

.admin-table > thead th {
  background-color: #faf8f7;
  border-bottom: 1px solid var(--admin-border);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--admin-muted);
  padding: 0.7rem 1.25rem;
  white-space: nowrap;
}

.admin-table > tbody td {
  padding: 0.85rem 1.25rem;
  border-bottom: 1px solid #eee9e6;
  vertical-align: middle;
}

.admin-table > tbody tr:last-child td {
  border-bottom: 0;
}

.admin-table > tbody tr:hover {
  background-color: #faf8f7;
}

.admin-table a {
  color: inherit;
  text-decoration: none;
  font-weight: 600;
}

.admin-table a:hover {
  color: var(--intense-color);
  text-decoration: underline;
}

.admin-table .admin-row-actions {
  text-align: right;
  white-space: nowrap;
}

/* Stat tiles -------------------------------------------------------------- */

.admin-stat {
  display: block;
  background-color: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-top: 3px solid var(--intense-color);
  padding: 1.1rem 1.25rem;
  color: inherit;
  text-decoration: none;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.admin-stat:hover {
  box-shadow: 0 0.35rem 1rem rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
  color: inherit;
}

.admin-stat-value {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
}

.admin-stat-label {
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--admin-muted);
}

/* Definition lists on show pages ------------------------------------------ */

.admin-definitions {
  margin: 0;
}

.admin-definitions dt {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--admin-muted);
  font-weight: 600;
  margin-bottom: 0.15rem;
}

.admin-definitions dd {
  margin-bottom: 1.25rem;
}

.admin-definitions dd:last-child {
  margin-bottom: 0;
}

.admin-definitions dd :last-child {
  margin-bottom: 0;
}

/* Forms ------------------------------------------------------------------- */

.admin .form-label {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--admin-muted);
}

.admin .form-control:focus,
.admin .form-select:focus {
  border-color: var(--intense-color);
  box-shadow: 0 0 0 0.15rem rgba(187, 39, 27, 0.15);
}

.admin trix-editor {
  min-height: 10rem;
  background-color: #fff;
  border-color: var(--admin-border);
}

.admin trix-toolbar .trix-button-group {
  border-color: var(--admin-border);
}

.admin .field_with_errors {
  display: contents;
}

.admin .field_with_errors .form-control,
.admin .field_with_errors .form-select {
  border-color: var(--intense-color);
}

/* Thumbnails -------------------------------------------------------------- */

.admin-thumb {
  width: 100%;
  height: 160px;
  object-fit: cover;
  border: 1px solid var(--admin-border);
}

/* Empty state ------------------------------------------------------------- */

.admin-empty {
  padding: 3rem 1.25rem;
  text-align: center;
  color: var(--admin-muted);
}

.admin-empty i {
  font-size: 2rem;
  display: block;
  margin-bottom: 0.75rem;
  opacity: 0.5;
}

/* Reordering the attached images of a record. */
.image-order-list {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
}

.image-order-item {
  position: relative;
  border: 2px solid transparent;
  border-radius: .5rem;
  padding: .25rem;
  cursor: grab;
  background: #fff;
}

.image-order-item.is-hero {
  border-color: var(--bs-primary, #b5332a);
}

.image-order-item.dragging {
  opacity: .4;
}

.image-order-thumb {
  display: block;
  width: 7rem;
  height: 7rem;
  object-fit: cover;
  border-radius: .35rem;
  pointer-events: none;
}

.image-order-hero-label {
  display: none;
  position: absolute;
  top: .5rem;
  left: .5rem;
  padding: .1rem .4rem;
  border-radius: .25rem;
  font-size: .7rem;
  background: var(--bs-primary, #b5332a);
  color: #fff;
}

.image-order-item.is-hero .image-order-hero-label {
  display: block;
}

.image-order-buttons {
  display: flex;
  justify-content: center;
  gap: .25rem;
  margin-top: .25rem;
}

.image-order-item.is-removing {
  opacity: .45;
  border-color: var(--bs-danger, #dc3545);
}

.image-order-remove {
  display: block;
  margin-top: .25rem;
  font-size: .75rem;
  color: #6c757d;
  text-align: center;
  cursor: pointer;
}

.admin-thumb-sm {
  width: 3rem;
  height: 3rem;
}

/* Help ------------------------------------------------------------------- */

/* The contents follow along on wide screens. The offset clears the sticky
   topbar, which the anchors below have to clear as well. */
.admin-help-contents {
  position: sticky;
  top: 5.5rem;
}

.admin-help-toc {
  margin: 0;
  padding-left: 1.2rem;
  font-size: 0.9rem;
}

.admin-help-toc li {
  margin-bottom: 0.5rem;
}

.admin-help-toc li:last-child {
  margin-bottom: 0;
}

.admin-help-toc a {
  color: inherit;
  text-decoration: none;
}

.admin-help-toc a:hover {
  text-decoration: underline;
}

/* Jumping to a topic must not hide its heading behind the topbar. */
.admin-help-topic {
  scroll-margin-top: 5.5rem;
}

.admin-help p:last-child,
.admin-help ol:last-child,
.admin-help ul:last-child {
  margin-bottom: 0;
}

.admin-help li {
  margin-bottom: 0.4rem;
}

.admin-help dd code {
  color: inherit;
  background-color: var(--admin-bg);
  padding: 0.05rem 0.25rem;
}

/* A group of fields inside a form panel, for the few that answer a question of
   their own. Tinted rather than white, so it reads as a box inside the panel
   instead of as a second panel laid on top of it. */

.admin-fieldgroup {
  background-color: var(--admin-bg);
  border: 1px solid var(--admin-border);
  padding: 1rem 1.25rem;
}

/* Protocol ---------------------------------------------------------------- */

.trail {
  list-style: none;
  margin: 0;
  padding: 0;
}

.trail-item {
  position: relative;
  padding: 0 0 1.25rem 1.5rem;
  border-left: 2px solid var(--admin-border);
}

.trail-item:last-child {
  border-left-color: transparent;
  padding-bottom: 0;
}

/* Square, like everything else in here. */
.trail-item::before {
  content: "";
  position: absolute;
  left: -0.3rem;
  top: 0.35rem;
  width: 0.45rem;
  height: 0.45rem;
  background: var(--admin-muted);
}

.trail-item.is-additive::before { background: #3f7d20; }
.trail-item.is-destructive::before { background: var(--bs-primary, #b5332a); }
.trail-item.is-backfilled::before { background: var(--admin-border); }

.trail-diff {
  margin-top: 0.4rem;
  padding: 0.5rem 0.75rem;
  background: var(--admin-bg);
  border: 1px solid var(--admin-border);
  font-size: 0.8125rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  overflow-wrap: anywhere;
}

.trail-diff del {
  color: #8a2b24;
  text-decoration: line-through;
}

.trail-diff ins {
  color: #3f7d20;
  text-decoration: none;
}

/* Jumping to a related list must not hide its heading behind the topbar --
   the same offset the help topics use. */
.admin-anchor {
  scroll-margin-top: 5.5rem;
}

/* Was ist neu ------------------------------------------------------------- */

/* Prose, so the paragraphs read like prose rather than like table rows. The
   last one keeps the panel from carrying an empty line at its foot. */
.admin-changelog p {
  max-width: 68ch;
}

.admin-changelog .admin-panel-body p:last-child {
  margin-bottom: 0;
}

/* Marked in config/changelog.yml with **so**: a highlighter over the words
   worth noticing, in the same colour the whole-paragraph block uses. */
.admin-changelog mark {
  background-color: var(--highlight-color);
  padding: 0 0.15em;
  border-radius: 0.15rem;
  color: inherit;
}

/* A paragraph where the whole of it is the point -- the same colour again, as
   a block, with the intense bar to catch an eye scrolling past. Rare on
   purpose: a page of these marks nothing. */
.admin-changelog-important {
  background-color: var(--highlight-color);
  border-left: 3px solid var(--intense-color);
  padding: 0.75rem 1rem;
  border-radius: 0 0.25rem 0.25rem 0;
}

.admin-changelog-important mark {
  background-color: transparent;
  font-weight: 600;
  padding: 0;
}

/* Reihenfolge ziehen ------------------------------------------------------ */

/* The first cell of a draggable row: grip, number, arrows, on one line. */
.admin-order-cell {
  white-space: nowrap;
  color: var(--bs-secondary-color);
}

/* Shown only where the list can actually be reordered. A searched list cannot
   be -- it is missing the rows that did not match -- so the controls go with
   the drag instead of standing there failing. The number stays either way. */
.admin-order-grip,
.admin-order-arrows {
  display: none;
}

.is-reorderable .admin-order-grip {
  display: inline;
}

.is-reorderable .admin-order-arrows {
  display: inline;
}

/* The grip alone carries the drag, so a row cannot be moved by brushing past
   it while reading. */
.admin-order-grip {
  cursor: grab;
  opacity: 0.45;
  padding: 0 0.15rem;
}

.admin-order-grip:hover {
  opacity: 1;
}

.admin-order-grip:active {
  cursor: grabbing;
}

.admin-order-number {
  display: inline-block;
  min-width: 1.25em;
  text-align: right;
}

/* Always there rather than revealed on hover: they are the path for anyone not
   using a mouse, and a control that has to be hovered to be found is not one. */
.admin-order-arrow {
  border: 0;
  background: none;
  padding: 0 0.1rem;
  line-height: 1;
  color: inherit;
  opacity: 0.45;
}

.admin-order-arrow:hover,
.admin-order-arrow:focus-visible {
  opacity: 1;
}

.admin-table tr.is-dragging {
  opacity: 0.4;
}

/* Said once, briefly, in the corner: a saved drag needs an answer but not a
   whole flash message pushing the list down the page. */
.admin-order-note {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1080;
  padding: 0.5rem 0.9rem;
  border-radius: 0.375rem;
  background-color: #1f2937;
  color: #fff;
  font-size: 0.875rem;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
}

.admin-order-note.is-error {
  background-color: var(--intense-color);
}

/* Banner ------------------------------------------------------------------ */

/* The real proportions of the two places the banner is seen, so the preview
   crops the way the page will: 550 pixels tall on the front page, 340 on the
   production's own. */
/* Ausschnitte --------------------------------------------------------------- */

/* A preview box has the aspect ratio of the place it stands for, so what is
   cut off here is what is cut off there. */
.crop-preview {
  overflow: hidden;
  border-radius: 0.375rem;
  background-color: var(--bs-secondary-bg);
}

.crop-ratio-banner {
  aspect-ratio: 1400 / 550;
}

.crop-ratio-header {
  aspect-ratio: 1400 / 340;
}

.crop-ratio-card {
  aspect-ratio: 570 / 200;
}

.crop-ratio-teaser {
  aspect-ratio: 450 / 320;
}

.crop-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.align-field {
  min-width: 0;
}

/* The nine anchors in the shape of the choice: a 3x3 grid of radio buttons,
   where "oben rechts" is picked by pointing at the top right corner. The radio
   itself is hidden behind its cell rather than removed, so the grid keeps its
   keyboard and its screen reader. */
.align-picker {
  display: grid;
  grid-template-columns: repeat(3, 1.6rem);
  gap: 2px;
  flex: 0 0 auto;
}

.align-cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border: 1px solid var(--admin-border);
  border-radius: 0.2rem;
  background-color: white;
  cursor: pointer;
}

.align-cell input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.align-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background-color: var(--admin-border);
}

.align-cell:hover .align-dot {
  background-color: var(--admin-muted);
}

.align-cell:has(input:checked) {
  border-color: var(--intense-color);
  background-color: color-mix(in srgb, var(--intense-color) 12%, white);
}

.align-cell:has(input:checked) .align-dot {
  background-color: var(--intense-color);
}

.align-cell:has(input:focus-visible) {
  outline: 2px solid var(--intense-color);
  outline-offset: 1px;
}

/* Suche ------------------------------------------------------------------- */

/* Narrow enough to sit beside the buttons it shares the header with, and wide
   enough for a title. On a phone the header wraps and it takes the row. */
.admin-search .form-control {
  width: 12rem;
}

@media (max-width: 575.98px) {
  .admin-search {
    width: 100%;
  }

  .admin-search .form-control {
    width: auto;
    flex: 1 1 auto;
  }
}

/* Hints -------------------------------------------------------------------
   The "?" beside a page title leads to the manual; the one beside a field
   (ui/hint) opens a few sentences in place. Both stay quiet until pointed
   at, so a form full of them still reads as a form. */
.admin-page-help,
.admin-hint-toggle {
  color: var(--admin-muted);
  text-decoration: none;
  line-height: 1;
}

.admin-page-help {
  font-size: 1.1rem;
}

.admin-hint-toggle {
  font-size: 0.9em;
  margin-left: 0.25rem;
}

.admin-page-help:hover,
.admin-page-help:focus-visible,
.admin-hint-toggle:hover,
.admin-hint-toggle:focus-visible,
.admin-hint-toggle[aria-expanded="true"] {
  color: var(--intense-color);
}

.admin-hint-popover {
  --bs-popover-max-width: 22rem;
  --bs-popover-font-size: 0.875rem;
  --bs-popover-body-padding-x: 0.9rem;
  --bs-popover-body-padding-y: 0.7rem;
}
