@import url("helpers/fonts.d3e6cb6309f8.css");

body {
  background: #f3f3f3;
}

a {
  color: #05396b;
}

p {
  margin-bottom: 0px !important;
}

.box {
  background: white;
  padding: 2rem;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
  transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}

.box-standalone {
  margin-top: 2.5rem;
}

/* These styles are generated from project.scss. */

.alert-debug {
  color: black;
  background-color: white;
  border-color: #d6e9c6;
}

.alert-error {
  color: #b94a48;
  background-color: #f2dede;
  border-color: #eed3d7;
}

.dontdisplay {
  display: none;
}


hr {
  margin-top: 1rem;
  margin-bottom: 1rem;
  border: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.custom-85-width {
  max-width: 85%;
}

.custom-100-width {
  max-width: 100%;
}

.jSignature {
  border: 1px solid !important;
}

html {
  height: 100%;
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

/* #150: one shared normal-flow sticky footer for every shell (authenticated and
   public). The page is a flex column at least as tall as the viewport; the footer
   is the last in-flow child and margin-top:auto pushes it to the bottom on short
   pages while letting tall pages simply grow past it. This replaces the old
   absolute footer + fixed padding-bottom:6rem reservation, which tall content
   could out-grow so the footer overlapped it. body keeps position:relative so any
   body-relative absolute descendant is unaffected. */
body {
  position: relative;
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* #150: a single, stable gap between the page content and the footer, defined
   once here instead of per-page ad-hoc spacers. */
body > .container {
  margin-bottom: 2rem;
}


.footer {
  position: static;
  margin-top: auto;
  padding: 1rem;
  background-color: #efefef;
  text-align: center;
}

.willkommen {
  margin-top: 30px;
}

.first-steps {
  margin-top: 30px;
}

.dashboard-general {
  margin-top: 30px;
}

.dashboard-uebersicht {
  margin-bottom: 30px;
}

.dashboard-gemeinde-stats {
  margin-bottom: 10px;
}

.dashboard-standardtext {
  font-size: 12px;
}

.copybutton {
  margin-left: 10px;
  font-size: 12px;
  padding: 6px 10px;
  min-height: 32px;
}

body {
  font-family: 'Montserrat', Arial;
  font-weight: 300;
  font-size: 14px;
}

@media only screen and (min-width: 1200px) {
  .container {
    max-width: 1500px;
  }
}

.mb-1, .my-1 {
  margin-bottom: 35px !important;
}

h1 {
  font-size: 32px;
  margin-bottom: 15px;
}

h2 {
  font-size: 25px;
  margin-bottom: 15px;
}

h3 {
  font-size: 20px;
  margin-bottom: 5px;
}

table.dataTable thead .sorting:before, table.dataTable thead .sorting_asc:before, table.dataTable thead .sorting_desc:before, table.dataTable thead .sorting_asc_disabled:before, table.dataTable thead .sorting_desc_disabled:before {
  display: none;
}

table.dataTable thead .sorting:after, table.dataTable thead .sorting_asc:after, table.dataTable thead .sorting_desc:after, table.dataTable thead .sorting_asc_disabled:after, table.dataTable thead .sorting_desc_disabled:after {
  display: none;
}

.bg-light {
  background-color: #05396b !important;
}

.navbar-brand {
  color: #fff !important;
}

.navbar-light .navbar-nav .nav-link {
  color: #fff !important;
}

.footer {
  background-color: #adb5bd !important;
}

.footer a {
  color: #fff !important;
  font-weight: 300 !important;
}

.footer .text-center {
  color: #fff !important;
  font-weight: 300 !important;
}

.btn-success {
  background-color: #04726d !important;
  color: #fff !important;
  font-weight: 300 !important;
}

.btn-primary {
  background-color: #04726d !important;
  border-color: #04726d !important;
  color: #fff !important;
  font-weight: 300 !important;
}

.page-item.active .page-link {
  z-index: 1;
  color: #fff;
  background-color: #05396b;
  border-color: #05396b;
}

.btn-sm {
  font-weight: 300 !important;
  font-size: 13px !important;
  padding: 6px 10px !important;
  min-height: 32px;
}

.dashboard-general {
  margin-top: 50px;
  margin-bottom: 50px;
}

.dashboard-number {
  font-size: 50px;
}

.dashboard-day {
  font-size: 12px;
}

.attention {
  padding: 20px;
  color: #dc3545;
  border: 1px solid #dc3545;
}

.alert {
  padding: 20px;
  color: #000;
  border: 1px solid #000;
}

.card-header {
  background-color: #04726d !important;
  color: #fff !important;
}

.card {
  margin-top: 25px;
}

.navbar-light .navbar-toggler-icon {
  filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(102%) contrast(102%);
}

.navbar-light .navbar-toggler {
  color: rgba(255, 255, 255, 0.9);
  border-color: rgba(255, 255, 255, 0.9);
}

.table td {
  padding: 0.75rem 0.75rem 0.75rem 0;
}

@media only screen and (max-width: 767px) {
  /* Legacy stacked layout for form-style tables (e.g. the guest
     additional-visitor form in new_entry.html). Data tables opt out below. */
  .table td {
    padding: 0.75rem 0;
    display: block;
  }

  /* Horizontally-scrollable data tables keep real table semantics so no column
     collapses to character width. Covers .table-responsive wrappers and
     DataTables (incl. scrollX head/body tables); identical head+body padding
     keeps scrollX columns aligned. */
  .table-responsive table.table > thead > tr > th,
  .table-responsive table.table > tbody > tr > td,
  .table-responsive table.table > tbody > tr > th,
  .table-responsive table.table > tfoot > tr > td,
  .table-responsive table.table > tfoot > tr > th,
  .dataTables_wrapper table.dataTable > thead > tr > th,
  .dataTables_wrapper table.dataTable > tbody > tr > td,
  .dataTables_wrapper table.dataTable > tbody > tr > th {
    display: table-cell;
    white-space: nowrap;
    padding: 0.6rem 1rem 0.6rem 0;
  }
  /* #186: the shared statistics totals row lives in a <tfoot> inside a
     .table-responsive wrapper. Without the tfoot rule above it inherited the
     legacy `.table td { display:block }` stacking, so at 390px the "Summe"
     values stacked vertically out of the column grid instead of staying under
     their columns in the inner horizontal-scroll area. No column/value is
     hidden and no page is widened. */

  /* Responsive pagination on phones: reduced number count comes from DataTables
     `numbers_length` (datatables-defaults.js); these rules only let the short
     pager wrap and centre so Zurück/Weiter and the page numbers never overflow
     or clip. Tablet/desktop keep the default single-line pager. */
  .dataTables_wrapper .dataTables_paginate {
    float: none;
    text-align: center;
    padding-top: 0.25rem;
  }

  .dataTables_wrapper .dataTables_paginate .pagination {
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 0;
  }

  .dataTables_wrapper .dataTables_paginate .page-link,
  .dataTables_wrapper .dataTables_paginate .paginate_button {
    padding: 0.4rem 0.65rem;
  }
}

@media only screen and (max-width: 500px) {
  .jSignature {
    width: 320px !important;
  }

  /* Collapsed navbar submenu renders inline (static, unclipped) on phones, but
     must still respect its caret toggle: only show when Bootstrap marks it
     .show. Previously it was force-`display:block`, so a submenu (Aktiv/Storniert)
     stayed visible after the caret was closed even though aria-expanded=false
     (QA F-006). Table/content action dropdowns stay real toggles. */
  .navbar-nav .dropdown-menu {
    position: static;
    float: none;
  }
  .navbar-nav .dropdown-menu.show {
    display: block;
  }

  #div_id_additionalvisitor_set-0-DELETE {
    display: none;
  }
}

@media only screen and (max-width: 320px) {
  .jSignature {
    width: 319px !important;
  }
}

@media only screen and (min-width: 510px) {
  .guest-smaller {
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
  }

  .border-dash {
    border-right: 1px solid #acabab;
  }

  .dropdown:hover .dropdown-menu {
    display: block;
  }
}


@media only screen and (max-width: 767px) {
  .box {
    padding: 1rem;
  }

  .box-standalone {
    margin-top: 1rem;
  }
}

.custom-control-label::before {
  top: 2px;
}

.col-logo {
  text-align: right;
}

.col-logo img:first-of-type {
  width: 85px;
  margin-right: 1rem;
}

.col-logo img:last-of-type {
  width: 96px
}

.arrow-icon {
  padding-left: 7px;
}

/* Sprint 060 / #280: an `@import url("/helpers/spacing.css")` used to sit here.
   It was doubly ineffective: the path is root-absolute (the file is
   css/helpers/spacing.css), so every page load produced a 404, and CSS only
   honours @import before any rule — this one sat after several hundred. No
   declaration it could have brought in was ever applied, so removing it changes
   no rendered style; it only stops the 404. */

.btn-no-share {
  position: relative;
}

.btn-no-share:before {
  content: "";
  border-bottom: 1px solid white;
  width: 30px;
  height: 2px;
  position: absolute;
  transform: rotate(-45deg);
  top: auto;
  left: 5px;
  bottom: 17px;
}

#s_color_picker_id .picker_wrapper {
  margin: 0 -0.5em;
  margin-bottom: 0.5rem;
  background: white;
  border: 0;
  box-shadow: none;
}

.picker_editor, .picker_sample, .picker_done {
  display: none;
}
/* ============================================================
   Sprint 016: remove remaining responsive full-page overflow and
   add a clear focus state on inputs (esp. login). Desktop unchanged.
   ============================================================ */
body {
  overflow-x: hidden;
  max-width: 100%;
}

.form-control:focus,
input:focus,
select:focus,
textarea:focus {
  border-color: #05396b;
  box-shadow: 0 0 0 0.2rem rgba(5, 57, 107, 0.25);
  outline: none;
}

@media only screen and (max-width: 767px) {
  .form-control,
  select,
  input,
  textarea {
    max-width: 100%;
  }

  .dataTables_wrapper {
    max-width: 100%;
  }

  .dataTables_wrapper .dataTables_scrollHead {
    overflow: hidden !important;
  }
}


/* -------------------------------------------------------------------------
   Sprint 084 (#313): QA-002's rules for the fixed cookie banner are gone with
   the banner. They existed to stop an overlay covering the submit button on a
   390x844 viewport; the notice that replaced it is an ordinary line of page
   content, in the flow, overlapping nothing and reserving nothing.

   The `.cookiealert { display: none }` rule in the print/report chrome
   (ortstaxe/display_report.html and friends) is deliberately left alone: it
   names an element that no longer exists, which makes it inert, and three
   tests pin that chrome string for reasons of their own.
   ------------------------------------------------------------------------- */
/* Sprint 090 / #338 — AT-19. The line above was too quiet to do its job:
   0.82rem of grey, unseparated, at the very bottom of the page. UAT read it as
   "zu klein, unauffällig, unattraktiv", and since this is the page's ONLY
   statement about cookies and its only route to the data-protection notice,
   being overlooked is a substantive cost and not a cosmetic one.

   It is still the same notice — no button, no cookie, no JavaScript, no state,
   and it still asks for nothing (see the snippet's own comment for why adding a
   consent obligation here would be the wrong answer). Only its presentation
   changes: body-sized text, a calm card that separates it from the footer, a
   real link affordance, and a measure that stays readable on a phone instead of
   running the full 1500px the desktop container allows. */
.ib-privacy-notice {
  max-width: 46rem;
  margin: 2rem auto 1.5rem;
  padding: 0.875rem 1.25rem;
  border: 1px solid #e2e8f0;
  border-left: 4px solid #05396b;
  border-radius: 8px;
  background-color: #ffffff;
  color: #4a5568;
  font-size: 0.9375rem;
  line-height: 1.55;
}

.ib-privacy-notice a {
  color: #05396b;
  font-weight: 600;
  text-decoration: underline;
}

/* The link must never be split across two lines away from the sentence that
   introduces it — on a 320px display that is exactly what happened. */
.ib-privacy-notice .ib-privacy-notice-link {
  white-space: nowrap;
}

@media (max-width: 575.98px) {
  .ib-privacy-notice {
    margin: 1.5rem 0.75rem 1.25rem;
    padding: 0.75rem 1rem;
  }
}

/* -------------------------------------------------------------------------
   Shared guest-sheet status chips (Sprint 017 UI harmonisation, §6 / QA-017).
   Austria and Global render the Aktiv/Abgeschlossen/Storniert status with the
   same component and palette. Also defined inline on the Global list for older
   cached templates; identical values, so there is no conflict.
   ------------------------------------------------------------------------- */
.status-badge { font-size: .78rem; padding: .3em .6em; }
.status-open { background: #e7f1ff; color: #05396b; border: 1px solid #b6d4fe; }
.status-closed { background: #d2f1ba; color: #1e5631; border: 1px solid #b4e197; }
.status-cancelled { background: #eea6b0; color: #7d1420; border: 1px solid #e58a97; }

/* -------------------------------------------------------------------------
   Shared guest-sheet LIST toolbar + action controls (Sprint 020 parity).
   Austria and Global both render #entry_table with the same object-filter
   <select> toolbar and the same "quick action icon + Aktionen dropdown"
   controls (a mobile kebab replaces the label on phones). Previously the
   Austria rules were inline on its list and Global used its own pill-chip
   toolbar; both jurisdictions now share this one source.
   ------------------------------------------------------------------------- */
.entry-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  margin: 0.5rem 0 1rem;
}
.entry-toolbar .filter-group { display: flex; flex-direction: column; }
.entry-toolbar label {
  font-size: 0.8rem;
  font-weight: 600;
  color: #05396b;
  margin-bottom: 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.entry-toolbar select {
  min-width: 220px;
  max-width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  background-color: #fff;
  color: #05396b;
}
.entry-toolbar select:focus {
  outline: none;
  border-color: #04726d;
  box-shadow: 0 0 0 2px rgba(4, 114, 109, 0.2);
}
/* Sprint 090 / #338 — GL-05: the shared empty state of a guest-sheet list.
   ------------------------------------------------------------------------
   Both lists render `.entry-empty-state` with an `.entry-empty-actions`
   cluster. Austria has used those two class names since Sprint 203 and neither
   of them had a single declaration, so the buttons sat flush against each other
   and against the paragraph above them, and the Global list — which had no
   shared hook at all — wrapped a different structure entirely. Stating the two
   rules once is what makes "the same empty state" a fact rather than two
   templates that happen to contain similar words. */
.entry-empty-state { margin: 0.5rem 0 1rem; }
.entry-empty-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
}

/* GL-03: the object-list toolbar row. The two lists put their header and their
   create/import actions in one `d-flex justify-content-between` row; on a phone
   that row wraps, and without this the wrapped action block had no space above
   it on either page. */
.entry-toolbar.mr-3 { margin-bottom: 0; }

table.dataTable thead th { color: #05396b; }
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
  background: #05396b !important;
  border-color: #05396b !important;
  color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  background: #04726d !important;
  border-color: #04726d !important;
  color: #fff !important;
}
.dataTables_wrapper .dataTables_filter input:focus,
.dataTables_wrapper .dataTables_length select:focus {
  outline: none;
  border-color: #04726d;
}
#entry_table td, #entry_table th, #vo_table td, #vo_table th { vertical-align: middle; }
/* Action-control cluster used on every list (guest sheets AND objects, Austria
   and Global): a quick-action button + a labelled "Aktionen" dropdown that
   collapses to a kebab on phones. Scoped to .entry-actions (not a table id) so
   any list table can reuse it. */
.entry-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  white-space: nowrap;
}
/* POST actions rendered as dropdown items (Global close/cancel/toggle) look
   identical to Austria's <a> dropdown items. */
.entry-actions .dropdown-item.as-form { padding: 0; }
.entry-actions .dropdown-item.as-form button {
  all: unset;
  cursor: pointer;
  display: block;
  width: 100%;
  padding: .25rem 1.5rem;
  box-sizing: border-box;
}
.entry-actions .dropdown-item.as-form button:hover { background: #f8f9fa; }
/* The kebab icon is desktop-hidden; the word "Aktionen" is shown. */
.entry-actions .action-kebab { display: none; }
@media (max-width: 575.98px) {
  .entry-actions .action-label { display: none; }
  .entry-actions .action-kebab { display: inline-flex; }
  .entry-actions .btn { padding: 0.25rem 0.4rem; line-height: 1; }
  .entry-actions .dropdown-toggle::after { display: none; }
  .entry-actions .dropdown-menu { right: 0; left: auto; }

  /* HOTFIX: the collapsed kebab measured 20x29 CSS px — far below a reliable
     touch target, which is why the action menu "sometimes did not react" on a
     phone. Give it the standard 44x44 minimum and centre the glyph; the button
     keeps its small padding, the box just cannot shrink below the target. */
  .entry-actions .btn {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* HOTFIX: Bootstrap's `.dropdown-item` is `white-space: nowrap`, so the long
     labels ("Stammgast-Link kopieren") rendered 311px wide inside a 265px menu
     — the text ran out past the menu's white panel, which is what made the open
     menu look like a detached oversized block. Let the labels wrap, keep the
     panel inside the viewport, and give each entry a comfortable tap height. */
  /* A definite width, not shrink-to-fit: project.js pins the menu with
     `position: fixed`, so an `auto` width collapses to whatever space happens
     to be right of the pin point and the labels then spill out of the panel. */
  .entry-actions .dropdown-menu {
    width: 16rem;
    max-width: calc(100vw - 1rem);
  }
  /* The project resets box-sizing via `* { box-sizing: inherit }`, and these
     items end up inheriting `content-box`, so Bootstrap's 1.5rem left/right
     padding was ADDED to the panel width — every label overhung the menu by
     48px. Pin them to border-box so they stay inside the panel. */
  .entry-actions .dropdown-item {
    box-sizing: border-box;
    white-space: normal;
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .entry-actions .dropdown-item.as-form { padding: 0; }
  .entry-actions .dropdown-item.as-form button { min-height: 44px; }
}

/* -------------------------------------------------------------------------
   QA hotfix: the Aktion column must be reachable without sideways scrolling.

   `ibindoListTableLayout()` (datatables-defaults.js) now uses DataTables
   Responsive for every width below Bootstrap's lg breakpoint, so the wide
   guest-sheet tables collapse into child rows on phones AND tablets instead of
   parking the Aktion column outside a horizontally scrolling box.

   Responsive can only do that if it can MEASURE that the full table is wider
   than the viewport: it hides low-priority columns until the ones it must keep
   ("Name"/"Aktion", `className: "all"`) fit. That measurement is the table's
   min-content width — the sum of each cell's longest unbreakable run.

   The mobile rule further up forces `white-space: nowrap` on every DataTables
   cell — correct for a scrollX table, wrong for a Responsive one, where an
   unbreakable name would push the action cluster past the right edge. So inside
   a Responsive table (DataTables adds `.dtr-inline`) cells must be allowed to
   wrap. But they must wrap on WORD boundaries only. `overflow-wrap: anywhere`
   and `word-break: break-word` collapse a cell's min-content to a single
   character, so DataTables measured every table as "already fitting 390px",
   collapsed no column, and instead squeezed all 8-11 columns into the phone
   width — the reported #146 damage: every heading and value broken
   letter-by-letter, stacked vertically down the screen. `overflow-wrap:
   break-word` (NOT `anywhere`) with `word-break: normal` keeps the min-content
   at the longest word, so the column collapse still triggers, while a genuinely
   over-long single token still breaks as a last resort instead of overflowing
   the card. Desktop (>=992px, scrollX) is untouched.
   ------------------------------------------------------------------------- */
@media only screen and (max-width: 991.98px) {
  table.dataTable.dtr-inline {
    max-width: 100%;
    table-layout: auto;
  }

  /* Wrap on word boundaries only. `word-break: normal` + `overflow-wrap:
     break-word` preserve each cell's min-content (its longest word), which is
     exactly what DataTables Responsive measures to decide a column must collapse
     into the child row instead of being crushed to character width at 390px. */
  table.dataTable.dtr-inline > thead > tr > th,
  table.dataTable.dtr-inline > tbody > tr > td,
  table.dataTable.dtr-inline > tbody > tr > th {
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
  }

  /* The action cluster itself must never wrap mid-cluster (the buttons stay on
     one line) but the cell it lives in may be as narrow as the cluster. */
  table.dataTable.dtr-inline .entry-actions {
    white-space: nowrap;
  }

  /* Expanded child row: label/value pairs wrap on word boundaries; a genuinely
     over-long token still breaks (last resort) instead of widening the table,
     but normal text is never broken letter-by-letter. */
  table.dataTable.dtr-inline > tbody > tr > td.child ul.dtr-details,
  table.dataTable.dtr-inline > tbody > tr > td.child li,
  table.dataTable.dtr-inline > tbody > tr > td.child .dtr-data {
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
  }

  /* The action menu is right-anchored across the whole Responsive range, not
     just on phones. Without a `.dataTables_scrollBody` there is nothing for
     project.js to pin the menu to, so Bootstrap's own left-aligned placement
     applies — and on a 768px tablet that put a 265px menu ~67px past the right
     viewport edge. `data-display="static"` on the toggle keeps Popper out of
     the way, so this is the placement that actually wins. */
  .entry-actions .dropdown-menu {
    right: 0;
    left: auto;
    max-width: calc(100vw - 1rem);
  }
}

/* HOTFIX: the object <select> is sized by its longest option ("Ferienwohnung
   Panoramablick Obergeschoss Süd in 1010 Wien"). `.filter-group` is a flex item
   with the default `min-width: auto`, so it refused to shrink and the control
   measured 505px inside a 390px viewport — the right-hand part of the filter,
   including the drop-down arrow, sat outside the content area and was only
   hidden by the root `overflow-x: hidden`. Letting the group shrink (and
   filling the row on phones) keeps the toolbar inside the card at every width. */
.entry-toolbar .filter-group {
  min-width: 0;
  max-width: 100%;
}
@media (max-width: 767.98px) {
  .entry-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }
  .entry-toolbar select {
    width: 100%;
    min-width: 0;
  }
}

/* #358 / #360 F02: the Austria list's header controls at 390px.
   The select and the search field carried an inline `style="width:auto"`, which
   outranks every stylesheet rule — so the `width: 100%` above never applied and
   the object select kept the width of its longest option. Its wrapper was a flex
   item with the default `min-width: auto`, so nothing above it could shrink
   either: the toolbar measured ~473px in a 390px viewport and the root
   `overflow-x: hidden` merely hid the cut. The desktop width now lives here, and
   below the md breakpoint the whole cluster — filter, search, submit and the CSV
   export — is allowed to fill, and never exceed, the content column.
   Scoped to `.entry-list-header`, which only the Austria list carries: the
   Global list already fits and its layout is left exactly as it is. */
.entry-list-header > .d-flex.align-items-end { min-width: 0; max-width: 100%; }
.entry-list-header .entry-toolbar .form-control { width: auto; max-width: 100%; }
@media (max-width: 767.98px) {
  .entry-list-header > .d-flex.align-items-end { flex: 1 1 100%; }
  .entry-list-header .entry-toolbar {
    flex: 1 1 100%;
    min-width: 0;
    margin-right: 0 !important;
  }
  .entry-list-header .entry-toolbar .form-control { width: 100%; min-width: 0; }
  .entry-list-header .entry-toolbar .ml-1 { margin-left: 0 !important; }
}

/* -------------------------------------------------------------------------
   #147: guest-sheet action buttons must stay a reliable >= 44x44 touch target
   across the WHOLE responsive/tablet range, not only on phones.

   The phone block above (<= 575.98px) already gives the .entry-actions cluster
   a 44x44 minimum. This minimum was first extended to Bootstrap's lg breakpoint
   (991px) because the wide lists run in DataTables Responsive mode below lg --
   the DEV browser gate (run 30705446207) measured a button at 31.015625 x 38 px
   on Austria/iPad portrait (768px), below the 44x44 minimum.

   A follow-up DEV browser gate (run 30706129521) then found the SAME defect one
   band higher: at 1024px (iPad landscape) the lists are already back in the
   non-responsive scrollX layout, but the icon-only quick action still kept
   Bootstrap's native size and measured 26 x 38 px -- again below 44x44. So the
   minimum must reach past lg, up to Bootstrap's xl breakpoint (1200px). That
   also matches the tablet navigation layout, which stays collapsed up to
   1200px. Use `max-width: 1199.98px` so the whole 576-1199px band is covered.

   Extend the minimum to every VISIBLE .entry-actions button (quick action +
   Aktionen toggle) and to the open menu's rows across the whole tablet band.
   Desktop (>= 1200px, e.g. the 1440px reference) keeps Bootstrap's native size.
   Only a minimum box is enforced -- icons, labels, tooltips, routes and the
   dropdown/POST actions are unchanged. Guest sheets only (Austria + Global);
   the object-list `.object-actions` cluster is a separate, out-of-scope control.
   ------------------------------------------------------------------------- */
@media (max-width: 1199.98px) {
  .entry-actions .btn {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* The open menu's rows are touch targets too once the dropdown is expanded. */
  .entry-actions .dropdown-item {
    min-height: 44px;
  }
  .entry-actions .dropdown-item.as-form button {
    min-height: 44px;
  }
}

/* -------------------------------------------------------------------------
   Shared OBJECT-list action cluster (Sprint 024.02, §6).
   Austria and Global render the same icon buttons for an object row, but on
   Global they stacked vertically: the Aktionen column is the last of eight, so
   the browser wrapped the inline <a> buttons one per line and inflated the row
   height. Both jurisdictions now use this one flex cluster — same size, same
   gaps, same order, no wrapping on desktop — and it degrades in a controlled
   way on phones instead of overflowing the page.
   ------------------------------------------------------------------------- */
.object-actions {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem;
  white-space: nowrap;
}
.object-actions > .btn,
.object-actions > form > .btn {
  flex: 0 0 auto;
  margin: 0;
}
/* A POST action (e.g. activate/deactivate) sits in its own <form>; it must line
   up with the plain link buttons instead of introducing a block-level break. */
.object-actions > form {
  display: inline-flex;
  margin: 0;
}
@media (max-width: 575.98px) {
  /* Phones: ONE horizontal row. Sprint 093 (#341) — this was `flex-wrap: wrap`,
     which is what folded five actions into the reported 3+2 block and made the
     object rows twice as tall as they need to be. The cluster now sits inside
     `.object-list-table`'s horizontal scroll area, so the full row stays
     reachable by scrolling the table sideways instead of being wrapped onto a
     second line or clipped — and the page itself still never overflows.
     Button size, order, icons, routes and confirmations are unchanged. */
  .object-actions {
    flex-wrap: nowrap;
    justify-content: flex-start;
  }
  .object-actions > .btn,
  .object-actions > form > .btn {
    min-width: 2.5rem;
    min-height: 2.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* -------------------------------------------------------------------------
   Sprint 093 (#341): the OBJECT-list table on phones.
   Both object lists wrap their table in `.table-responsive.object-list-table`.
   `.table-responsive` is the sanctioned horizontal scroll box and already
   carries the "cells stay real table cells" opt-out from the legacy stacked
   `.table td { display: block }` form-table layout further up this file — that
   stacking is what broke Stadt/Link/Status/Aktion into letter-wide columns on
   the reported 390px screen whenever DataTables was not (yet) initialised.

   The minimum width is scoped to `:not(.dataTable)` and to a direct child on
   purpose: it is the pre-initialisation / JavaScript-off fallback only. Once
   DataTables initialises, it moves the table into its own `scrollX` body inside
   this container and sizes the columns itself; that inner body is exactly 100%
   wide, so the outer box has nothing left to scroll and no second scrollbar
   appears.

   Object lists only — no other table or form layout is affected.
   ------------------------------------------------------------------------- */
.object-list-table {
  max-width: 100%;
}

.object-list-table > table.table:not(.dataTable) {
  min-width: 48rem;
}

/* Same `:not(.dataTable)` scope, for the same reason: the headings must not
   break letter by letter while the table is still the plain server-rendered
   one. Once DataTables owns the table its own head/body rules apply and
   desktop is left exactly as it was. */
.object-list-table > table.table:not(.dataTable) > thead > tr > th {
  white-space: nowrap;
}

/* -------------------------------------------------------------------------
   Shared object-status badge (Sprint 054, #273).
   The Global object list carried these two rules in a local <style> block. Now
   that the Austrian list renders the same status, they live here once — one
   definition, one appearance in both jurisdictions. Values unchanged, so Global
   looks exactly as before. Both pairs stay above the WCAG AA 4.5:1 contrast
   ratio, and the state is never signalled by colour alone: the badge carries the
   word "Aktiv"/"Inaktiv" as text.
   ------------------------------------------------------------------------- */
.badge-active { background:#d2f1ba; color:#1e5631; }
.badge-inactive { background:#e0e0e0; color:#555; }

/* ============================================================
   Sprint 024 (F-004): no page-wide horizontal overflow on mobile.
   Wide data tables scroll INSIDE their own container; the page root
   never widens past the viewport. Long links/e-mails wrap instead of
   forcing the document wider. Desktop unchanged.
   ============================================================ */
html {
  overflow-x: hidden;
  max-width: 100%;
}

@media only screen and (max-width: 767px) {
  .container,
  .container-fluid {
    max-width: 100%;
  }

  .dataTables_wrapper,
  .dataTables_scroll,
  .dataTables_scrollHead,
  .dataTables_scrollHeadInner,
  .dataTables_scrollBody {
    max-width: 100%;
  }

  .dataTables_scrollBody {
    overflow-x: auto;
  }

  a,
  p,
  .alert,
  .value,
  .detail-value,
  .box {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
}


/* ============================================================
   QA-UI-004: complete the mobile (390px) responsive pass for Global.
   Charts, maps and any embedded media stay within the viewport instead of
   forcing the page wider (which the root overflow-x:hidden would otherwise
   merely clip). Every wide table lives in a real scroll container. Desktop
   (>=1200px, verified 1440x900) is untouched — these rules are phone-scoped.
   ============================================================ */
img,
svg,
canvas,
iframe,
embed,
video {
  max-width: 100%;
}

@media only screen and (max-width: 767px) {
  #stat-chart,
  #charts-container,
  #maps-container,
  .highcharts-container,
  .highcharts-root {
    max-width: 100% !important;
    width: 100% !important;
  }

  .table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  .jSignature,
  #signature,
  .signature-wrapper canvas {
    max-width: 100% !important;
  }
}


/* -------------------------------------------------------------------------
   #142 (public Austria guest sheet): keep the submit/DSGVO closing block and
   the FAQ/imprint block decoupled at every breakpoint (390/768/1024/1440 px).

   The FAQ block is now its own grid column (.entry-faq) instead of a raw
   flex-sibling of the crispy form column, so it already carries proper Bootstrap
   gutters and can never ride up under the "Absenden" button. These rules only
   add a clear visual separation above it and make sure the collapsible FAQ
   panels (and their nested .row negative margins) can never overhang the card.
   Submit / validation / signature / DSGVO behaviour is untouched.
   ------------------------------------------------------------------------- */
.entry-faq {
  clear: both;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

.entry-faq .collapse,
.entry-faq .collapsing {
  max-width: 100%;
}

/* -------------------------------------------------------------------------
   #149: profile / settings shell. From lg up the profile navigation is a side
   column (settings_base.html gives it col-lg-2); below lg it collapses into a
   compact, wrapped horizontal bar so the profile, personal-data and logout pages
   use the full tablet width for their actual content instead of losing a fixed
   side column. Nav links and routes are unchanged — only their layout.
   ------------------------------------------------------------------------- */
@media (max-width: 991.98px) {
  .settings-nav .sidebar-sticky {
    position: static;
  }
  .settings-nav .nav.flex-column {
    flex-direction: row !important;
    flex-wrap: wrap;
    gap: 0.25rem;
  }
  .settings-nav .nav-item {
    flex: 0 1 auto;
  }
  .settings-nav .nav-link {
    white-space: nowrap;
  }
}

/* -------------------------------------------------------------------------
   B-12 (QA-UI-012): soften the mobile profile navigation. Below lg the
   settings nav is a full-width solid dark-blue block that visually overwhelms
   the actual profile content. Keep the same links, routes and full tap targets
   but render them as a light, chip-style bar with a clear active/hover state.
   Desktop (>= lg) keeps the existing side-column styling untouched.
   ------------------------------------------------------------------------- */
@media (max-width: 991.98px) {
  .settings-nav .nav.bg-light {
    background-color: transparent !important;
  }
  .settings-nav .nav-item.border {
    border: 0 !important;
  }
  .settings-nav .nav-link {
    background-color: #f1f3f5;
    color: #05396b !important;
    border: 1px solid #d5dbe2;
    border-radius: 0.5rem;
    padding: 0.5rem 0.9rem;
  }
  .settings-nav .nav-link:hover,
  .settings-nav .nav-link:focus,
  .settings-nav .nav-link.active {
    background-color: #05396b;
    color: #fff !important;
    border-color: #05396b;
  }
}

/* -------------------------------------------------------------------------
   #189: profile contrast & active states.

   Desktop (>= lg) settings navigation used the low-contrast Bootstrap
   `.text-light` link colour on a light background (that class is now removed
   from settings_base.html). These rules give the side-column nav a
   high-contrast dark-blue text (>= 4.5:1 on the light background), visibly
   distinct hover / focus / active / pressed states, and a `:focus-visible`
   outline (>= 3:1) so keyboard users always see where they are. The turquoise
   `.btn-primary` download button and every route are untouched — colour only.
   ------------------------------------------------------------------------- */
@media (min-width: 992px) {
  .settings-nav .nav-link {
    color: #05396b;
    background-color: #fff;
  }
  .settings-nav .nav-link:hover {
    color: #05396b;
    background-color: #e9eef4;
  }
  .settings-nav .nav-link.active,
  .settings-nav .nav-link[aria-current="page"] {
    color: #fff;
    background-color: #05396b;
    font-weight: 600;
  }
  .settings-nav .nav-link:active {
    background-color: #042a4f;
    color: #fff;
  }
}

/* Keyboard focus is always clearly visible (>= 3:1), on both viewports. */
.settings-nav .nav-link:focus-visible {
  outline: 3px solid #0b5ed7;
  outline-offset: 2px;
}

/* #189: the profile meta labels ("Adresse", "USt ID", …) used an inline
   #8e8e8e that failed 4.5:1 on white. This reusable class raises the contrast
   (#4d5157 on white is ~7:1) and keeps the small-label sizing in one place. */
.profile-meta {
  color: #4d5157;
  font-size: 12px;
}

/* #191: a client-side "required" marker for the conditionally-required foreign
   ID-document fields. The JS toggle adds `.field-required` to a field wrapper
   when the guest's citizenship makes it mandatory; crispy does not know this at
   render time because the requirement depends on a value chosen in the form.
   Presentation only — EntryForm.clean() is authoritative. */
.field-required > label:first-child::after,
.field-required .create-label::after {
  content: " *";
  color: #dc3545;
}

/* -------------------------------------------------------------------------
   B-03 (QA-UI-003): raise core interactive targets to ~44x44 CSS px on phone
   and tablet so login, registration, password-reset and other core controls
   (inputs, primary buttons, the navbar toggler) are comfortably tappable. The
   rules are gated below lg, so the desktop layout is unchanged.
   ------------------------------------------------------------------------- */
@media (max-width: 991.98px) {
  .form-control,
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
  select,
  textarea {
    min-height: 44px;
  }
  .btn:not(.btn-sm) {
    min-height: 44px;
  }
  .navbar-toggler {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ---------------------------------------------------------------------------
   Sprint 257 / #252 — server-side sortable list headers and the visible list
   state bar. Compiled counterpart of the SCSS block; kept in sync by hand
   exactly like every other block in this file (gulp is not run on deploy).

   The sort affordance is deliberately NOT DataTables' sorting_asc/sorting_desc:
   those belong to a client-side sort that can only reorder the rows already on
   screen, which on a paginated list is misleading. These are plain links to a
   server-side ordering.
   ------------------------------------------------------------------------- */
.ib-sort-col {
  white-space: nowrap;
}

a.ib-sort {
  color: inherit;
  text-decoration: none;
}

a.ib-sort:hover,
a.ib-sort:focus {
  color: inherit;
  text-decoration: underline;
}

a.ib-sort:focus-visible {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

.ib-sort-active > a.ib-sort {
  font-weight: 700;
}

.ib-sort-arrow {
  font-size: 0.75em;
  line-height: 1;
}

.ib-list-state .ib-list-state-item + .ib-list-state-item::before {
  content: " \00b7 ";
}

/* ---------------------------------------------------------------------------
   QA21-UI-004 — the public guest sheet's DE/EN control. Compiled counterpart of
   the SCSS block; kept in sync by hand exactly like every other block in this
   file (gulp is not run on deploy).

   The inline copy this replaces dimmed the whole control with `opacity: .5`,
   which also dimmed the browser's focus ring — a keyboard user could not see
   where they were. Only the *flag* is dimmed now, never the outline, and the
   button carries a real 44x44 target so the touch size matches the rest of the
   mobile UI.
   ------------------------------------------------------------------------- */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 4px;
}

.lang-switch .lang-form {
  display: inline;
  margin: 0;
}

.lang-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 44px;
  min-height: 44px;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  font-size: 14px;
  line-height: 1;
  color: inherit;
}

.lang-button .lang-flag {
  /* Sprint 090 / #338 — AT-07. `images/de.png` and `images/uk.png` are 64x64
     SQUARES, and the markup asked for them at `width="28" height="19"`. The
     browser therefore scaled the two axes by different factors (0.44 against
     0.30) and every guest saw a horizontally stretched flag. One number for
     both axes here as well as in the snippet, so neither a stylesheet that
     loads later nor a missing width attribute can reintroduce the distortion.
     `object-fit: contain` keeps that true for any replacement asset whose own
     aspect ratio is not 1:1. */
  width: 22px;
  height: 22px;
  object-fit: contain;
  flex: 0 0 auto;
  opacity: 0.5;
}

.lang-button:hover .lang-flag,
.lang-button:focus .lang-flag,
.lang-button[aria-current="true"] .lang-flag {
  opacity: 1;
}

.lang-button-label {
  font-weight: 700;
  letter-spacing: 0.03em;
}

.lang-button[aria-current="true"] {
  border-color: #05396b;
}

.lang-button:focus,
.lang-button:focus-visible {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   Sprint 057 (#155) — support entry point, form honeypot and system status.

   Hand-kept in sync with the SCSS block at the end of sass/project.scss,
   exactly like every other block in this file (gulp is not run on deploy).
   ------------------------------------------------------------------------- */
/* Sprint 083 (#312): text-only. `gap` is gone with the glyph it separated —
   on a narrow viewport it was a ragged extra gap next to exactly one item in a
   navigation that is otherwise words. The 44x44 target and the focus ring stay:
   they belong to the control, not to the icon. */
.ib-support-link {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
}

.ib-support-link:focus,
.ib-support-link:focus-visible {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

/* The honeypot is moved off-screen rather than display:none. A field that is
   display:none is skipped by several form fillers, which is precisely the
   traffic this field exists to catch; off-screen still reaches no human,
   because it is also out of the tab order and aria-hidden. */
.ib-support-honeypot-wrap {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Sprint 084 (#313): the signup honeypot. `{{ form|crispy }}` renders every
   field the same way, so the field is hidden by the container crispy generates
   for it (`div_id_<name>`) rather than by a wrapper this template would have to
   write by hand. Off-screen rather than display:none, for the reason above:
   several form fillers skip a hidden field, which is the traffic it exists to
   catch. It is also aria-hidden and out of the tab order (see
   ibindo.custom_auth.forms). */
#div_id_company_website {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.ib-support-form textarea,
.ib-support-form select,
.ib-support-form input[type="file"] {
  max-width: 100%;
}

.ib-support-form .btn,
.ib-support-sent .btn {
  min-height: 44px;
}

.ib-status-list {
  margin: 0;
  padding: 0;
}

.ib-status-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 0;
  border-bottom: 1px solid #e6e6e6;
}

.ib-status-name {
  overflow-wrap: anywhere;
}

.ib-status-state {
  font-weight: 700;
}

.ib-status-state-operational {
  color: #1c6b3c;
}

.ib-status-state-limited {
  color: #8a5a00;
}

.ib-status-state-outage {
  color: #97231f;
}

.ib-status-state-maintenance {
  color: #05396b;
}

@media (max-width: 767px) {
  .ib-status-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Sprint 058 (#275) — support-centre navigation and the operating manual.
   Kept byte-for-byte in step with sass/project.scss, as in this repository. */

.ib-support-nav {
  margin: 0 0 16px 0;
  border-bottom: 1px solid #e6e6e6;
}

.ib-support-nav-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-support-nav-list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.ib-support-nav-list a:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

/* Sprint 083 (#312) — the current step. The meaning is carried by
   aria-current="page" in the markup; this only makes it visible, and it does so
   with weight and an underline as well as colour, so it survives a colour
   deficiency and a monochrome print. */
.ib-support-nav-link-current {
  font-weight: 700;
  border-bottom: 2px solid #05396b;
}

/* Sprint 083 (#312) — the support start: help, then status, then contact. */
.ib-support-lead,
.ib-support-form-lead,
.ib-support-form-first,
.ib-support-faq-intro,
.ib-support-faq-answer,
.ib-support-step-note {
  max-width: 70ch;
}

.ib-support-steps {
  margin: 0;
  padding-left: 20px;
}

.ib-support-step {
  margin-bottom: 28px;
}

.ib-support-step-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.ib-support-step-link:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

.ib-support-faq {
  margin: 0;
  padding: 0;
}

.ib-support-faq-item {
  padding: 12px 0;
  border-top: 1px solid #e6e6e6;
}

.ib-support-faq-question {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 6px;
  max-width: 70ch;
}

.ib-support-faq-scope {
  font-size: 0.875rem;
  color: #05396b;
  margin-bottom: 6px;
}

.ib-support-faq-more a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.ib-support-faq-more a:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

/* The contact form, kept calm: one column, full-width controls on a phone,
   never wider than a comfortable measure on a desktop. */
.ib-support-field {
  max-width: 46rem;
}

.ib-support-field textarea,
.ib-support-field select,
.ib-support-field input[type="file"] {
  width: 100%;
}

.ib-support-actions {
  margin-top: 20px;
}

@media (max-width: 767px) {
  .ib-support-steps {
    padding-left: 18px;
  }

  .ib-support-actions .btn {
    width: 100%;
  }
}

.ib-manual-title {
  overflow-wrap: anywhere;
}

.ib-manual-intro,
.ib-manual-summary {
  max-width: 70ch;
}

.ib-manual-banner {
  padding: 10px 12px;
  border-left: 3px solid #8a5a00;
  background-color: #fdf6e6;
}

.ib-manual-scope {
  display: inline-block;
  font-size: 0.875rem;
  color: #05396b;
}

.ib-manual-toc {
  margin: 0;
  padding-left: 20px;
}

.ib-manual-toc-item {
  margin-bottom: 12px;
}

.ib-manual-toc-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.ib-manual-toc-link:focus,
.ib-manual-editions a:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

.ib-manual-toc-summary {
  display: block;
  color: #5a5a5a;
  max-width: 70ch;
}

.ib-manual-section {
  margin: 20px 0;
}

.ib-manual-text,
.ib-manual-list,
.ib-manual-steps {
  max-width: 70ch;
}

.ib-manual-note {
  padding-left: 12px;
  border-left: 3px solid #adb5bd;
  max-width: 70ch;
}

.ib-manual-table-wrap {
  overflow-x: auto;
}

.ib-manual-table {
  width: 100%;
  border-collapse: collapse;
}

.ib-manual-table th,
.ib-manual-table td {
  padding: 8px;
  border: 1px solid #d5d5d5;
  text-align: left;
  vertical-align: top;
}

/* Sprint 102 (#350) — the manual's own pictures. Mirrors the block appended to
   static/sass/project.scss.

   The rules that matter are the ones that keep a 1363 px wide screenshot from
   breaking a 390 px viewport: the figure has no horizontal margin of its own,
   the image is bounded by its container and keeps its natural proportions
   through `height: auto`. The width/height attributes carry the real pixel
   size, so the browser reserves the correct box before the bytes arrive, and
   `height: auto` is what stops those same attributes from squashing the picture
   once CSS bounds the width. */
.ib-manual-figure {
  margin: 20px 0 24px;
  max-width: 100%;
}

.ib-manual-image {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid #d5d5d5;
  border-radius: 3px;
  background-color: #fff;
}

.ib-manual-figure-zoom {
  display: block;
  max-width: 100%;
}

.ib-manual-figure-zoom:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

.ib-manual-figure-caption {
  margin-top: 10px;
  font-size: 0.875rem;
  color: #5a5a5a;
  max-width: 70ch;
}

.ib-manual-figure-number {
  font-weight: 600;
  color: #05396b;
}

.ib-manual-editions {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-manual-editions a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

@media print {
  .ib-support-nav,
  .ib-manual-actions,
  .ib-manual-breadcrumb {
    display: none;
  }

  .ib-manual-section,
  .ib-manual-table,
  .ib-manual-figure {
    page-break-inside: avoid;
  }

  .ib-manual-image {
    max-width: 100%;
    height: auto;
  }

  .ib-manual-section-title {
    page-break-after: avoid;
  }
}

/* -------------------------------------------------------------------------
   Sprint 090 / #338 — AT-01 (operator navigation), AT-06 (the object's
   background colour tinting the form) and AT-20 (the public sheet's header on
   a narrow viewport).

   Hand-kept in sync with the block appended to sass/project.scss, exactly like
   every other block in this file (gulp is not run on deploy).
   ------------------------------------------------------------------------- */

/* --- AT-01: the right-hand operator navigation ---------------------------- */
/* Support / Neuigkeiten / Kommunikation / Mein Profil / Abmelden sat on five
   different baselines, Support visibly the worst. Three separate causes, none
   of them the items themselves:

   * `.ib-support-link` is the ONLY item with a box of its own. Sprint 057 gave
     it `display: inline-flex` and `min-height: 44px` so support would have a
     real touch target; its four neighbours are plain block `.nav-link`s whose
     height is whatever Bootstrap's padding makes it. One item measured and
     aligned differently from the rest, which is precisely why the reported
     symptom singled it out.
   * From xl up the <ul> is a flex row with the default `align-items: stretch`.
     Any item that wraps to two lines therefore makes its neighbours align
     against a taller line box instead of a shared centre.
   * Nothing stopped "Kommunikation" and "Mein Profil" wrapping, and between
     roughly 1200px and 1320px — the width at which the navigation has just
     expanded — they do.

   The fix normalises the BOX rather than the items: every link in this
   navigation becomes the same flex line box with the same 44px minimum target,
   the expanded row centres them on one axis, and the short labels do not wrap.
   No item is added, removed or reordered, and `.ib-support-link` keeps its own
   target and focus ring for the pages that render it outside this navigation
   (the support sub-navigation and the manual). */
.ib-operator-nav .nav-link {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  line-height: 1.2;
  white-space: nowrap;
}

@media (min-width: 1200px) {
  /* The expanded row only. Below this width the navigation is the collapsed
     column, where `align-items: center` would centre every label horizontally
     and take away the shared left edge a stacked menu is read by. */
  .ib-operator-nav {
    align-items: center;
  }

  .ib-operator-nav .nav-item + .nav-item {
    margin-left: 0.25rem;
  }
}

/* --- AT-06: the configured background colour must not tint the form ------- */
/* `custom_background_color` is an inline background on the OUTER card, and
   `.box` is the only rule that paints that card white. Every block inside it —
   the crispy form groups, `.guest-sheet-step`, `.entry-faq`,
   `.impressum-text`, the error summary — has no background of its own, so all
   of them inherited the tint. With anything darker than a pastel the sheet's
   dark-blue labels ended up as dark ink on a dark ground, on the one page a
   guest types their address, birthday and identity-document number into.

   The colour is the accommodation's and it stays: the card still carries it and
   still frames the page. What changes is that each content block sits on that
   card as its own opaque white panel, so the contrast of the text is fixed at
   ink-on-white for EVERY value the colour picker can produce. Nothing here
   reads the configured colour, computes a contrast ratio or picks a foreground,
   which is what makes the guarantee total rather than a heuristic that a
   sufficiently unusual colour could defeat.

   Deliberately a class on the existing grid columns rather than a new wrapper:
   a Bootstrap `.col-*` already carries the 15px gutter this panel needs as its
   inner padding, so the white edges line up exactly with the card's own
   padding and no element moves in the DOM. */
.guest-sheet-panel {
  background-color: #ffffff;
  border-radius: 8px;
  padding-top: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 1.25rem;
}

/* #142 gave the FAQ/imprint block a top border to separate it from the submit
   block it used to share a background with. The panel IS that separation now,
   and a rule across the top of a white card on a coloured ground reads as a
   seam rather than a divider. The block, its grid column and its collapse
   behaviour are untouched — only the two declarations that drew the seam. */
.guest-sheet-panel.entry-faq {
  margin-top: 0;
  padding-top: 1rem;
  border-top: 0;
}

/* The blocks that carry their own frame inside a panel must not go on drawing
   a second background under it. `.impressum-text` and `.guest-sheet-step` are
   named explicitly because both are reachable from a template that does not
   use the panel class (the mobile sheet head, the legacy sheet). */
.guest-sheet-card .impressum-text {
  background-color: transparent;
}

/* --- AT-20: the public sheet's header on a narrow viewport ---------------- */
/* The header was a `col-3` / `col-9` grid pair. At 390px `col-3` is 97px, of
   which 67px is content — and the DE/EN control is two 44px minimum touch
   targets plus their gap, i.e. 92px. A column whose width is a fixed FRACTION
   of the viewport cannot hold a control whose width is a fixed NUMBER OF
   PIXELS, so the control broke out of its column and the two language buttons
   came apart onto separate lines.

   The header is intrinsically sized now. The language control takes exactly the
   width it needs (`col-auto`), the brand takes whatever is left, and neither
   can overflow the row. Below 360px — a genuinely narrow display, not a normal
   phone — the brand wraps onto its own line and aligns left, which is a wrap
   the layout chose rather than one a too-small column forced.

   `.col-logo` is no longer applied here. Its `img:first-of-type` / `:last-of-type`
   rules were written for the two-image marketing header that Sprint 060 / #280
   removed; with a single image left, both matched it and the later one silently
   won, pinning the brand to 96px regardless of the inline `max-width`. The rules
   are left in place, inert, rather than deleted — deleting them is a separate
   decision about a selector this sprint does not otherwise touch. */
.guest-sheet-header {
  align-items: center;
  row-gap: 0.75rem;
}

.guest-sheet-header-lang {
  flex: 0 0 auto;
}

.guest-sheet-header-brand {
  /* `min-width: 0` lets the brand column actually shrink: a flex item's default
     `min-width: auto` is its content's min-content width, which for an image is
     its intrinsic width — the second way this header could overflow. */
  min-width: 0;
  text-align: right;
}

/* Sprint 107 (#362) F6: `max-width` now also says "never wider than the column".
   A bare `max-width: 220px` let the logo keep its 220px inside a brand column
   that `min-width: 0` had correctly shrunk next to the 92px language switch,
   so at 390px it ended 18px beyond the viewport — invisible only because the
   page-level overflow guard clipped it. The logo now scales down instead. */
.guest-sheet-brand {
  width: auto;
  max-width: min(220px, 100%);
  height: auto;
}

/* Two 44px targets and a 4px gap is 92px and it is not negotiable — it is the
   minimum touch size, not a preference. The control must therefore never be
   asked to wrap; the row around it is what gives way. */
.lang-switch {
  flex-wrap: nowrap;
}

.lang-button,
.lang-button-label {
  white-space: nowrap;
}

@media (max-width: 359.98px) {
  .guest-sheet-header-brand {
    text-align: left;
  }

  .guest-sheet-brand {
    max-width: min(160px, 100%);
  }
}

/* -------------------------------------------------------------------------
   Sprint 100 (#348), F02 — the stored Nächtigungsstatistik.

   Reported as „voll gepackt und ohne Abstand“: the report was one column of
   paragraphs separated by `<br>` tags, with the three export controls pressed
   against each other and wrapping unevenly. The template now emits named
   sections; these rules are the spacing and the table behaviour those sections
   need, and nothing else — colours and typography stay the site's.

   Hand-kept in sync with the block appended to sass/project.scss, exactly like
   every other block in this file (gulp is not run on deploy).
   ------------------------------------------------------------------------- */
.stats-report-section + .stats-report-section {
  margin-top: 1.5rem;
}

/* One consistent gap under every notice, on a phone and on a desktop alike.
   `.alert` already carries Bootstrap's bottom margin; this stops a run of two
   notices collapsing into one visual block. */
.stats-notice {
  margin-bottom: 0.75rem;
}

/* The disclosure that holds the long calculation explanation. A native
   <details>, so it works with JavaScript off; only the summary is given a
   real affordance and a 44px target. */
.stats-basis-details > summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: #05396b;
  font-size: 0.875rem;
  cursor: pointer;
}

.stats-basis-details > summary:focus {
  outline: 2px solid #05396b;
  outline-offset: 2px;
}

/* Eight columns of figures. The headings wrap to two or three lines instead of
   forcing the table wider than its own scroll container — the page itself must
   never become horizontally overbroad, which is what `.table-responsive`
   around this table guarantees. */
.stats-basis-table {
  min-width: 44rem;
}

.stats-basis-table > thead > tr > th {
  white-space: normal;
  overflow-wrap: break-word;
  vertical-align: bottom;
  font-size: 0.8125rem;
  line-height: 1.2;
}

.stats-basis-table > tbody > tr > td,
.stats-basis-table > tfoot > tr > th {
  white-space: nowrap;
}

/* The three export links. `inline-flex` + `gap` gives them the same spacing
   whether they sit on one row or wrap onto three, which is the uneven wrap the
   screenshot showed. */
.stats-export .btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0 0.5rem 0.5rem 0;
}

/* -------------------------------------------------------------------------
   Sprint 101 (#349) — der Ortstaxe-Bildschirmbericht.

   Gemeldet als „noch etwas überladen und die Abstände fehlen … bitte aufräumen
   wie auf der Seite für die Nächtigungsstatistik“. Die Anordnung übernimmt die
   abgenommenen `.stats-report-section`, `.stats-notice`,
   `.stats-basis-details` und `.stats-export` aus Sprint 100 unverändert — neue
   Regeln gibt es nur für den lesbaren Gesamtbetrag und für die beiden Tabellen,
   deren Spaltenform von der Statistik abweicht.

   Hand-kept in sync with the block appended to sass/project.scss, exactly like
   every other block in this file (gulp is not run on deploy).
   ------------------------------------------------------------------------- */
.taxe-amount {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.3;
}

/* Zwei Spalten, kein Scrollcontainer nötig. Die vier „davon“-Zeilen sind
   Teilmengen und werden dafür eingerückt statt über ein Inline-`padding-left`. */
.taxe-split-table {
  max-width: 34rem;
}

.taxe-split-table > tbody > tr > th {
  font-weight: 400;
}

.taxe-split-table > tbody > tr > td {
  text-align: right;
  white-space: nowrap;
}

.taxe-split-table > tbody > tr.taxe-split-sub > th {
  padding-left: 2rem;
}

/* Gästeblatt- und Objekttabelle: die Kopfzeilen brechen um, statt die Tabelle
   breiter zu machen als ihren eigenen `.table-responsive`-Container — die Seite
   selbst wird dadurch nie überbreit. */
.taxe-report-table {
  min-width: 46rem;
}

.taxe-report-table > thead > tr > th {
  white-space: normal;
  overflow-wrap: break-word;
  vertical-align: bottom;
  font-size: 0.8125rem;
  line-height: 1.2;
}

.taxe-report-table > tbody > tr > td {
  white-space: nowrap;
}

/* Objektname und Berechnungstext sind lange Freitexte. Sie brechen um; das
   frühere `font-size:11px` auf der Berechnungsspalte hat das Layout über eine
   kaum lesbare Schrift erzwungen und ist ersatzlos entfallen. */
.taxe-report-table > tbody > tr > td.taxe-wrap-cell {
  white-space: normal;
  overflow-wrap: break-word;
  min-width: 12rem;
  max-width: 22rem;
}

/* Sprint 107 (#362) F4 — a tooltip is a label, never a click target.
   Bootstrap 4 confines a tooltip to its scroll parent (`boundary:
   'scrollParent'`). Once a DataTables search left a single row in the
   `scrollX` body, that body was one row tall, Popper pushed the tooltip back
   on top of the very button it describes, and the first real click landed on
   the tooltip: "Styling" and "Deaktivieren" only showed their label until the
   filter was cleared. The object lists now initialise tooltips with
   `boundary: 'window'`; this rule makes sure no tooltip anywhere can swallow a
   click again, whatever its placement. */
.tooltip {
  pointer-events: none;
}
