/* ==========================================================================
   vibequiz.online — design system
   Fonts: Bodoni Moda (display, never below 20px) + Space Grotesk (body).
   No frameworks, no images.
   ========================================================================== */

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --bg: #FAF6F0;
  --ink: #1C1A17;
  --muted: #8C8880;
  --text-secondary: #8C8880;
  --border: #E8DDD0;
  --accent: #8E79C9;
  --accent-dark: #3a2d7a;
  --card: #FFFFFF;
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --max-width: 480px;
  --font-display: 'Bodoni Moda', 'Didot', Georgia, serif;
  --font-body: 'Space Grotesk', 'Helvetica Neue', Arial, sans-serif;

  /* Per-quiz identity (5c). Defaults match aesthetic-quiz so pages with
     no #quiz-app in the DOM (homepage, 404) render the same as before. */
  --radius: 10px;
  --rule: 1px;
}

/* ==========================================================================
   Per-quiz art direction (5c) — keyed off the data-slug attribute that
   build.py already writes onto #quiz-app (data-slug="{{SLUG}}"). No body
   class exists to hook into (template.html is out of this phase's scope),
   so :root:has() reaches up from that descendant to retheme the whole
   document, including the background, which a sibling combinator alone
   could not reach. Exact-match attribute selectors only — aesthetic-quiz
   is a literal prefix of aesthetic-quiz-clothing's slug, so ^= would leak
   aesthetic's tokens onto the clothing quiz. */
:root:has(#quiz-app[data-slug="aesthetic-quiz"]) {
  --bg: #FAF6F0;
  --accent: #8E79C9;
  --radius: 10px;
  --rule: 1px;
}
:root:has(#quiz-app[data-slug="aesthetic-quiz-clothing"]) {
  --bg: #F6F4F1;
  --accent: #B53A62;
  --radius: 2px;
  --rule: 1px;
}
:root:has(#quiz-app[data-slug="what-food-am-i"]) {
  --bg: #FDF7EE;
  --accent: #E56B3F;
  --radius: 16px;
  --rule: 2px;
}
:root:has(#quiz-app[data-slug="what-bird-am-i"]) {
  --bg: #F4F6F1;
  --accent: #72845C;
  --radius: 4px;
  --rule: 1px;
}
:root:has(#quiz-app[data-slug="what-dessert-am-i"]) {
  --bg: #FCF4F5;
  --accent: #C45A83;
  --radius: 20px;
  --rule: 2px;
}

html {
  background: var(--bg);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Display default for headings. Bodoni Moda's thin strokes disappear
   below 20px, so any h1/h2/h3/.display element that renders smaller than
   that gets an explicit font-family: var(--font-body) override at its own
   selector — see the six below-20px overrides throughout this file. New
   headings should default to display and get corrected if they land small. */
h1, h2, h3, .display {
  font-family: var(--font-display);
  font-weight: 600;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font-family: var(--font-body);
  cursor: pointer;
}

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 20px;
}

/* Quiz-page main only. Scoped to main.wrap (not the shared .wrap class
   header/footer/homepage also use) so #quiz-article can break out to
   near-full-viewport width without a wrapper element in template.html.
   Grid tracks size off main.wrap's own rendered box, never off vw units,
   so this is safe under a classic (non-overlay) scrollbar that the
   previous width:100vw/margin-left:-50vw approach was not. */
main.wrap {
  max-width: none;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr min(calc(var(--max-width) - 40px), calc(100% - 40px)) 1fr;
}

main.wrap > * {
  grid-column: 2;
}

/* ==========================================================================
   Textures — pure CSS, applied as ::after on .moodboard
   ========================================================================== */

.moodboard {
  position: relative;
  height: 220px;
  overflow: hidden;
}

.moodboard::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.moodboard.texture-grain::after {
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.moodboard.texture-lines::after {
  opacity: 0.06;
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.6) 0,
    rgba(0, 0, 0, 0.6) 1px,
    transparent 1px,
    transparent 6px
  );
}

.moodboard.texture-dots::after {
  opacity: 0.05;
  background-image: radial-gradient(rgba(0, 0, 0, 0.9) 1px, transparent 1px);
  background-size: 10px 10px;
}

.moodboard.texture-scanlines::after {
  opacity: 0.08;
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.9) 0,
    rgba(0, 0, 0, 0.9) 1px,
    transparent 1px,
    transparent 2px
  );
}

.moodboard.texture-none::after {
  content: none;
}

.moodboard-color {
  position: absolute;
  top: 0;
  bottom: 0;
}

.moodboard-dots {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 2;
  display: flex;
  gap: 5px;
}

.moodboard-dots span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: block;
}

.moodboard-text {
  position: absolute;
  left: 20px;
  bottom: 18px;
  right: 20px;
  z-index: 2;
}

.moodboard-label {
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.1em;
  font-weight: 700;
  margin-bottom: 4px;
}

/* RESULT NAME — 42px desktop / 32px mobile, not larger. Constrained by
   the 220x220 reveal card and the 220px moodboard header. */
.moodboard-name {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1.05;
  font-weight: 600;
}

@media (min-width: 800px) {
  .moodboard-name {
    font-size: 42px;
    line-height: 1.0;
  }
}

/* ==========================================================================
   Header / homepage
   ========================================================================== */

.site-header {
  padding: 28px 0 20px;
}

.logo {
  font-family: var(--font-display);
  font-size: 28px;
  color: var(--ink);
  text-transform: lowercase;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.logo-mark {
  color: var(--accent);
}

.tagline {
  font-size: 13px;
  color: var(--muted);
  margin-top: 4px;
}

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

.site-nav a {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--ink);
}

.site-nav-current {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
}

@media (max-width: 480px) {
  .site-nav {
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
}

.flagship-card {
  display: block;
  position: relative;
  border: 2px solid #8FAF7E;
  border-radius: var(--radius-lg);
  padding: 28px 24px;
  margin: 20px 0;
  background: var(--card);
  animation: vibe-cycle 8s ease-in-out infinite, vibe-bg-cycle 8s ease-in-out infinite;
}

@keyframes vibe-cycle {
  0%, 100% { border-color: #8FAF7E; }
  20%      { border-color: #2D2449; }
  40%      { border-color: #FF2D78; }
  60%      { border-color: #F2C4CE; }
  80%      { border-color: #001233; }
}

@keyframes vibe-bg-cycle {
  0%, 100% { background: var(--card); }
  16.66%   { background: rgba(143, 175, 126, 0.04); }
  33.33%   { background: rgba(45, 36, 73, 0.04); }
  50%      { background: rgba(255, 45, 120, 0.04); }
  66.66%   { background: rgba(242, 196, 206, 0.04); }
  83.33%   { background: rgba(0, 18, 51, 0.04); }
}

.flagship-card .quiz-title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
}

.flagship-card .quiz-subtitle {
  font-size: 12px;
  color: var(--muted);
  margin-top: 6px;
}

.flagship-card .quiz-cta {
  display: inline-block;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--accent-dark);
  font-weight: 600;
  margin-top: 16px;
}

.secondary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 8px;
  padding-bottom: 40px;
}

.secondary-card {
  display: block;
  position: relative;
  min-height: 92px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  background: var(--card);
}

.card-completed-marker {
  position: absolute;
  top: 8px;
  right: 10px;
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 700;
}

.secondary-card .quiz-title {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
}

.secondary-card .quiz-subtitle {
  font-size: 11px;
  color: var(--muted);
  margin-top: 6px;
}

.homepage-content {
  max-width: 680px;
  margin: 32px auto 0;
  padding: 0 20px 48px;
  border-top: 1px solid var(--border);
  padding-top: 32px;
}

/* 18px — below the 20px floor, so this stays Space Grotesk even though
   it's an h2 (the blanket h1/h2/h3 rule defaults it to display). */
.homepage-content h2 {
  font-family: var(--font-body);
  font-size: 18px;
  color: var(--ink);
  margin: 32px 0 10px;
  line-height: 1.3;
}

.homepage-content p {
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--muted);
  line-height: 1.70;
  margin: 0;
}

/* ==========================================================================
   Quiz page shell
   ========================================================================== */

.quiz-header {
  padding: 20px 0 8px;
}

.quiz-h1 {
  font-size: 24px;
  line-height: 1.3;
  margin-top: 8px;
}

.quiz-intro {
  font-size: 13px;
  color: var(--muted);
  margin-top: 8px;
  margin-bottom: 4px;
}

.not-found-h1 {
  font-size: 24px;
  line-height: 1.3;
  margin-top: 8px;
}

.not-found-message {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--muted);
  margin-top: 8px;
  margin-bottom: 20px;
}

/* ==========================================================================
   Quiz app (JS-driven)
   ========================================================================== */

#quiz-app {
  padding: 12px 0 40px;
}

.quiz-topbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 18px;
}

.quiz-topbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sound-toggle {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 20px;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 5px 10px;
}

/* Odometer question counter — 18px, below the 20px floor, so Space
   Grotesk even though it visually reads as a heading. */
.q-counter {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-body);
  font-size: 18px;
  color: var(--ink);
}

.q-counter-track {
  display: block;
  height: 1.1em;
  overflow: hidden;
  position: relative;
}

/* Per-quiz label vocabulary (5c). Lives on .q-counter's ::before, not
   .q-counter-track's, so the label stays put while the digit rolls —
   putting it inside the track would drag static text through the same
   slot-machine transform on every question change. quiz-engine.js is out
   of this phase's scope, so the prefix is pure CSS content off the same
   data-slug attribute the theme tokens use, not a new DOM node. 18px
   .q-counter text clears the 14px floor for accent-coloured labels. */
#quiz-app[data-slug="aesthetic-quiz"] .q-counter::before { content: "VIBE"; }
#quiz-app[data-slug="aesthetic-quiz-clothing"] .q-counter::before { content: "LOOK"; }
#quiz-app[data-slug="what-food-am-i"] .q-counter::before { content: "COURSE"; }
#quiz-app[data-slug="what-bird-am-i"] .q-counter::before { content: "FIELD NOTE"; }
#quiz-app[data-slug="what-dessert-am-i"] .q-counter::before { content: "COURSE"; }

#quiz-app[data-slug] .q-counter::before {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.03em;
}

.q-counter-digit {
  display: block;
  height: 1.1em;
  line-height: 1.1em;
}

.q-counter-track.is-rolling {
  transform: translateY(-1.1em);
  transition: transform 220ms cubic-bezier(.3, .8, .3, 1);
}

.q-counter-total {
  font-family: var(--font-body);
  font-size: 18px;
  color: var(--ink);
}

.quiz-back {
  background: transparent;
  border: none;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 12px;
  padding: 4px 0;
}

.quiz-back[hidden] {
  display: none;
}

/* Progress bar (thin bar + dot trail together) */
.progress-bar-track {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 14px;
}

.progress-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  width: 0%;
}

.dot-trail {
  display: flex;
  gap: 4px;
  margin-bottom: 28px;
}

.dot-trail span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--border);
  display: block;
  transform: scale(1);
}

.dot-trail span.filled {
  background: var(--accent);
}

.dot-trail span.just-filled {
  animation: dot-fill-pulse 200ms ease-in-out;
}

@keyframes dot-fill-pulse {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.4); }
  100% { transform: scale(1); }
}

.question-card {
  transition: transform 200ms ease-in, opacity 200ms ease-in;
}

.question-card.is-leaving {
  opacity: 0;
  transform: translateY(-8px) scale(0.985);
}

.question-card.is-entering {
  opacity: 0;
  transform: translateY(12px);
}

.question-card.is-entered {
  opacity: 1;
  transform: translateY(0);
  transition: transform 300ms cubic-bezier(.2, .9, .3, 1),
              opacity 300ms ease-out;
}

/* QUESTION TEXT — 26px/1.20 mobile, 34px/1.15 desktop. Weight 600 per
   the confirmed mapping (overrides the reference doc's 500). */
.question-text {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.20;
  font-weight: 600;
  margin-bottom: 20px;
}

@media (min-width: 800px) {
  .question-text {
    font-size: 34px;
    line-height: 1.15;
  }
}

.options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ==========================================================================
   5d — question layout templates, cycled by index % 4 via the
   q-layout-{a,b,c,d} class quiz-engine.js writes onto #quiz-app.
   Composition, type scale, and alignment only — no colour changes between
   questions. Answer-tile fill/border/radius (per-quiz, from 5c) and every
   interaction transition are untouched here; only .question-card/.q-counter
   geometry changes.
   ========================================================================== */

/* Template A (index % 4 === 0) — the existing default composition. No
   overrides: label above, question left-aligned at standard size. */

/* Template B (index % 4 === 1) — no word label, larger centred question,
   more vertical space. The numeric counter ("04 / 12") stays visible;
   only the VIBE/LOOK/COURSE word from 5c is hidden. */
#quiz-app.q-layout-b .q-counter::before {
  content: none;
}

#quiz-app.q-layout-b .question-text {
  font-size: 32px;
  text-align: center;
  margin-top: 32px;
  margin-bottom: 36px;
}

@media (min-width: 800px) {
  #quiz-app.q-layout-b .question-text {
    font-size: 42px;
    margin-top: 48px;
    margin-bottom: 44px;
  }
}

/* Template C (index % 4 === 2) — label stays, question left, accent rule
   underneath the question. */
#quiz-app.q-layout-c .question-text {
  padding-bottom: 20px;
  border-bottom: var(--rule) solid var(--accent);
}

/* Template D (index % 4 === 3) — oversized hanging question number beside
   the question, generated from data-qnum via CSS content (no new DOM
   node). Mobile-first: below 800px this template is intentionally
   unstyled and falls back to Template A's plain stacked arrangement — the
   hanging number does not fit on a phone. */
@media (min-width: 800px) {
  #quiz-app.q-layout-d .q-counter::before {
    content: none;
  }
  #quiz-app.q-layout-d .q-counter {
    font-size: 13px;
    opacity: 0.6;
  }
  #quiz-app.q-layout-d .question-card {
    display: grid;
    grid-template-columns: 88px 1fr;
    column-gap: 24px;
    align-items: start;
  }
  #quiz-app.q-layout-d .question-card::before {
    content: attr(data-qnum);
    grid-column: 1;
    grid-row: 1 / -1;
    font-family: var(--font-display);
    font-size: 64px;
    line-height: 0.85;
    font-weight: 700;
    color: var(--accent);
  }
  #quiz-app.q-layout-d .question-text,
  #quiz-app.q-layout-d .options {
    grid-column: 2;
  }
}

/* Idle float — CSS only, offloaded to the compositor. Amplitude stays
   tiny (<=3px, <=0.4deg) on purpose; more than this reads as broken
   rather than alive. Paused during press/select via animation-play-state. */
@keyframes tile-drift-a {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-0.3deg); }
  50%      { transform: translate3d(0, -3px, 0) rotate(0.3deg); }
}
@keyframes tile-drift-b {
  0%, 100% { transform: translate3d(0, -2px, 0) rotate(0.4deg); }
  50%      { transform: translate3d(0, 1px, 0) rotate(-0.2deg); }
}
@keyframes tile-drift-c {
  0%, 100% { transform: translate3d(0, 1px, 0) rotate(0.2deg); }
  50%      { transform: translate3d(0, -2px, 0) rotate(-0.4deg); }
}

.answer-tile:nth-child(1) { animation: tile-drift-a 5.2s ease-in-out infinite; }
.answer-tile:nth-child(2) { animation: tile-drift-b 6.1s ease-in-out infinite; animation-delay: -1.4s; }
.answer-tile:nth-child(3) { animation: tile-drift-c 5.7s ease-in-out infinite; animation-delay: -2.8s; }
.answer-tile:nth-child(4) { animation: tile-drift-a 6.4s ease-in-out infinite; animation-delay: -0.9s; }
.answer-tile:nth-child(5) { animation: tile-drift-b 5.5s ease-in-out infinite; animation-delay: -3.3s; }

.answer-tile {
  width: 100%;
  min-height: 52px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  background: var(--card);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.45;
  font-weight: 500;
  color: var(--ink);
  text-align: left;
  transform: scale(1);
  transition: transform 180ms cubic-bezier(.2, 1.4, .3, 1),
              opacity 180ms ease-out,
              border-color 120ms ease-out;
}

/* Per-quiz resting-state tile treatment (5c). Radius already varies via
   --radius above; these only touch fill/border/padding. Every
   background/border override is gated :not(.is-selected) so the shared
   selected-state feedback (border-color: var(--accent); background:
   #F0EBF8) always wins once a tile is chosen — interaction physics stay
   identical across all five quizzes; only the resting look differs. */
#quiz-app[data-slug="aesthetic-quiz-clothing"] .answer-tile:not(.is-selected) {
  background: transparent;
  border-color: var(--border);
}
#quiz-app[data-slug="aesthetic-quiz-clothing"] .answer-tile {
  padding: 10px 16px;
}

#quiz-app[data-slug="what-food-am-i"] .answer-tile:not(.is-selected) {
  background: rgba(229, 107, 63, 0.06);
}
#quiz-app[data-slug="what-food-am-i"] .answer-tile {
  padding: 18px 20px;
}

#quiz-app[data-slug="what-bird-am-i"] .answer-tile:not(.is-selected) {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
}

#quiz-app[data-slug="what-dessert-am-i"] .answer-tile:not(.is-selected) {
  background: rgba(196, 90, 131, 0.08);
  border-color: rgba(196, 90, 131, 0.18);
}

.answer-tile.is-pressing {
  transform: scale(0.96);
  transition-duration: 70ms;
  transition-timing-function: ease-out;
  animation-play-state: paused;
}

.answer-tile.is-selected {
  transform: scale(1.04);
  border-color: var(--accent);
  background: #F0EBF8;
  color: var(--accent-dark);
  animation-play-state: paused;
}

.answer-tile.is-selected.is-expanding {
  transform: scale(1.08);
}

.answer-tile.is-dismissed {
  opacity: 0;
  transform: translateY(6px) scale(0.98);
  transition-duration: 200ms;
}

.no-js-note {
  font-size: 13px;
  color: var(--muted);
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

/* Reduced motion — mandatory, not optional polish. Quiz stays fully
   completable; it just advances instantly with no drift/overshoot. */
@media (prefers-reduced-motion: reduce) {
  .answer-tile,
  .question-card,
  .q-counter-track,
  .dot-trail span,
  .progress-bar-fill,
  .reveal-card,
  .reveal-flash {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   Result screen
   ========================================================================== */

#results-app[hidden] {
  display: none;
}

.result-screen {
  display: none;
}

.result-screen.active {
  display: block;
  animation: result-in 0.25s ease;
}

@keyframes result-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   Reveal card — plays before the result screen on a real completion.
   Skipped entirely on shared (?r=) links and under reduced motion (JS
   never adds .is-visible/.is-flipping in those cases; this file also
   flattens it under the reduced-motion query below as a defense-in-depth).
   ========================================================================== */

.reveal-card {
  position: relative;
  width: 220px;
  height: 220px;
  margin: 60px auto;
  opacity: 0;
  transform-style: preserve-3d;
  perspective: 1200px;
  transition: opacity 200ms ease-out, transform 440ms cubic-bezier(.4, .1, .3, 1);
}

.reveal-card.is-visible {
  opacity: 1;
  animation: reveal-wobble 220ms ease-in-out 3;
}

.reveal-card.is-flipping {
  opacity: 1;
  animation: none;
  transform: rotateY(180deg) scale(1);
}

@keyframes reveal-wobble {
  0%, 100% { transform: rotate(-1deg); }
  50%      { transform: rotate(1deg); }
}

.reveal-card-back,
.reveal-card-face {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
  backface-visibility: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
}

.reveal-card-back {
  background: linear-gradient(
    135deg,
    var(--p1) 0%,  var(--p1) 38%,
    var(--p2) 38%, var(--p2) 68%,
    var(--p3) 68%, var(--p3) 100%
  );
}

.reveal-label {
  font-family: var(--font-body);
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.12em;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

.reveal-card-face {
  background: var(--card);
  border: 1px solid var(--border);
  transform: rotateY(180deg);
}

.reveal-eyebrow {
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: 8px;
}

/* 26px — kept flat (no desktop/mobile split), constrained by the 220x220
   reveal card. */
.reveal-name {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.15;
  font-weight: 600;
  color: var(--ink);
}

.reveal-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
}

.reveal-flash.is-flashing {
  animation: reveal-flash-fade 180ms ease-out;
}

@keyframes reveal-flash-fade {
  0%   { opacity: 0.12; }
  100% { opacity: 0; }
}

.vibe-fragments {
  padding: 20px;
}

.vibe-fragments-heading {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: 10px;
}

/* 15px — below the 20px floor, so Space Grotesk despite the display feel. */
.fragment-line {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  line-height: 1.8;
  border-left: 2px solid var(--accent);
  padding-left: 12px;
  margin-bottom: 6px;
}

.result-verdict {
  font-size: 15px;
  color: var(--ink);
  line-height: 1.5;
  margin: 12px 20px;
}

.result-rarity {
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--accent-dark);
  text-align: center;
  margin: 8px 20px;
  text-transform: uppercase;
}

.signal-tags {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 16px 20px 4px;
  -webkit-overflow-scrolling: touch;
}

.signal-tag {
  font-size: 11px;
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 12px;
  white-space: nowrap;
  flex: 0 0 auto;
}

.score-breakdown {
  padding: 20px;
}

.score-breakdown-heading {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: 12px;
}

.score-row {
  margin-bottom: 12px;
}

.score-row-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}

.score-row-name {
  font-size: 12px;
  color: var(--ink);
}

.score-row.winner .score-row-name {
  color: var(--accent-dark);
}

.score-row-pct {
  font-size: 11px;
  color: var(--muted);
}

.score-bar-track {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}

.score-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
}

.result-description {
  padding: 4px 20px 0;
  font-size: 15px;
  color: var(--ink);
  line-height: 1.70;
}

.action-row {
  display: flex;
  gap: 8px;
  padding: 24px 20px 0;
}

.action-row button {
  flex: 1;
  min-height: 44px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  letter-spacing: 0.05em;
  font-weight: 600;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink);
}

.action-row .btn-share {
  background: var(--accent);
  color: var(--accent-dark);
  border-color: var(--accent);
}

.result-footer {
  font-size: 11px;
  color: var(--muted);
  text-align: center;
  margin-top: 24px;
  padding-bottom: 20px;
}

/* ==========================================================================
   All-results (crawlable, hidden by default; revealed via "all results" btn)
   ========================================================================== */

#all-results {
  display: none;
  padding: 20px;
  border-top: 1px solid var(--border);
}

#all-results.revealed {
  display: block;
}

/* 16px — below the 20px floor, so Space Grotesk despite being an h3. */
#all-results h3 {
  font-family: var(--font-body);
  font-size: 16px;
  margin-top: 20px;
}

#all-results h3:first-of-type {
  margin-top: 0;
}

#all-results p {
  font-size: 15px;
  color: var(--ink);
  line-height: 1.65;
  margin-top: 6px;
}

/* ==========================================================================
   Article / FAQ (always pre-rendered, always visible)
   ========================================================================== */

#quiz-faq {
  padding: 32px 20px;
  border-top: 1px solid var(--border);
}

/* #quiz-article breaks out of <main class="wrap">'s max-width so the
   article can use a wider desktop measure (776px via .article-grid)
   than the quiz-taking area (which stays inside .wrap on purpose —
   splitting the physical answer tiles across a wide screen adds eye
   travel for no gain). template.html is out of scope for 5b, so this
   is a pure-CSS breakout rather than a new wrapper element. */
#quiz-article {
  grid-column: 1 / -1;
  padding: 32px 0;
  border-top: var(--rule) solid var(--border);
}

.article-kicker {
  display: block;
  max-width: 776px;
  margin: 0 auto;
  padding: 0 20px;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.10em;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 20px;
}

.article-grid {
  display: grid;
  grid-template-columns: 96px minmax(0, 640px);
  column-gap: 40px;
  max-width: 776px;
  margin: 0 auto;
  padding: 0 20px;
}

@media (max-width: 800px) {
  .article-grid {
    grid-template-columns: 1fr;
    row-gap: 0;
  }
}

.article-section {
  display: contents;
}

/* ARTICLE SECTION NUMBER — 40px mobile, 64px desktop. Hangs in the left
   margin column on desktop; sits above its heading once the grid
   collapses to one column below 800px. */
.section-number {
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 0.85;
  font-weight: 700;
  color: var(--accent);
}

@media (min-width: 800px) {
  .section-number {
    font-size: 64px;
  }
}

/* ARTICLE H2 — 22px mobile, 26px desktop. 20px flat was too close to
   body copy to create hierarchy. Rule sits 16px below the heading text,
   full width of the content column, in the quiz's accent colour. */
#quiz-article h2, #quiz-faq h2 {
  font-size: 22px;
  line-height: 1.25;
  padding-bottom: 16px;
  margin-bottom: 20px;
  border-bottom: var(--rule) solid var(--accent);
}

@media (min-width: 800px) {
  #quiz-article h2, #quiz-faq h2 {
    font-size: 26px;
    line-height: 1.20;
  }
}

/* Drop cap — ::first-letter only, never float:left on the paragraph
   itself (float causes wrapping bugs on narrow screens and confuses
   some screen readers). */
.section-body > p:first-of-type::first-letter {
  font-family: var(--font-display);
  font-size: 3.4em;
  font-weight: 600;
  line-height: 0.82;
  float: left;
  padding: 0.06em 0.08em 0 0;
}

@media (max-width: 800px) {
  .section-body > p:first-of-type::first-letter {
    font-size: 2.8em;
  }
}

/* ARTICLE BODY — 16px mobile, 17px desktop. This was the actual source
   of the "reads small and dense" complaint that started Phase 5. */
#quiz-article p {
  font-size: 16px;
  line-height: 1.70;
  font-weight: 400;
  color: var(--ink);
  margin-bottom: 14px;
}

@media (min-width: 800px) {
  #quiz-article p {
    font-size: 17px;
  }
}

.pull-quote {
  grid-column: 1 / -1;
  position: relative;
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--ink);
  margin: 32px 0;
  padding-left: 24px;
}

.pull-quote::before {
  content: "\201C";
  position: absolute;
  left: 0;
  top: -6px;
  font-size: 1.5em;
  color: var(--accent);
}

.faq-number {
  display: inline-block;
  min-width: 24px;
  margin-right: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--accent-dark);
}

.section-body a,
.faq-item a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--border);
  text-underline-offset: 2px;
}

.section-body a:hover,
.faq-item a:hover {
  text-decoration-color: currentColor;
}

/* FAQ ANSWER — flat 16px, no desktop bump. */
#quiz-faq p {
  font-size: 16px;
  line-height: 1.70;
  font-weight: 400;
  color: var(--ink);
}

.faq-item {
  margin-top: 16px;
}

/* FAQ QUESTION — bumped 14px -> 16px; at 14px it was the same size as
   its own answer text. Below the 20px floor, so Space Grotesk. */
.faq-item h3 {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 4px;
}

.site-footer {
  text-align: center;
  padding: 32px 20px;
  color: var(--muted);
}

.footer-links {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 8px;
}

.footer-links a {
  color: var(--muted);
}

.footer-links a:not(:last-child)::after {
  content: " · ";
}

.footer-domain {
  font-size: 13px;
  color: var(--muted);
}

/* ==========================================================================
   Vibe Passport — result-screen block (3a) and homepage strip (3b)
   ========================================================================== */

#passport-strip:empty {
  display: none;
}

.passport-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  margin: 10px 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  font-family: var(--font-body);
}

.passport-strip-title {
  font-size: 11px;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: var(--ink);
}

.passport-strip-status {
  font-size: 12px;
  color: var(--muted);
  margin-left: auto;
}

.passport-strip-bar {
  font-family: monospace;
  font-size: 11px;
  color: var(--accent-dark);
  letter-spacing: 0.05em;
}

.passport-strip-pickup {
  font-size: 11px;
  color: var(--accent-dark);
}

.passport-expanded {
  margin-top: 6px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
}

.vibe-passport {
  padding: 16px 20px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.vibe-passport-heading {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: 10px;
}

.passport-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 10px;
}

.passport-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}

.passport-row.is-filled {
  color: var(--ink);
  font-weight: 600;
}

.passport-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: transparent;
  border: 1px solid var(--border);
}

.passport-row.is-filled .passport-dot {
  border: none;
}

.passport-dim {
  flex: 0 0 76px;
  font-size: 10px;
  letter-spacing: 0.05em;
  opacity: 0.8;
}

.passport-nudge {
  font-size: 11px;
  color: var(--muted);
  text-align: center;
  margin-bottom: 8px;
}

.passport-next-btn {
  display: block;
  text-align: center;
  min-height: 40px;
  line-height: 40px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  font-size: 12px;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}

/* ==========================================================================
   Archetype screen — the in-quiz unlock (after the 5th completion) and the
   homepage ?dna= shared view share this markup via buildArchetypeScreenHtml.
   Sized to fit 390x844 with no scrolling — that is the screenshot.
   ========================================================================== */

.archetype-overlay {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.archetype-overlay-inline {
  padding: 12px 0 0;
}

.archetype-screen {
  width: 100%;
  max-width: 390px;
  margin: 0 auto;
  border-radius: var(--radius-lg);
  padding: 28px 22px;
  text-align: center;
  font-family: var(--font-body);
}

/* 15px — below the 20px floor, so Space Grotesk. */
.archetype-kicker {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 18px;
}

.unlock-rows {
  text-align: left;
  margin-bottom: 14px;
}

.unlock-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  padding: 4px 0;
  border-bottom: 1px solid rgba(128, 128, 128, 0.2);
}

.unlock-num {
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
  width: 16px;
  flex: 0 0 auto;
}

.unlock-dim {
  flex: 0 0 84px;
  letter-spacing: 0.06em;
  font-size: 10px;
  opacity: 0.7;
}

.unlock-name {
  font-weight: 600;
}

.archetype-divider {
  width: 40px;
  height: 1px;
  background: currentColor;
  opacity: 0.3;
  margin: 14px auto;
}

.archetype-name {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 10px;
}

.archetype-line {
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 20px;
  opacity: 0.9;
}

.archetype-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.archetype-actions button,
.archetype-actions a {
  display: block;
  min-height: 44px;
  line-height: 44px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  letter-spacing: 0.05em;
  font-weight: 600;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  text-decoration: none;
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (min-width: 540px) {
  :root {
    --max-width: 520px;
  }
}
