/* === Layout resets ===
   The system font stack is declared ONCE here; everything inherits.
   (The early duplicate on .large-heading was dead — the type-scale
   section deliberately uses font-family: inherit.) */
html {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

body {
    margin: 0;
    box-sizing: border-box;
    /* fruity ships its own body font-family (IBMPlexSans chain) — the
       stack must be re-asserted on body, html alone loses that fight */
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* === Hide LimeSurvey internal logo === */
svg.ls-logo {
    display: none !important;
}

/* === Header logos & "..." menu — geometry via CSS variables ===
   Layout (all widths): institute logo top-left (per-survey theme options
   brandlogo/brandlogofile), TU logo top-right, "..." menu LEFT of the TU
   logo with its dots vertically centered on the logo height. One pair of
   variables drives every dependent rule. */
:root {
    --tu-logo-h: 64px;    /* mobile: compact brand mark */
    --tu-logo-w: 174px;   /* follows the SVG aspect (141.1 x 51.86) */
    --header-gap: 20px;   /* air between menu and TU logo */
}

@media (min-width: 768px) {
    :root {
        --tu-logo-h: 88px;
        --tu-logo-w: 238px;
    }
}

#tug-logo-container {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 9999;
    background-color: transparent;
    padding: 8px 20px 8px 0;
    width: var(--tu-logo-w);
    height: var(--tu-logo-h);
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

#tug-logo-container svg#tu-logo {
    width: 100%;
    height: auto;
    display: block;
    margin: 0;                /* former 1rem/2rem margins inflated the box to 96px */
}

/* Institute logo slot — layout_global.twig renders it only when the
   per-survey option brandlogo=on with an uploaded file exists */
#institute-logo {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9999;
    height: var(--tu-logo-h);
    max-width: 45vw;
    padding: 8px 0 8px 20px;
    display: flex;
    align-items: center;
}

#institute-logo img {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
}

/* "..." menu: left of the TU logo, dots vertically centered on logo height.
   position:fixed pops it out of the (right-aligned) navbar flow — the
   menu was unreachable under the logo below ~1100px viewport width. */
#navbar-menu {
    position: fixed;
    top: calc((var(--tu-logo-h) - 31px) / 2);
    right: calc(var(--tu-logo-w) + var(--header-gap));
    z-index: 10001;
}

/* Dropdown panel: anchor to the viewport right edge (below the TU logo)
   instead of the 43px toggle button — the ~250px panel otherwise leaves
   the viewport on narrow screens (measured x=-69 at 390px). */
#navbar-menu > #main-dropdown {
    position: fixed !important;
    top: calc(var(--tu-logo-h) + 8px) !important;
    right: var(--header-gap) !important;
    left: auto !important;
    inset: auto;
    transform: none !important;
    will-change: auto;
}

/* Content clearance under the fixed header logos. !important outranks the
   fruity JS that redefines body padding-top per title length. */
body {
    padding-top: calc(var(--tu-logo-h) + 24px) !important;
}

/* === Footer === */
.tu-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    padding: 2rem 1rem;
    text-align: center;
    font-size: var(--tu-body);
    color: #444;
    background-color: #fff;
    border-top: 1px solid #eee;
    z-index: 1000;
}

.tu-footer-links {
    display: flex;
    justify-content: center;
    gap: 2rem;
    flex-wrap: wrap;
}

.tu-footer-links a {
    color: #444;
    text-decoration: none;
    font-weight: 400;
    transition: color 0.3s;
}

.tu-footer-links a:hover {
    color: #e4154b;
    text-decoration: underline;
}

body > article {
    padding-bottom: 140px;
}

/* === Progress Bar === */
#progress-bar-wrapper {
    width: calc(100% - 24px);  /* mobile: flush with the type area margins */
    margin: 0 auto 1rem;       /* top gap now comes from the body padding */
}

@media (min-width: 1200px) {
    #progress-bar-wrapper {
        width: 80%;            /* flush with the desktop type area */
    }
}

#progress-bar-wrapper .progress {
    height: 1.5rem;
}

#progress-bar-wrapper .progress-bar {
    font-size: var(--tu-body);
}

/* === Type area (Satzspiegel) ===
   Mobile/tablet: full width with a slim 12px margin; desktop (>=1200px,
   bootstrap xl): 80% of the viewport, centered. Replaces fruity's
   col-xl-8 (2/3) column and the former 15%-padding construction
   (which left only 70% usable width at every size). */
.col-centered.col-xl-8 {
    width: 100% !important;
    flex: 0 0 100% !important;
    max-width: 100% !important;
    margin: 0 auto !important;
    padding-left: 12px !important;
    padding-right: 12px !important;
}

@media (min-width: 1200px) {
    .col-centered.col-xl-8 {
        width: 80% !important;
        flex: 0 0 80% !important;
        max-width: 80% !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
}

.survey-name {
    text-align: center !important;
}

.form-heading p,
.survey-description p,
.survey-welcome p {
    text-align: center !important;
}

/* === Center bottom anonymous text === */
.ls-emailed-token,
.survey-anonymous,
#ls-token-entry {
    text-align: center !important;
}
/* === Question Layout === */
.question-container {
/*    display: flex !important;*/
    flex-direction: column !important;
    gap: 0 !important;
    row-gap: 0 !important;
    margin-top: 0 !important;
    margin-bottom: 20px !important;
    margin-left: 0 !important;   /* BS .row ships -12px — pulls broad fields
                                    (textareas, file upload) 12px left of the
                                    19px indent line (measured on 699811) */
    margin-right: 0 !important;
    padding: 0 !important;
}

/* === Answer controls on ONE indent line ===
/* (indent-line rule removed — everything flush left now, see the
   .answer-container rule further below) */

/* Datepicker col wrapper has a 2px odd padding — neutralize only that.
   ALL inner col wrappers get 0 padding: the flush-left layout means the
   title, controls, and radios all sit at the type area's left edge.
   The old col-md-12 12px compensation is no longer needed since the
   question-title-container also has padding-left: 0 now. */
/* (obsolete Einzelfall-Regeln entfernt — siehe Catch-All unten) */

/* Tipp-/Validierungshinweise ("Bitte wählen Sie…", EM-Hinweise):
   .question-valid-container und .question-help-container tragen
   Bootstrap's .col-12 mit 12px padding-left. Spezifität (0,2,0)
   schlägt Bootstrap's (0,1,0) — kein !important nötig. */
.question-container .question-valid-container,
.question-container .question-help-container {
    padding-left: 0;
    padding-right: 0;
}

li.answer-item.imageselect-container {
    padding-left: 0 !important;
}

/* === Group rhythm: one gap instead of stacked ones ===
   Stock utilities ship group-outer/group-container margins of 15/30px and
   the h2 a 1em top margin — stacked with the question margin that summed
   up to 134px between a group's last answer and the next group title
   (measured on 258439 'Adresse'). */
.group-outer-container,
.group-container {
    margin-top: 8px;
    margin-bottom: 12px;
}

.group-container .group-title {
    margin-top: 8px;           /* stock: 1em — the container margins already provide the air */
}
/* === Remove space between label and answer box === */
.question-title-container,
.question-title-container.col-12 {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
    padding-left: 0 !important;   /* flush left — no BS col gutter */
    margin-left: 0 !important;
}

.question-container > [class*="col-"] {
    padding-bottom: 0 !important;
    margin-bottom: 0 !important;
}

/* Rhythmus um Validierungstips (699811 Upload): Stock setzt
   margin-top:10px auf den valid-container (Fresluft über der Meldung),
   unsere Catch-alls oben erzwingen margin-bottom:0 — die Meldung klebte
   am Steuerelement. Neu: 4px über, 6px unter der Meldung. Muss NACH den
   Catch-alls stehen und !important tragen, sonst wird sie von ihnen
   gefressen (gleiche Spezifität, Source-Order). Fragen ohne Tip haben
   keinen valid-container — deren Rhythmus bleibt unberührt. */
.question-container .question-valid-container {
    margin-top: 4px !important;
    margin-bottom: 6px !important;
}

/* Der LETZTE Absatz des Fragetexts trägt Stock margin-bottom:16px,
   die durch alle Container durchkollabiert (gemessen 699811 Upload:
   16px Phantom zwischen Textende und Validierungsmeldung trotz
   margin-0-Catch-alls — erzwungene 0-Margins blockieren das
   Durchkollabieren nicht). Auf 0 setzen — aber NUR bei Fragen mit
   valid-container: der 4/6px-Tip-Rhythmus braucht es; tip-lose Fragen
   behalten die 16px Durchkollabier-Luft als Text→Kontrolle-Abstand. */
.question-container:has(.question-valid-container) .question-text p:last-of-type,
.question-container:has(.question-valid-container) .ls-label-question p:last-of-type {
    margin-bottom: 0;
}

/* === Answer box spacing === */
.question-text-container {
    margin: 0 !important;
    padding: 0 !important;
}

.ls-answers {
    margin: 0 !important;
    padding-top: 0 !important;
}

.ls-label-question {
    margin-bottom: 0 !important;
}

.text-long .answer-item {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

/* Textareas sit directly in .ls-answers (no col-wrapper like col-md-12
   that gives other fields their +12px) — add it here so broad fields
   land on the same 19px indent line (measured on 699811) */
.question-container .text-long .ls-answers {
    padding-left: 12px;
}

/* === Type scale (design tokens) ===
   Single anchor --tu-h1 (the survey title); every other level is a
   ratio of it — DOM-position safe (an em cascade would break across the
   sibling containers title/group/question live in). The mobile block
   flips the whole scale with one knob; individual levels can be
   decoupled later by overriding their var per breakpoint.
   NOTE: the anchor is px ON PURPOSE (h1 is specified as an absolute
   24px at 100% browser zoom); body text stays fruity-controlled rem —
   if fruity ever changes its body size or root scaling, the h1:body
   RATIO drifts, not the h1 size. The --tu-* names are a public API
   for child themes (institute logos etc.) — do not rename. */
:root {
    --tu-h1: 25px;                                /* desktop anchor */
    --tu-h2: calc(var(--tu-h1) * 0.84);           /* 21px: group titles ("Ihre Arbeitsbelastung" feedback: +2px) */
    --tu-question: calc(var(--tu-h1) * 0.68);     /* 17px: question text, bold — one step below group titles */
    --tu-body: calc(var(--tu-h1) * 0.6);          /* 15px: body + answer labels */
    --tu-zebra: rgb(243, 244, 249);               /* array row striping, between white and hover */
}

@media (max-width: 767.98px) {
    :root {
        --tu-h1: 20px;                            /* one knob moves the whole scale */
        --tu-body: 14px;                          /* px override does not ride fruity's root scaling */
    }
}

/* Body rides the token scale too — otherwise the question text would fall
   BELOW the fruity body size and answer labels would outsize their own
   question. */
body {
    font-size: var(--tu-body);
}

/* === Page headings ===
   Group titles render as <h2> in most surveys, one level BELOW the
   survey title (h1). font-family: inherit drops the stale IBMPlexSerif
   first-family (webfont removed earlier). */
.large-heading {
    font-size: var(--tu-h1);
    line-height: 1.25;
    font-family: inherit;
}

.group-container .group-title {
    font-size: var(--tu-h2);
    line-height: 1.3;
    font-family: inherit;
}

/* === Rich-text headings: visual hierarchy ===
   Scoped to rich-text containers; the theme chrome keeps its own design.
   h3/h4 sit at body level by design (a 24px h1 leaves only ~1.3x of
   headroom over the 18.24px body) — expressed as em in body context,
   so they follow any future body/root change automatically.
   .group-description is included since CSBME re-audit 2026-09-11: an
   author <h4> rendered at stock 27.36px — BIGGER than the 25px h1
   (measured on 699811 g2/g3). */

/* Frage-Text-Container: alle col-Wrapper auf 0 — betrifft Q-Type-Fragen
   (multiple short text, etc.) deren Titel-Bereich eigene col-* Klassen
   trägt. Gemessen auf 883434 "Prüfungssenat" (+194px) und 715539
   "Rückfragen" (+98px). Spezifität (0,2,0) schlägt Bootstrap. */
.question-container .question-text[class*="col-"],
.question-container .question-text > [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
}

/* Auch die direkten col-Kinder des Frage-Containers, die nicht
   answer/valid/help sind (z.B. Q-Type multiple short text) */
.question-container > [class*="col-"]:not(.answer-container):not(.question-valid-container):not(.question-help-container) {
    padding-left: 0;
    padding-right: 0;
}

/* Alle col-Wrapper innerhalb von .answer-item neutralisieren.
   .ls-answers und .answer-item sind auf DEMSELBEN Element — der
   Selektor .ls-answers .answer-item matcht nur verschachtelte Elemente,
   nicht Geschwister. Verwende .ls-answers direkt als Elter.
   Spezifität (0,2,1) schlägt Bootstrap (0,1,0). */
.question-container .ls-answers > [class*="col-"] {
    padding-left: 0;
}

.survey-description h1,
.group-description h1,
.question-text h1,
.ls-label-question h1 {
    font-size: var(--tu-h1);
    line-height: 1.3;
}

.survey-description h2,
.group-description h2,
.question-text h2,
.ls-label-question h2 {
    font-size: var(--tu-h2);
    line-height: 1.3;
}

.survey-description h3,
.group-description h3,
.question-text h3,
.ls-label-question h3 {
    font-size: 1.01em;
    line-height: 1.35;
}

.survey-description h4,
.group-description h4,
.question-text h4,
.ls-label-question h4 {
    font-size: 1em;
    line-height: 1.4;
}

/* h5/h6: flat at body level like h4 (staircase below h2 is intentionally
   flat; they only differ by weight). No rule existed before — stock
   sizes applied (h5 18.24px > body). */
.survey-description h5,
.survey-description h6,
.group-description h5,
.group-description h6,
.question-text h5,
.question-text h6,
.ls-label-question h5,
.ls-label-question h6 {
    font-size: 1em;
    line-height: 1.4;
}

/* === Survey description text: one step smaller (matches the h2 scale-down;
   stock .form-heading ships 1.2825rem which would outsize the new h2) === */
/* === Survey description text: rides body level (formerly 1.15rem,
    which would now outsize the body itself) === */
.survey-description {
    font-size: 1em;
}

/* === Content links: always recognizable ===
   BS5 ships text-decoration:none; a TU blue link without underline is
   indistinguishable from body text (reported: "email address doesn't
   look like a link"). Content links get the underline back. */
.survey-description a,
.group-description a,
.question-text a,
.ls-label-question a,
.answer-container a {
    text-decoration: underline;
}

.survey-description a:hover,
.group-description a:hover,
.question-text a:hover,
.ls-label-question a:hover,
.answer-container a:hover {
    text-decoration: underline;
}

/* === Group/survey titles: never break mid-word (wrap at spaces only) === */
.group-title,
.large-heading {
    word-break: normal;
    overflow-wrap: normal;
    hyphens: none;
}

/* === Question text: 16px, bold — clearly above the 14px answer labels === */
.question-container .ls-label-question {
    font-size: var(--tu-question); /* stock: 24px */
    font-weight: 700;
}

/* === Answer-level texts in tables: ride the body token ===
   fruity pins array row labels AND column headers (and multiple-choice
   table items) at its legacy 1.14rem (18.24px) — they ignored the body
   override because they carry their own font-size. Row labels render
   like body text (w400), column headers keep semi-bold for contrast. */
table.ls-answers th.answertext {
    font-size: var(--tu-body);
    font-weight: 400;
}

/* Radio arrays: the row labels ARE the questions' statements — bold,
   matching the question-text weight. Scoped to .radio-array so
   checkbox tables (answer options, not questions) stay normal. */
table.radio-array th.answertext {
    font-weight: 700;
}

table.ls-answers thead th.answer-text {
    font-size: var(--tu-body);
    font-weight: 700;
}

/* Text arrays: ROW labels dock right against their input column (stock
   left-aligns short labels like "Name" leaving 133px of dead space) and
   render bold like question statements. tbody only — the thead cells of
   text arrays carry the SAME class 'answertext' (no hyphen, unlike radio
   arrays' 'answer-text') and would inherit the right-alignment. */
table.text-array tbody th.answertext {
    text-align: right;
    font-weight: 700;
}

/* Text-array column headers: bold, docking LEFT at their own field's
   edge (the inputs sit 8px inside the cell). Specificity note: stock
   centers these headers; the cells may carry 'answertext' (no hyphen)
   OR 'answer-text' depending on question view — cover both, the class
   bump outguns the stock centering. */
table.text-array thead th.answertext,
table.text-array thead th.answer-text {
    text-align: left;
    padding-left: 8px;
    font-weight: 700;
    font-size: var(--tu-body);
}

/* === Zebra striping on array tables, one tone ===
   Stock zebra only hit tables at rgb(249,249,251); this keeps it on
   array/matrix tables (where it groups the row visually, e.g. the
   senate composition matrix) at a slightly darker tone between the old
   zebra and the hover colour rgb(238,239,247). List questions (radio/
   checkbox options) stay white — zebra there looked noisy. */
table.ls-answers.table-striped > tbody > tr:nth-child(2n),
table.ls-answers tbody tr.ls-even {
    background-color: var(--tu-zebra);
}

/* Checked-option feedback: stock paints the label of a checked
   radio/checkbox green (#14AE5C — contrast ~2.6:1, far below AA 4.5:1;
   found by the a11y suite — LS pre-checks "Keine Antwort" on newtest,
   so this fires on every fresh page). TU blue + semibold keeps the
   feedback visible AND accessible (5.7:1). Same specificity as the
   stock rule, later file wins. */
.radio-item input[type="radio"]:checked + label,
.checkbox-item input[type="checkbox"]:checked + label {
    color: #0c5a77;
    font-weight: 600;
}

/* Unchecked option labels: fruity dims them (110,116,140 ~ 4.0:1 — just
   below AA). They are real answer texts (mobile collapse shows them) —
   inherit the body color instead. */
table.ls-answers label.ls-label-xs-visibility,
li.radio-item > label,
li.checkbox-item > label,
table.ls-answers .answertext label {
    color: inherit;
}

/* No-answer options additionally inherit body color when unchecked. */
li.noanswer-item,
td.noanswer-item,
li.noanswer-item label,
td.noanswer-item label,
li.noanswer-item .answertext,
td.noanswer-item .answertext,
table.ls-answers .noanswer-item .ls-label-xs-visibility {
    color: inherit;
}

/* Ranking options ride the token scale — the selector MIRRORS the stock
   rule (.select-sortable-lists:not(...) li, specificity 0,3,1); custom.css
   loads later and wins the tie. */
.select-sortable-lists:not(.ranking-advanced-style) .list-group-item,
.select-sortable-lists:not(.ranking-advanced-style) li,
li.ls-choice {
    font-size: var(--tu-body);
}

/* O-type (list with comment): the radio list wrapper (.answers-list)
   carries a Bootstrap gutter pushing it 12px past the answer indent
   line (measured 162 vs 150 on the fixture) */
.question-container .ls-answers > .answers-list.radio-list {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Group descriptions are body-level text (stock pins them at 18px via
   ".group-container .group-description" — matched selector for selector) */
.group-container .group-description {
    font-size: var(--tu-body);
}

/* === Buttons: uniform 14px (stock .btn 1.14rem / .btn-lg 1.425rem) === */
.btn,
.btn-lg {
    font-size: var(--tu-body);
}

/* === Legacy-size cleanup: every remaining fruity text level rides a token.
   Sources verified via CSSOM audit (theme_apple.css): answer labels,
   welcome/description prose, language changer, dropdown entries,
   datasecurity notice, ranking/numeric helpers, error pages (45.6px
   titles!), completed/end page, quota + thank-you messages, alerts,
   public statistics, print-answers view. */
.form-heading,
.ls-answers label,
.answer-item label,
.control-label,
.ls-answers .ls-heading th,
.form-change-lang .control-label,
.form-change-lang #language-changer-select,
.dropdown-menu .dropdown-item,
.datasecurity-checkbox-label,
.select-sortable-lists:not(.ranking-advanced-style) .label,
.numeric-multi .dynamic-total,
.question-count-text,
.slider-list .slider .tooltip,
body.error-page .error-content,
body.error-page .error-link,
.completed-wrapper .completed-Content,
.quotamessage,
.alert > .alert-header,
.public-stats .statsNumRecords,
.printanswers-container span {
    font-size: var(--tu-body);
}

body.error-page .error-title,
.completed-wrapper .completed-heading,
.public-stats .statsSurveyTitle {
    font-size: var(--tu-h1);      /* these are page-level headings */
}

.well .thankyou {
    font-size: var(--tu-h2);
}

/* === Radios & checkboxes: touch-friendly, TU brand color ===
   The parent theme ships the "awesome-bootstrap-checkbox" system:
   the real input is hidden (opacity:0, absolute 17px) and a FAKE
   control is drawn via label::before/::after (19px ring, green dot).
   We disable the fakes and style the REAL inputs instead.

   List items stay in normal INLINE flow (no flex): the estate carries
   two markup generations — older questions put the input directly in
   the li (e.g. 258439), newer wrap it in .row > .col-auto (638847).
   In both, input and label share one line box, so vertical-align
   (see input rule below) centers the control on the text line and
   anchors it to the FIRST line of multi-line labels. Flex would make
   the input a flex item in the old markup and silently ignore
   vertical-align there. */
li.radio-item,
li.checkbox-item,
li.radio-text-item,
li.checkbox-text-item {
    /* Touch-friendly rows with the text VERTICALLY centered */
    padding: 10px 0;
    margin-bottom: 0;
}

.radio-item label::before,
.radio-item label::after,
.checkbox-item label::before,
.checkbox-item label::after,
.radio-text-item label::before,
.radio-text-item label::after,
.checkbox-text-item label::before,
.checkbox-text-item label::after {
    content: none !important;
    display: none !important;
}

.radio-item input[type="radio"],
.checkbox-item input[type="checkbox"],
.radio-text-item input[type="radio"],
.checkbox-text-item input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    position: static;          /* stock: absolute 17px box */
    opacity: 1;                /* stock: 0 (invisible) */
    width: 18px;               /* proportional to the 14px answer text */
    height: 18px;
    flex: none;
    /* List controls live INSIDE .row > .col-auto as inline content next to
       their label — top margins are eaten by baseline alignment there.
       vertical-align: middle centers the control on the glyph line. */
    vertical-align: middle;
    margin: 0 0.5rem 0 0;
    cursor: pointer;
    background-color: #fff;
}

.radio-item input[type="radio"],
.radio-text-item input[type="radio"] {
    border: 2px solid #767676;
    border-radius: 50%;
}

.checkbox-item input[type="checkbox"],
.checkbox-text-item input[type="checkbox"] {
    border: 2px solid #767676;
    border-radius: 3px;
}

.radio-item input[type="radio"]:checked,
.radio-text-item input[type="radio"]:checked {
    border-color: #0c5a77;
    background: radial-gradient(circle, #0c5a77 0 44%, transparent 50%);
}

.checkbox-item input[type="checkbox"]:checked,
.checkbox-text-item input[type="checkbox"]:checked {
    border-color: #0c5a77;
    background-color: #0c5a77;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'%3e%3cpath d='M12.7 5.3a1 1 0 0 1 0 1.4l-4.5 4.5a1 1 0 0 1-1.4 0L3.3 7.7a1 1 0 0 1 1.4-1.4l2.2 2.2 3.8-3.8a1 1 0 0 1 1.4 0z'/%3e%3c/svg%3e");
    background-size: 100% 100%;
}

.radio-item input[type="radio"]:hover:not(:disabled),
.checkbox-item input[type="checkbox"]:hover:not(:disabled),
.radio-text-item input[type="radio"]:hover:not(:disabled),
.checkbox-text-item input[type="checkbox"]:hover:not(:disabled) {
    border-color: #0c5a77;
}

.radio-item input[type="radio"]:focus-visible,
.checkbox-item input[type="checkbox"]:focus-visible,
.radio-text-item input[type="radio"]:focus-visible,
.checkbox-text-item input[type="checkbox"]:focus-visible {
    outline: 2px solid #0c5a77;
    outline-offset: 2px;
}

.radio-item input[type="radio"]:disabled,
.checkbox-item input[type="checkbox"]:disabled,
.radio-text-item input[type="radio"]:disabled,
.checkbox-text-item input[type="checkbox"]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Touch target: generous vertical padding on the answer labels */
/* Labels in flex column next to their input: text wraps WITHIN its own
   column, never under the radio/checkbox. align-items: flex-start puts
   the input at the TOP (first text line); margin-top centers it on that
   line. Measured on 654416 G09Q24 ("Serviceeinheiten…" wraps to 3 lines). */
/* "Other"-Optionen: checkbox-text-item / radio-text-item haben eigene
   Klassennamen — ohne sie rutscht die Other-Checkbox auf Bootstrap-
   Default. Der Input sitzt in einem .row > .col-auto Wrapper (nicht als
   direktes li-Kind), deshalb zusätzlich die inneren Wrapper neutralisieren. */
li.radio-item,
li.checkbox-item,
li.radio-text-item,
li.checkbox-text-item {
    display: flex;
    align-items: flex-start;
}

li.radio-item > input[type="radio"],
li.checkbox-item > input[type="checkbox"],
li.radio-text-item input[type="radio"],
li.checkbox-text-item input[type="checkbox"] {
    flex: none;
    margin: 1px 8px 0 0;
}

/* Innerer Wrapper der Other-Option: LS rendert ein
   <div class="checkbox-item othertext-label-…"> (kein <li>!) um den
   Input und das Label. Ohne Flex-Layout steht der Input 20px rechts
   der Linie (gemessen auf 289688). Ziel dieses Wrappers gezielt. */
li.checkbox-text-item .checkbox-item,
li.radio-text-item .radio-item {
    display: flex;
    align-items: flex-start;
    padding: 0;
    margin: 0;
    width: 100%;
}

li.checkbox-text-item .checkbox-item input[type="checkbox"],
li.radio-text-item .radio-item input[type="radio"] {
    flex: none;
    margin: 1px 8px 0 0;
}

li.checkbox-text-item .checkbox-item label,
li.radio-text-item .radio-item label {
    flex: 1;
    margin: 0;
    cursor: pointer;
}

.radio-item label,
.checkbox-item label,
.radio-text-item label,
.checkbox-text-item label {
    flex: 1;
    margin: 0;
    cursor: pointer;
}

/* === Array cells: radios exactly under the column headers ===
   In array questions (type F etc.) every td.answer-cell also carries
   .radio-item and contains the answer text again in a
   label.ls-label-xs-visibility (fruity's responsive fallback). Stock hides
   only its INNER span offscreen — the label box itself stays inline
   (~26px) next to the input. With the real-input redesign above the input
   became flow-relevant, so the input+label group gets centered and every
   array radio sits ~15.5px LEFT of its column header center (measured on
   survey 638847 G06Q17, headers at 624.0 vs radios at 608.5).
   Hide the ghost box ONLY outside fruity's collapse band — inside it
   (viewport <=760px, or iPad-like device-width 768-1024) the thead is
   hidden by "table.ls-answers thead {display:none}" and these labels are
   the ONLY answer texts shown. The media list below is the exact
   complement of fruity's collapse condition. */
@media (min-width: 761px) and (max-device-width: 767px),
       (min-width: 761px) and (min-device-width: 1025px) {
    td.answer-item.radio-item label.ls-label-xs-visibility,
    td.answer-item.checkbox-item label.ls-label-xs-visibility {
        display: none;
    }
}

td.answer-item.radio-item input[type="radio"],
td.answer-item.checkbox-item input[type="checkbox"] {
    display: block;
    margin: 0 auto;           /* block centers horizontally; the td's own
                                  vertical-align: middle centers the row height —
                                  no baseline game, no hand-tuned margins */
}

/* Mobile collapse: option cells laid out like a LIST question — radio
    column left on ONE shared line (constant left padding), label text
    left-aligned beside it, zebra striping for row guidance. fruity's
    collapse stacks the cells with 28px asymmetric fake-checkbox padding
    and centered/stacked elements otherwise. Selector mirrors fruity's
    ".ls-answers > tbody > tr > td.radio-item" (0,2,3) — ours loads later
    and wins the tie. Desktop geometry stays untouched.
    The media list MIRRORS fruity's collapse condition exactly (core css,
    "For iPads specifically"): max-width:760px OR device-width 768-1024 —
    iPads collapse in BOTH orientations. With only max-width:767.98 the
    iPads fell through into fruity's collapse layout and the global
    input { display:block; margin:0 auto } rule centered every circle in
    its full-width cell: circle at x≈378 while the option text sat at
    x≈36 (measured 654416 G06Q16 SQ02, iPad portrait 2026-09-14). */
@media (max-width: 760px),
       (min-device-width: 768px) and (max-device-width: 1024px) {
    table.ls-answers tbody tr td.answer-item {
        display: flex;
        flex-direction: row;
        align-items: center;          /* radio vertically centered on the text */
        justify-content: flex-start;
        gap: 0.5rem;
        text-align: left;
        padding: 10px 8px 10px 16px;  /* constant left → one radio line */
    }

    table.ls-answers td.answer-item label.ls-label-xs-visibility {
        text-align: left;
        flex: 1 1 auto;               /* long labels wrap, stay left */
    }

    table.ls-answers tbody tr td.answer-item:nth-of-type(even) {
        background-color: var(--tu-zebra);
    }

    /* Row zebra is a DESKTOP concept (one tr = one subquestion
       statement). In the collapse band a tr IS a whole option block —
       row striping paints every second block fully gray (user report
       654416 page 2, iPad portrait 2026-09-14: the row tone plus the
       per-option zebra share --tu-zebra, so even/odd tds look
       identical). Reset the row tone here — the per-option zebra above
       does the striping. Same selectors as the desktop rule, later in
       this file → wins the cascade. */
    table.ls-answers tbody tr.ls-even,
    table.ls-answers.table-striped > tbody > tr:nth-child(2n) {
        background-color: transparent;
    }
}

/* === Array column widths: use the available space ===
   LimeSurvey renders arrays with an inline colgroup — label column
   hard-coded 70%, every answer column 5%. On single-statement arrays
   (empty row label, e.g. 638847 qid 353075) 70% of the table is dead
   space and each answer column gets ~50px: headers wrap, radios squeeze
   right. Override the inline widths (!important beats them): label
   column 30% (fits the longest subquestion label on one line), answer
   columns without a width share the remaining 70% EQUALLY per the
   fixed-table-layout algorithm. */
/* FLUSH LEFT: everything on the type area's left edge — question text,
   answer controls, help texts. Only the mandatory asterisk protrudes
   left (see .asterisk rule below). */
.question-container .answer-container {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

table.ls-answers colgroup.col-responses col.ls-col-odd,
table.ls-answers colgroup.col-responses col.ls-col-even {
    width: auto;
}

/* The ONE justified !important: single-statement arrays (ALL row
   labels empty — marked by tugMarkNoLabelArrays() in
   layout_global.twig) have an empty label column. LS writes
   width:33% (default) inline on it when answer_width is not set —
   but a column with no content should never take space, regardless
   of whether the value came from the LS default or the author.
   Arrays WITH row labels respect answer_width fully (no ! there). */
table.ls-answers.array-no-label col.col-answers {
    width: 0% !important;
}

/* Tighter header padding: "sehr ungern" needs ~105px of the 118px column —
   the stock 8px horizontal padding pushed it into a wrap. */
table.ls-answers thead th {
    padding-inline: 4px;
}

/* === Links: TU theme primary blue ===
   Content links get the theme primary color (matches buttons/progress).
   Footer links keep their own gray styling (.tu-footer-links a is more
   specific and remains defined below/above). */
a {
    color: #0c5a77;
}

/* font-size: inherit cancels the parent's GLOBAL
   "a { font-size: 0.9975rem }" (theme_apple.css etc.), which pins every
   link to 15.96px: visibly smaller than welcome/question text (20–20.5px)
   and larger than footer text (14.4px). Links must flow with their
   context; scoped anchor rules in the parent (nav dropdown, datasecurity
   link) keep winning by specificity and stay intact. custom.css loads
   after the variation CSS, so source order settles the tie. */
a {
    font-size: inherit;
}

a:hover {
    color: #0e6d8f;
}

/* === Mandatory marker: TU brand red, gap to the text EXACTLY 6px ===
   Two variants (both verified by ink-pixel measurement, f6770a6):
   1) ABSOLUTE (default, left-aligned questions): the star hangs in the
      left margin of the Satzspiegel. Fixed 18px box, glyph right-aligned
      inside → gap independent of glyph width/font size; box protrudes
      24px, translateY(0.15em) optically centers the high-sitting glyph.
   2) INLINE (author centered the question text via inline style): the
      star follows the text. inline-block + margin-right 6px = same gap;
      transform: none is load-bearing (blocks this rule's translateY
      leak; natural baseline already centers the ink within ~0.5px).
   The * glyph sits high in its em box — vertical centering must be
   judged by INK pixels (tools/ink_star.py), not em-box geometry. */
.question-title-container {
    position: relative;
}

.asterisk.asterisk-text {
    position: absolute;
    left: -24px;
    width: 18px;                /* 24px protrusion − 6px gap */
    text-align: right;          /* glyph hugs the box's right edge */
    color: #e4154b;
    font-weight: 700;
    font-style: normal;
    line-height: inherit;
    transform: translateY(0.15em);
}

/* Author centered the question text → asterisk inline next to the text.
   width:auto + transform:none explicitly neutralize the base rule's
   fixed box and translateY (cascade-leak trap, see header above). */
.question-container:has(.ls-label-question [style*="text-align:center"]) .asterisk.asterisk-text {
    position: static;
    display: inline-block;
    width: auto;
    margin-left: 0;
    margin-right: 6px;
    transform: none;
}

/* Mobile exception: the body padding is only ~12px at <768px, so a 6px
   gap + 6.6px glyph would push the star's left tip off the viewport
   (measured glyphLeft 0.7px at 390px). Reduce the gap to 4px — the
   glyph then starts at ~1.4px. Desktop gap stays 6px. */
@media (max-width: 767px) {
    .asterisk.asterisk-text {
        left: -20px;             /* 20px box reach − 16px width = 4px gap */
        width: 16px;
    }
    .question-container:has(.ls-label-question [style*="text-align:center"]) .asterisk.asterisk-text {
        margin-right: 4px;
    }
}

/* === TABLET BAND — column lists collapse to one column ============
   BAND POLICY: Mobile <768px · TABLET 768–1023px + Hochkant ≤1200px
   · Desktop ≥1024px quer (Spalten aktiv, Satzspiegel 144).
   Ursache (Mitarbeiterinnenbefragung 654416, iPad-Feedback 2026-09-14):
   display_columns erzeugt data-column-count + nbcol-N auf der Liste;
   die Stock-Kollaps-Grenze liegt bei 767px — iPad-Hochkant (768/810/820)
   liegt DARÜBER: Spalten aktiv, schmal, Labels umbrechen je Spalte
   ungleich (Zeilenhöhen 40/60/100, gemessene negative Gap-Tops =
   Spaltenumbrüche). Mit diesem Band stapeln alle Tablets im Hochkant
   wie das iPhone; Querformat ≥1024 und Desktop behalten Spalten.
   Die orientation-Klausel fängt iPad Pro 12.9" Hochkant (1024px breit).
   Selektor (0,2,1) schlägt die Stock-Attributregeln [data-column-count]
   (0,1,0) — kein !important nötig.
   Verwandt, aber NICHT migriert: der device-width-Hack fuer
   Array-Labels weiter oben (~Zeile 839) — Migration separat pruefen. */
@media (max-width: 1023px),
       (orientation: portrait) and (max-width: 1200px) {
    .question-container ul[data-column-count] {
        column-count: 1;
    }
}

/* Question texts are wrapped in <p> blocks; the first one must flow
   inline with the asterisk so the marker never sits on its own line. */
.ls-label-question p:first-of-type {
    display: inline;
}

/* === Readable text: darken gray answer/label text to black ===
   Scoped intentionally — semantic colors (validation errors, alerts,
   muted help texts) keep their meaning. Do NOT reintroduce a global
   "force everything black" rule: it hides error feedback. */
body {
    color: #000000;
}

.answertext,
.control-label,
.answertext.control-label,
.ls-answers .answertext,
.subquestion-list .answertext,
.answer-item,
.radio-item,
.answers-list,
.ls-label-question,
.question-text,
.ls-question-text,
th.answertext,
td.answer-item {
    color: #000000 !important;
}


/* === Fix welcome container width === */
#welcome-container {
    max-width: 100% !important;
    width: 100% !important;
    text-align: center !important;
    /* no extra horizontal padding — the type area (Satzspiegel) already
       provides the margins; the former 10% doubled them up */
}

/* === Center privacy/anonymous text === */
.ls-privacy-block {
    text-align: center !important;
}

.ls-privacy-head,
.ls-privacy-body {
    text-align: center !important;
}

.ls-privacy-body p {
    text-align: center !important;
}

/* ============================================================
   TU Graz brand colors (primary: TU blue #0c5a77)
   The parent theme (fruity_twentythree) ships compiled CSS
   with literal colors (stock green #14AE5C) — tokens alone do
   not recolor everything, so the affected components are
   overridden here with strong specificity. custom.css loads
   last, after css/variations/*.css from the parent.
   ============================================================ */
:root {
    --bs-primary: #0c5a77;
    --bs-primary-rgb: 12, 90, 119;
}

.btn-primary {
    color: #ffffff;
    background-color: #0c5a77;
    border-color: #0c5a77;
}

.btn-primary:hover,
.btn-primary:focus {
    color: #ffffff;
    background-color: #0e6d8f;
    border-color: #0e6d8f;
}

.btn-primary:active,
.btn-primary.active,
.btn-check:checked + .btn-primary {
    color: #ffffff;
    background-color: #0a4c64;
    border-color: #0a4c64;
}

.btn-primary:disabled,
.btn-primary.disabled {
    color: #ffffff;
    background-color: #0c5a77;
    border-color: #0c5a77;
    opacity: 0.65;
}

.btn-outline-primary {
    color: #0c5a77;
    border-color: #0c5a77;
}

.btn-outline-primary:hover,
.btn-outline-primary:focus {
    color: #ffffff;
    background-color: #0c5a77;
    border-color: #0c5a77;
}

.progress-bar {
    background-color: #0c5a77;
    color: #ffffff;
}

/* Text/link utilities built from the primary token */
.text-primary {
    color: #0c5a77 !important;
}

.bg-primary {
    background-color: #0c5a77 !important;
}
