/* ==========================================================================
   rsa-school design system v2: the mock theory test
   Loaded after tokens.css and school.css by base.njk, for the one page that
   declares designSheet: "theory".

   This sheet exists because /mock-theory-test/ is the most interactive page on
   the site after the shop, and almost all of its markup is assembled by its own
   script as strings. Thirty-six class names appear nowhere in any template:
   option-btn, selected, btn-nav, btn-next, btn-submit, quiz-timer and the
   result-screen set. They used to be styled by a 135-line inline <style> block
   on the page. They are styled here instead, UNDER THE SAME NAMES, because the
   script writes them by name and a rename does not error: the page looks right
   and the quiz quietly stops working.

   So: nothing in this sheet renames a hook. The only names that are new are the
   tt- ones, which belong to wrappers this rebuild introduced and no script
   touches.
   ========================================================================== */

/* ---------- 1. Hero, and the gate inside it ---------- */

/* The email gate is the page's only conversion control, so it sits beside the
   heading rather than under the intro copy. It needs more room than the town
   pages' narrow price aside, hence this page's own hero ratio.
   The modifier is named again in the collapse at the end of this sheet: a
   two-class rule out-specifies a single-class responsive collapse at every
   width, which is finding 20 and left a lessons row in two columns on a
   phone. */
.tt-hero .sm-hero__grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.78fr);
}

/* The photograph is a person holding a licence against a black ground, with the
   subject on the right. This hero is taller than a town hero, because the gate
   sets its height, so the frame scales from its height and there is almost no
   horizontal crop left to move the subject with: measured, 60px of 1440.
   The fade is the control that works, and the default 220px was not enough: the
   chalk 110 landed on the pale licence, the lightest thing in the frame.
   The pack has a name for this: --hero-form-band, "hero photo stops 104px above
   bottom, form bar sits there". The band here is the proof bar, so the ramp is
   solid for the 260px the bar and the hero's bottom padding occupy and fades
   over the 260px above it. Measured at 1440: the bar's top rule is 227px above
   the hero's bottom edge. Only the height and the stops change; the ramp is
   still the one school.css draws, so nothing is competing for this
   pseudo-element. background-image, not the shorthand, per finding 16. */
.tt-hero .sm-hero__photo::after {
  height: 520px;
  background-image: linear-gradient(0deg, var(--rsa-night) 0 260px, rgba(0, 0, 0, 0) 100%);
}
.tt-hero .sm-hero__photo img { object-position: 72% 18%; }

.tt-gate {
  position: relative;
  padding: var(--pad-card);
  /* background-color, never the `background` shorthand: the shorthand resets
     background-size and background-repeat, which is what inverted a
     gradient-drawn select arrow on the lead form (finding 16). */
  background-color: var(--color-panel);
  border: 1px solid var(--rsa-line-12);
  border-radius: var(--radius-xs);
  box-shadow: var(--shadow-card);
}

/* The pack's green dashed road line, topping the card that matters. Nothing
   else in any sheet targets .tt-gate's pseudo-elements, which is checked
   because two rules cannot share one ::before (finding 19). */
.tt-gate::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 6px;
  background-image: var(--road-dash-h);
}

.tt-gate__head {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-bottom: var(--space-4);
}

/* A card title, not a section heading, so it is sized here rather than left at
   the sheet's 32-50px section step. Line height stays at 1 so it cannot read
   as a caption. */
.tt-gate h2 {
  margin: 0;
  font-size: clamp(24px, 2.4vw, 30px);
  line-height: 1;
}

.tt-gate__sub {
  margin: 0 0 var(--space-12);
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
}

/* ---------- 2. The gate's fields ---------- */

.tt-field { margin-bottom: var(--space-10); }

.tt-field label {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.tt-input {
  width: 100%;
  /* Rule 15's sibling: a 48px control is a real target at 390px. */
  min-height: 48px;
  padding: var(--space-6) var(--space-8);
  background-color: var(--color-bg-deep);
  border: 1px solid var(--color-field-border);
  border-radius: var(--radius-xs);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  transition: border-color var(--dur-fast);
}

.tt-input::placeholder { color: var(--color-placeholder); }

/* No `outline: none` here. The old sheet removed the focus ring from all three
   gate fields, which is rule 15 straight through. The green border is in
   addition to the ring tokens.css draws, never instead of it. */
.tt-input:focus { border-color: var(--color-accent); }

/* The whole row is the target, not the 24px box in it. */
.tt-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  margin: 0 0 var(--space-12);
}

.tt-toggle input[type="checkbox"] {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  margin: 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.tt-toggle label {
  display: flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  font-size: var(--fs-body-sm);
  line-height: 1.4;
  color: var(--color-text-body);
  cursor: pointer;
}

/* ---------- 3. btn-start, written by the script as well as the markup ---------- */

/* The script re-creates this class on the results screen's "Take it again"
   button, so it has to stand on its own with no sm-btn beside it. */
.btn-start {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  padding: var(--pad-btn);
  border: 1px solid transparent;
  border-radius: var(--radius-xs);
  background-color: var(--color-action);
  color: var(--color-on-action);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast);
}

.btn-start:hover { background-color: var(--color-action-hover); }

.btn-start:disabled {
  background-color: var(--rsa-graphite);
  color: var(--color-text-faint);
  cursor: not-allowed;
}

/* Retake is a secondary action, so it is the ghost. It replaces an inline
   background of #555, which is 3.5:1 behind white text. */
.tt-retake {
  width: auto;
  background-color: transparent;
  border-color: var(--rsa-line-25);
  color: var(--color-text);
}
.tt-retake:hover { background-color: var(--rsa-line-08); border-color: var(--color-text); }

.tt-retake-row { margin: var(--space-16) 0 0; text-align: center; }

/* ---------- 4. How it works ---------- */

/* A hanging indent, not a grid list. A marker-plus-text list built with
   display:grid puts every inline child in its own cell. */
.tt-checks {
  margin: 0;
  padding: 0;
  list-style: none;
  max-width: 72ch;
}

.tt-checks li {
  position: relative;
  padding: var(--space-6) 0 var(--space-6) var(--space-20);
  border-bottom: 1px solid var(--rsa-line-08);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-relaxed);
  color: var(--color-text-body);
}
.tt-checks li:last-child { border-bottom: 0; }

.tt-checks li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: var(--space-6);
  font-family: var(--font-display);
  font-size: var(--fs-body-lg);
  font-weight: var(--fw-black);
  line-height: var(--lh-relaxed);
  color: var(--color-accent);
}

/* ---------- 5. The quiz and results stages ---------- */

/* Not .sm-section, because the script owns the display of both and neither
   carries copy of its own for a lane marker to label. The rhythm matches
   .sm-section so the page does not change pace when a stage appears. */
.tt-stage { padding: var(--space-section) 0; }

/* A quiz reads at a narrower measure than the 1280px container. */
.sm-wrap.tt-stage__inner { width: min(100% - (var(--gutter) * 2), 860px); }

/* The script replaces #resultsScreen's whole innerHTML and then appends to it,
   so it cannot hold an inner wrapper: the measure lives on the element. */
.tt-results {
  width: min(100% - (var(--gutter) * 2), 860px);
  margin-inline: auto;
}

/* The script moves focus to whichever stage replaced the one it was on, so a
   keyboard user is not dropped on the body. Chrome treats that scripted focus as
   :focus-visible and drew a green box around the whole results screen, which
   reads as a fault rather than an indicator. These two containers carry
   tabindex="-1" and are not keyboard-reachable controls, so the ring comes off
   them and off nothing else: every control inside keeps the one tokens.css
   draws, and the move is announced through the status region.
   The box-shadow goes with it: tokens.css pairs the outline with a 7px black
   ring, and on a road-black page that ring read as two faint vertical lines
   down the edges of the results column. Measured: 0px none, no shadow. */
.tt-stage:focus-visible { outline: none; box-shadow: none; }

.tt-bar {
  display: flex;
  align-items: flex-end;
  gap: var(--space-12);
  margin-bottom: var(--space-16);
}

.tt-bar .quiz-progress { flex: 1 1 auto; min-width: 0; }

.progress-text {
  display: flex;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* The track is the pack's grey dashed road line, so the fill reads as distance
   covered rather than as a loading bar. */
.progress-bar {
  position: relative;
  height: 6px;
  background-image: repeating-linear-gradient(90deg, var(--rsa-line-25) 0 22px, transparent 22px 36px);
}

.progress-fill {
  height: 6px;
  background-color: var(--color-accent);
  transition: width var(--dur-base) var(--ease-reveal);
}

/* The script reassigns className wholesale here, to "quiz-timer",
   "quiz-timer warning" or "quiz-timer danger". All three are kept. */
.quiz-timer {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-black);
  line-height: 1;
  letter-spacing: var(--ls-tight);
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}
.quiz-timer.warning { color: var(--color-eyebrow); }
/* Red as text on a dark ground is the FIX F7 value, not the button red. */
.quiz-timer.danger { color: var(--color-text-red); animation: tt-pulse 1s infinite; }

@keyframes tt-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* ---------- 6. The question card ---------- */

.question-card {
  position: relative;
  padding: var(--space-16) var(--space-16) var(--space-20);
  background-color: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-radius: var(--radius-xs);
}

.question-card::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 6px;
  background-image: var(--road-dash-h);
}

/* The category is the pack's lane-marker chip, shear and all: the one piece of
   green at the top of every question. */
.q-category {
  display: inline-block;
  margin-bottom: var(--space-8);
  padding: 3px var(--space-5) 2px;
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);
}

.q-text {
  margin: 0 0 var(--space-12);
  font-family: var(--font-body);
  font-size: clamp(18px, 1.6vw, 21px);
  font-weight: var(--fw-bold);
  line-height: 1.45;
  color: var(--color-text);
}

/* ---------- 7. The answers ---------- */

/* The option letter is drawn from a counter, so it is never a text node and
   never content. */
.options-list {
  counter-reset: tt-opt;
  margin: 0;
  padding: 0;
  list-style: none;
}
.options-list li { counter-increment: tt-opt; margin-bottom: var(--space-5); }
.options-list li:last-child { margin-bottom: 0; }

.option-btn {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  width: 100%;
  /* The touch target at 390px, with room for a two-line answer. */
  min-height: 56px;
  padding: var(--space-6) var(--space-8);
  background-color: var(--color-bg-deep);
  border: 2px solid var(--rsa-line-12);
  border-radius: var(--radius-xs);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-fast), border-color var(--dur-fast);
}

.option-btn::before {
  content: counter(tt-opt, upper-alpha);
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-round);
  background-color: var(--rsa-track);
  color: var(--color-text-body);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-black);
}

.option-btn:hover { border-color: var(--color-accent); }

/* The pack's own fix: a selected state changes ground, not just text colour. */
.option-btn.selected {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
  font-weight: var(--fw-bold);
}
.option-btn.selected::before {
  background-color: var(--rsa-road-black);
  color: var(--color-accent);
}

.option-btn:disabled { cursor: default; }

/* Review states. The script does not write these today; they were in the
   page's inline sheet and are kept under their names so an answer-reveal pass
   does not have to invent them again. */
.option-btn.correct,
.option-btn.reveal-correct { border-color: var(--color-accent); color: var(--color-accent); }
.option-btn.incorrect { border-color: var(--color-action); color: var(--color-text-red); }

/* Stated as well as inherited from tokens.css: every answer control is
   operable by keyboard and has to show where the keyboard is. */
.option-btn:focus-visible {
  outline: 3px solid var(--rsa-go-green);
  outline-offset: 2px;
}

/* ---------- 8. Navigation ---------- */

.quiz-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--space-6);
  margin-top: var(--space-16);
}

/* The script reassigns #nextBtn's className to "btn-nav btn-next" or
   "btn-nav btn-submit" on every render, so nothing else may be added to that
   element's class list in the markup. */
.btn-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: var(--pad-btn);
  border: 2px solid transparent;
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast), border-color var(--dur-fast);
}

.btn-prev {
  background-color: transparent;
  border-color: var(--rsa-line-25);
  color: var(--color-text);
}
.btn-prev:hover { background-color: var(--rsa-line-08); border-color: var(--color-text); }

.btn-next {
  background-color: var(--color-action);
  border-color: var(--color-action);
  color: var(--color-on-action);
}
.btn-next:hover { background-color: var(--color-action-hover); border-color: var(--color-action-hover); }

/* Green is the payoff, so the last press of the quiz is the green one. */
.btn-submit {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}
.btn-submit:hover { background-color: var(--rsa-go-green-hover); border-color: var(--rsa-go-green-hover); }

.btn-nav:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---------- 9. The results screen ---------- */

.results-section { text-align: left; }

.results-score { margin-bottom: var(--space-24); text-align: center; }

/* A real number, big. The score is the content of this screen. */
.score-circle {
  display: inline-grid;
  place-items: center;
  width: 192px;
  height: 192px;
  margin-bottom: var(--space-10);
  border-radius: var(--radius-round);
  font-family: var(--font-display);
  font-size: clamp(40px, 5vw, 56px);
  font-weight: var(--fw-black);
  line-height: 1;
  letter-spacing: var(--ls-tighter);
}
.score-circle.pass { background-color: var(--color-accent); color: var(--color-on-accent); }
.score-circle.fail { background-color: var(--color-action); color: var(--color-on-action); }

/* A div, not a heading, so it is sized here. */
.results-verdict {
  margin-bottom: var(--space-6);
  font-family: var(--font-display);
  font-size: var(--fs-h2-sm);
  font-weight: var(--fw-black);
  line-height: 1;
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
.results-verdict.pass { color: var(--color-accent); }
.results-verdict.fail { color: var(--color-text-red); }

.results-detail {
  max-width: 54ch;
  margin: 0 auto;
  font-size: var(--fs-lede);
  line-height: var(--lh-lede);
  color: var(--color-text-lede);
}

.category-breakdown {
  margin-bottom: var(--space-20);
  padding: var(--pad-card);
  background-color: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-top: var(--rule-green-top);
  border-radius: var(--radius-xs);
}

.cat-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-8);
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--rsa-line-08);
}
.cat-row:last-child { border-bottom: 0; }

.cat-name {
  font-size: var(--fs-body-sm);
  color: var(--color-text-body);
  text-transform: capitalize;
}

.cat-score {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-black);
}
.cat-score.perfect { color: var(--color-accent); }
.cat-score.partial { color: var(--color-eyebrow); }
.cat-score.zero { color: var(--color-text-red); }

.wrong-answers { margin-bottom: var(--space-20); }

.wrong-item {
  margin-bottom: var(--space-10);
  padding: var(--space-12) var(--space-16);
  background-color: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-left: 3px solid var(--color-action);
  border-radius: var(--radius-xs);
}

.wi-q {
  margin: 0 0 var(--space-5);
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
  line-height: 1.4;
  color: var(--color-text);
}
.wi-your { margin: 0 0 var(--space-1); font-size: var(--fs-body-sm); color: var(--color-text-red); }
.wi-correct { margin: 0 0 var(--space-5); font-size: var(--fs-body-sm); color: var(--color-accent); }
.wi-explain {
  margin: 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--rsa-line-08);
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
}

.share-section {
  margin-bottom: var(--space-20);
  padding: var(--pad-card);
  background-color: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-radius: var(--radius-xs);
  text-align: center;
}

.share-sub { margin: 0 0 var(--space-12); font-size: var(--fs-body-sm); color: var(--color-text-muted); }

.share-btns {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  justify-content: center;
}

.share-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-5) var(--space-10);
  border-radius: var(--radius-xs);
  color: var(--rsa-white);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  text-decoration: none;
  transition: opacity var(--dur-fast);
}
.share-btn:hover { opacity: 0.85; color: var(--rsa-white); }
.share-btn svg { width: 16px; height: 16px; fill: currentColor; }

/* The four network grounds. Two are the brand colour darkened, and WhatsApp
   takes dark type instead, because white on #1877f2 is 3.1:1 and white on
   #25d366 is 2.2:1 and these labels are 12.5px. The hue is still each
   network's own. */
.share-btn.facebook { background-color: #0b5ed7; }
/* X's own ground is black, which is the card's ground here too, so it took a
   hairline or it disappeared: measured at #161618 on #161618. The inset shadow
   is the keyline, so the button keeps the same box as the other three. */
.share-btn.twitter {
  background-color: var(--rsa-night);
  box-shadow: inset 0 0 0 1px var(--rsa-line-25);
}
.share-btn.whatsapp { background-color: #25d366; color: var(--rsa-road-black); }
.share-btn.whatsapp:hover { color: var(--rsa-road-black); }
.share-btn.linkedin { background-color: #0a66c2; }

/* The closing call, on the page's one red ground, closed by the pack's white
   centre line. Buttons on a red band are black, never red on red. */
.results-cta {
  position: relative;
  overflow: hidden;
  margin-bottom: var(--space-16);
  padding: var(--space-20) var(--space-16) var(--space-24);
  background-color: var(--color-action);
  border-radius: var(--radius-xs);
}
.results-cta::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 8px;
  background-image: repeating-linear-gradient(90deg, var(--rsa-chalk) 0 60px, transparent 60px 96px);
  opacity: 0.9;
}
.results-cta h3 { color: var(--color-on-action); }
.results-cta p { margin-bottom: var(--space-12); color: var(--color-on-red-muted); }

.btn-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: var(--pad-btn);
  border-radius: var(--radius-xs);
  background-color: var(--rsa-night);
  color: var(--color-text);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  transition: background-color var(--dur-fast);
}
.btn-cta:hover { background-color: var(--rsa-surface); }

/* The script appends this after the results, and sets its colour inline to a
   token on success or failure. */
.tt-email-status {
  margin: var(--space-12) 0 0;
  font-size: var(--fs-small);
  color: var(--color-text-muted);
  text-align: center;
}

/* ---------- 10. Responsive ---------- */

/* The pack's framing threshold, and the collapse that has to name the modifier
   above or it never wins. */
@media (max-width: 1100px) {
  .tt-hero .sm-hero__grid { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  /* One column of a portrait frame: the subject needs to sit higher or the
     crop lands on a cheek. The proof bar is three stacked rows here, so the
     solid part of the ramp has further to reach. */
  .tt-hero .sm-hero__photo img { object-position: 74% 12%; }
  .tt-hero .sm-hero__photo::after {
    height: 620px;
    background-image: linear-gradient(0deg, var(--rsa-night) 0 400px, rgba(0, 0, 0, 0) 100%);
  }

  .tt-stage { padding: var(--sm-space-64) 0; }
  .tt-gate { padding: var(--space-12); }
  .question-card { padding: var(--space-12) var(--space-12) var(--space-16); }
  .tt-checks li { font-size: var(--fs-body); }
  .tt-checks li::before { font-size: var(--fs-body); }

  /* The timer moves under the progress line rather than squeezing it. */
  .tt-bar { flex-direction: column; align-items: stretch; gap: var(--space-8); }
  .quiz-timer { text-align: right; }

  .quiz-nav { gap: var(--space-5); }
  .btn-nav { flex: 1 1 0; min-width: 0; padding: var(--space-6) var(--space-8); }

  .score-circle { width: 150px; height: 150px; }
  .share-btns { flex-direction: column; }
  .share-btn { justify-content: center; }
  .results-cta { padding: var(--space-16) var(--space-12) var(--space-20); }
}
