/* ------------------------------------------------------------------
   Questionnaire app styles.

   Self-contained by design — no CDN or client-side framework. The app is a
   handful of server-rendered forms, so a stylesheet is the whole front end.
   ------------------------------------------------------------------ */

:root {
    --ink:            #14181f;
    --ink-soft:       #4a5361;
    --ink-faint:      #79828f;
    --rule:           #e2e6ec;
    --surface:        #ffffff;
    --canvas:         #f5f7fa;
    --accent:         #1f3864;
    --accent-soft:    #eef2f8;
    --positive:       #17614a;
    --positive-soft:  #e6f4ef;
    --negative:       #96271f;
    --negative-soft:  #fdeceb;
    --warning-soft:   #fdf5e3;
    --warning-rule:   #e5c76b;

    --radius:   10px;
    --radius-s: 6px;
    --shadow:   0 1px 2px rgba(20, 24, 31, .05), 0 4px 16px rgba(20, 24, 31, .05);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--canvas);
    color: var(--ink);
    font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.wrap { width: 100%; max-width: 880px; margin: 0 auto; padding: 0 20px; }

/* ---------- Header / footer ---------- */

.site-header {
    background: var(--surface);
    border-bottom: 1px solid var(--rule);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    min-height: 60px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 650;
    letter-spacing: -.01em;
    color: var(--ink);
    text-decoration: none;
}

.brand-mark {
    width: 20px; height: 20px;
    border-radius: 5px;
    background: var(--accent);
}

.site-nav { display: flex; align-items: center; gap: 20px; }

.site-nav a, .link-button {
    color: var(--ink-soft);
    text-decoration: none;
    font-size: 14.5px;
    font-weight: 500;
}

.site-nav a:hover, .link-button:hover { color: var(--accent); text-decoration: underline; }

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

.link-button {
    background: none; border: 0; padding: 0;
    font-family: inherit; cursor: pointer;
}

/* ---------- Language picker ---------- */

.lang-picker { display: inline-flex; align-items: center; gap: 8px; margin: 0; }

/* The form-field rule further down gives every select width:100% and 15px text,
   which in a header would push the nav off the end of the line. Reeled back in
   here to something nav-sized, in the nav's own colour. */
.lang-picker select {
    width: auto;
    padding: 4px 8px;
    font-size: 14px;
    color: var(--ink-soft);
    border-color: var(--rule);
    cursor: pointer;
}

.lang-picker select:hover { color: var(--accent); border-color: #ccd3dc; }

/* Available to a screen reader, invisible to everyone else — display:none and
   visibility:hidden would take it out of the accessibility tree along with the
   layout, leaving the picker as an unlabelled select. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.site-main { flex: 1; padding-top: 32px; padding-bottom: 56px; }

.site-footer {
    border-top: 1px solid var(--rule);
    background: var(--surface);
    padding: 18px 0;
    color: var(--ink-faint);
    font-size: 13.5px;
}

/* ---------- Typography ---------- */

h1 { font-size: 26px; line-height: 1.25; letter-spacing: -.02em; margin: 0 0 8px; }
h2 { font-size: 19px; letter-spacing: -.01em; margin: 32px 0 12px; }
h3 { font-size: 16px; margin: 0 0 6px; }

.lede { color: var(--ink-soft); margin: 0 0 24px; }
.muted { color: var(--ink-faint); }
.small { font-size: 13.5px; }

/* ---------- Cards ---------- */

.card {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px;
    margin-bottom: 20px;
}

.card-tight { padding: 18px 20px; }

/* ---------- Alerts ---------- */

.alert {
    border-radius: var(--radius-s);
    padding: 12px 16px;
    margin-bottom: 20px;
    font-size: 14.5px;
    border: 1px solid transparent;
}

.alert-success { background: var(--positive-soft); color: var(--positive); border-color: #bfe0d4; }
.alert-error   { background: var(--negative-soft); color: var(--negative); border-color: #f2c9c5; }
.alert-info    { background: var(--accent-soft);   color: var(--accent);   border-color: #ccd8ea; }
.alert-warning { background: var(--warning-soft);  color: #7a5c12;         border-color: var(--warning-rule); }

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

.field { margin-bottom: 18px; }

label.field-label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 6px;
}

input[type=text], input[type=email], input[type=password], input[type=file], select {
    width: 100%;
    padding: 9px 12px;
    font: inherit;
    font-size: 15px;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid #ccd3dc;
    border-radius: var(--radius-s);
}

input[type=text]:focus, input[type=email]:focus, input[type=password]:focus, select:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

.validation-message { color: var(--negative); font-size: 13.5px; display: block; margin-top: 5px; }

.validation-summary ul { margin: 0; padding-inline-start: 18px; }

/* ---------- Buttons ---------- */

.btn {
    display: inline-block;
    padding: 10px 18px;
    font: inherit;
    font-size: 15px;
    font-weight: 550;
    border-radius: var(--radius-s);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
}

.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: #16294a; }

.btn-secondary { background: var(--surface); color: var(--ink); border-color: #ccd3dc; }
.btn-secondary:hover { background: var(--canvas); }

/* Destructive actions are the only place red is used as a button fill, so the
   colour itself carries the warning rather than the label alone. */
.btn-danger { background: var(--negative); color: #fff; }
.btn-danger:hover { background: #7c1f18; }

.btn-small { padding: 6px 12px; font-size: 13.5px; }

.btn:disabled, .btn[disabled] {
    opacity: .5;
    cursor: not-allowed;
}

/* `display: inline-block` above beats the browser's own rule for [hidden], so
   every button has to opt back out of it explicitly or `hidden` does nothing. */
.btn[hidden] { display: none; }

.btn-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 20px; }

/* `display: flex` beats the browser's own rule for [hidden], so any element
   given a display here has to opt back out of it explicitly. The respondent's
   Submit row is hidden on every page but the last. */
.btn-row[hidden] { display: none; }

/* ---------- Destructive confirmation ---------- */

.detail-list {
    display: grid;
    grid-template-columns: minmax(120px, max-content) 1fr;
    gap: 8px 20px;
    margin: 0;
}

.detail-list dt { color: var(--ink-faint); font-size: 14px; }
.detail-list dd { margin: 0; }

.confirm-check {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 14px 16px;
    border: 1px solid #f2c9c5;
    border-radius: var(--radius-s);
    background: var(--negative-soft);
    cursor: pointer;
}

.confirm-check input { margin-top: 4px; flex: none; }

/* The end-questionnaire checkbox is ticked by default and choosing it is the
   lenient option, so the red "are you sure" treatment would read wrong. */
.confirm-check-neutral {
    border-color: var(--rule);
    background: var(--canvas);
}

.link-button.danger { color: var(--negative); }
.link-button.danger:hover { color: var(--negative); }

.row-actions { white-space: nowrap; }
.row-actions > * + * { margin-inline-start: 14px; }

@media (max-width: 520px) {
    .detail-list { grid-template-columns: 1fr; gap: 2px 0; }
    .detail-list dd { margin-bottom: 10px; }
}

/* ---------- Questions ---------- */

.category-heading {
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 30px 0 10px;
}

/* Logical, not left: in Arabic this accent belongs on the right-hand edge, beside
   where the question actually starts. Identical rendering in the other seven. */
.question { border-inline-start: 3px solid transparent; }
.question.has-error { border-inline-start-color: var(--negative); }

/* The card is focused programmatically on every page change so a screen reader
   starts reading the new question rather than staying where the pressed button
   used to be. That is not the respondent tabbing to it, so it gets no focus
   ring; :focus-visible is left alone for anyone who really does tab here. */
.question:focus { outline: none; }

.question-head { display: flex; gap: 10px; align-items: baseline; }
.question-number { color: var(--ink-faint); font-variant-numeric: tabular-nums; font-size: 14px; }
.question-text { font-weight: 600; }
.question-help { color: var(--ink-soft); font-size: 14px; margin: 4px 0 0; }

.required-flag { color: var(--negative); margin-inline-start: 3px; }

.options { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 8px; }

.option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    cursor: pointer;
}

.option:hover { background: var(--accent-soft); border-color: #ccd8ea; }
.option input { margin: 3px 0 0; flex: none; }
.option:has(input:checked) { background: var(--accent-soft); border-color: var(--accent); }

/* ---------- Score summary ---------- */

.score-hero { text-align: center; padding: 28px 24px; }
.score-value { font-size: 46px; font-weight: 700; letter-spacing: -.03em; line-height: 1.05; }
.score-of { color: var(--ink-faint); font-size: 17px; font-weight: 500; }

.meter {
    height: 9px;
    background: var(--rule);
    border-radius: 99px;
    overflow: hidden;
    margin: 18px auto 8px;
    max-width: 420px;
}

.meter-fill { height: 100%; background: var(--accent); border-radius: 99px; }

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

.table-scroll { overflow-x: auto; }

table.grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 14.5px;
}

table.grid th, table.grid td {
    text-align: start;
    padding: 10px 12px;
    border-bottom: 1px solid var(--rule);
    vertical-align: top;
}

table.grid th {
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-faint);
    font-weight: 650;
    white-space: nowrap;
}

table.grid tbody tr:last-child td { border-bottom: 0; }
table.grid tbody tr:hover { background: var(--canvas); }

.num { text-align: end; font-variant-numeric: tabular-nums; }

/* ---------- Misc ---------- */

.pill {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 99px;
    font-size: 12px;
    font-weight: 650;
    letter-spacing: .02em;
}

.pill-live    { background: var(--positive-soft); color: var(--positive); }
.pill-draft   { background: var(--rule);          color: var(--ink-soft); }
.pill-pending { background: var(--warning-soft);  color: #7a5c12; }
/* Deliberately stopped, rather than merely superseded — read as a state, not an
   error, so it borrows the warning palette rather than the negative one. */
.pill-ended   { background: var(--warning-soft);  color: #7a5c12; }
/* An empty media slot: outstanding work, not a failure. */
.pill-idle    { background: var(--warning-soft);  color: #7a5c12; }

.error-list { margin: 0; padding-inline-start: 20px; }
.error-list li { margin-bottom: 6px; }
.error-list code {
    background: var(--negative-soft);
    color: var(--negative);
    padding: 1px 5px;
    border-radius: 4px;
    font-size: 13px;
}

.stat-row { display: flex; flex-wrap: wrap; gap: 28px; margin-bottom: 4px; }
.stat-label { font-size: 12.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); }
.stat-value { font-size: 22px; font-weight: 650; font-variant-numeric: tabular-nums; }

.empty-state { text-align: center; padding: 44px 24px; color: var(--ink-soft); }

hr.rule { border: 0; border-top: 1px solid var(--rule); margin: 24px 0; }

@media (max-width: 600px) {
    h1 { font-size: 22px; }
    .card { padding: 18px; }
    .score-value { font-size: 38px; }
}

/* ------------------------------------------------------------------
   Question media — pictures and video

   Everything that HIDES something is scoped to html.js, set by the inline
   script in _Layout before this file is applied. With JavaScript off there
   is nothing to un-hide it again, so the rule must simply not apply: the
   questionnaire then renders with the picture, the video (with its own
   native controls) and every answer option visible at once. Degraded, but
   answerable — which matters more than the stimulus being enforced.
   ------------------------------------------------------------------ */

/* ---------- Admin: preview badges ---------- */

.media-badge {
    display: inline-block;
    margin-inline-start: 6px;
    padding: 1px 8px;
    border-radius: 99px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 12px;
    font-weight: 600;
}

/* ---------- Admin: media manager ---------- */

.media-slot-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.media-preview {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    align-items: flex-start;
    padding: 14px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    background: var(--canvas);
    margin-bottom: 14px;
}

.media-thumb, .media-thumb-video {
    width: 220px;
    max-width: 100%;
    border-radius: var(--radius-s);
    background: #000;
    display: block;
}

.media-thumb { height: auto; }

.media-meta { flex: 1 1 220px; min-width: 0; }
.media-meta code { word-break: break-all; }

.media-form { margin: 0; }

.drop-zone {
    border: 2px dashed #c3ccd8;
    border-radius: var(--radius-s);
    background: var(--canvas);
    padding: 18px;
    text-align: center;
}

.drop-zone.is-dragging {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.drop-zone-text { margin: 0 0 4px; font-size: 14.5px; }
.drop-zone-hint { margin: 0 0 12px; }

.drop-zone-input {
    /* Kept visible on purpose. Hiding a `required` input makes the browser
       refuse to submit and then fail to show why, because it cannot focus
       what it cannot display. */
    max-width: 420px;
    margin: 0 auto;
}

.drop-zone-file { margin: 10px 0 0; color: var(--ink-soft); min-height: 1.2em; }
.drop-zone-file.is-error { color: var(--negative); font-weight: 600; }

.link-like {
    color: var(--accent);
    text-decoration: underline;
    cursor: pointer;
}

/* ---------- Respondent: paging ---------- */

/* Pages 2..n are hidden with the attribute, not removed: their inputs have to
   stay in the document or they would drop out of the POST. */
.page[hidden] { display: none; }

.pager {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 18px;
    align-items: center;
    justify-content: space-between;
    margin: 22px 0 0;
    padding-top: 18px;
    border-top: 1px solid var(--rule);
}

.pager[hidden] { display: none; }

.pager-progress { flex: 1 1 200px; min-width: 0; }

.pager-status {
    margin: 0 0 8px;
    font-size: 13px;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
}

.pager-bar {
    height: 6px;
    border-radius: 99px;
    background: var(--rule);
    overflow: hidden;
}

.pager-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 99px;
    background: var(--accent);
    transition: width .2s ease;
}

/* Next is disabled, not hidden, while a question is unanswered or its media is
   still running: a button that greys out is easier to follow than one that
   disappears. It is only hidden on the last page, where Submit replaces it —
   and `.btn[hidden]` above is what makes that stick. */
.pager-buttons { display: flex; gap: 10px; flex: none; }

/* ---------- Respondent: the gate ---------- */

/* The whole gating mechanism, in one rule — scoped to the marker class that
   questionnaire-media.js sets on startup. If that file ever fails to load, this
   rule simply does not apply and the options stay visible, instead of being
   hidden by CSS with nothing left running to reveal them. */
.js.media-ready .question.is-gated .options { display: none; }

/* Only meaningful when the script never ran. */
.js .media-nojs { display: none; }

.media-stage {
    margin: 16px 0 0;
    padding: 16px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    background: var(--canvas);
    text-align: center;
}

.media-stage[hidden] { display: none; }

.media-image, .media-video {
    display: block;
    max-width: 100%;
    max-height: 420px;
    margin: 0 auto;
    border-radius: var(--radius-s);
    background: #000;
}

.media-status {
    margin: 12px 0 0;
    font-size: 14px;
    color: var(--ink-soft);
}

.media-countdown {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--accent);
}

.media-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    justify-content: center;
    margin-top: 14px;
}

.media-play[hidden], .media-mute[hidden] { display: none; }

/* Display only — there is no seek bar, and this is not one. Clicks do nothing
   by design, so it is marked role="presentation" in the markup. */
.media-progress {
    flex: 1 1 160px;
    max-width: 320px;
    height: 7px;
    border-radius: 99px;
    background: var(--rule);
    overflow: hidden;
}

.media-progress-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 99px;
    background: var(--accent);
}

@media (max-width: 600px) {
    .media-thumb, .media-thumb-video { width: 100%; }
    .media-image, .media-video { max-height: 280px; }
}
