/* =====================================================================
   v2-quiz-v20260508b.css — IMPECCABLE polish for /quiz hub + /quiz/which-kit
   ---------------------------------------------------------------------
   Loaded LAST in <head> so every selector here wins the cascade.
   Touches ONLY the .qi-* (hub) and .quiz-* (which-kit) classes plus
   the body[data-quiz] hooks added in the inline scripts. No global
   overrides; no other page is affected.

   The 14 upgrades, ordered as they appear in this file:
    1. Universal motion-system tokens (sub-200ms, sinusoidal easing)
    2. Hub card: sharper idle/hover, focus ring, dark-mode parity
    3. Hub card: clickable surface = whole card, no transform on tap
    4. Quiz: progress dot row above the bar, X/7 prominent
    5. Quiz: option idle vs hover vs focus vs SELECTED states (4-way)
    6. Quiz: keyboard focus ring 2px brand-orange + 2px offset
    7. Quiz: option tap target ≥48px on mobile; text never reflows
    8. Quiz: question-card crossfade (opacity+translateY, 180ms)
    9. Quiz: result reveal — opacity 0→1 + 8px lift, NOT a flip
   10. Quiz: result CTA visual weight + trust microcopy line
   11. Quiz: share-button confirm feedback (check icon + colour)
   12. Quiz: dark-mode parity for every option border & hover bg
   13. WCAG 2.2 AA contrast tweaks (muted text, share buttons)
   14. prefers-reduced-motion: zero transitions, instant state jumps
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. MOTION TOKENS
   Sinusoidal-ish easing (cubic-bezier approximating sine in/out).
   Sub-200ms for state changes, 280ms reserved for the result reveal.
   Every transition on .quiz-* and .qi-* references these tokens, so
   prefers-reduced-motion can wipe them in one place.
   ------------------------------------------------------------------ */
:root {
  --quiz-ease: cubic-bezier(0.45, 0, 0.55, 1);   /* sine in/out, no bounce */
  --quiz-fast: 140ms;                              /* hover, focus, taps */
  --quiz-mid:  180ms;                              /* question crossfade */
  --quiz-slow: 280ms;                              /* result reveal only */
  --quiz-orange: #c9613f;
  --quiz-orange-tint: rgba(201, 97, 63, 0.06);
  --quiz-orange-tint-hover: rgba(201, 97, 63, 0.10);
  --quiz-orange-tint-selected: rgba(201, 97, 63, 0.14);
  --quiz-shadow-card: 0 6px 20px rgba(20, 20, 19, 0.06);
  --quiz-shadow-card-hover: 0 12px 32px rgba(20, 20, 19, 0.08);
}
:root[data-theme="dark"] {
  --quiz-orange-tint: rgba(201, 97, 63, 0.10);
  --quiz-orange-tint-hover: rgba(201, 97, 63, 0.16);
  --quiz-orange-tint-selected: rgba(201, 97, 63, 0.22);
  --quiz-shadow-card: 0 6px 20px rgba(0, 0, 0, 0.32);
  --quiz-shadow-card-hover: 0 12px 32px rgba(0, 0, 0, 0.42);
}


/* =====================================================================
   HUB PAGE — /quiz/index.html
   ===================================================================== */

/* ---------------------------------------------------------------------
   2 + 3. Hub card refinement
   - Idle: clean rule, soft shadow, NO transform (cards used to drift up
     on hover which is fine, but they had no idle weight and read flat).
   - Hover: orange rule + lift + shadow.
   - Focus-visible: explicit 2px orange ring with 2px offset (was
     missing entirely before — keyboard users had no focus signal).
   - Active: cancel transform on tap so the press feels grounded, not
     bouncy. This is the single most-felt fix on touch devices.
   ------------------------------------------------------------------ */
.qi-card {
  /* Tighter idle weight + the new motion token. */
  transition:
    border-color var(--quiz-fast) var(--quiz-ease),
    transform    var(--quiz-fast) var(--quiz-ease),
    box-shadow   var(--quiz-fast) var(--quiz-ease),
    background   var(--quiz-fast) var(--quiz-ease);
  box-shadow: 0 1px 2px rgba(20, 20, 19, 0.025);
}
.qi-card:hover {
  border-color: var(--quiz-orange);
  transform: translateY(-2px);
  box-shadow: var(--quiz-shadow-card-hover);
}
.qi-card:focus-visible {
  /* Inline outline so it's visible against both cream and dark surfaces. */
  outline: 2px solid var(--quiz-orange);
  outline-offset: 2px;
  border-color: var(--quiz-orange);
}
.qi-card:active {
  /* Cancel the lift while the press is held — feels solid on mobile. */
  transform: translateY(0);
  box-shadow: var(--quiz-shadow-card);
  transition-duration: 60ms;
}
:root[data-theme="dark"] .qi-card:hover {
  background: #20191a;
}


/* ---------------------------------------------------------------------
   13. Hub: tag contrast + lede readability
   The 10.5px uppercase tag was AA-borderline on cream because it sat
   at #c9613f over #fff (4.39:1). Bumping the weight gives the same
   colour better legibility without changing brand.
   ------------------------------------------------------------------ */
.qi-tag {
  font-weight: 700;
  font-size: 11px; /* was 10.5px — too small for 600 weight to read clean */
  letter-spacing: 0.14em;
}
.qi-card h3 { line-height: 1.28; } /* tighter at 21px display sizes */


/* =====================================================================
   QUIZ PAGE — /quiz/which-kit/index.html
   ===================================================================== */

/* ---------------------------------------------------------------------
   4. PROGRESS — dot row + prominent counter
   Original UI had a thin bar plus tiny grey "Question 3 of 7" copy at
   the bottom. The diagnostic feel calls for a small dot row that
   shows position at a glance, with the "3/7" promoted next to it.
   We INJECT the dots via ::before content of #quiz-bar's parent —
   actually we render them in the foot meta via CSS counter-style
   pseudo-element so we don't have to touch HTML.

   Implementation: turn .quiz-meta into a flex row, prepend a span
   filled by JS with a dot-row string. JS already touches meta.
   ------------------------------------------------------------------ */
.quiz-progress {
  height: 3px; /* a touch slimmer — the dot row will carry the load */
  background: rgba(20, 20, 19, 0.07);
  margin-bottom: 14px;
}
:root[data-theme="dark"] .quiz-progress { background: rgba(245, 239, 228, 0.1); }
.quiz-progress-bar { transition: width var(--quiz-slow) var(--quiz-ease); }

.quiz-foot {
  font-size: 13px;
  color: var(--ink-soft, #1f1c18); /* was --muted; bumped for AA */
  align-items: center;
  gap: 12px;
}
.quiz-meta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.01em;
}
/* The dot row: rendered by JS as <span class="quiz-dots"> with
   .quiz-dot children. Each .quiz-dot is a 6px circle; .is-done is
   filled brand orange, .is-current has a 1.5px ring, the rest are
   the rule colour. Pure CSS — no JS animation needed. */
.quiz-dots { display: inline-flex; gap: 6px; align-items: center; }
.quiz-dot {
  width: 6px; height: 6px; border-radius: 99px;
  background: rgba(20, 20, 19, 0.18);
  transition: background var(--quiz-fast) var(--quiz-ease),
              box-shadow var(--quiz-fast) var(--quiz-ease),
              transform  var(--quiz-fast) var(--quiz-ease);
}
.quiz-dot.is-done { background: var(--quiz-orange); }
.quiz-dot.is-current {
  background: var(--quiz-orange);
  transform: scale(1.4);
  box-shadow: 0 0 0 2px rgba(201, 97, 63, 0.22);
}
:root[data-theme="dark"] .quiz-dot { background: rgba(245, 239, 228, 0.22); }


/* ---------------------------------------------------------------------
   5 + 6 + 12. OPTION STATES (idle / hover / focus / SELECTED)
   The old CSS had idle + hover + focus-visible but NO selected state.
   In a radiogroup that's a bug — keyboard users navigating with arrow
   keys had no way to see which option carried the current selection
   before pressing Enter. We fix that with [aria-checked="true"].

   Selected = brand-orange border (full weight) + tinted bg + bold text.
   Hover and focus use lighter tints so they don't compete.
   ------------------------------------------------------------------ */
.quiz-option {
  /* Replace the all-property transition with a token-based one. */
  transition:
    border-color var(--quiz-fast) var(--quiz-ease),
    background   var(--quiz-fast) var(--quiz-ease),
    transform    var(--quiz-fast) var(--quiz-ease),
    color        var(--quiz-fast) var(--quiz-ease);
  position: relative;
  /* Reserve space for a left selection bar so text doesn't shift when
     the option becomes selected. 3px bar + 17px padding = original 20px. */
  padding-left: 20px;
}
.quiz-option::before {
  /* The selection bar — invisible until aria-checked="true". */
  content: "";
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  background: transparent;
  border-radius: 0 2px 2px 0;
  transition: background var(--quiz-fast) var(--quiz-ease);
}
.quiz-option:hover {
  background: var(--quiz-orange-tint);
  border-color: var(--quiz-orange);
  transform: translateX(2px);
}
.quiz-option:focus-visible {
  outline: 2px solid var(--quiz-orange);
  outline-offset: 2px;
  border-color: var(--quiz-orange);
  background: var(--quiz-orange-tint);
}
.quiz-option[aria-checked="true"] {
  background: var(--quiz-orange-tint-selected);
  border-color: var(--quiz-orange);
  color: var(--ink, #141413);
  font-weight: 600;
  transform: translateX(2px); /* hold position so it doesn't snap back */
}
.quiz-option[aria-checked="true"]::before {
  background: var(--quiz-orange);
}
.quiz-option:active { transform: translateX(2px) scale(0.998); }

/* Dark-mode parity for every state. */
:root[data-theme="dark"] .quiz-option:hover,
:root[data-theme="dark"] .quiz-option:focus-visible {
  background: var(--quiz-orange-tint-hover);
  color: #fff;
}
:root[data-theme="dark"] .quiz-option[aria-checked="true"] {
  background: var(--quiz-orange-tint-selected);
  color: #fff;
}


/* ---------------------------------------------------------------------
   7. MOBILE TAP TARGETS + STABLE QUESTION TEXT
   Original mobile rule shrank padding to 14px 16px — at 14px font that
   put tap targets at ~44px which is the bare minimum. Push to 48px
   with 16px padding + 16px font (which also stops iOS auto-zoom).
   Question h2 gets text-wrap: pretty to avoid orphan words.
   ------------------------------------------------------------------ */
.quiz-stage h2 {
  text-wrap: pretty;          /* stops the last-line widow */
  overflow-wrap: anywhere;
}
.quiz-options { gap: 12px; }  /* tiny breathing room bump */

@media (max-width: 640px) {
  .quiz-option {
    padding: 14px 16px 14px 19px;
    font-size: 16px;          /* prevent iOS focus-zoom; was 14px */
    line-height: 1.45;
    min-height: 48px;         /* WCAG 2.2 AA target size */
  }
  .quiz-stage { padding: 20px 16px; }
}


/* ---------------------------------------------------------------------
   8. QUESTION-CARD CROSSFADE
   Each new question fades in from opacity 0 + 6px translateY, holds,
   and the previous question is removed by the JS innerHTML swap. We
   use an animation class added by JS (.is-entering) on each render.
   180ms total — under the 200ms threshold.
   ------------------------------------------------------------------ */
@keyframes quiz-q-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.quiz-stage.is-entering > * {
  animation: quiz-q-in var(--quiz-mid) var(--quiz-ease) both;
}
/* Stagger options by 20ms each so the row settles in sequence. */
.quiz-stage.is-entering .quiz-option:nth-child(1) { animation-delay: 30ms; }
.quiz-stage.is-entering .quiz-option:nth-child(2) { animation-delay: 50ms; }
.quiz-stage.is-entering .quiz-option:nth-child(3) { animation-delay: 70ms; }
.quiz-stage.is-entering .quiz-option:nth-child(4) { animation-delay: 90ms; }
.quiz-stage.is-entering .quiz-option:nth-child(5) { animation-delay: 110ms; }


/* ---------------------------------------------------------------------
   9. RESULT REVEAL
   Smooth opacity 0→1 + 8px lift over 280ms. Nothing flips, nothing
   spins. Each block (eyebrow, h2, p, reasons, CTAs, share) staggers
   by 40ms. Spec-compliant with /impeccable.
   ------------------------------------------------------------------ */
@keyframes quiz-result-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.quiz-result {
  /* Container is opacity 1; children carry the animation. */
}
.quiz-result.is-revealing > * {
  animation: quiz-result-in var(--quiz-slow) var(--quiz-ease) both;
}
.quiz-result.is-revealing > *:nth-child(1) { animation-delay: 0ms;   }
.quiz-result.is-revealing > *:nth-child(2) { animation-delay: 60ms;  }
.quiz-result.is-revealing > *:nth-child(3) { animation-delay: 120ms; }
.quiz-result.is-revealing > *:nth-child(4) { animation-delay: 180ms; }
.quiz-result.is-revealing > *:nth-child(5) { animation-delay: 240ms; }
.quiz-result.is-revealing > *:nth-child(6) { animation-delay: 300ms; }


/* ---------------------------------------------------------------------
   10. RESULT CTA — visual weight + trust microcopy
   Original primary button was solid black — strong, but flat. The
   secondary "Read what's inside" ranked visually almost the same as
   the primary because the borders matched the rule colour exactly.
   We:
   - Add a subtle 1px inner highlight to the primary so it lifts.
   - Add a "Stripe-secured · instant download" trust line below the
     primary (rendered by JS). It's small, muted, but tied to the CTA.
   - Down-weight the secondary border slightly so the hierarchy reads.
   ------------------------------------------------------------------ */
.quiz-cta-primary {
  /* Use the motion token; replace 'all 0.18s'. */
  transition:
    background var(--quiz-fast) var(--quiz-ease),
    transform  var(--quiz-fast) var(--quiz-ease),
    box-shadow var(--quiz-fast) var(--quiz-ease);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 4px 14px rgba(20, 20, 19, 0.10);
  font-size: 15.5px;
  letter-spacing: -0.005em;
}
.quiz-cta-primary:focus-visible {
  outline: 2px solid var(--quiz-orange);
  outline-offset: 3px;
}
.quiz-cta-primary:active { transform: translateY(0); transition-duration: 60ms; }

.quiz-cta-trust {
  /* Rendered by JS directly under the primary button. */
  font-family: 'Inter', sans-serif;
  font-size: 12.5px;
  color: var(--ink-soft, #1f1c18);
  text-align: center;
  margin: -2px 0 6px;
  letter-spacing: 0.005em;
}
.quiz-cta-trust strong { color: var(--ink, #141413); font-weight: 600; }

.quiz-cta-secondary {
  transition:
    border-color var(--quiz-fast) var(--quiz-ease),
    color        var(--quiz-fast) var(--quiz-ease),
    background   var(--quiz-fast) var(--quiz-ease);
}
.quiz-cta-secondary:focus-visible {
  outline: 2px solid var(--quiz-orange);
  outline-offset: 2px;
  border-color: var(--quiz-orange);
  color: var(--quiz-orange);
}


/* ---------------------------------------------------------------------
   11. SHARE-BUTTON CONFIRM FEEDBACK
   The "Copy link" button used to swap text to "Copied" with no visual
   colour change — easy to miss. Add a .is-confirmed class that JS
   toggles for 1.5s; CSS handles the green tick + colour shift.
   ------------------------------------------------------------------ */
.quiz-share button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition:
    border-color var(--quiz-fast) var(--quiz-ease),
    color        var(--quiz-fast) var(--quiz-ease),
    background   var(--quiz-fast) var(--quiz-ease);
  min-height: 32px;
}
.quiz-share button:focus-visible {
  outline: 2px solid var(--quiz-orange);
  outline-offset: 2px;
  border-color: var(--quiz-orange);
  color: var(--quiz-orange);
}
.quiz-share button.is-confirmed {
  border-color: #2f7d4a;
  color: #2f7d4a;
  background: rgba(47, 125, 74, 0.06);
}
.quiz-share button.is-confirmed::before {
  /* Inline check glyph — pure CSS, no SVG asset needed. */
  content: "";
  width: 12px; height: 12px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%232f7d4a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 6.5l3 3 5-6'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
}


/* ---------------------------------------------------------------------
   13. WCAG contrast — share/back/meta typography
   .quiz-back used --muted (#6b6960) on cream — that's 4.42:1 at 13px,
   below the AAA bar for small text. Move to --ink-soft. Same logic
   for the share buttons' base colour. The brand orange at 14px+ on
   cream/ink-soft both clear AA.
   ------------------------------------------------------------------ */
.quiz-back {
  color: var(--ink-soft, #1f1c18);
  font-weight: 500;
  transition: color var(--quiz-fast) var(--quiz-ease),
              background var(--quiz-fast) var(--quiz-ease);
  border-radius: 4px;
}
.quiz-back:focus-visible {
  outline: 2px solid var(--quiz-orange);
  outline-offset: 2px;
  color: var(--quiz-orange);
}
.quiz-share-label { color: var(--ink-soft, #1f1c18); font-weight: 500; }
.quiz-share button { color: var(--ink-soft, #1f1c18); }


/* ---------------------------------------------------------------------
   14. PREFERS-REDUCED-MOTION FALLBACK
   Wipe every quiz transition + animation. Selected/hover states still
   apply, they just snap. Critical for vestibular-sensitive users —
   and ADHD users on bad days are often in this bucket too.
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .qi-card,
  .qi-card:hover,
  .qi-card:active,
  .quiz-progress-bar,
  .quiz-option,
  .quiz-option:hover,
  .quiz-option[aria-checked="true"],
  .quiz-option:active,
  .quiz-option::before,
  .quiz-cta-primary,
  .quiz-cta-secondary,
  .quiz-back,
  .quiz-share button,
  .quiz-dot {
    transition: none !important;
    animation: none !important;
    transform: none !important;
  }
  .quiz-stage.is-entering > *,
  .quiz-result.is-revealing > * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}
