/* ============================================================
   anketa.id — studio.css (LimeSurvey 5 / Bootstrap 3)
   Differences from the LimeSurvey 6 build, all verified against the vanilla
   theme shipped with this instance:
     * grid is Bootstrap 3: no .col-auto, no --bs-gutter-x, columns carry a
       fixed 15px side padding and .row a -15px side margin
     * selects are .form-control, not .form-select
     * buttons are .btn-default / .btn-primary, not .btn-outline-*
     * the array collapses at 760px here, not 767px (noTablesOnMobile.css)
     * the checked-mark colour is set in the theme's own theme.css
       (label::after{background-color:#337ab7}), not in a core package
   Variables are emitted server-side by views/subviews/header/custom_header.twig
   Mode classes are set on <html> by the same file (no flash of wrong layout):
     .st-op / .st-resp     interface mode
     .st-dark / .st-contrast
     .st-compact
     .st-codes             show answer codes
     .st-sticky            sticky navigator
     .st-rowhl             highlight whole answer row
     .st-zebra             striped array rows
   ============================================================ */

/* ---------- font classes (body gets .font-<value> from vanilla layout) ---------- */
/* The font picker was removed from the theme options, so the body may carry
   no .font-* class at all. The family is therefore pinned here rather than
   left to that class — a missing class must not fall back to a serif. */
body,
body.font-system {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Helvetica Neue", Arial, sans-serif;
}
body.font-noto      { font-family: "Noto Sans", system-ui, Arial, sans-serif; }
body.font-arial     { font-family: Arial, Helvetica, sans-serif; }
body.font-verdana   { font-family: Verdana, Geneva, sans-serif; }
body.font-tahoma    { font-family: Tahoma, Verdana, sans-serif; }
body.font-georgia   { font-family: Georgia, "Times New Roman", Times, serif; }
body.font-courier   { font-family: "Courier New", Courier, monospace; }

/* ---------- page shell ---------- */
body {
  background-color: var(--st-canvas);
  color: var(--st-text);
  /* no tall tail after the buttons: the frame is short */
  padding-bottom: var(--st-nav-gap, 0.5rem);
  -webkit-font-smoothing: antialiased;
}

.container,
.container-fluid {
  max-width: var(--st-maxw);
}

.top-container,
.top-container .top-content {
  background: transparent;
  margin-bottom: 0;
  padding-bottom: 0;
}

/* Header bar */
#survey-nav.navbar {
  background-color: var(--st-header) !important;
  border-bottom: 1px solid var(--st-border);
  min-height: 3rem;
  box-shadow: 0 1px 2px rgba(15, 23, 32, 0.06);
}
#survey-nav .navbar-brand {
  color: var(--st-text);
  font-weight: 600;
  font-size: 0.95rem;
}
#survey-nav .logo { max-height: 2.1rem; width: auto; }
/* Language switcher (Survey settings -> Presentation -> show language switcher).
   It is a survey-level feature, not a theme option, so the theme only styles it. */
#survey-nav .navbar-nav .nav-link,
#survey-nav select,
.language-changer select,
.language-changer .nav-link {
  color: var(--st-text);
  font-size: 0.95rem;
}
#survey-nav select { min-height: 2rem; padding-block: 0.1rem; }

/* Survey / group headings */
h1.survey-name {
  margin: 0 0 0.35rem;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--st-text);
  text-align: left;
}
.survey-description,
.survey-welcome {
  color: var(--st-muted);
  text-align: left;
}

.group-title {
  font-size: var(--st-fs-grouptitle);
  font-weight: var(--st-fw-grouptitle);
  color: var(--st-text);
  text-align: left;
  margin: 0 0 0.25rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--st-accent);
  display: block;
}
.group-description {
  font-size: var(--st-fs-groupdesc);
  font-weight: var(--st-fw-groupdesc);
  color: var(--st-muted);
  margin-bottom: var(--st-gap);
}

#welcome-container {
  background: var(--st-surface);
  border: 1px solid var(--st-border);
  border-radius: var(--st-radius);
  padding: 1.25rem;
  margin-top: 1.25rem;
}

/* ---------- question card ---------- */
.row.question-container { margin-left: 0; margin-right: 0; }

.question-container {
  position: relative;
  background: var(--st-surface);
  border: 1px solid var(--st-border);
  border-radius: var(--st-radius);
  border-left: 3px solid var(--st-accent);
  margin-bottom: var(--st-gap);
  padding: var(--st-card-pad);
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.question-container:focus-within,
.question-container.st-active {
  border-color: var(--st-accent);
  box-shadow: 0 0 0 3px var(--st-accent-ring);
}
/* The question the keyboard is currently aimed at. Enter moves this marker
   down the page and only submits once it is on the last visible question. */
.question-container.st-active { border-left-width: 5px; }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* Question title: plain strong text, no colour band (band stays available via option) */
.question-title-container {
  background: var(--st-qtitle-bg);
  color: var(--st-qtitle-fg);
  font-size: var(--st-fs-qtitle);
  font-weight: var(--st-fw-qtitle);
  line-height: 1.4;
  padding: 0 0 0.6rem;
  margin: 0;
  border: none;
}
.question-title-container p:last-child { margin-bottom: 0; }

/* Mandatory asterisk / question code */
.question-container .asterisk,
.question-container .ls-asterisk { color: var(--st-danger); }
/* The code is an operator aid: it tells them which variable they are reading
   out and matches the paper questionnaire. A respondent has no use for it, so
   it is pulled out of the text (by studio.js) and hidden here. */
html.st-resp .ls-questioncode { display: none; }

.ls-questioncode {
  display: inline-block;
  font-family: var(--st-mono);
  font-size: 0.78em;
  color: var(--st-muted);
  background: var(--st-code-bg);
  border-radius: 4px;
  padding: 0.05em 0.4em;
  margin-right: 0.45em;
  vertical-align: 0.1em;
}

/* Help / validation.
   These wrappers are NEVER empty: LimeSurvey leaves whitespace and newlines
   inside them even when there is nothing to say, so :empty never matches and
   a styled wrapper renders as a thin yellow strip under every question.
   Style the CONTENT and leave the wrapper transparent — then an "empty"
   wrapper has nothing to paint, and a validation message that EM inserts
   later is styled the moment it appears, with no JS involved. */
.question-help-container,
.question-valid-container {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
}
.question-help-container > *,
.question-valid-container > *,
.ls-questionhelp {
  background: var(--st-help-bg);
  border-radius: calc(var(--st-radius) / 1.5);
  padding: 0.4rem 0.6rem;
  margin: 0.35rem 0;
  font-size: 0.9em;
  color: var(--st-text);
}
.question-help-container > :empty,
.question-valid-container > :empty,
.ls-questionhelp:empty { display: none; }
.em_num_answers.error,
.error { color: var(--st-danger); }

/* ---------- answers: list of options ---------- */
.answer-container { padding: 0; }

/* vanilla's theme.css puts padding-top:15px / padding-bottom:15px on
   .ls-answers — the wrapper <div> around the option list. That is the gap
   between the question text and the first option, and the tail of empty space
   after the last one. Both are replaced by the theme's own rhythm.
   Note .ls-answers is the DIV in a list question and the TABLE in an array,
   so the table keeps its own margin set further down. */
.answer-container .ls-answers {
  padding-top: var(--st-answers-pad, 0px);
  padding-bottom: var(--st-answers-pad, 0px);
  margin-bottom: 0;
}
/* Bootstrap reboot gives every <ul> a 1rem bottom margin; inside the answer
   list that is another invisible tail after the final option. */
.answer-container ul,
.answer-container ol {
  margin-top: 0;
  margin-bottom: 0;
  padding-left: 0;
}

/* The visible radio/checkbox is an Awesome-Bootstrap-Checkbox pseudo-element
   (label::before at margin-left:-20px), so the option row MUST keep a 20px
   inline-start gutter for it. Never set `padding` as a shorthand here: it
   silently removes that gutter and the control lands on top of the label.
   Horizontal padding is therefore added on top of the gutter, not instead.
   Two knobs, and they are independent:
     --st-ctl-inset  distance from the row edge to the control. The control
                     lands at (padding-inline-start - 20px), so this var —
                     not the row's horizontal padding — moves it. Keep it
                     small or the answer block drifts right of the title.
     --st-ctl-gap    extra space between the control and the label text.
                     ABC fixes the control 20px left of the text and the
                     control is 17px wide, so the bare gap is only 3px.
                     This is padding on the LABEL: padding does not move a
                     padding-box edge, so the ::before control stays put and
                     only the text shifts. Total gap = 3px + this value. */
/* :not(td) matters. Real LimeSurvey array markup is
   <td class="answer_cell_5 answer-item radio-item">, i.e. a table cell
   carries .answer-item too. Without this guard the list-row geometry below
   leaks into every array cell and fights the array rules further down. */
.answer-container .answer-item:not(td),
.answer-container li.radio-item:not(td),
.answer-container li.checkbox-item:not(td) {
  position: relative;
  padding: var(--st-opt-pad-y, 4px) var(--st-row-pad-x, 0.6rem);
  padding-inline-start: calc(20px + var(--st-ctl-inset, 6px));
  border: 1px solid transparent;
  border-radius: calc(var(--st-radius) / 1.5);
  margin: 0;
  line-height: 1.35;
}
.answer-container .answer-item:not(td) label,
.answer-container li.radio-item:not(td) > label,
.answer-container li.checkbox-item:not(td) > label,
.answer-container .answer-item:not(td) .form-check-label {
  cursor: pointer;
  color: inherit;
  padding-inline-start: var(--st-ctl-gap, 5px);
}
/* The "Other" option.
   Real markup (confirmed from a rendered page):
     UNVERIFIED on this version: the wrapper classes below come from a
     LimeSurvey 6 page. Bootstrap 3 has no .col-auto, so the children are
     matched as plain divs instead of by column class.
   Bootstrap's .row adds negative side margins and every .col-auto adds half a
   gutter, so the label starts ~12px right of a plain option — and the control,
   drawn by label::before at -20px from the label, follows it. Zero the gutter
   and the row lines up with the rest by construction. Do NOT target
   ".other-item": that class does not exist in this markup. */
.answer-container .answer-item:not(td).radio-text-item,
.answer-container .answer-item:not(td).checkbox-text-item {
  /* Bootstrap 3 .row uses fixed -15px side margins and its columns a fixed
     15px side padding; there is no --bs-gutter-x to zero out. */
  margin-left: 0;
  margin-right: 0;
  display: flex;
  align-items: center;
  /* the label and the free-text field belong on one line: .row defaults to
     flex-wrap:wrap, which pushed the field underneath as soon as the two no
     longer fitted. Wrapping is allowed again only on a phone-width screen. */
  flex-wrap: nowrap;
  gap: 0.4rem 0.6rem;
}
@media (max-width: 575px) {
  .answer-container .answer-item:not(td).radio-text-item,
  .answer-container .answer-item:not(td).checkbox-text-item { flex-wrap: wrap; }
}
.answer-container .answer-item:not(td).radio-text-item > .othertext-label-checkox-container,
.answer-container .answer-item:not(td).checkbox-text-item > .othertext-label-checkox-container {
  flex: 0 0 auto;
  white-space: nowrap;
}
.answer-container .answer-item:not(td).radio-text-item > .other-text-item,
.answer-container .answer-item:not(td).checkbox-text-item > .other-text-item {
  flex: 1 1 auto;
  min-width: 0;
}
.answer-container .answer-item:not(td).radio-text-item > div,
.answer-container .answer-item:not(td).checkbox-text-item > div {
  padding-left: 0;
  padding-right: 0;
}
.answer-container .othertext-label-checkox-container {
  padding-top: 0;
  margin-right: 0;
  float: none;
}
.answer-container .othertext-label-checkox-container label.control-label {
  padding-inline-start: var(--st-ctl-gap, 9px);
  margin: 0;
}
.answer-container .other-text-item input[type="text"],
.answer-container input[id$="othertext"] {
  width: 100%;
  max-width: 22rem;
  min-height: var(--st-field-h);
}

/* Array cells are excluded from the list geometry by :not(td) above, so no
   reset is needed here — and a reset would be harmful: it would also wipe the
   5px that awesome-bootstrap-checkbox puts on the label itself, leaving the
   text sitting against the control. The stacked layout sets its own value
   from --st-ctl-gap-arr in the <761px block below. */

/* Nothing between the option rows but their own padding: a stray margin from
   Bootstrap's list or form-check spacing would make one question type sit
   looser than another even though --st-opt-pad-y is the same. */
.answer-container li.radio-item,
.answer-container li.checkbox-item,
.answer-container li.radio-text-item,
.answer-container li.checkbox-text-item,
.answer-container li.answer-item {
  margin-top: 0;
  margin-bottom: 0;
}
.answer-container .form-check { margin-bottom: 0; }

/* Vertical alignment of the option label against its control.
   The label cannot be moved directly: it is the containing block of the
   ::before/::after that draw the control, so shifting the label would drag
   the control along with it. Shifting the control instead gives the same
   relative result, works in both directions and costs no layout — a margin
   on an absolutely positioned pseudo-element moves nothing else.
   Positive = control lower, i.e. the label reads higher. */
/* List rows: centre the control against the first line of text.
   Awesome Bootstrap Checkbox pins label::before at top:0, which is the TOP of
   the line box, not its middle. With line-height 1.35 at 16px the line box is
   21.6px and the control is 17px, so the text ends up ~2.3px below the circle.
   Shift both pseudo-elements down by half that difference; --st-ctl-shift
   stays on top as the manual nudge. */
.answer-container .answer-item:not(td) label::before,
.answer-container .answer-item:not(td) label::after,
.answer-container li.checkbox-item:not(td) > label::before,
.answer-container li.checkbox-item:not(td) > label::after {
  margin-top: calc((var(--st-line-h, 1.35em) - var(--st-ctl-size, 17px)) / 2
                   + var(--st-ctl-shift, 0px));
}

/* Nothing here for array labels on purpose: the vertical nudge applied to
   list rows would move the mark relative to a box this theme does not
   position, so the core's own alignment inside a cell is left untouched. */
html.st-rowhl .answer-container .answer-item:not(td):hover { background: var(--st-surface-2); }
html.st-rowhl .answer-container .answer-item:not(td).st-selected {
  background: var(--st-accent-soft);
  border-color: var(--st-accent);
}
html.st-rowhl .answer-container .answer-item:not(td).st-selected label { font-weight: 600; }

input[type="radio"],
input[type="checkbox"] { accent-color: var(--st-check); }

/* Free-text and numeric answers (types S, T, N): the respondent types into
   them and the operator reads back what was typed, so they get a size of
   their own rather than the base body size. */
.answer-container input[type="text"],
.answer-container input[type="number"],
.answer-container input[type="email"],
.answer-container input[type="tel"],
.answer-container textarea,
.answer-container .form-control {
  font-size: var(--st-input-fs, 1.1rem);
  line-height: 1.4;
}

.form-control,
select,
textarea,
input[type="text"],
input[type="number"] {
  background: var(--st-surface);
  color: var(--st-text);
  border: 1px solid var(--st-border-strong);
  border-radius: calc(var(--st-radius) / 1.5);
  min-height: var(--st-field-h);
}
/* Dropdown questions (type ! and array columns): the option list is read at
   a glance, so it gets its own size knob rather than inheriting the base. */
.answer-container select,
.answer-container select.form-control {
  font-size: var(--st-select-fs, 1.05rem);
  line-height: 1.4;
  padding-block: 0.25rem;
}
.answer-container select option {
  font-size: var(--st-select-fs, 1.05rem);
  padding: 0.25rem 0.4rem;
}

.form-control:focus,
select:focus,
textarea:focus {
  border-color: var(--st-accent);
  box-shadow: 0 0 0 3px var(--st-accent-ring);
  background: var(--st-surface);
  color: var(--st-text);
}

/* ---------- the checked mark ----------
   Awesome Bootstrap Checkbox draws the tick as a FontAwesome glyph
   (content "\f00c", padding 0 0 13px 0, font-size 11px). Its position then
   depends on that font's metrics rather than on the box, which is why the
   mark sits off-centre — and it breaks outright if FontAwesome fails to load.
   Both marks are drawn here instead, sized off --st-ctl-size so they stay
   centred by construction: a round dot for radio, a two-border tick for
   checkbox. ABC also hard-codes the colour to #2c3e50; it follows the theme
   accent now. Offsets are measured from the same -20px origin ABC uses. */

/* The reset must skip array labels: inside a cell the core draws the radio
   dot with background-color, so blanking it here wiped the mark out and left
   only whatever the list rules below painted, at list coordinates. */
.answer-container .radio-item label:not(.ls-label-xs-visibility)::after,
.answer-container .checkbox-item label:not(.ls-label-xs-visibility)::after {
  background-color: transparent;
  color: var(--st-check, #12607e);
}

.answer-container .radio-item label:not(.ls-label-xs-visibility)::after {
  width: calc(var(--st-ctl-size, 17px) - 8px);
  height: calc(var(--st-ctl-size, 17px) - 8px);
  left: 4px;
  top: 4px;
  background-color: var(--st-check, #12607e);
}

/* NOTE: no `content` here on purpose. A ::after with no content is never
   generated, which is exactly how ABC keeps the tick hidden until the box is
   ticked — it declares the geometry in the base rule and only adds `content`
   under :checked. Putting `content: ""` here once made a tick appear on every
   option of every multiple-choice question. Geometry stays in the base rule;
   only the :checked rule brings the mark into existence. */
.answer-container .checkbox-item label:not(.ls-label-xs-visibility)::after {
  font-family: inherit;
  padding: 0;
  width: 9px;
  height: 5px;
  left: 4px;
  /* the tick is a 9x5 box rotated about its own centre, so that centre stays
     at top + 2.5px. To sit in the middle of a 17px box it needs (17-5)/2 = 6,
     not the 4 that a 9x9 dot would use. */
  top: 6px;
  border: 2px solid var(--st-check, #12607e);
  border-top: 0;
  border-right: 0;
  border-radius: 0;
  background: none;
  transform: rotate(-45deg);
}
.answer-container .checkbox-item input[type="checkbox"]:checked + label:not(.ls-label-xs-visibility)::after,
.answer-container .checkbox-item input[type="radio"]:checked + label:not(.ls-label-xs-visibility)::after {
  content: "";
  font-family: inherit;
  padding: 0;
}
/* the control outline picks up the accent once something is chosen */
.answer-container .radio-item input:checked + label::before,
.answer-container .checkbox-item input:checked + label::before {
  border-color: var(--st-check, #12607e);
}

/* Array cells: the mark is left entirely to the core.
   In LimeSurvey 6 template-core.css re-anchors the control inside a table cell
   (left:3px/top:3px instead of the -20px pull) and offsets its own mark to
   match. This version positions it differently, and since template-core.css
   is not part of the theme there is nothing here to read it from — so rather
   than guess the offsets a second time, the geometry inside a cell stays
   exactly as the core draws it and only the colour is taken over. The list
   rules above are scoped with :not(.ls-label-xs-visibility) so they cannot
   reach in here. */
.ls-answers label.ls-label-xs-visibility::after {
  background-color: var(--st-check, #12607e);
}
.ls-answers .checkbox-item label.ls-label-xs-visibility::after {
  color: var(--st-check, #12607e);
}

/* ---------- answer code badge (injected by studio.js) ---------- */
.st-code {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.15em;
  padding: 0.05em 0.35em;
  margin-right: 0.55em;
  font-family: var(--st-mono);
  font-size: 0.82em;
  font-variant-numeric: tabular-nums;
  color: var(--st-code-fg);
  background: var(--st-code-bg);
  border: 1px solid var(--st-border);
  border-radius: 4px;
  user-select: none;
}
.answer-item.st-selected .st-code {
  color: var(--st-accent-contrast);
  background: var(--st-accent);
  border-color: var(--st-accent);
}

/* typed-digit buffer indicator */
.st-keybuf {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1080;
  padding: 0.35rem 0.75rem;
  font-family: var(--st-mono);
  font-size: 1.1rem;
  color: var(--st-accent-contrast);
  background: var(--st-accent);
  border-radius: 999px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

/* ---------- arrays ----------
   LimeSurvey's own css/noTablesOnMobile.css turns every array table into
   stacked blocks at max-width 760px ("no more tables"): table/thead/tbody/
   tr/th/td all become display:block, the header row is hidden, and the
   per-cell label .ls-label-xs-visibility — present in the DOM at every width
   but visually hidden on desktop — is revealed so each option reads like an
   ordinary radio row.

   Therefore: everything table-shaped below is scoped to >=761px, so it can
   never fight that transform, and the stacked form gets its own block.
   Core also resets tr:hover to transparent under 760px — so the hover rule
   here must NOT be !important, or it would override that reset.
   ---------------------------------------------------------------- */
table.ls-answers {
  margin: 0.5rem 0;
  color: var(--st-text);
  border-collapse: separate;
  border-spacing: 0;
}
table.ls-answers .answertext,
table.ls-answers .control-label { text-align: left; }

/* the cell itself carries .radio-item / .checkbox-item (and may carry
   .answer-item): it must not inherit the padded, bordered list-row look */
.ls-answers td,
.ls-answers th,
.ls-answers td.answer-item,
.ls-answers th.answer-item {
  background: none;
  border-radius: 0;
}

@media (min-width: 761px) {
  table.ls-answers th,
  table.ls-answers td {
    border-color: var(--st-border);
    vertical-align: middle;
  }
  table.ls-answers .ls-heading th {
    font-weight: 600;
    font-size: var(--st-arr-head-fs, 0.95em);
    color: var(--st-muted);
    vertical-align: bottom;
    background: var(--st-surface-2);
  }
  .ls-answers td:not(.radio-item):not(.checkbox-item),
  .ls-answers th { padding: 0.35rem 0.5rem; border-width: 0; }

  /* Centre the control under its column heading.
     template-core keeps a 20px LEFT gutter on the cell (padding-left:20px,
     padding-right:0) and pulls the 23px label back by -20px. That pair is
     built for the stacked layout, where the control sits left of the text.
     In a centred table cell it puts the control about 11.5px left of the
     true centre, while the <th> above it centres honestly — the columns
     visibly drift apart. Both are zeroed here, so the 23px label centres
     plainly and the ::before inside it (left:3px) lands under the heading.
     Scoped >=761px, so the stacked layout keeps the core behaviour. */
  .dir-ltr .ls-answers td.radio-item,
  .dir-ltr .ls-answers td.checkbox-item,
  .dir-rtl .ls-answers td.radio-item,
  .dir-rtl .ls-answers td.checkbox-item {
    padding-left: 0;
    padding-right: 0;
    text-align: center;
    border-width: 0;
  }
  .dir-ltr .ls-answers td .ls-label-xs-visibility,
  .dir-rtl .ls-answers td .ls-label-xs-visibility {
    margin-left: 0;
    margin-right: 0;
  }
  html.st-zebra table.ls-answers tbody tr:nth-child(odd) { background: var(--st-surface-2); }
  table.ls-answers tbody tr:hover { background: var(--st-accent-soft); }
  /* the per-cell label is the screen-reader copy on desktop — keep it hidden */
  .ls-answers .ls-label-xs-visibility .st-code { display: none; }
}

/* ---------- arrays, stacked form (<761px) ---------- */
@media (max-width: 760px) {
  table.ls-answers tbody tr {
    border: 1px solid var(--st-border);
    border-radius: calc(var(--st-radius) / 1.5);
    padding: 0.5rem 0.6rem;
    margin-bottom: 0.6rem;
    background: var(--st-surface);
  }
  /* the row's subquestion text becomes the heading of its own little block */
  table.ls-answers tbody tr > .answertext,
  table.ls-answers tbody tr > .control-label {
    font-weight: 600;
    padding: 0 0 0.35rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--st-border);
  }
  /* and each option reads like a normal list row, same as a list question.
     Own knobs: --st-ctl-inset-arr / --st-ctl-gap-arr, same meaning as the
     list pair. studio.css is loaded AFTER noTablesOnMobile.css (see the
     <files> order in config.xml), so these win over the core 24px. */
  .ls-answers td.radio-item,
  .ls-answers td.checkbox-item {
    border: 1px solid transparent;
    border-radius: calc(var(--st-radius) / 1.5);
  }
  /* --st-opt-pad-y is the single source for the vertical step between
     options. A list row and a collapsed array cell are the same thing to
     the eye, but the core gives them different numbers (0.3rem vs a flat
     4px), so they drift apart on any density change. Both read this var. */
  .dir-ltr .ls-answers td.radio-item,
  .dir-ltr .ls-answers td.checkbox-item {
    padding: var(--st-opt-pad-y, 4px) 4px var(--st-opt-pad-y, 4px)
             calc(20px + var(--st-ctl-inset-arr, 6px));
  }
  .dir-rtl .ls-answers td.radio-item,
  .dir-rtl .ls-answers td.checkbox-item {
    padding: var(--st-opt-pad-y, 4px) calc(20px + var(--st-ctl-inset-arr, 6px))
             var(--st-opt-pad-y, 4px) 4px;
  }
  .ls-answers td label.ls-label-xs-visibility {
    padding-inline-start: var(--st-ctl-gap-arr, 5px);
  }
  html.st-rowhl .ls-answers td.radio-item.st-selected,
  html.st-rowhl .ls-answers td.checkbox-item.st-selected {
    background: var(--st-accent-soft);
    border-color: var(--st-accent);
  }
}

/* The active navigation unit inside an array is a single row, so the marker
   has to read as a row, not as a card. Placed after the zebra rule so it wins
   the tie on specificity by source order. */
html.st-zebra table.ls-answers tbody tr.st-active,
table.ls-answers tbody tr.st-active {
  background: var(--st-accent-soft);
  box-shadow: inset 3px 0 0 var(--st-accent);
}
/* Per-cell code in the wide array. Hidden by default: it only makes sense in
   the table layout, where the core clips the cell label away. In the stacked
   layout the ordinary badge is already visible next to the option text. */
.st-cellcode { display: none; }
@media (min-width: 761px) {
  html.st-codes .st-cellcode {
    display: block;
    margin-top: 1px;
    font-family: var(--st-mono);
    font-size: 0.72em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--st-muted);
    user-select: none;
  }
  html.st-codes .ls-answers tr.st-active .st-cellcode { color: var(--st-accent); font-weight: 600; }
}

/* Column-heading codes sit above a centred label, not beside it. */
.st-code.st-code-head {
  display: block;
  margin: 0 auto 0.15rem;
  min-width: 1.9em;
}

/* ---------- navigator / buttons ---------- */
/* vanilla reserves a lot of room around the buttons: .space-col gives the
   navigator (and the group above it) margin-top:1em / margin-bottom:2em, and
   #navigator-container adds padding-bottom:1em on top. In a small embedded
   iframe that is most of a screenful of nothing. All of it is replaced by one
   knob, --st-nav-gap. */
#navigator-container,
#navigator-container.space-col {
  margin-top: var(--st-nav-gap, 0.5rem);
  margin-bottom: var(--st-nav-gap, 0.5rem);
  padding: 0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
}
/* the gap BEFORE the buttons comes from the group wrapper, not the navigator */
.group-outer-container.space-col,
.group-container.space-col {
  margin-top: 0;
  margin-bottom: var(--st-nav-gap, 0.5rem);
}
#main-col.space-col { margin-top: 0; margin-bottom: 0; }

/* smaller than vanilla's .btn-lg, which is sized for a phone, not for an
   operator's embedded frame */
#navigator-container .btn,
#navigator-container .btn-lg,
#navigator-container .btn-default,
#navigator-container .btn-primary {
  min-height: var(--st-field-h);
  padding: 0.25rem 1rem;
  font-size: 0.95rem;
  line-height: 1.4;
  border-radius: calc(var(--st-radius) / 1.5);
}
/* the two halves are Bootstrap .col-6; keep them side by side and let the
   buttons keep their own width instead of stretching the row */
#navigator-container > * { flex: 1 1 0; min-width: 0; }
html.st-sticky #navigator-container {
  position: sticky;
  bottom: 0;
  z-index: 1030;
  background: var(--st-canvas);
  border-top: 1px solid var(--st-border);
  box-shadow: 0 -2px 8px rgba(15, 23, 32, 0.08);
}

.btn-primary {
  background: var(--st-accent);
  border: 1px solid var(--st-accent);
  color: var(--st-accent-contrast);
  font-weight: 600;
  min-height: var(--st-field-h);
  padding-inline: 1.25rem;
  border-radius: calc(var(--st-radius) / 1.5);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary.active {
  background: var(--st-accent);
  border-color: var(--st-accent);
  color: var(--st-accent-contrast);
  filter: brightness(0.88);
}
.btn-primary:focus-visible { box-shadow: 0 0 0 3px var(--st-accent-ring); }
.btn-default,
.btn-secondary {
  background: var(--st-surface);
  color: var(--st-text);
  border: 1px solid var(--st-border-strong);
  min-height: var(--st-field-h);
  border-radius: calc(var(--st-radius) / 1.5);
}
#ls-button-submit { min-width: 8rem; }

/* ---------- progress ---------- */
.progress {
  height: 0.5rem;
  border-radius: 999px;
  background: var(--st-progress-bg);
  box-shadow: none;
  margin-bottom: 0.75rem;
}
.progress-bar {
  background: var(--st-progress-fg);
  color: var(--st-progress-text);
  font-size: 0.7rem;
}

/* ---------- privacy / save / lists ---------- */
.privacy,
.privacy-block,
.save-form,
.save-survey-form,
#surveys-list-container {
  background: var(--st-surface);
  border: 1px solid var(--st-border);
  border-radius: var(--st-radius);
  padding: 1rem;
}
.privacy .form-check { background: var(--st-help-bg); padding: 0.75rem; border-radius: calc(var(--st-radius) / 1.5); }
.privacy .ls-privacy-head { font-weight: 600; }

/* ---------- SHARED LAYOUT (was operator-only) ----------
   Both modes render the same way. What still separates them is data entry
   only: answer codes, numeric keys, Enter-as-Next. Roominess is governed by
   the density and content-width options, not by the mode — set density to
   "comfortable" and width to "narrow" for the airy, classic web look. */
body { line-height: 1.35; }
.question-container { box-shadow: none; }
.question-title-container { padding-bottom: 0.45rem; }
.answer-container .answer-item:not(td) { border-radius: 4px; }
.group-title { margin-bottom: 0.15rem; }
h1.survey-name { font-size: 1.1rem; }

/* two columns of options when there are many and the screen is wide */
@media (min-width: 992px) {
  .answer-container.st-cols-2 ul.ls-answers,
  .answer-container.st-cols-2 > ul,
  .answer-container.st-cols-2 > div {
    column-count: 2;
    column-gap: 1.5rem;
  }
  .answer-container.st-cols-2 .answer-item { break-inside: avoid; }
}

/* An operator reads off the screen all shift — a decorative background is
   noise there. A respondent may legitimately want one, so it is only
   suppressed in operator mode. */
html.st-op body { background-image: none !important; }

/* ---------- COMPACT DENSITY ---------- */
html.st-compact .question-container { margin-bottom: calc(var(--st-gap) * 0.6); }

/* ---------- RESPONDENT MODE on a phone ----------
   A respondent holds the phone at arm's length and reads once; the operator
   sits at a monitor and reads the same wording all shift. So the base size is
   raised for the respondent only, and only at phone width — everything else
   in the theme is sized in rem, so the question, the options, the input
   fields and the dropdowns all grow with it in proportion.
   Operator mode (html.st-op) is deliberately untouched.
   Specificity note: custom_header.twig writes `html, body { font-size: … }`
   with !important, so this has to be !important as well — it wins on the
   extra class, not on the flag. */
@media (max-width: 760px) {
  html.st-resp,
  html.st-resp body { font-size: var(--st-fs-mobile, 18px) !important; }
}

/* ---------- RESPONDENT MODE: big tap targets on phones ---------- */
@media (max-width: 760px) {
  /* Bigger tap targets belong to the roomy layout only. Unscoped, this rule
     silently overrode the dense --st-row-pad-* on every phone-width screen,
     which made list rows look inflated next to a collapsed array (whose
     cells carry their own padding and were unaffected). */
  html.st-roomy .answer-container .answer-item:not(td) {
    padding: 0.7rem 0.6rem;
    padding-inline-start: calc(20px + var(--st-ctl-inset, 6px));
  }
  .btn-primary,
  .btn-default,
  .btn-secondary { width: 100%; margin-bottom: 0.5rem; }
}

/* ---------- accessibility ---------- */
:focus-visible { outline: 2px solid var(--st-accent); outline-offset: 2px; }
html.st-contrast .question-container { border-width: 2px; }
html.st-contrast .answer-container .answer-item:not(td).st-selected { outline: 2px solid var(--st-accent); }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---------- print ---------- */
@media print {
  #survey-nav, #navigator-container, .st-keybuf { display: none !important; }
  .question-container { break-inside: avoid; border: 1px solid #999; box-shadow: none; }
  body { background: #fff; }
}
