/* ═══════════════════════════════════════════════════════════════════════
   Quant Quest — design system
   Loaded last, on purpose. Every component in this app already reads the
   --qq-* tokens, so retuning them here re-skins the whole product instead of
   rewriting twenty stylesheets.

   What was wrong, specifically:

   The palette was Tailwind's defaults — sky-400 accent, slate text, one flat
   #0a0f18 surface used for every panel. That exact combination is the visual
   signature of a generated dashboard, and it reads as generated no matter how
   good the product underneath is. It also had no *depth*: a modal, a card and
   the page background were all the same colour, so nothing felt layered.

   And the motion had been switched off rather than tuned — 47 rules in
   styles.css literally say `animation:none` / `box-shadow:none`. Someone wrote
   the choreography, decided it was too much, and disabled it instead of
   dialling it back. Flat and lifeless is what is left.

   The fix is not "more effects". It is: one confident accent used sparingly,
   real surface layering, a type scale with actual hierarchy, and motion that
   is physical (springs, overshoot, weight) rather than decorative (glows,
   pulses, infinite loops).
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── surfaces ────────────────────────────────────────────────────────
     Five steps, not one. Each is a real elevation the eye can rank, and
     they are blue-black rather than neutral so the accent sits in the same
     family as the ground it stands on. */
  --qq-bg-0: #04060c;          /* page void */
  --qq-bg-1: #070b14;          /* app canvas */
  --qq-bg-2: #0b111d;          /* raised panel */
  --qq-bg-3: #111a29;          /* card on panel */
  --qq-bg-4: #172236;          /* hover / active surface */

  --qq-surface: rgba(11, 17, 29, .82);
  --qq-surface-strong: rgba(17, 26, 41, .94);

  /* Borders carry a little of the accent's hue so edges feel intentional
     rather than like a default grey stroke. */
  --qq-border: rgba(125, 160, 200, .10);
  --qq-border-hover: rgba(125, 160, 200, .22);
  --qq-border-strong: rgba(125, 160, 200, .32);

  /* ── text ────────────────────────────────────────────────────────────
     Slightly warm whites. Pure #fff on near-black is what makes a dark UI
     feel cheap; a hint of warmth reads as printed rather than emitted. */
  --qq-text-1: #f4f7fb;
  --qq-text-2: #9fb0c9;
  --qq-text-3: #6b7d97;
  --qq-text-4: #4a596f;

  /* ── accent ──────────────────────────────────────────────────────────
     Deeper and less saturated than the stock sky-400 it replaces, so it
     stops looking like a framework default while staying the same colour
     family the product was built around. */
  --qq-accent: var(--theme-accent, #3ba3e0);
  --qq-accent-bright: #6cc7f5;
  --qq-accent-deep: #1d6fa5;
  --qq-accent-ink: #071824;
  --qq-accent-glow: rgba(59, 163, 224, .28);

  /* Gold is the *earned* colour. It appears only when the player achieves
     something, which is what keeps it meaning anything. */
  --qq-gold: #e3b341;
  --qq-gold-bright: #ffd66b;
  --qq-gold-glow: rgba(227, 179, 65, .26);

  /* Market semantics never change: up is green, down is red, everywhere. */
  --qq-up: #3fcf8e;
  --qq-up-dim: rgba(63, 207, 142, .14);
  --qq-down: #f4676b;
  --qq-down-dim: rgba(244, 103, 107, .14);
  --qq-success: var(--qq-up);
  --qq-danger: var(--qq-down);
  --qq-warn: var(--qq-gold);

  /* ── radii ───────────────────────────────────────────────────────────
     A scale, not one rounded-xl everywhere. Small controls get small radii;
     uniform rounding is another generated-UI tell. */
  --qq-r-xs: 6px;
  --qq-r-sm: 9px;
  --qq-r-md: 13px;
  --qq-r-lg: 18px;
  --qq-r-xl: 24px;
  --qq-r-full: 999px;

  /* ── elevation ───────────────────────────────────────────────────────
     Shadows are near-black and tight rather than wide coloured glows.
     Coloured glow on everything is the other half of the generated look. */
  --qq-e-1: 0 1px 2px rgba(0,0,0,.4);
  --qq-e-2: 0 2px 8px rgba(0,0,0,.34), 0 1px 2px rgba(0,0,0,.4);
  --qq-e-3: 0 8px 24px rgba(0,0,0,.42), 0 2px 6px rgba(0,0,0,.34);
  --qq-e-4: 0 20px 48px rgba(0,0,0,.5), 0 4px 12px rgba(0,0,0,.36);
  --qq-e-lift: 0 12px 32px rgba(0,0,0,.44);

  /* ── motion ──────────────────────────────────────────────────────────
     Named by intent. Interfaces feel expensive when things have weight:
     they overshoot slightly and settle, instead of easing linearly into
     place. */
  --qq-ease: cubic-bezier(.22, 1, .36, 1);          /* standard out */
  --qq-ease-in: cubic-bezier(.4, 0, 1, 1);
  --qq-spring: cubic-bezier(.34, 1.56, .64, 1);     /* overshoot, settles */
  --qq-spring-soft: cubic-bezier(.22, 1.2, .36, 1);
  --qq-snap: cubic-bezier(.2, .9, .3, 1.2);         /* quick, confident */

  --qq-t-instant: 90ms;
  --qq-t-fast: 160ms;
  --qq-t-base: 260ms;
  --qq-t-slow: 420ms;
  --qq-t-story: 700ms;                              /* narrative beats */

  /* ── type ────────────────────────────────────────────────────────────
     Display face for headings, text face for reading. Tight tracking on
     large sizes, loose on small caps — the pairing that makes type look
     set rather than defaulted. */
  --qq-font-display: Outfit, "Segoe UI", sans-serif;
  --qq-font-text: Inter, "Segoe UI", sans-serif;
  --qq-font-mono: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, monospace;
}

/* ── typography primitives ─────────────────────────────────────────── */
.qq-display {
  font-family: var(--qq-font-display);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.04;
  color: var(--qq-text-1);
}
.qq-h1 { font-size: clamp(30px, 5.2vw, 54px); }
.qq-h2 { font-size: clamp(23px, 3.4vw, 34px); }
.qq-h3 { font-size: clamp(18px, 2.2vw, 22px); letter-spacing: -.02em; }

.qq-eyebrow {
  font-family: var(--qq-font-text);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .17em;
  color: var(--qq-text-3);
}

.qq-lede {
  font-family: var(--qq-font-text);
  font-size: clamp(14px, 1.6vw, 16.5px);
  line-height: 1.62;
  color: var(--qq-text-2);
  max-width: 58ch;          /* measure, so paragraphs are readable */
}

/* Numbers must never reflow while counting up. */
.qq-num {
  font-family: var(--qq-font-display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

/* ── interaction ───────────────────────────────────────────────────── */
/* Press feedback. A button that does not physically respond to being
   pressed feels like a picture of a button. */
.qq-press { transition: transform var(--qq-t-instant) var(--qq-ease),
                        filter var(--qq-t-fast) var(--qq-ease); }
.qq-press:active:not(:disabled) { transform: scale(.975); }

.btn { transition: transform var(--qq-t-fast) var(--qq-spring),
                   box-shadow var(--qq-t-fast) var(--qq-ease),
                   border-color var(--qq-t-fast) var(--qq-ease),
                   background-color var(--qq-t-fast) var(--qq-ease); }
.btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: var(--qq-e-lift); }
.btn:active:not(:disabled) { transform: translateY(0) scale(.985); transition-duration: var(--qq-t-instant); }

/* ── the four things that made it look generated ───────────────────── */

/* 1. One flat surface for every panel. */
.glass, .qq-card {
  background: linear-gradient(180deg, var(--qq-bg-3), var(--qq-bg-2));
  border: 1px solid var(--qq-border);
  border-radius: var(--qq-r-lg);
  box-shadow: var(--qq-e-2), inset 0 1px 0 rgba(255,255,255,.035);
}
.qq-card:hover { border-color: var(--qq-border-hover); }

/* 2. A primary button the colour of a framework default. */
.qq-btn-primary {
  background: linear-gradient(180deg, var(--qq-accent), var(--qq-accent-deep));
  border: 1px solid rgba(108, 199, 245, .34);
  border-radius: var(--qq-r-md);
  color: #f6fbff;
  font-family: var(--qq-font-display);
  font-weight: 700;
  letter-spacing: -.005em;
  box-shadow: var(--qq-e-2), inset 0 1px 0 rgba(255,255,255,.16);
}
.qq-btn-primary:hover:not(:disabled) {
  background: linear-gradient(180deg, var(--qq-accent-bright), var(--qq-accent));
  box-shadow: var(--qq-e-3), inset 0 1px 0 rgba(255,255,255,.2);
}

/* 3. Selection shown as a bare 2px outline. */
.sel {
  outline: none !important;
  border-color: var(--qq-accent) !important;
  background-image: linear-gradient(180deg, rgba(59,163,224,.15), rgba(59,163,224,.05)) !important;
  box-shadow: 0 0 0 1px var(--qq-accent), 0 6px 20px rgba(29,111,165,.28) !important;
}

/* 4. Motion that was written and then switched off. Restored, but tuned:
      short, once, and triggered by something the player did. */
.pulse { animation: qqBreath 3.4s var(--qq-ease) infinite; opacity: 1; }
@keyframes qqBreath { 0%, 100% { opacity: .78; } 50% { opacity: 1; } }

.breath { animation: qqBreathScale 4.2s var(--qq-ease) infinite; }
@keyframes qqBreathScale {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.018); }
}

.glow { box-shadow: 0 0 0 1px var(--qq-accent-glow), 0 8px 32px var(--qq-accent-glow); }

/* ── shared motion vocabulary ──────────────────────────────────────── */
/* Used by the entry sequence, the mascots and the lesson runner so the
   whole product moves in one language. */
@keyframes qqRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes qqPop {
  0%   { opacity: 0; transform: scale(.86); }
  62%  { opacity: 1; transform: scale(1.035); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes qqSlideInLeft {
  from { opacity: 0; transform: translateX(-22px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes qqNudge {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}

.qq-rise { animation: qqRise var(--qq-t-base) var(--qq-ease) both; }
.qq-pop  { animation: qqPop var(--qq-t-slow) var(--qq-spring) both; }

/* Staggered reveal: children arrive in sequence, which reads as composed
   rather than as everything appearing at once. */
.qq-stagger > * { animation: qqRise var(--qq-t-base) var(--qq-ease) both; }
.qq-stagger > *:nth-child(1) { animation-delay: 40ms; }
.qq-stagger > *:nth-child(2) { animation-delay: 110ms; }
.qq-stagger > *:nth-child(3) { animation-delay: 180ms; }
.qq-stagger > *:nth-child(4) { animation-delay: 250ms; }
.qq-stagger > *:nth-child(5) { animation-delay: 320ms; }
.qq-stagger > *:nth-child(6) { animation-delay: 390ms; }
.qq-stagger > *:nth-child(7) { animation-delay: 460ms; }
.qq-stagger > *:nth-child(8) { animation-delay: 530ms; }

/* ── scrollbars ────────────────────────────────────────────────────── */
/* Default scrollbars in a dark app are a loud grey stripe. */
* { scrollbar-width: thin; scrollbar-color: rgba(125,160,200,.22) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(125,160,200,.18);
  border-radius: var(--qq-r-full);
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(125,160,200,.3); background-clip: content-box; }

/* ── text selection ────────────────────────────────────────────────── */
::selection { background: rgba(59,163,224,.32); color: #fff; }

/* ── page ground ───────────────────────────────────────────────────── */
/* Two very low-contrast light sources rather than one obvious radial
   gradient, so the background has depth without announcing itself. */
.bg-realm {
  background:
    radial-gradient(ellipse 80% 50% at 50% -8%,  rgba(38, 92, 140, .20), transparent 60%),
    radial-gradient(ellipse 60% 40% at 88% 10%,  rgba(227, 179, 65, .045), transparent 55%),
    linear-gradient(180deg, var(--qq-bg-1) 0%, var(--qq-bg-0) 100%);
  background-attachment: fixed;
}

@media (prefers-reduced-motion: reduce) {
  .pulse, .breath { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   The cold open — the first thing anyone sees.

   Two things were wrong with the three choices.

   The grid was `1fr 1fr` with the third button spanning both columns, so it
   rendered 2-over-1. Three equal choices laid out unequally reads as a layout
   bug, not as a hierarchy.

   And "Şimdi gir" was the only light button. On a screen whose entire thesis
   is *notice your own reflex*, giving the impulsive option the visual weight
   of a primary action puts a thumb on the scale — the interface answers the
   question before the player does.

   Now all three carry equal weight and take the Arena's own semantic colours:
   green to enter, neutral to wait, red to reject. The player learns the
   product's three verbs in the first five seconds, from the colours they will
   press for the rest of the course, without a word of instruction.
   ═══════════════════════════════════════════════════════════════════════ */

.cold-open-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  max-width: 430px;
}

/* Not cards.

   Three filled, bordered, rounded tiles in a row is the shape a generated
   screen reaches for, and here it was arguing with everything around it: an
   editorial serif over a live market, and then a settings panel bolted to the
   bottom of it. The question being asked is "what is your instinct?", which
   is not a question a form should be collecting.

   So these are keys on a desk instead — a candle glyph, a word, and a rule in
   the option's own colour that lights when you reach for it. Nothing is
   filled, so nothing is recommended. */
.decision-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  padding: 6px 0 12px;
  border: 0;
  border-bottom: 1px solid rgba(148,163,184,.22);
  border-radius: 0;
  background: none;
  box-shadow: none;
  font-family: var(--qq-font-display);
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -.012em;
  text-align: left;
  color: var(--qq-text-2);
  cursor: pointer;
  transition: color var(--qq-t-fast) var(--qq-ease),
              border-bottom-color var(--qq-t-fast) var(--qq-ease),
              transform var(--qq-t-fast) var(--qq-spring);
}
.decision-choice-reject { grid-column: auto; }

/* Drawn at full strength: the glyph is the only illustration on this row, and
   it is the same vocabulary the first lesson teaches. */
.decision-choice-icon {
  width: 17px; height: 24px; flex: 0 0 auto;
  color: var(--qq-text-3);
  opacity: 1;
  transition: color var(--qq-t-fast) var(--qq-ease),
              transform var(--qq-t-fast) var(--qq-spring);
}
.decision-choice-enter  .decision-choice-icon { color: var(--qq-up); }
.decision-choice-reject .decision-choice-icon { color: var(--qq-down); }

/* Generic first, then the coloured variants — equal specificity, so the
   later rule is the one that paints. */
.decision-choice:hover,
.decision-choice:focus-visible {
  color: var(--qq-text-1);
  border-bottom-color: var(--qq-text-3);
  transform: translateY(-2px);
  outline: none;
}
.decision-choice-enter:hover,
.decision-choice-enter:focus-visible  { border-bottom-color: var(--qq-up); }
.decision-choice-reject:hover,
.decision-choice-reject:focus-visible { border-bottom-color: var(--qq-down); }
.decision-choice:hover .decision-choice-icon,
.decision-choice:focus-visible .decision-choice-icon { transform: translateY(-1px) scale(1.07); }
.decision-choice:active { transform: translateY(0); }

@media (max-width: 900px) {
  .cold-open-actions { grid-template-columns: 1fr; max-width: none; }
  .decision-choice { flex-direction: row; align-items: center; gap: 12px; min-height: 46px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   The sign-in screen.

   The form sat directly on a full-brightness candlestick chart with nothing
   between them. Labels and inputs floated over moving red and green bars, so
   the eye had to work to find the field it was in, and the whole thing read as
   a screenshot with a form pasted on top — which is exactly the "generated"
   impression the rest of this pass is removing.

   The chart is worth keeping: it says what the product is before a word is
   read. It just has to sit *behind* something.
   ═══════════════════════════════════════════════════════════════════════ */

/* The market is the one image that says what this product is before a word is
   read, and it was being served at .16 opacity, desaturated and blurred, under
   a veil that dimmed the whole frame. That is the worst of both: too faint to
   be a market, still present enough to muddy the type over it.

   So: let the candles live, and buy legibility with a *focused* pool of dark
   under the form rather than by dimming the picture everywhere. */
.login-chart-bg { opacity: .5; filter: saturate(1.04) contrast(1.03); }
.login-chart-veil {
  background:
    radial-gradient(ellipse 44% 54% at 50% 50%,
      rgba(3,6,12,.95) 0%, rgba(3,6,12,.88) 34%,
      rgba(3,6,12,.5) 66%, rgba(3,6,12,0) 88%),
    linear-gradient(180deg,
      rgba(3,6,12,.66) 0%, rgba(3,6,12,0) 24%,
      rgba(3,6,12,0) 72%, rgba(3,6,12,.84) 100%);
}

/* No card.

   Every stage of the cold open was wrapped in the same bordered dark panel —
   the default shape a generated screen reaches for, and the reason this one
   looked generated. The form has nothing to sit on now except the dark the
   veil already puts behind it, which is what "spacious" was supposed to mean
   before a surface was added to make the text readable. */
#teaser-auth, #teaser-intro, #teaser-choice, #teaser-result, #teaser-boot {
  position: relative;
  padding: clamp(18px, 3vw, 28px) clamp(2px, 1.4vw, 12px);
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Editorial serif, the same face the cold open brands itself with, so the
   screen after the chart belongs to the screen before it. */
#auth-heading {
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-size: clamp(30px, 4vw, 40px);
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1.08;
  color: #f4f6f8;
}

/* A ruled field, not a filled box: one line that lights up when you are in it. */
#qq-login input[type="email"],
#qq-login input[type="password"],
#qq-login input[type="text"] {
  padding: 10px 2px;
  border: 0;
  border-bottom: 1px solid rgba(148,163,184,.26);
  border-radius: 0;
  background: transparent;
  color: var(--qq-text-1);
  font-size: 15px;
  transition: border-color var(--qq-t-fast) var(--qq-ease),
              box-shadow var(--qq-t-fast) var(--qq-ease);
}
#qq-login input:focus {
  outline: none;
  background: transparent;
  border-bottom-color: var(--qq-accent);
  /* Thickens the rule without shifting the text a pixel. */
  box-shadow: 0 1px 0 0 var(--qq-accent);
}
#qq-login input::placeholder { color: var(--qq-text-4); }

/* The mascot line was a bordered tile holding a lettered avatar chip — two
   more boxes to say one sentence. */
.qq-login-speaker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-left: 13px;
  border-left: 2px solid rgba(108,199,245,.5);
  text-align: left;
}
.qq-login-speaker-name {
  font-family: var(--qq-font-display);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--qq-accent);
}
.qq-login-speaker p {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--qq-text-2);
}

/* The CTAs were raw Tailwind cyan — the default blue every generated page
   ships with, and the first thing on screen that said "template". The one
   loud colour this product owns is the market's own up-green, already used
   for every "go" key inside the lessons. The door into the product now uses
   the same physical-key language as the product itself. */
#qq-login button.bg-cyan-600,
#qq-login button.bg-cyan-700,
#qq-login .cta-primary {
  background: linear-gradient(180deg, #4bdb9a, #23a56f) !important;
  color: #032015 !important;
  border: 1px solid rgba(120,240,190,.4);
  border-radius: var(--qq-r-md);
  font-family: var(--qq-font-display);
  font-weight: 800;
  letter-spacing: -.01em;
  box-shadow: 0 4px 0 #17734d, var(--qq-e-2), inset 0 1px 0 rgba(255,255,255,.28);
  transition: transform var(--qq-t-fast) var(--qq-spring),
              box-shadow var(--qq-t-fast) var(--qq-ease),
              filter var(--qq-t-fast) var(--qq-ease);
}
#qq-login button.bg-cyan-600:hover,
#qq-login button.bg-cyan-700:hover,
#qq-login .cta-primary:hover {
  filter: brightness(1.07);
  transform: translateY(-2px);
  box-shadow: 0 6px 0 #17734d, var(--qq-e-3), inset 0 1px 0 rgba(255,255,255,.34);
}
#qq-login button.bg-cyan-600:active,
#qq-login button.bg-cyan-700:active,
#qq-login .cta-primary:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 #17734d, var(--qq-e-1), inset 0 1px 0 rgba(255,255,255,.2);
}

/* The auth tabs were a grey underline; the active one now carries the accent
   so the current mode is obvious at a glance. */
#auth-tab-login, #auth-tab-register { transition: color var(--qq-t-fast), border-color var(--qq-t-fast); }
#qq-login .border-b-2.border-white { border-color: var(--qq-accent) !important; }

/* ═══════════════════════════════════════════════════════════════════════
   The lesson CTA.

   `#74d45a` — a lime green that appears nowhere else in the product. A
   learning app wanting a green "go" button is a good instinct and worth
   keeping; picking a green unrelated to the palette is what makes it look
   bolted on. This is the same green the charts use for up, so the one loud
   colour on the screen is a colour the player is already being taught.
   ═══════════════════════════════════════════════════════════════════════ */
.aca-check-btn,
.aca-hook-btn,
.aca-live-nav-primary,
#academy-level-content.aca-lesson-open .aca-action-dock .aca-hook-btn {
  min-height: 52px;
  border-radius: var(--qq-r-md);
  background: linear-gradient(180deg, #4bdb9a, #23a56f) !important;
  color: #032015 !important;
  border: 1px solid rgba(120, 240, 190, .4) !important;
  font-family: var(--qq-font-display);
  font-weight: 800;
  letter-spacing: -.01em;
  /* A solid bottom edge instead of a blur: the button reads as a physical key
     that depresses when pressed, which is what makes tapping it satisfying. */
  box-shadow: 0 4px 0 #17734d, var(--qq-e-2), inset 0 1px 0 rgba(255,255,255,.28) !important;
  transition: transform var(--qq-t-fast) var(--qq-spring),
              box-shadow var(--qq-t-fast) var(--qq-ease),
              filter var(--qq-t-fast) var(--qq-ease);
}
.aca-check-btn:hover:not(:disabled),
.aca-hook-btn:hover:not(:disabled),
.aca-live-nav-primary:hover:not(:disabled) {
  filter: brightness(1.07);
  transform: translateY(-2px);
  box-shadow: 0 6px 0 #17734d, var(--qq-e-3), inset 0 1px 0 rgba(255,255,255,.34) !important;
}
/* Pressed: the button travels down onto its own edge. */
.aca-check-btn:active:not(:disabled),
.aca-hook-btn:active:not(:disabled),
.aca-live-nav-primary:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: 0 1px 0 #17734d, inset 0 1px 0 rgba(255,255,255,.2) !important;
}
.aca-check-btn:disabled, .aca-hook-btn:disabled { filter: grayscale(.5) brightness(.7); }

/* ═══════════════════════════════════════════════════════════════════════
   The lesson stage.

   academy.css carries two competing designs for this screen, both live.
   Line 617 builds a centred vertical stack with a 188px mascot, and its own
   comment says it exists to remove a "sparse 2-col void". Line 2038 then
   overrides it back into a two-column grid with a 76px mascot in a rounded
   box. The later one wins, so the screen is exactly the void the earlier
   comment warned about — two designers' opinions frozen in one file, with the
   loser's code still shipping.

   Measured on a 1912x948 viewport: the copy column was 459x173 inside a 684px
   row and the visual column held a 220px canvas in 684px of space. Roughly a
   quarter of the screen carried content; the rest was empty.

   A hook is one line of narration, one sentence of setup and one chart. That
   is not enough material for two tall columns, and no amount of alignment will
   make it so. One centred column, sized to its content, with the chart as a
   full-width band underneath the sentence it illustrates.
   ═══════════════════════════════════════════════════════════════════════ */

@media (min-width: 900px) {
  #academy-level-content.aca-lesson-open .aca-hook-card {
    display: flex !important;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(14px, 2.2vh, 26px);
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: clamp(16px, 2.6vh, 30px) 24px;
    text-align: center;
    grid-template-columns: none;
  }

  /* Copy and visual become rows in one column rather than columns in a void. */
  #academy-level-content.aca-lesson-open .aca-hook-copy {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(12px, 2vh, 20px);
    width: 100%;
    max-width: 100%;
    text-align: center;
  }
  #academy-level-content.aca-lesson-open .aca-hook-visual {
    width: 100%;
    align-self: stretch;
    display: block;
  }
  /* The chart sat visibly left of the guide in every lesson. The visual column
     above is a full-width block, and the preview inside it caps itself at
     520px with `margin:0` — a capped block with no auto margin hugs the left
     edge. Everything else in the hook is centred, so the chart alone looked
     knocked out of alignment. */
  #academy-level-content.aca-lesson-open .aca-hook-preview {
    margin-left: auto !important;
    margin-right: auto !important;
  }

  /* The guide is a character, not an avatar chip. No box, no border — the
     drawing is the thing, and the rig makes it move. */
  #academy-level-content.aca-lesson-open .aca-hook-mascot-wrap {
    flex-direction: column !important;
    align-items: center !important;
    gap: 10px !important;
    margin: 0 !important;
    width: 100%;
  }
  #academy-level-content.aca-lesson-open .aca-hook-mascot {
    width: clamp(96px, 11vh, 132px) !important;
    height: clamp(96px, 11vh, 132px) !important;
    flex: 0 0 auto !important;
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }
  #academy-level-content.aca-lesson-open .aca-hook-mascot svg {
    width: 100% !important;
    height: 100% !important;
  }

  /* Speech bubble with a tail, pointing back at who is talking. */
  #academy-level-content.aca-lesson-open .aca-hook-bubble {
    position: relative;
    max-width: 560px;
    padding: 13px 20px;
    border-radius: var(--qq-r-lg);
    background: linear-gradient(180deg, rgba(23,34,54,.95), rgba(11,17,29,.95));
    border: 1px solid var(--qq-border-hover);
    box-shadow: var(--qq-e-2);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.5;
    color: var(--qq-text-2);
  }
  #academy-level-content.aca-lesson-open .aca-hook-bubble::after {
    content: "";
    position: absolute;
    top: -7px; left: 50%;
    width: 12px; height: 12px;
    transform: translateX(-50%) rotate(45deg);
    background: rgba(23,34,54,.95);
    border-left: 1px solid var(--qq-border-hover);
    border-top: 1px solid var(--qq-border-hover);
  }

  /* The sentence is the point of the screen, so it gets the size. */
  #academy-level-content.aca-lesson-open .aca-hook-text,
  #academy-level-content.aca-lesson-open .aca-hook-beat {
    max-width: 22ch;
    margin: 0 auto;
    font-family: var(--qq-font-display);
    font-size: clamp(26px, 3.4vh, 40px);
    font-weight: 800;
    line-height: 1.14;
    letter-spacing: -.035em;
    color: var(--qq-text-1);
  }

  /* The chart sits directly under the words it illustrates, full width. */
  #academy-level-content.aca-lesson-open .aca-hook-preview-frame {
    border-radius: var(--qq-r-lg);
    background: linear-gradient(180deg, var(--qq-bg-2), var(--qq-bg-1));
    border: 1px solid var(--qq-border);
    box-shadow: var(--qq-e-3);
  }
  #academy-level-content.aca-lesson-open .aca-hook-preview-frame canvas {
    height: clamp(180px, 26vh, 250px) !important;
  }

  /* The action bar spans the stage rather than floating at the far corner:
     the eye finishes reading and the button is already under it. */
  #academy-level-content.aca-lesson-open .aca-action-dock {
    justify-content: center;
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding-top: clamp(10px, 1.6vh, 18px);
    border-top: 1px solid var(--qq-border);
  }
  #academy-level-content.aca-lesson-open .aca-action-dock .aca-hook-btn {
    width: min(420px, 100%);
  }
}

/* Beat dots: which part of the hook you are on. */
.aca-hook-beat-dots { display: flex; gap: 7px; justify-content: center; }
.aca-hook-beat-dots span {
  width: 7px; height: 7px;
  border-radius: var(--qq-r-full);
  background: rgba(125,160,200,.22);
  transition: background var(--qq-t-base) var(--qq-ease), width var(--qq-t-base) var(--qq-spring);
}
.aca-hook-beat-dots span.is-on { width: 20px; background: var(--qq-accent); }

@media (max-width: 899px) {
  #academy-level-content.aca-lesson-open .aca-hook-mascot {
    width: 84px !important; height: 84px !important;
    background: transparent; border: 0; overflow: visible;
  }
  #academy-level-content.aca-lesson-open .aca-hook-text,
  #academy-level-content.aca-lesson-open .aca-hook-beat {
    font-size: clamp(21px, 5.4vw, 28px);
    max-width: 18ch;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   The standing panel — where am I, and what does this unlock.

   Replaces a second copy of the mission card. Deliberately holds no title, no
   description and no button: the mission card two columns over owns all three,
   and duplicating any of them is what made the screen feel unowned.
   ═══════════════════════════════════════════════════════════════════════ */
.aca-standing { display: flex; flex-direction: column; gap: 22px; }

.aca-standing-kicker {
  font-family: var(--qq-font-text);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--qq-accent-bright);
}
.aca-standing-unit h3 {
  margin: 5px 0 2px;
  font-family: var(--qq-font-display);
  font-size: 21px; font-weight: 800;
  letter-spacing: -.03em;
  color: var(--qq-text-1);
}
.aca-standing-pos { margin: 0 0 11px; font-size: 12.5px; color: var(--qq-text-3); }

.aca-standing-track {
  height: 7px;
  border-radius: var(--qq-r-full);
  background: rgba(125,160,200,.1);
  overflow: hidden;
}
.aca-standing-fill {
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--qq-accent-deep), var(--qq-accent-bright));
  /* Grows from zero on render, so returning to this screen shows progress
     happening rather than progress already having happened. */
  animation: standingGrow 1.05s var(--qq-ease) both;
}
.aca-standing-fill.is-goal { background: linear-gradient(90deg, #23a56f, #4bdb9a); }
@keyframes standingGrow { from { transform: scaleX(0); transform-origin: left; } }

.aca-standing-meta { margin: 7px 0 0; font-size: 11.5px; color: var(--qq-text-4); }

.aca-standing-stats { display: flex; gap: 26px; }
.aca-standing-stat { display: flex; flex-direction: column; gap: 1px; }
.aca-standing-stat .qq-num {
  font-family: var(--qq-font-display);
  font-size: 30px; font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.04em; line-height: 1;
  color: var(--qq-text-1);
}
.aca-standing-stat em {
  font-style: normal;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .06em;
  color: var(--qq-text-4);
}
.aca-standing-track--goal { margin-top: -8px; }

.aca-standing-unlock {
  margin: 0;
  padding: 13px 15px;
  border-radius: var(--qq-r-md);
  background: rgba(227,179,65,.06);
  border: 1px solid rgba(227,179,65,.16);
  border-left: 2px solid var(--qq-gold);
  font-size: 12.5px; line-height: 1.5;
  color: var(--qq-text-2);
}
.aca-standing-unlock b { color: var(--qq-gold-bright); font-weight: 700; }

@media (prefers-reduced-motion: reduce) { .aca-standing-fill { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════
   The lesson HUD.

   The grid was `44px minmax(0,1fr) 56px`. The right-hand column has to hold
   five hearts (96px on its own) *and* the step counter, in 56px. So the hearts
   were squeezed to near-invisibility and the counter wrapped — "1 /" on one
   line and "10" on the next, which is why it read as an unintelligible number.

   The column now sizes to its contents, and both items get enough weight to be
   glanceable: hearts are what the player can lose, the counter is how much is
   left. Those are the two facts that matter mid-lesson.
   ═══════════════════════════════════════════════════════════════════════ */
#academy-level-content.aca-lesson-open .aca-lesson-hud,
.aca-lesson-hud {
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 16px;
}

.aca-lesson-hud-right {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── hearts ──────────────────────────────────────────────────────────── */
/* Big enough to feel like something you can lose. */
.aca-hearts-hud { gap: 5px; min-height: 26px; }
.aca-hearts-hud .aca-heart {
  width: 22px; height: 22px;
  font-size: 19px;
  color: rgba(125, 160, 200, .22);
  transition: transform var(--qq-t-base) var(--qq-spring),
              color var(--qq-t-base) var(--qq-ease);
}
.aca-hearts-hud .aca-heart.full {
  color: var(--qq-down);
  text-shadow: 0 0 12px rgba(244, 103, 107, .5);
}
/* The last remaining heart pulses: one mistake left is worth knowing without
   having to count. */
.aca-hearts-hud .aca-heart.full:first-child:last-of-type,
.aca-hearts-hud.is-critical .aca-heart.full {
  animation: heartUrgent 1.4s var(--qq-ease) infinite;
}
@keyframes heartUrgent {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.16); }
}

/* ── step counter ────────────────────────────────────────────────────── */
/* A fraction, laid out as one: the number you are on reads large, the total
   stays quiet, and it can never wrap. */
.aca-lesson-count {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  font-family: var(--qq-font-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--qq-text-3);
  line-height: 1;
}
.aca-lesson-count b {
  font-size: 19px;
  font-weight: 800;
  color: var(--qq-text-1);
  letter-spacing: -.03em;
}
.aca-lesson-count span { font-size: 12.5px; font-weight: 600; }

/* ── progress bar ────────────────────────────────────────────────────── */
.aca-lesson-progress {
  height: 9px;
  border-radius: var(--qq-r-full);
  background: rgba(125, 160, 200, .1);
  overflow: hidden;
}
.aca-lesson-progress-fill {
  background: linear-gradient(90deg, var(--qq-accent-deep), var(--qq-accent-bright));
  transition: width var(--qq-t-slow) var(--qq-ease);
}

@media (max-width: 640px) {
  #academy-level-content.aca-lesson-open .aca-lesson-hud,
  .aca-lesson-hud { grid-template-columns: 38px minmax(0, 1fr) auto; gap: 10px; }
  .aca-hearts-hud .aca-heart { width: 18px; height: 18px; font-size: 16px; }
  .aca-lesson-count b { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .aca-hearts-hud .aca-heart.full { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   The level-up.

   Replaces a 1.4-second grey toast reading "Bir adım daha" that never said
   what changed. The order of the card is the order the questions get asked:
   what did I learn, what did it open, how far am I. The number comes last on
   purpose — a rank badge alone produces "a number went up", which is gone by
   the next screen.
   ═══════════════════════════════════════════════════════════════════════ */
.qq-lvl { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; }
.qq-lvl-scrim {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 45%, rgba(4,6,12,.82), rgba(4,6,12,.96));
  animation: lvlScrim .34s var(--qq-ease) both;
}
@keyframes lvlScrim { from { opacity: 0; } }

.qq-lvl-card {
  position: relative;
  width: min(430px, calc(100vw - 32px));
  padding: 30px 28px 24px;
  text-align: center;
  border-radius: var(--qq-r-xl);
  background: linear-gradient(180deg, rgba(28,40,62,.98), rgba(9,14,24,.99));
  border: 1px solid rgba(227,179,65,.3);
  box-shadow: var(--qq-e-4), 0 0 70px rgba(227,179,65,.14), inset 0 1px 0 rgba(255,255,255,.07);
  animation: lvlCard .6s var(--qq-spring) both;
  overflow: hidden;
}
@keyframes lvlCard {
  from { opacity: 0; transform: translateY(26px) scale(.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* A slow sweep behind the card. Gold is the earned colour and this is the one
   screen that has earned it. */
.qq-lvl-rays {
  position: absolute; inset: -40% -40% auto;
  height: 200%;
  background: conic-gradient(from 0deg, transparent 0 12%, rgba(227,179,65,.12) 14%, transparent 16% 50%,
                             rgba(227,179,65,.09) 52%, transparent 54% 100%);
  animation: lvlRays 14s linear infinite;
  pointer-events: none;
}
@keyframes lvlRays { to { transform: rotate(360deg); } }

.qq-lvl-guide { position: relative; width: 104px; height: 104px; margin: 0 auto 12px; }
.qq-lvl-guide svg { width: 100%; height: 100%; }

.qq-lvl-kicker {
  position: relative;
  margin: 0 0 5px;
  font-family: var(--qq-font-text);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--qq-gold-bright);
}
.qq-lvl-learned {
  position: relative;
  margin: 0 0 10px;
  font-family: var(--qq-font-display);
  font-size: clamp(21px, 4.4vw, 27px);
  font-weight: 800; letter-spacing: -.035em; line-height: 1.14;
  color: var(--qq-text-1);
}
.qq-lvl-rule {
  position: relative;
  margin: 0 auto 16px;
  max-width: 30ch;
  font-size: 13.5px; line-height: 1.5; font-style: italic;
  color: var(--qq-text-2);
}

.qq-lvl-unlocks {
  position: relative;
  margin: 0 0 18px; padding: 0;
  list-style: none;
  display: flex; flex-direction: column; gap: 7px;
  text-align: left;
}
.qq-lvl-unlocks li {
  position: relative;
  padding: 9px 12px 9px 32px;
  border-radius: var(--qq-r-md);
  background: rgba(227,179,65,.07);
  border: 1px solid rgba(227,179,65,.16);
  font-size: 13px; color: var(--qq-text-2);
  animation: qqRise var(--qq-t-base) var(--qq-ease) both;
}
.qq-lvl-unlocks li:nth-child(1) { animation-delay: .30s; }
.qq-lvl-unlocks li:nth-child(2) { animation-delay: .40s; }
.qq-lvl-unlocks li:nth-child(3) { animation-delay: .50s; }
.qq-lvl-unlocks li::before {
  content: "✓";
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--qq-gold-bright); font-weight: 800; font-size: 12px;
}

.qq-lvl-meter {
  position: relative;
  display: flex; justify-content: center; align-items: flex-end; gap: 26px;
  margin-bottom: 6px;
}
.qq-lvl-level, .qq-lvl-xp { display: flex; align-items: baseline; gap: 5px; }
.qq-lvl-level span, .qq-lvl-xp span {
  font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  color: var(--qq-text-4);
}
.qq-lvl-level b {
  font-family: var(--qq-font-display);
  font-size: 40px; font-weight: 800; letter-spacing: -.05em; line-height: 1;
  color: var(--qq-gold-bright);
}
.qq-lvl-xp b {
  font-family: var(--qq-font-display);
  font-size: 24px; font-weight: 800; letter-spacing: -.04em;
  color: var(--qq-up);
}
.qq-lvl-next { position: relative; margin: 0 0 20px; font-size: 12px; color: var(--qq-text-4); }
.qq-lvl-next b { color: var(--qq-text-2); }

.qq-lvl-go {
  position: relative;
  width: 100%; min-height: 48px;
  border-radius: var(--qq-r-md);
  border: 1px solid rgba(255,214,107,.34);
  background: linear-gradient(180deg, var(--qq-gold-bright), var(--qq-gold));
  color: #241902;
  font-family: var(--qq-font-display);
  font-size: 15px; font-weight: 800;
  cursor: pointer;
  box-shadow: 0 4px 0 #8a6a1c, var(--qq-e-2);
}
.qq-lvl-go:active { transform: translateY(3px); box-shadow: 0 1px 0 #8a6a1c; }

.qq-lvl.is-leaving .qq-lvl-card { animation: lvlOut .3s var(--qq-ease-in) both; }
.qq-lvl.is-leaving .qq-lvl-scrim { animation: lvlScrimOut .3s var(--qq-ease-in) both; }
@keyframes lvlOut { to { opacity: 0; transform: translateY(16px) scale(.96); } }
@keyframes lvlScrimOut { to { opacity: 0; } }

body.qq-lvl-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .qq-lvl-rays { animation: none; }
  .qq-lvl-card, .qq-lvl-scrim, .qq-lvl-unlocks li { animation: none; }
}


/* The celebration surface. Sits above the page, never intercepts a click, and
   is removed the moment it finishes — a leftover full-screen canvas silently
   eats every tap underneath it. */
.qq-celebrate-canvas{
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9998;
}

/* ── Account: identity and the danger zone ────────────────────────────────
   The account screen used to put "Çıkış yap" in the same red a delete would
   use, and had no delete at all. Signing out is routine; erasing an account
   is not. They must not look alike. */

/* The email sits in the hero, in the same register as the name it
   belongs to — not in a separate bordered table below. */
.qq-account-email{
  margin: 2px 0 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--qq-text-dim, #94a3b8);
  overflow-wrap: anywhere;
}
.qq-account-email:empty{ display: none; }

/* One plain row, not a boxed table: a label and the same .qq-lang-btn
   pill the header uses, so the control looks identical everywhere it
   appears rather than being redrawn per screen. */
.qq-account-lang-row{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 0;
}
.qq-account-lang-row .qq-account-section-label{ margin-bottom: 0; }
.qq-account-lang-btns{ display: flex; gap: 6px; }

/* Collapsed by default. An irreversible action should take a deliberate act
   to even look at, let alone reach. */
.qq-acc-danger{
  margin-top: 8px;
  border: 1px solid rgba(244,103,107,.22);
  border-radius: 16px;
  background: rgba(244,103,107,.045);
  overflow: hidden;
}
.qq-acc-danger > summary{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 16px;
  cursor: pointer;
  list-style: none;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #f4676b;
}
/* WebKit needs its own marker pseudo-element hidden; every other engine
   (Firefox, and the CSS spec generally) hides the native disclosure triangle
   via list-style on the summary element itself. Setting only the WebKit rule
   left a second, unstyled browser-default triangle sitting next to the
   custom lucide chevron in Firefox — two arrows on one control. */
.qq-acc-danger > summary{ list-style: none; }
.qq-acc-danger > summary::-webkit-details-marker{ display: none; }
.qq-acc-danger > summary i{ transition: transform .2s ease; }
.qq-acc-danger[open] > summary i{ transform: rotate(180deg); }
.qq-acc-danger-body{
  padding: 4px 16px 16px;
  border-top: 1px solid rgba(244,103,107,.16);
}
.qq-acc-danger-body h4{
  margin: 12px 0 6px;
  font-size: 15px;
  font-weight: 700;
  color: var(--qq-text, #e6edf7);
}
.qq-acc-danger-body p{
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--qq-text-dim, #94a3b8);
  max-width: 54ch;
}

/* The confirm dialog. */
.qq-danger-dialog{ position: fixed; inset: 0; z-index: 9997; display: grid; place-items: center; padding: 20px; }
.qq-danger-scrim{ position: absolute; inset: 0; background: rgba(3,7,14,.72); backdrop-filter: blur(3px); }
.qq-danger-card{
  position: relative;
  width: min(430px, 100%);
  padding: 24px;
  border-radius: 20px;
  background: var(--qq-surface-2, #0d1526);
  border: 1px solid rgba(244,103,107,.3);
  box-shadow: 0 28px 70px rgba(0,0,0,.55);
  animation: qqDangerIn .2s ease-out both;
}
@keyframes qqDangerIn{ from{ opacity:0; transform: translateY(10px) scale(.985);} to{ opacity:1; transform:none; } }
.qq-danger-card h3{ margin: 0 0 8px; font-size: 18px; font-weight: 750; color: var(--qq-text, #e6edf7); }
.qq-danger-lead{ margin: 0 0 18px; font-size: 13px; line-height: 1.6; color: var(--qq-text-dim, #94a3b8); }
.qq-danger-field{ display: block; margin-bottom: 14px; }
.qq-danger-field > span{
  display: block; margin-bottom: 6px;
  font-size: 12px; font-weight: 650; color: var(--qq-text-dim, #94a3b8);
}
.qq-danger-field > span b{ color: #f4676b; letter-spacing: .06em; }
.qq-danger-field input{
  width: 100%;
  padding: 11px 13px;
  border-radius: 11px;
  border: 1px solid var(--qq-border, rgba(148,163,184,.2));
  background: var(--qq-surface-1, #0a1120);
  color: var(--qq-text, #e6edf7);
  font-size: 14px;
  font-family: inherit;
}
.qq-danger-field input:focus{ outline: 2px solid rgba(244,103,107,.5); outline-offset: 1px; border-color: transparent; }
.qq-danger-error{ margin: 0 0 12px; font-size: 12.5px; font-weight: 600; color: #f4676b; }
.qq-danger-actions{ display: flex; gap: 10px; justify-content: flex-end; align-items: stretch; margin-top: 4px; }
.qq-danger-actions .qq-acc-btn{ flex: 0 0 auto; }
/* In the two-button action row (e.g. the "Şifreni unuttun?" modal) the primary
   button must NOT take the full width its standalone style asks for — that
   stretched it across the row and shoved "Vazgeç" out of alignment. */
.qq-danger-actions .qq-acc-btn--go{ width: auto; }
.qq-danger-actions .qq-acc-btn--danger:disabled{ opacity: .42; cursor: not-allowed; }

/* ── Recovery code ────────────────────────────────────────────────────────
   The one dialog in the product that must not be dismissible by accident:
   the code is shown once and cannot be retrieved. No scrim click, no Escape,
   and the continue button stays disabled until the player says they have it. */
.qq-recovery{ position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; padding: 20px; }
.qq-recovery-scrim{ position: absolute; inset: 0; background: rgba(3,7,14,.82); backdrop-filter: blur(4px); }
.qq-recovery-card{
  position: relative;
  width: min(470px, 100%);
  padding: 26px;
  border-radius: 22px;
  background: var(--qq-surface-2, #0d1526);
  border: 1px solid rgba(227,179,65,.32);
  box-shadow: 0 30px 80px rgba(0,0,0,.6);
}
.qq-recovery-kicker{
  margin: 0 0 6px; font-size: 11.5px; font-weight: 750;
  letter-spacing: .14em; text-transform: uppercase; color: #e3b341;
}
.qq-recovery-card h2{
  margin: 0 0 10px; font-size: 20px; font-weight: 750; line-height: 1.25;
  color: var(--qq-text-1, #f4f7fb);
}
.qq-recovery-lead{
  margin: 0 0 18px; font-size: 13px; line-height: 1.62;
  color: var(--qq-text-2, #9fb0c9);
}
/* Monospace and generously spaced: this string gets read off a screen and
   typed back in by hand, sometimes from a photo. */
.qq-recovery-code{
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: clamp(15px, 3.4vw, 20px);
  font-weight: 700;
  letter-spacing: .1em;
  text-align: center;
  padding: 16px 12px;
  border-radius: 14px;
  background: var(--qq-bg-1, #070b14);
  border: 1px dashed rgba(227,179,65,.42);
  color: #ffd66b;
  user-select: all;
  overflow-wrap: anywhere;
}
.qq-recovery-tools{ display: flex; gap: 10px; margin: 14px 0 16px; }
.qq-recovery-tools .qq-acc-btn{ flex: 1; }
.qq-recovery-ack{
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 16px;
  font-size: 13px; color: var(--qq-text-2, #9fb0c9); cursor: pointer;
}
.qq-recovery-ack input{ margin-top: 2px; width: 16px; height: 16px; accent-color: #e3b341; }
.qq-acc-btn--go{
  width: 100%;
  background: linear-gradient(180deg,#e3b341,#c9922c);
  border-color: #b8862a;
  color: #16120a;
  font-weight: 750;
}
.qq-acc-btn--go:disabled{ opacity: .4; cursor: not-allowed; }
.qq-forgot-link{
  display: block; width: 100%; margin-top: 14px;
  background: none; border: 0; padding: 4px;
  font-size: 12.5px; font-weight: 600; color: var(--qq-text-3, #61728c);
  cursor: pointer; transition: color .16s ease;
}
.qq-forgot-link:hover{ color: var(--qq-text-2, #9fb0c9); text-decoration: underline; }

/* The evidence counter. The scene asks for a specific number of pieces and
   used to accept one, then mark the answer wrong — the requirement was only
   visible in the failure message. */
.aca-why-need{
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 650;
  color: var(--qq-gold, #e3b341);
}
.aca-why-count{
  margin: 10px 0 4px;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: .04em;
  color: var(--qq-text-3, #61728c);
  transition: color .18s ease;
}
.aca-why-count.is-ready{ color: #4bdb9a; }
.aca-why-count.is-over{ color: #f4676b; }

/* ── The guide inside its frame ───────────────────────────────────────────
   styles.css sizes the avatar box at 58px and lets the drawing fill it, so
   it was centred by construction. academy.css then grows the box to 80px and
   pins the drawing to 52px — with no centring declared anywhere, a 52px
   child in an 80px box lands at the top-left corner, 14px off on both axes.

   That is the crooked mascot in every question scene: not a drawing problem,
   a box that grew and left its contents behind. */
.aca-orion-avatar{
  display: grid !important;
  place-items: center !important;
}
.aca-orion-avatar .mascot-svg,
.aca-orion-avatar > svg{
  /* Beat the !important width/height above without touching them: the
     drawing keeps its size, it just sits in the middle of the frame. */
  grid-area: 1 / 1;
  margin: auto;
}
.aca-orion-glow{
  grid-area: 1 / 1;
  /* The glow was absolutely positioned against the old, smaller box. Let it
     track the frame it is actually in. */
  place-self: center;
  width: 100%;
  height: 100%;
}

/* ── Getting it right ─────────────────────────────────────────────────────
   The verdict used to be a grey strip with the word DOĞRU in it. Nothing
   moved, nothing was earned on screen, and the guide who asked the question
   said nothing back. */
.aca-quiz-verdict{
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 12px 0;
  padding: 14px 16px;
  border-radius: 16px;
  border: 1px solid var(--qq-border, rgba(125,160,200,.14));
  background: var(--qq-surface-2, #0d1526);
  animation: qqVerdictIn .34s cubic-bezier(.34,1.4,.5,1) both;
}
@keyframes qqVerdictIn{
  from{ opacity: 0; transform: translateY(9px) scale(.975); }
  to  { opacity: 1; transform: none; }
}
.aca-quiz-verdict.is-correct{
  border-color: rgba(75,219,154,.42);
  background: linear-gradient(180deg, rgba(75,219,154,.10), rgba(75,219,154,.03));
}
.aca-quiz-verdict.is-wrong{
  border-color: rgba(244,103,107,.38);
  background: linear-gradient(180deg, rgba(244,103,107,.09), rgba(244,103,107,.02));
}

/* The mark draws itself. A glyph that appears is a label; one that is drawn
   reads as somebody marking your work while you watch. */
.aca-qv-mark{ width: 28px; height: 28px; flex: 0 0 28px; overflow: visible; }
.aca-qv-ring, .aca-qv-tick{ fill: none; stroke-linecap: round; stroke-linejoin: round; }
.aca-qv-ring{ stroke-width: 1.6; opacity: .34; stroke-dasharray: 63; stroke-dashoffset: 63;
  animation: qqDraw .42s ease-out .04s forwards; }
.aca-qv-tick{ stroke-width: 2.6; stroke-dasharray: 26; stroke-dashoffset: 26;
  animation: qqDraw .3s cubic-bezier(.5,0,.3,1) .22s forwards; }
@keyframes qqDraw{ to{ stroke-dashoffset: 0; } }
.is-correct .aca-qv-ring, .is-correct .aca-qv-tick{ stroke: #4bdb9a; }
.is-wrong   .aca-qv-ring, .is-wrong   .aca-qv-tick{ stroke: #f4676b; }

.aca-qv-body{ display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.aca-qv-body > b{ font-size: 14.5px; font-weight: 750; letter-spacing: .01em; }
.is-correct .aca-qv-body > b{ color: #4bdb9a; }
.is-wrong   .aca-qv-body > b{ color: #f4676b; }
.aca-qv-body > span{ font-size: 13px; line-height: 1.55; color: var(--qq-text-2, #9fb0c9); }
.aca-qv-body em{ font-style: normal; font-weight: 650; color: var(--qq-text-1, #f4f7fb); }

/* What it was worth, arriving a beat after the mark so the two do not
   compete for the same instant. */
.aca-qv-xp{
  flex: 0 0 auto;
  align-self: center;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(227,179,65,.13);
  border: 1px solid rgba(227,179,65,.34);
  color: #e3b341;
  font-size: 12.5px;
  font-weight: 750;
  white-space: nowrap;
  animation: qqVerdictIn .3s cubic-bezier(.34,1.4,.5,1) .26s both;
}

/* The answer area itself acknowledges the result, so the feedback is not
   confined to one strip in the corner. */
.aca-answered-ok .aca-option-card.is-correct,
.aca-answered-ok .duo-option-card.correct{
  border-color: rgba(75,219,154,.6) !important;
  box-shadow: 0 0 0 1px rgba(75,219,154,.34), 0 8px 26px rgba(75,219,154,.16);
  animation: qqAnswerLock .5s cubic-bezier(.34,1.5,.5,1) both;
}
@keyframes qqAnswerLock{
  0%  { transform: scale(1); }
  38% { transform: scale(1.022); }
  100%{ transform: scale(1); }
}

@media (prefers-reduced-motion: reduce){
  .aca-quiz-verdict, .aca-qv-xp,
  .aca-answered-ok .aca-option-card.is-correct,
  .aca-answered-ok .duo-option-card.correct{ animation: none !important; }
  .aca-qv-ring, .aca-qv-tick{ stroke-dashoffset: 0 !important; animation: none !important; }
}

/* ── Sign-up: the 18+ confirmation ────────────────────────────────────────
   The Terms have always required it; nothing ever asked. Deliberately plain —
   a consent row that shouts reads as a trick, and this one has to be read. */
.qq-age-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 22px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #94a3b8;
  cursor: pointer;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid transparent;
  transition: border-color .2s ease, background .2s ease;
}
.qq-age-row input[type="checkbox"] {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  accent-color: #22d3ee;
  cursor: pointer;
}
.qq-age-row a { color: #7dd3fc; text-decoration: underline; text-underline-offset: 2px; }
.qq-age-row.is-missing {
  border-color: rgba(248, 113, 113, .55);
  background: rgba(248, 113, 113, .08);
}

/* ── The standing disclaimer ──────────────────────────────────────────────
   Quiet on purpose. Loud enough to read, calm enough that it does not compete
   with the lesson — a warning that shouts gets tuned out, and this one needs
   to survive being seen every day. Sits directly above the mobile nav. */
.qq-risk-strip {
  position: fixed;
  left: 0; right: 0;
  /* --qq-mnav-h already includes env(safe-area-inset-bottom); adding it again
     here floated the strip a home-indicator's height (34px) above the nav on
     iPhones, leaving a gap and stealing that much content space. */
  bottom: var(--qq-mnav-h, 62px);
  min-height: var(--qq-risk-h, 0px);
  box-sizing: border-box;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 5px 12px;
  font-size: 10.5px;
  line-height: 1.35;
  letter-spacing: .01em;
  color: #7c8ba1;
  background: rgba(4, 7, 12, .94);
  border-top: 1px solid rgba(148, 163, 184, .10);
  text-align: center;
  pointer-events: auto;
}
.qq-risk-strip a { color: #94a3b8; text-decoration: underline; text-underline-offset: 2px; }
/* Full-screen moments own the whole viewport; a strip pinned over a lesson
   canvas or the cold open would be furniture in the wrong room. */
body:has(#academy-level-content.aca-lesson-open) .qq-risk-strip,
body:has(#qq-login:not(.hidden)) .qq-risk-strip { display: none; }
/* 761px, not 821px: the bottom nav disappears at 760px, so between 761 and 820
   the strip was floating 62px above the bottom with nothing underneath it. */
@media (min-width: 761px) {
  .qq-risk-strip { bottom: 0; }
}

/* ── Sign-up handoff ──────────────────────────────────────────────────────
   Covers the gap between the account being created and the first screen
   arriving. Full-viewport by design: a partial cover still lets the reader
   see an empty app underneath, which is the impression this exists to fix. */
.qq-handoff {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #05070a;
  animation: qq-handoff-in .22s ease both;
}
.qq-handoff.is-out { animation: qq-handoff-out .3s ease both; }
@keyframes qq-handoff-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes qq-handoff-out { to { opacity: 0; } }
.qq-handoff-inner { text-align: center; padding: 24px; }
.qq-handoff-mark { display: flex; justify-content: center; margin-bottom: 22px; min-height: 76px; }
.qq-handoff-title {
  font-size: 19px;
  font-weight: 600;
  color: #f1f5f9;
  letter-spacing: -0.01em;
}
.qq-handoff-sub {
  margin-top: 7px;
  font-size: 13px;
  color: #64748b;
}
