/**
 * The quiz shortcode and the quiz progress bar shortcode, which are always
 * placed together. The headings, the copy, the buttons and the loader are
 * Desensitize Elements basic elements, so their type, gradients, borders and
 * turning come from that stylesheet and the theme's. This one only lays them
 * out, draws the answer states, stacks the slides and draws the progress
 * bar's markers.
 */

.ds-quiz {
    /* how wide the answers and the nav buttons are, at most */
    --ds-quiz-controls-width: 26.25rem;

    /* the fade of an answer's gradient */
    --ds-quiz-state-duration: 0.2s;

    /* the loader and the buttons easing in and out of the wait after an
       answer, eased out and never running past where they end */
    --ds-quiz-loading-duration: 0.32s;
    --ds-quiz-loading-easing: cubic-bezier( 0.25, 1, 0.5, 1 );

    display: grid;
    /* the slides share one cell, and the first slide's references sit under
       it. That row collapses while they are out of view, so the slides have
       the quiz's whole height to themselves the rest of the time */
    grid-template-areas: "stack" "refs";
    /* the slides' row takes all the height the quiz is given, and every slide
       in it is stretched to that height */
    grid-template-rows: 1fr auto;

    flex: 1 1 auto;

    width: 100%;

    /* the heading basic element takes its family from a wrapper, which the
       quiz is to it */
    font-family: var(--main-font);
}

/* The quiz fills whatever it is placed in. Elementor puts a shortcode in a
   widget and a wrapper of its own, which only ever take the height of what
   they hold, so the two holding a quiz are made to grow into their column
   and pass that height down. A column with no set height is left as tall as
   the quiz is. */
.elementor-widget-shortcode:has( > .elementor-shortcode > .ds-quiz ) {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    align-self: stretch;
}

.elementor-shortcode:has( > .ds-quiz ) {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

/* Slides
   -------------------------------------------------- */

/* The intro, the questions and the results share one cell, and so do the
   question slides inside the stage. A slide out of view is hidden rather
   than taken out of the layout, so it still counts towards the height and
   nothing below the quiz moves from one slide to the next. The script marks
   the slide in view, and the one leaving while it fades out. */
.ds-quiz__view {
    grid-area: stack;

    min-width: 0;

    visibility: hidden;
}

.ds-quiz > .ds-quiz__view--active,
.ds-quiz > .ds-quiz__view--leaving {
    visibility: visible;
}

/* A question in view only inherits the visibility, so it stays hidden while
   the questions around it are: a visible child would show through a hidden
   parent. */
.ds-quiz__stage > .ds-quiz__view--active,
.ds-quiz__stage > .ds-quiz__view--leaving {
    visibility: inherit;
}

.ds-quiz__view--leaving {
    pointer-events: none;
}

/* The slides take the focus as they come into view, only so a screen reader
   starts reading there, which needs no ring. */
.ds-quiz__view:focus,
.ds-quiz__title:focus {
    outline: none;
}

/* The title of a slide looks the way headings do everywhere, except for its
   line height. Two classes, like the heading's own rule, and in a stylesheet
   that comes after it, so the line height here is the one that applies. */
.ds-quiz__title.ds-quiz__title {
    line-height: var(--heading-line-height-500);
}

.ds-quiz__screen {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--el-spacing-550);
}

.ds-quiz__main {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--el-spacing-400);

    width: 100%;
}

/* Intro
   -------------------------------------------------- */

/* The references belong to the first slide but are printed beside it, so that
   on mobile they can come after the steps below the slides. They take the row
   under them, which puts them at the very bottom of the quiz, where the first
   slide's own bottom is, however much room the title, the body text and the
   start button leave above them.

   They come and go with the slide they belong to, the way the slides
   themselves do, so the script fades them along with it. Once it has gone
   they keep no room at all.

   Beside the progress bar the column sets the quiz's height and the row above
   them takes whatever is left, so they are already held off the slide and are
   given no room of their own. Only on mobile, where the quiz is as tall as it
   makes itself and they sit right under the steps, are they spaced away. */
.ds-quiz > .ds-quiz__references {
    grid-area: refs;
    justify-self: start;
}

.ds-quiz > .ds-quiz__references:not(.ds-quiz__view--active):not(.ds-quiz__view--leaving) {
    display: none;
}

/* The body texts are written in the editor on the First slide and
   Questions tabs, so they arrive as paragraphs and lists. Their own margins are
   taken off and the room between them set here, the room the heading keeps
   from the body text. */
.ds-quiz .ds-quiz__rich-text {
    display: flex;
    flex-direction: column;
    gap: var(--el-spacing-400);
}

.ds-quiz .ds-quiz__rich-text > * {
    margin: 0;
}

.ds-quiz .ds-quiz__rich-text ol {
    padding-inline-start: 1.25em;
}

/* A bulleted list is drawn with a short dash in front of every item. */
.ds-quiz .ds-quiz__rich-text ul {
    display: flex;
    flex-direction: column;
    gap: var(--el-spacing-100);

    padding: 0;

    list-style: none;
}

.ds-quiz .ds-quiz__rich-text ul > li {
    display: flex;
    align-items: center;
    gap: 0.75rem;

    margin: 0;
    padding: 0;
}

.ds-quiz .ds-quiz__rich-text ul > li::before {
    content: '';

    flex: none;

    width: 0.75rem;
    height: 3px;

    border-radius: 999px;
    background-color: currentColor;
}

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

/* The stage grows into all the height the questions screen has, and every
   question slide is stretched to it, the way the screens are in the quiz. */
.ds-quiz__stage {
    position: relative;

    display: grid;
    grid-template-areas: "stack";
    grid-template-rows: 1fr;

    flex: 1 1 auto;

    width: 100%;
}

/* The answers follow straight on from the title, or the body text when a
   question has one. */
.ds-quiz__question {
    display: flex;
    flex-direction: column;
    gap: var(--el-spacing-550);
}

.ds-quiz__answers {
    display: flex;
    flex-direction: column;
    gap: var(--el-spacing-250);

    width: min( 100%, var(--ds-quiz-controls-width) );
}

.ds-quiz__nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--el-spacing-250);

    width: min( 100%, var(--ds-quiz-controls-width) );
}

/* Results
   -------------------------------------------------- */

/* The results slide is the one slide taken out of the layout while it is out
   of view, at every width rather than on mobile alone. The slides otherwise
   share their cell and all keep their room in it, so that nothing below the
   quiz moves from one to the next, and an Elementor template is as tall as it
   was built to be: held in that cell it would set the height of the intro and
   of every question before it was ever reached. It is the last slide, so
   nothing after it is left waiting on its room either way, and the script
   grows the quiz into it as it comes in.

   It still keeps its room while it fades, the way the other slides do, so
   going back from it is no different to any other move. */
.ds-quiz > .ds-quiz__results:not(.ds-quiz__view--active):not(.ds-quiz__view--leaving) {
    display: none;
}

/* The Loader basic element the answers are counted up behind, drawn at the top
   of the slide and across the middle of it, at the one size at every width.

   It is taken out of the flow, the way the stage's is, so the outcome sits at
   the very top of the slide once it is in and nothing is left standing where
   the loader was. */
.ds-quiz__results {
    position: relative;
}

.ds-quiz__results-loader {
    --ds-loader-duration: var(--ds-quiz-loading-duration);
    --ds-loader-easing: var(--ds-quiz-loading-easing);

    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    z-index: 1;

    margin-inline: auto;
}

/* The loader stands out of the flow, so the slide holds nothing while it
   counts. Only from the mobile breakpoint down is that a height the quiz
   would take: there it is as tall as the slide in view, so the results are
   held at the height of the question they replaced, which the script passes
   in, and the slide grows or shrinks into the outcome once the count is over.
   Above that breakpoint the column beside the progress bar sets the quiz's
   height and there is nothing to hold. */
@media ( max-width: 767px ) {
    /* and the loader is dropped clear of the top of the slide there, rather
       than sitting right on it */
    .ds-quiz__results-loader {
        top: var(--sc-padding-block-350);
    }

    .ds-quiz__results--counting {
        min-height: var(--ds-quiz-results-hold, 0px);
    }
}

/* Both outcomes are printed in the results slide, and the script shows the one
   the answers call for. The other is hidden, and is given no room at all, so
   the slide is only ever as tall as the outcome in view.

   Each one is an Elementor template, which lays itself out, so nothing is set
   on it beyond the full width of the slide: the slide starts its children at
   its inline start, where a template left to its own width would sit narrow. */
.ds-quiz__outcome {
    width: 100%;
}

.ds-quiz__outcome[hidden] {
    display: none;
}

/* Loader
   -------------------------------------------------- */

/* The Loader basic element, which draws itself and fades in and out under its
   own active class, put on it by the script. The quiz only places it: every
   question slide carries one, taken out of the flow and laid in the stage's
   bottom right corner, so the slide holding it is the only one it is ever
   seen with. It is eased along with the buttons that fade back beside it. */
.ds-quiz__loader {
    --ds-loader-duration: var(--ds-quiz-loading-duration);
    --ds-loader-easing: var(--ds-quiz-loading-easing);

    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 1;
}

/* The loaders are all turned on together, since only one slide is ever in
   view, and the element shows itself by turning visible. A visible child is
   drawn inside a hidden parent though, so left at that every slide's loader
   would show through the slide in view. It inherits the visibility instead,
   exactly as a question in the stage does, and only the slide in view carries
   one that is seen. */
.ds-quiz__loader.ds-loader--active {
    visibility: inherit;
}

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

/* Every button is a real button element, so the browser's own look is taken
   off. The size, the borders and the hover come from the site's button. */
.ds-quiz .ds-button {
    -webkit-appearance: none;
    appearance: none;
}

.ds-quiz .ds-button:focus-visible {
    outline: 2px solid var(--color-1);
    outline-offset: 3px;
}

.ds-quiz .ds-quiz__answer {
    width: 100%;
}

/* An answer rests on the see-through secondary button colors with the dark
   label. Its own gradient, burgundy for yes and gold for no, is faded in over
   them on its background layer only once it is chosen, never on hover or
   focus. */
.ds-quiz .ds-quiz__answer {
    background: var(--color-btn-secondary-bg-1);
    border-color: var(--color-btn-secondary-border-1);

    transition:
        color var(--ds-quiz-state-duration) ease,
        opacity var(--ds-quiz-loading-duration) var(--ds-quiz-loading-easing),
        filter 0.2s ease;
}

.ds-quiz .ds-quiz__answer:not(.ds-quiz__answer--selected) {
    color: var(--color-1);
}

.ds-quiz .ds-quiz__answer .ds-button__background {
    opacity: 0;

    transition: opacity var(--ds-quiz-state-duration) ease;
}

.ds-quiz .ds-quiz__answer--selected .ds-button__background {
    opacity: 1;
}

.ds-quiz .ds-quiz__back {
    background: none;
}

/* While an answer is taken in nothing answers the pointer: the chosen answer
   keeps its gradient, and the other one and the back button fade back. They
   stay faded on the slide leaving once the wait is over, rather than coming
   back as it goes. */
.ds-quiz__nav {
    transition: opacity var(--ds-quiz-loading-duration) var(--ds-quiz-loading-easing);
}

.ds-quiz--loading .ds-quiz__answers,
.ds-quiz--loading .ds-quiz__nav {
    cursor: progress;
}

.ds-quiz--loading .ds-quiz__answer,
.ds-quiz--loading .ds-quiz__back {
    pointer-events: none;
}

.ds-quiz.ds-quiz--loading .ds-quiz__answer:not(.ds-quiz__answer--selected),
.ds-quiz--loading .ds-quiz__nav,
.ds-quiz .ds-quiz__view--leaving:has( .ds-quiz__answer--selected ) .ds-quiz__answer:not(.ds-quiz__answer--selected),
.ds-quiz__view--leaving:has( .ds-quiz__answer--selected ) .ds-quiz__nav {
    opacity: 0.4;
}

/* ==================================================
   Progress bar
   The steps down a line beside the quiz. The text is a body text basic
   element and the dots between the steps a dot connector one, this lays the
   steps out, draws the markers and colors every part for the state the quiz
   is in.
   ================================================== */

.ds-quiz-progress {
    /* a part that has been reached, and one that has not */
    --ds-quiz-progress-on: var(--color-6);
    --ds-quiz-progress-off: rgba( 248, 247, 243, 0.48 );

    /* short, eased out, never running past */
    --ds-quiz-progress-duration: 0.28s;
    --ds-quiz-progress-easing: cubic-bezier( 0.25, 1, 0.5, 1 );

    /* the circle becoming a ring, and back, takes a little longer to read */
    --ds-quiz-progress-morph-duration: 0.42s;

    /* the marker is drawn in a 32 unit box: the ring is 5.76 wide around a middle
       line at 13.12, and twice that radius fills the whole circle, the stroke
       then being cut back to the circle's edge */
    --ds-quiz-progress-ring-width: 5.76px;
    --ds-quiz-progress-disc-width: 26.24px;

    font-family: var(--main-font);
    color: var(--ds-quiz-progress-on);
}

@supports ( color: color-mix( in srgb, red 48%, transparent ) ) {
    .ds-quiz-progress {
        --ds-quiz-progress-off: color-mix( in srgb, var(--color-6) 48%, transparent );
    }
}

/* nothing is shown until the script has found a quiz to follow */
.ds-quiz-progress[hidden] {
    display: none;
}

/* The bar is the desktop half of this: below the mobile breakpoint the quiz
   prints the steps around its own slides instead, so the bar goes whether or
   not the page hides the column it sits in. The two are never both shown. */
@media ( max-width: 767px ) {
    .ds-quiz-progress {
        display: none;
    }
}

/* Progress bar steps
   -------------------------------------------------- */

.ds-quiz-progress .ds-quiz-progress__steps {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;

    margin: 0;
    padding: 0;

    list-style: none;
}

.ds-quiz-progress .ds-quiz-progress__step {
    display: flex;
    align-items: flex-start;
    gap: var(--el-spacing-250);

    margin: 0;
    padding: 0;
}

/* The marker and the dots down to the next step. */
.ds-quiz-progress__rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;

    flex: none;
}

.ds-quiz-progress__circle,
.ds-quiz-progress__meter {
    display: block;

    width: 2rem;
    height: 2rem;
}

.ds-quiz-progress__circle {
    border-radius: 999px;
    background-color: currentColor;
}

/* The text is centred on its marker. Two lines run past the marker's height
   above and below, the way the design sets them, without pushing the steps
   apart. */
.ds-quiz-progress__label {
    display: flex;
    align-items: center;

    height: 2rem;
}

/* The middle step's three texts share one cell and cross fade. The cell is as
   tall as the longest of them and each is centred in it, so a text of one
   line sits on the marker's middle just as one of two does. */
.ds-quiz-progress__variants {
    display: grid;
    grid-template-areas: "stack";
    align-items: center;
}

.ds-quiz-progress__variant {
    grid-area: stack;

    opacity: 0;
    visibility: hidden;

    transition:
        opacity var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing),
        visibility 0s linear var(--ds-quiz-progress-duration);
}

.ds-quiz-progress__variant--active {
    opacity: 1;
    visibility: visible;

    transition:
        opacity var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing),
        visibility 0s;
}

/* Progress bar colors per state
   -------------------------------------------------- */

/* Every marker and every text is drawn in currentColor, so fading its color
   fades its fill and its text together. The first step has always been
   reached. */
.ds-quiz-progress__circle,
.ds-quiz-progress__label,
.ds-quiz-progress__disc {
    color: var(--ds-quiz-progress-off);

    transition: color var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing);
}

/* The dots down to a step are all at a quarter until that step is reached,
   when they are drawn as the dot connector draws them. The quarter is set on
   the dots themselves, over the opacities they would inherit from the
   connector, so reaching the step only has to hand those back. */
.ds-quiz-progress__connector .ds-dot-connector__dot {
    --ds-dot-connector-center-opacity: 0.25;
    --ds-dot-connector-near-opacity: 0.25;

    transition: opacity var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing);
}

.ds-quiz-progress__step--start .ds-quiz-progress__circle,
.ds-quiz-progress__step--start .ds-quiz-progress__label {
    color: var(--ds-quiz-progress-on);
}

/* answering the questions: the way to them and their text are reached */
.ds-quiz-progress--questions .ds-quiz-progress__step--questions .ds-quiz-progress__label {
    color: var(--ds-quiz-progress-on);
}

.ds-quiz-progress--questions .ds-quiz-progress__step--start .ds-quiz-progress__connector .ds-dot-connector__dot {
    --ds-dot-connector-center-opacity: inherit;
    --ds-dot-connector-near-opacity: inherit;
}

/* on the results everything is */
.ds-quiz-progress--results .ds-quiz-progress__circle,
.ds-quiz-progress--results .ds-quiz-progress__label,
.ds-quiz-progress--results .ds-quiz-progress__disc {
    color: var(--ds-quiz-progress-on);
}

.ds-quiz-progress--results .ds-quiz-progress__connector .ds-dot-connector__dot {
    --ds-dot-connector-center-opacity: inherit;
    --ds-dot-connector-near-opacity: inherit;
}

/* Progress bar marker
   -------------------------------------------------- */

.ds-quiz-progress__meter {
    position: relative;
}

.ds-quiz-progress__ring {
    display: block;

    width: 100%;
    height: 100%;

    overflow: visible;
}

/* A filled circle on the intro and the results, the ring's track while the
   questions are answered. Only the stroke's width changes, so the circle
   hollows out from its middle into the ring and fills back in. */
.ds-quiz-progress__disc {
    fill: none;
    stroke: currentColor;
    stroke-width: var(--ds-quiz-progress-disc-width);

    transition:
        stroke-width var(--ds-quiz-progress-morph-duration) var(--ds-quiz-progress-easing),
        color var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing);
}

.ds-quiz-progress--questions .ds-quiz-progress__disc {
    stroke-width: var(--ds-quiz-progress-ring-width);
}

/* The filled part of the ring. The script sets its stroke-dashoffset: the path
   is 360 long, and the gap is longer than that so nothing of a second dash
   ever shows. It is only drawn while the questions are answered. */
.ds-quiz-progress__arc {
    fill: none;
    stroke: var(--ds-quiz-progress-on);
    stroke-width: var(--ds-quiz-progress-ring-width);
    stroke-linecap: round;
    stroke-dasharray: 360 400;
    stroke-dashoffset: 360;

    opacity: 0;

    transition:
        stroke-dashoffset var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing),
        opacity var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing);
}

.ds-quiz-progress--questions .ds-quiz-progress__arc {
    opacity: 1;
}

/* The check, on the filled circle once every question is answered. It comes
   in as the circle fills. */
.ds-quiz-progress__check {
    position: absolute;
    inset: 0;

    display: flex;
    align-items: center;
    justify-content: center;

    color: var(--color-1);

    opacity: 0;
    transform: scale( 0.6 );

    transition:
        opacity var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing),
        transform var(--ds-quiz-progress-duration) var(--ds-quiz-progress-easing);
}

.ds-quiz-progress__check__icon {
    display: block;

    width: 1.0454rem;
    height: 0.7803rem;
}

.ds-quiz-progress--results .ds-quiz-progress__check {
    opacity: 1;
    transform: none;

    transition-delay: 0.12s;
}

/* The ring takes its new value and shape at once, the colors and the check
   still fade. */
@media ( prefers-reduced-motion: reduce ) {
    .ds-quiz-progress__disc {
        transition: color var(--ds-quiz-progress-duration) linear;
    }

    .ds-quiz-progress__arc {
        transition: opacity var(--ds-quiz-progress-duration) linear;
    }

    .ds-quiz-progress__check,
    .ds-quiz-progress--results .ds-quiz-progress__check {
        transform: none;

        transition: opacity var(--ds-quiz-progress-duration) linear;
    }
}

/* ==================================================
   Progress steps on mobile
   The same three steps as the progress bar, printed by the quiz around its
   own slides from the mobile breakpoint down, where the bar is hidden with
   the column it sits in. The half above the slides holds the steps the quiz
   has reached, the half below the ones still to come, so the line they sit on
   reads straight through the slide in view.

   They are laid out the way the bar's steps are, but drawn differently: on
   the cream page rather than on the darker column, so in the burgundy, with
   smaller markers, and with only the step the quiz is on lit rather than
   every step it has passed. That is why they are named with a block of their
   own: sharing the bar's would have each undoing the other's rules.
   ================================================== */

/* Nothing of them above the breakpoint, and nothing until the script has
   found the quiz to follow, so they never flash the wrong step. */
.ds-quiz__steps,
.ds-quiz__steps[hidden] {
    display: none;
}

@media ( max-width: 767px ) {
    /* The slides keep their one cell and go on stacking in it, so nothing
       about the way they move changes. The two halves take the rows above
       and below that cell, and the references the row under them all. Each
       keeps its own room rather than the rows being spaced apart, so a half
       out of view leaves no gap behind it. */
    .ds-quiz {
        /* the cell a slide on its way out is laid over is its own, which it is
           only given from here */
        position: relative;

        grid-template-areas: "above" "stack" "below" "refs";
        grid-template-rows: auto 1fr auto auto;
    }

    .ds-quiz > .ds-quiz__steps--above {
        grid-area: above;

        margin-block-end: var(--el-spacing-400);
    }

    .ds-quiz > .ds-quiz__steps--below {
        grid-area: below;

        margin-block-start: var(--el-spacing-400);
    }

    .ds-quiz > .ds-quiz__references {
        margin-block-start: var(--sc-padding-block-500);
    }

    /* Beside the quiz the column sets its height, so a screen out of view
       costing room there costs nothing. Here the quiz is only as tall as it
       makes itself, and the steps below it sit right under the slide in view,
       so a screen out of view keeps no room at all: otherwise the first slide
       would be followed by however much taller the questions are.

       The question slides inside the stage are the exception, and keep their
       room the way they do beside the quiz. They are one screen of the three,
       so holding them all to the height of the longest one only sets the
       height the quiz stands at while the questions are answered: the first
       slide and the results are each still only as tall as they are. Within
       that screen nothing moves at all, so whatever the page carries under the
       quiz stays where it is from the first question to the last, rather than
       travelling with every question that is shorter or taller than the one
       before it. */
    .ds-quiz > .ds-quiz__screen:not(.ds-quiz__view--active):not(.ds-quiz__view--leaving) {
        display: none;
    }

    /* The slide on its way out is taken out of the layout as it goes, so the
       box around it is the height of the slide coming in from the moment the
       move starts and the script can grow or shrink it into that height rather
       than letting it drop into place at the end.

       It is laid over the cell it was in and cut to it, so as that box closes
       the slide fading out closes with it instead of running on over the steps
       below. A screen out of view is given no room at all, so the cell is the
       height of the one screen in view. */
    .ds-quiz > .ds-quiz__screen.ds-quiz__view--leaving,
    .ds-quiz__stage > .ds-quiz__view--leaving {
        position: absolute;
        inset: 0;

        overflow: hidden;
    }

    /* The references go the same way, so the row they are in is already
       closed while they fade. Their own height is left alone, since nothing
       follows them inside the quiz to be cut to. */
    .ds-quiz > .ds-quiz__references.ds-quiz__view--leaving {
        position: absolute;
        inset-block-start: 0;
        inset-inline: 0;
    }

    /* A step crossing from one half to the other is uncovered as that half
       grows, rather than appearing beyond it while it is still growing. */
    .ds-quiz__steps {
        overflow: hidden;
    }

    .ds-quiz__steps {
        /* a part that has been reached, and one that has not */
        --ds-quiz-steps-on: var(--color-1);
        --ds-quiz-steps-off: rgba( 117, 54, 74, 0.48 );

        /* the same short, eased out timings the bar is drawn with */
        --ds-quiz-steps-duration: 0.28s;
        --ds-quiz-steps-easing: cubic-bezier( 0.25, 1, 0.5, 1 );
        --ds-quiz-steps-morph-duration: 0.42s;

        /* the marker is drawn in a 24 unit box: the ring is 5.76 wide around a
           middle line at 9.12, the same width as the bar's in its wider box,
           and twice that radius fills the whole circle, the stroke then being
           cut back to the circle's edge */
        --ds-quiz-steps-ring-width: 5.76px;
        --ds-quiz-steps-disc-width: 18.24px;

        display: flex;
        flex-direction: column;
        gap: var(--el-spacing-300);

        font-family: var(--main-font);
        color: var(--ds-quiz-steps-on);
    }

    @supports ( color: color-mix( in srgb, red 48%, transparent ) ) {
        .ds-quiz__steps {
            --ds-quiz-steps-off: color-mix( in srgb, var(--color-1) 48%, transparent );
        }
    }

    /* Which steps each half shows
       -------------------------------------------------- */

    /* The half above ends on the step the quiz is on, and the half below
       starts after it. The half below holds no first step at all, since the
       quiz is never before it. */
    .ds-quiz__steps--above.ds-quiz-progress--intro .ds-quiz-steps__step--questions,
    .ds-quiz__steps--above.ds-quiz-progress--intro .ds-quiz-steps__step--results,
    .ds-quiz__steps--above.ds-quiz-progress--questions .ds-quiz-steps__step--results,
    .ds-quiz__steps--below.ds-quiz-progress--questions .ds-quiz-steps__step--questions {
        display: none;
    }

    /* On the results there is nothing left to come. */
    .ds-quiz__steps--below.ds-quiz-progress--results {
        display: none;
    }

    /* Steps
       -------------------------------------------------- */

    .ds-quiz__steps .ds-quiz-steps__list {
        display: flex;
        flex-direction: column;
        gap: var(--el-spacing-300);

        margin: 0;
        padding: 0;

        list-style: none;
    }

    .ds-quiz__steps .ds-quiz-steps__step {
        display: flex;
        align-items: flex-start;
        gap: var(--el-spacing-300);

        margin: 0;
        padding: 0;
    }

    /* The marker and the dots down to the next step. */
    .ds-quiz-steps__rail {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--el-spacing-300);

        flex: none;
    }

    /* The dots the half above ends on, carried on past the slide. They stand
       in the marker's column, so the line reads straight. */
    .ds-quiz-steps__lead {
        display: flex;
        justify-content: center;

        width: 1.5rem;
    }

    .ds-quiz-steps__circle,
    .ds-quiz-steps__meter {
        display: block;

        width: 1.5rem;
        height: 1.5rem;
    }

    .ds-quiz-steps__circle {
        border-radius: 999px;
        background-color: currentColor;
    }

    /* The text is centred on its marker, the way the bar's is: the box is the
       marker's own height, so the middle step's stack, which is as tall as its
       longest of three texts, is centred on the marker rather than pushing the
       box taller and carrying the text it is showing below the marker's
       middle. A text of two lines runs past the marker above and below, the
       way the design sets it, without pushing the steps apart. */
    .ds-quiz-steps__label {
        display: flex;
        align-items: center;

        height: 1.5rem;
    }

    /* The steps are read against the slide between them here rather than as a
       list beside it, so their text is set a step heavier than the bar's. */
    .ds-quiz__steps .ds-quiz-progress__text {
        font-weight: 600;
    }

    /* Colors per state
       -------------------------------------------------- */

    /* Every marker and every text is drawn in currentColor, so fading its
       color fades its fill and its text together. Only the step the quiz is
       on is lit: unlike the bar, a step it has passed goes back to being
       faint, since here the steps are read against the slide between them
       rather than as a list of what is done. */
    .ds-quiz-steps__circle,
    .ds-quiz-steps__label,
    .ds-quiz-steps__disc {
        color: var(--ds-quiz-steps-off);

        transition: color var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing);
    }

    .ds-quiz__steps.ds-quiz-progress--intro .ds-quiz-steps__step--start .ds-quiz-steps__circle,
    .ds-quiz__steps.ds-quiz-progress--intro .ds-quiz-steps__step--start .ds-quiz-steps__label,
    .ds-quiz__steps.ds-quiz-progress--questions .ds-quiz-steps__step--questions .ds-quiz-steps__label,
    .ds-quiz__steps.ds-quiz-progress--results .ds-quiz-steps__step--results .ds-quiz-steps__circle,
    .ds-quiz__steps.ds-quiz-progress--results .ds-quiz-steps__step--results .ds-quiz-steps__label {
        color: var(--ds-quiz-steps-on);
    }

    /* Every run of dots is at a quarter but the one under the step the quiz is
       on, which is drawn as the dot connector draws it. The quarter is set on
       the dots themselves, over the opacities they would inherit from the
       connector, so the lit step only has to hand those back. */
    .ds-quiz-steps__connector .ds-dot-connector__dot {
        --ds-dot-connector-center-opacity: 0.25;
        --ds-dot-connector-near-opacity: 0.25;

        transition: opacity var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing);
    }

    .ds-quiz__steps.ds-quiz-progress--intro .ds-quiz-steps__step--start .ds-quiz-steps__connector .ds-dot-connector__dot,
    .ds-quiz__steps.ds-quiz-progress--questions .ds-quiz-steps__step--questions .ds-quiz-steps__connector .ds-dot-connector__dot {
        --ds-dot-connector-center-opacity: inherit;
        --ds-dot-connector-near-opacity: inherit;
    }

    /* Marker
       -------------------------------------------------- */

    .ds-quiz-steps__meter {
        position: relative;
    }

    .ds-quiz-steps__ring {
        display: block;

        width: 100%;
        height: 100%;

        overflow: visible;
    }

    /* A filled circle on the intro and the results, the ring's track while the
       questions are answered. Only the stroke's width changes, so the circle
       hollows out from its middle into the ring and fills back in. */
    .ds-quiz-steps__disc {
        fill: none;
        stroke: currentColor;
        stroke-width: var(--ds-quiz-steps-disc-width);

        transition:
            stroke-width var(--ds-quiz-steps-morph-duration) var(--ds-quiz-steps-easing),
            color var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing);
    }

    .ds-quiz__steps.ds-quiz-progress--questions .ds-quiz-steps__disc {
        stroke-width: var(--ds-quiz-steps-ring-width);
    }

    /* The filled part of the ring. The script sets its stroke-dashoffset: the
       path is 360 long, and the gap is longer than that so nothing of a second
       dash ever shows. It is only drawn while the questions are answered. */
    .ds-quiz-steps__arc {
        fill: none;
        stroke: var(--ds-quiz-steps-on);
        stroke-width: var(--ds-quiz-steps-ring-width);
        stroke-linecap: round;
        stroke-dasharray: 360 400;
        stroke-dashoffset: 360;

        opacity: 0;

        transition:
            stroke-dashoffset var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing),
            opacity var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing);
    }

    .ds-quiz__steps.ds-quiz-progress--questions .ds-quiz-steps__arc {
        opacity: 1;
    }

    /* The check, on the filled circle once every question is answered. It
       comes in as the circle fills, and is drawn in the cream the page is laid
       on, since the circle under it is the burgundy. */
    .ds-quiz-steps__check {
        position: absolute;
        inset: 0;

        display: flex;
        align-items: center;
        justify-content: center;

        color: var(--color-6);

        opacity: 0;
        transform: scale( 0.6 );

        transition:
            opacity var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing),
            transform var(--ds-quiz-steps-duration) var(--ds-quiz-steps-easing);
    }

    .ds-quiz-steps__check__icon {
        display: block;

        width: 0.784rem;
        height: 0.5852rem;
    }

    .ds-quiz__steps.ds-quiz-progress--results .ds-quiz-steps__check {
        opacity: 1;
        transform: none;

        transition-delay: 0.12s;
    }

    /* Loader
       -------------------------------------------------- */

    /* The loader takes its place in the slide rather than the stage's corner,
       at the smaller size the element is given: it is the last thing in the
       question, so it follows straight on from the answers, and the room the
       slide has over them, which every question keeps so that none of them
       moves the quiz, is left under it. The stage holds a little room of its
       own below besides, so the question that needs the most of it is not
       left with the loader against the steps under the quiz.

       Its room is kept whether it shows or not, so nothing moves as it comes
       and goes: out of the flow it would take none, so it is put back into it
       and only its drawing is left to the element. */
    .ds-quiz__stage {
        padding-block-end: var(--el-spacing-550);
    }

    .ds-quiz__loader {
        position: static;

        align-self: center;
    }

    /* The ring takes its new value and shape at once, the colors and the check
       still fade. */
    @media ( prefers-reduced-motion: reduce ) {
        .ds-quiz-steps__disc {
            transition: color var(--ds-quiz-steps-duration) linear;
        }

        .ds-quiz-steps__arc {
            transition: opacity var(--ds-quiz-steps-duration) linear;
        }

        .ds-quiz-steps__check,
        .ds-quiz__steps.ds-quiz-progress--results .ds-quiz-steps__check {
            transform: none;

            transition: opacity var(--ds-quiz-steps-duration) linear;
        }
    }
}
