/* Page styles: oeffentlich - loaded directly by views/partials/header.ejs
   after Bootstrap and public/style/panel.css. Plain CSS, only panel.css
   tokens. Holds what Bootstrap utilities in the templates cannot express
   (hooks set by scripts, few shared patterns of this page group). */

/* ---------------------------------------------------------------------------
   FRAME OF A PUBLIC PAGE
   Logged out, header.ejs opens a <main> without padding, so a public page
   brings its own centred frame. Logged in, the same page sits in the app
   layout, whose <main class="app-inhalt"> already pads - there the frame
   drops its own padding instead of doubling it. Width comes from one of the
   rahmen-* modifiers next to the class.
   --------------------------------------------------------------------------- */
.oeffentlich-rahmen { width: 100%; margin-left: auto; margin-right: auto; padding: 3rem var(--z-gutter); }
@media (min-width: 576px) { .oeffentlich-rahmen { padding-top: 4rem; padding-bottom: 4rem; } }
.rahmen-schmal { max-width: 36rem; }
.rahmen-text { max-width: 48rem; }
.rahmen-mittel { max-width: 64rem; }
.rahmen-breit { max-width: 72rem; }
.rahmen-docs { max-width: 90rem; }
@media (min-width: 992px) { .rahmen-docs { padding-left: 1.5rem; padding-right: 1.5rem; } }
.app-inhalt .oeffentlich-rahmen { padding: 0; }

/* Short centred statement (views/whitemode.ejs) */
.oeffentlich-mitte { min-height: 50vh; display: grid; place-items: center; text-align: center; }

/* ---------------------------------------------------------------------------
   LANDING PAGE (views/index.ejs)
   --------------------------------------------------------------------------- */
@media (min-width: 576px) { .oeffentlich-held { padding-top: 6rem; padding-bottom: 6rem; } }
.held-titel { margin: 0; font-size: 2.25rem; font-weight: 600; letter-spacing: -.02em; }
@media (min-width: 576px) { .held-titel { font-size: 3rem; } }
.held-text { max-width: 42rem; }

/* The typed line (public/js/typing-animation.js fills .typing-text); the
   fixed height keeps the page from jumping while it types. */
.tipp-zeile { display: flex; align-items: center; height: 2.25rem; font-size: 1.25rem; font-weight: 500; color: var(--z-text); }
@media (min-width: 576px) { .tipp-zeile { font-size: 1.5rem; } }
.tipp-cursor { display: inline-block; width: 2px; height: 1.5rem; margin-left: .25rem; background: var(--z-text); animation: oeffentlich-blinken 1s infinite; }
@keyframes oeffentlich-blinken {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* Feature cards: square icon field above the title */
.merkmal-icon { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 1px solid var(--z-border); border-radius: var(--z-radius-sm); background: var(--z-bg); color: var(--z-text); }

/* Provider strip: the list is drawn twice, the track moves by half its
   width, so the end joins the start seamlessly. */
.laufband { overflow: hidden; padding: 2rem 0; border: 1px solid var(--z-border); border-radius: var(--z-radius); background: var(--z-surface);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent); }
.laufband-spur { display: flex; width: max-content; animation: oeffentlich-laufband 50s linear infinite; }
.laufband-spur:hover { animation-play-state: paused; }
.laufband-eintrag { display: flex; flex-shrink: 0; align-items: center; justify-content: center; margin: 0 2rem; }
.laufband-eintrag img { height: 3rem; width: auto; max-width: 9rem; object-fit: contain; opacity: .8; transition: opacity .15s ease; }
.laufband-eintrag img:hover { opacity: 1; }
@keyframes oeffentlich-laufband {
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .tipp-cursor, .laufband-spur { animation: none; }
}

/* ---------------------------------------------------------------------------
   CHANGELOG (views/changelog.ejs)
   The inline script there toggles aria-pressed on the filter buttons and
   "hidden" on .cl-gruppe / .cl-version - display is set here without
   !important, so Bootstrap's [hidden] rule still wins.
   --------------------------------------------------------------------------- */
.cl-filter { display: inline-flex; align-self: flex-start; gap: .25rem; padding: .25rem; border-radius: var(--z-radius-sm); background: var(--z-hover); }
.cl-filter button { display: inline-flex; align-items: center; gap: .5rem; padding: .25rem .75rem; border: 0; border-radius: var(--z-radius-xs); background: none; color: var(--z-muted); font-size: .875rem; font-weight: 500; }
.cl-filter button:hover { color: var(--z-strong); }
.cl-filter button[aria-pressed="true"] { background: var(--z-bg); color: var(--z-strong); }
.cl-filter button span { color: var(--z-muted); font-size: var(--z-fs-xs); }
.cl-monat { margin: 0; font-size: .875rem; font-weight: 500; color: var(--z-muted); }
.cl-versionen { display: flex; flex-direction: column; gap: .75rem; margin: 0; padding: 0; list-style: none; }
.cl-version { display: grid; gap: .75rem; padding: 1rem; border: 1px solid var(--z-border); border-radius: var(--z-radius); background: var(--z-surface); scroll-margin-top: 5rem; }
@media (min-width: 576px) { .cl-version { grid-template-columns: 9rem minmax(0, 1fr); padding: 1.25rem; } }
.cl-version:target { border-color: var(--z-accent); }
.cl-version-nummer { font-family: var(--z-mono); font-size: .875rem; font-weight: 600; color: var(--z-strong); text-decoration: none; }
.cl-version-nummer:hover { text-decoration: underline; color: var(--z-strong); }
.cl-version ul { margin: 0; padding-left: 1.25rem; font-size: .875rem; }
.cl-version li + li { margin-top: .25rem; }
.cl-version li::marker { color: var(--z-muted); }

/* ---------------------------------------------------------------------------
   PUBLIC PROFILE (views/user.ejs)
   --------------------------------------------------------------------------- */
.profil-raster { display: grid; gap: var(--z-gap); align-items: start; }
@media (min-width: 768px) { .profil-raster { grid-template-columns: 18rem minmax(0, 1fr); } }
.profil-bild { width: 6rem; height: 6rem; border-radius: 50%; object-fit: cover; }
.profil-initiale { display: grid; place-items: center; background: rgba(var(--z-accent-rgb), var(--z-soft-alpha)); color: var(--z-soft-primary); font-size: 1.875rem; font-weight: 600; }

/* ---------------------------------------------------------------------------
   LEGAL TEXT (views/legal/privacy-policy.ejs)
   --------------------------------------------------------------------------- */
.rechtstext { color: var(--z-muted); }
.rechtstext h2 { margin: .5rem 0 0; font-size: 1.05rem; font-weight: 600; color: var(--z-strong); }
.rechtstext p, .rechtstext ul { margin: 0; }
.rechtstext ul { padding-left: 1.5rem; }
.rechtstext li + li { margin-top: .25rem; }

/* ---------------------------------------------------------------------------
   LOGIN PAGES (views/auth/*.ejs): one centred card, at most 26rem wide
   --------------------------------------------------------------------------- */
.anmelde-seite { min-height: calc(100svh - 4rem); display: grid; place-items: center; padding: 3rem var(--z-gutter); }
.anmelde-spalte { width: min(100%, 26rem); display: flex; flex-direction: column; gap: 1.5rem; }
.anmelde-spalte > .card > .card-body { padding: 1.75rem 1.5rem; }
.anmelde-kopf { display: flex; flex-direction: column; align-items: center; gap: .35rem; text-align: center; }
.anmelde-kopf img { width: 2.5rem; height: 2.5rem; margin-bottom: .5rem; }
.anmelde-kopf .card-title { font-size: 1.25rem; }
.anmelde-kopf p { margin: 0; color: var(--z-muted); font-size: var(--z-fs-small); }
.anmelde-fuss { text-align: center; color: var(--z-muted); font-size: .875rem; }
.anmelde-fuss p { margin: 0 0 .25rem; }
.anmelde-fuss p:last-child { margin-bottom: 0; }
.anmelde-fuss a { color: var(--z-muted); text-decoration: none; }
.anmelde-fuss a:hover { color: var(--z-strong); text-decoration: underline; }
.anmelde-fuss a.anmelde-fuss-ziel { color: var(--z-text); text-decoration: underline; }

/* 2FA code field: six digits, spaced; the inline script in twofactor.ejs
   swaps the class for a backup code */
.zweifaktor-code { height: 3rem; text-align: center; font-family: var(--z-mono); font-size: 1.25rem; letter-spacing: .5em; text-indent: .5em; }

/* Password strength (public/js/auth.js)
   auth.js sets stufe-0 … stufe-4 on .anmeld-staerke and "erfuellt" on each
   fulfilled requirement. */
.anmeld-staerke { display: flex; flex-direction: column; gap: .375rem; margin-top: .5rem; }
.anmeld-staerke-balken { display: flex; gap: .25rem; }
.anmeld-staerke-balken > span { height: .25rem; flex: 1; border-radius: 99px; background: var(--z-hover); transition: background-color .15s ease; }
.anmeld-staerke.stufe-1 .anmeld-staerke-balken > span:nth-child(1) { background: var(--z-danger); }
.anmeld-staerke.stufe-2 .anmeld-staerke-balken > span:nth-child(-n+2) { background: var(--z-soft-danger); }
.anmeld-staerke.stufe-3 .anmeld-staerke-balken > span:nth-child(-n+3) { background: var(--z-warning); }
.anmeld-staerke.stufe-4 .anmeld-staerke-balken > span { background: var(--z-success); }
.anmeld-staerke-text { color: var(--z-muted); font-size: var(--z-fs-xs); }

.anmeld-regeln { display: grid; gap: .125rem .75rem; margin: 0; padding: 0; list-style: none; color: var(--z-muted); font-size: var(--z-fs-xs); }
@media (min-width: 400px) { .anmeld-regeln { grid-template-columns: 1fr 1fr; } }
.anmeld-regeln li { display: flex; align-items: center; gap: .375rem; }
.anmeld-regeln li::before { content: '○'; }
.anmeld-regeln li.erfuellt { color: var(--z-soft-success); }
.anmeld-regeln li.erfuellt::before { content: '✓'; }

/* ---------------------------------------------------------------------------
   DOCUMENTATION LAYOUT (views/docs/*.ejs)
   One column on narrow screens, outline | text from lg, plus the anchors of
   the page from xxl. The mobile bar (.docs-leiste) carries d-lg-none: if it
   stayed on desktop it would take the first grid column and shift the rest.
   Every sticky column carries align-self-start - a stretched grid child
   cannot stick.
   --------------------------------------------------------------------------- */
.docs-raster { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 992px) { .docs-raster { grid-template-columns: 16rem minmax(0, 1fr); column-gap: 2.5rem; } }
@media (min-width: 1400px) { .docs-raster { grid-template-columns: 16rem minmax(0, 1fr) 13rem; column-gap: 3rem; } }

/* Mobile bar with the outline button, bleeds to the window edge */
.docs-leiste { margin: 0 calc(-1 * var(--z-gutter)) 1rem; padding: .6rem var(--z-gutter); border-bottom: 1px solid var(--z-border); background: rgba(var(--bs-body-bg-rgb), .95); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
/* Logged in, the app's sticky top bar (.oberleiste) covers the top of the
   window on narrow screens - the docs bar sticks below it. */
.app-inhalt .docs-leiste { top: 3.25rem; }

/* Outline: a drawer on narrow screens (public/js/docs.js switches data-offen
   between "nein" and "ja"), a sticky column from lg. bottom/left are reset
   explicitly there - a sticky element with both top and bottom set does not
   stick. */
.docs-gliederung { position: fixed; top: 0; bottom: 0; left: 0; z-index: 1045; width: min(84vw, 20rem); overflow-y: auto; padding: 1.25rem 1rem 2.5rem; border-right: 1px solid var(--z-border); background: var(--z-bg); transform: translateX(-100%); transition: transform .2s ease; }
.docs-gliederung[data-offen="ja"] { transform: none; }
@media (min-width: 992px) {
  .docs-gliederung { position: sticky; top: 1rem; bottom: auto; left: auto; z-index: auto; width: auto; max-height: calc(100vh - 2rem); padding: 1.5rem 1rem 1.5rem 0; border-right: 0; background: transparent; transform: none; transition: none; }
}
/* Backdrop behind the open drawer, created by public/js/docs.js */
.docs-schleier { position: fixed; inset: 0; z-index: 1040; padding: 0; border: 0; background: var(--z-backdrop); }

.docs-suche { position: relative; margin-bottom: 1rem; }
.docs-suche > .bi { position: absolute; top: 50%; left: .65rem; transform: translateY(-50%); color: var(--z-muted); font-size: .85rem; pointer-events: none; }
.docs-suche .form-control { padding-left: 2rem; }

/* Lists toggled with the hidden attribute: display without !important */
.docs-treffer { display: flex; flex-direction: column; gap: .25rem; margin-bottom: .5rem; }
.docs-treffer-link { display: block; padding: .5rem .625rem; border-radius: var(--z-radius-sm); color: var(--z-text); text-decoration: none; }
.docs-treffer-link:hover { background: var(--z-hover); color: var(--z-strong); }
.docs-treffer-link strong { color: var(--z-strong); }
.docs-baum { display: flex; flex-direction: column; gap: 1.25rem; }
.docs-bereich { display: flex; flex-direction: column; gap: .125rem; }
.docs-bereich-titel { display: block; padding: 0 .625rem .375rem; color: var(--z-muted); font-size: var(--z-fs-xs); font-weight: 500; }
.docs-link { display: block; padding: .375rem .625rem; border-radius: var(--z-radius-sm); color: var(--z-muted); font-size: .875rem; text-decoration: none; transition: background-color .15s ease, color .15s ease; }
.docs-link:hover { background: var(--z-hover); color: var(--z-strong); }
.docs-link[aria-current="page"] { background: var(--z-hover); color: var(--z-strong); font-weight: 500; box-shadow: inset 2px 0 0 var(--z-accent); }

/* Middle column */
.docs-inhalt { padding: .5rem 0 4rem; }
@media (min-width: 992px) { .docs-inhalt { padding: 2.5rem 0 6rem; } }
.docs-pfad { display: flex; flex-wrap: wrap; align-items: center; gap: .375rem; margin-bottom: .75rem; color: var(--z-muted); font-size: .875rem; }
.docs-pfad a { color: inherit; text-decoration: none; }
.docs-pfad a:hover { color: var(--z-strong); }
.docs-titel { margin: 0 0 .75rem; font-size: 1.875rem; font-weight: 600; letter-spacing: -.02em; text-wrap: balance; }
@media (min-width: 576px) { .docs-titel { font-size: 2.25rem; } }
.docs-einleitung { max-width: 48rem; margin-bottom: 2rem; color: var(--z-muted); font-size: 1.05rem; }
.docs-breite { max-width: 48rem; }

/* Overview cards (index.ejs, internal-index.ejs): the whole card is a link */
.docs-karten { display: grid; gap: 1rem; max-width: 48rem; }
@media (min-width: 576px) { .docs-karten { grid-template-columns: 1fr 1fr; } }
.docs-karte { color: var(--z-text); text-decoration: none; transition: background-color .15s ease; }
.docs-karte:hover { --bs-card-bg: var(--z-hover); color: var(--z-text); }

/* Paging at the end of an article */
.docs-blaettern { display: grid; gap: .75rem; max-width: 48rem; margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--z-border); }
@media (min-width: 576px) { .docs-blaettern { grid-template-columns: 1fr 1fr; } }
.docs-blatt { display: block; padding: 1rem; border: 1px solid var(--z-border); border-radius: var(--z-radius); color: var(--z-text); text-decoration: none; transition: background-color .15s ease; }
.docs-blatt:hover { background: var(--z-hover); color: var(--z-strong); }

/* Right column: the headings of this page; public/js/docs.js sets .ist-hier */
.docs-marken { top: 2.5rem; max-height: calc(100vh - 5rem); overflow-y: auto; padding: 2.5rem 0; }
.docs-marke { display: block; padding: .25rem 0 .25rem .75rem; border-left: 2px solid var(--z-border); color: var(--z-muted); font-size: .875rem; line-height: 1.375; text-decoration: none; transition: color .15s ease; }
.docs-marke:hover { color: var(--z-strong); }
.docs-marke[data-ebene="3"] { padding-left: 1.5rem; font-size: var(--z-fs-xs); }
.docs-marke.ist-hier { border-left-color: var(--z-accent); color: var(--z-strong); }

@media (prefers-reduced-motion: reduce) {
  .docs-gliederung, .docs-link, .docs-karte, .docs-blatt, .docs-marke { transition: none; }
}

/* ---------------------------------------------------------------------------
   DOCUMENTATION TEXT
   The article HTML is rendered from Markdown by services/docsService.js
   (plain h2/h3/p/ul/ol/table/pre/code plus the notice blocks .docs-block--*),
   so it is styled from the outside. Also used for the running text of
   /about/technologie.
   --------------------------------------------------------------------------- */
.docs-text { max-width: 48rem; font-size: .9375rem; line-height: 1.75rem; color: var(--z-text); }
.docs-text > :first-child { margin-top: 0; }
.docs-text :is(h1, h2, h3) { scroll-margin-top: 5rem; font-weight: 600; letter-spacing: -.015em; color: var(--z-strong); }
.docs-text h1 { margin: 2.5rem 0 1rem; font-size: 1.5rem; }
.docs-text h2 { margin: 2.5rem 0 .75rem; padding-bottom: .5rem; border-bottom: 1px solid var(--z-border); font-size: 1.25rem; }
.docs-text h3 { margin: 2rem 0 .5rem; font-size: 1.125rem; }
.docs-text p { margin: 0 0 1rem; }
.docs-text a { font-weight: 500; color: var(--z-strong); text-decoration: underline; text-decoration-color: var(--z-muted); text-underline-offset: 4px; }
.docs-text a:hover { text-decoration-color: var(--z-strong); }
.docs-text strong { font-weight: 600; color: var(--z-strong); }
.docs-text :is(ul, ol) { margin: 0 0 1rem; padding-left: 1.5rem; }
.docs-text li + li { margin-top: .375rem; }
.docs-text ul { list-style: disc; }
.docs-text ol { list-style: decimal; }
.docs-text li::marker { color: var(--z-muted); }
.docs-text code { padding: .125rem .375rem; border-radius: var(--z-radius-xs); background: var(--z-hover); font-family: var(--z-mono); font-size: .85em; color: var(--z-text); overflow-wrap: anywhere; }
.docs-text pre { margin: 0 0 1.25rem; padding: 1rem; overflow-x: auto; border: 1px solid var(--z-border); border-radius: var(--z-radius); background: var(--z-bg); }
.docs-text pre code { padding: 0; background: transparent; font-size: .8125rem; line-height: 1.625; overflow-wrap: normal; }
/* Tables scroll on their own - the page never scrolls sideways */
.docs-text table { display: block; width: 100%; margin: 0 0 1.25rem; overflow-x: auto; border-collapse: collapse; font-size: .875rem; }
.docs-text :is(th, td) { padding: .5rem .75rem; border: 1px solid var(--z-border); text-align: left; white-space: nowrap; }
.docs-text th { background: var(--z-hover); font-weight: 500; color: var(--z-strong); }
.docs-text blockquote { margin: 0 0 1.25rem; padding-left: 1rem; border-left: 2px solid var(--z-border); color: var(--z-muted); }

/* :::hinweis / :::tipp / :::warnung / :::achtung */
.docs-text .docs-block { margin: 0 0 1.25rem; padding: .75rem 1rem; border: 1px solid var(--z-border); border-left-width: 4px; border-radius: var(--z-radius); background: rgba(var(--z-neutral-rgb), .04); }
.docs-text .docs-block > :last-child { margin-bottom: 0; }
.docs-block-titel { display: flex; align-items: center; gap: .5rem; margin-bottom: .375rem; font-size: var(--z-fs-xs); font-weight: 600; letter-spacing: .025em; text-transform: uppercase; }
.docs-text .docs-block--hinweis { border-left-color: var(--z-info); }
.docs-block--hinweis .docs-block-titel { color: var(--z-soft-info); }
.docs-text .docs-block--tipp { border-left-color: var(--z-success); }
.docs-block--tipp .docs-block-titel { color: var(--z-soft-success); }
.docs-text .docs-block--warnung { border-left-color: var(--z-warning); }
.docs-block--warnung .docs-block-titel { color: var(--z-soft-warning); }
.docs-text .docs-block--achtung { border-left-color: var(--z-danger); }
.docs-block--achtung .docs-block-titel { color: var(--z-soft-danger); }

/* ---------------------------------------------------------------------------
   PRIVACY SHIELD (views/partials/privacy-blur.ejs)
   The script there toggles .sichtbar.
   --------------------------------------------------------------------------- */
.datenschutz-schild {
  opacity: 0;
  visibility: hidden;
  transition: opacity .22s ease, visibility 0s linear .22s;
}
.datenschutz-schild.sichtbar {
  opacity: 1;
  visibility: visible;
  transition: opacity .22s ease, visibility 0s;
}
/* Moves slightly towards the viewer when fading in */
.datenschutz-tafel {
  transform: translateY(6px);
  transition: transform .22s cubic-bezier(.16, 1, .3, 1);
}
.datenschutz-schild.sichtbar .datenschutz-tafel { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .datenschutz-schild, .datenschutz-tafel { transition: none; }
}
