:root {
  --gold: #d4af5a;
  --gold-2: #f3dc95;
  --gold-dim: #8a6f2f;
  --ink: #070a12;
  --panel: rgba(8, 11, 21, 0.86);
  --panel-2: rgba(14, 18, 32, 0.9);
  --text: #ece6d6;
  --muted: #a7aec0;
  --line: rgba(212, 175, 90, 0.35);
  --class: var(--gold);
  --serif: "Cinzel", "Trajan Pro", Georgia, serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

* { box-sizing: border-box; }
html { color-scheme: dark; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100dvh;
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; }
[hidden] { display: none !important; }

/* Background */
.bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; background: var(--ink); }
.bg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 35%; }
.bg-lqip { filter: blur(24px); transform: scale(1.1); }
.bg-img { opacity: 0; transition: opacity 900ms ease; animation: bg-drift 60s ease-in-out infinite alternate; }
.bg-img.loaded { opacity: 1; }
.bg-vignette {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 50% 20%, rgba(7,10,18,0) 0%, rgba(7,10,18,0.35) 55%, rgba(7,10,18,0.85) 100%),
    linear-gradient(180deg, rgba(7,10,18,0.25) 0%, rgba(7,10,18,0.15) 35%, rgba(7,10,18,0.9) 100%);
}
@keyframes bg-drift { from { transform: scale(1.02) translate3d(0,0,0); } to { transform: scale(1.08) translate3d(-1%, -1%, 0); } }

.flash { position: fixed; inset: 0; z-index: 50; pointer-events: none; background: #fff; opacity: 0; }
.flash.go { animation: flash 700ms ease-out forwards; }
@keyframes flash { 0% { opacity: 0.9; } 100% { opacity: 0; } }

/* Layout */
#app { min-height: calc(100dvh - 150px); display: grid; place-items: center; padding: clamp(24px, 5vh, 56px) 16px 24px; }
.view { width: 100%; max-width: 760px; text-align: center; animation: view-in 600ms var(--ease-out) both; }
@keyframes view-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.eyebrow {
  font-family: var(--serif); font-weight: 700; font-size: 12px; letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 10px;
}
h1, h2, h3 { font-family: var(--serif); font-weight: 900; line-height: 1.05; margin: 0; }
.gold-text, .hero-title, .reveal-name, .card-class {
  background: linear-gradient(180deg, #fff3cf 0%, var(--gold-2) 40%, var(--gold) 70%, #a9822f 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 0 rgba(0,0,0,0.35)) drop-shadow(0 10px 30px rgba(0,0,0,0.6));
}

/* Landing */
.landing .logo { width: clamp(220px, 34vw, 300px); height: auto; margin: 0 auto 6px; filter: drop-shadow(0 12px 30px rgba(0,0,0,0.6)); animation: logo-in 900ms var(--ease-out) both; }
@keyframes logo-in { from { opacity: 0; transform: translateY(-10px) scale(0.96); } to { opacity: 1; transform: none; } }
.hero-title { font-size: clamp(34px, 7vw, 64px); margin: 4px 0 6px; }
.hero-sub { font-family: var(--serif); font-weight: 700; font-size: clamp(15px, 2.4vw, 22px); letter-spacing: 0.08em; color: #f3e7cb; margin: 0 0 28px; text-wrap: balance; }
.hero-title em { font-style: normal; }
.lede { font-size: clamp(16px, 2.2vw, 19px); color: var(--text); max-width: 560px; margin: 0 auto 26px; text-wrap: pretty; }
.lede strong { color: #fff; font-weight: 600; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px; padding: 0 26px; border-radius: 6px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text);
  font-family: var(--serif); font-weight: 700; font-size: 15px; letter-spacing: 0.08em; text-transform: uppercase;
  text-decoration: none; cursor: pointer; transition: transform 160ms var(--ease-out), box-shadow 200ms, filter 200ms;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { transform: translateY(-1px); filter: brightness(1.08); }
.btn:active { transform: translateY(0) scale(0.99); }
.btn:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; }
.btn-primary {
  color: #1b1405; border-color: #f2d78a;
  background: linear-gradient(180deg, #fbe7ad 0%, #e2b95e 45%, #c9972f 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.6), 0 8px 30px rgba(212,175,90,0.28), 0 2px 6px rgba(0,0,0,0.5);
}
.btn-primary:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,0.6), 0 10px 40px rgba(212,175,90,0.45), 0 2px 6px rgba(0,0,0,0.5); }
.btn-ghost { background: transparent; border-color: rgba(255,255,255,0.18); }
.x-logo { width: 18px; height: 18px; fill: currentColor; }

/* Landing fills the viewport; the read-only line sits at the bottom edge, the rest stays centered. */
.view.landing { display: flex; flex-direction: column; align-items: center; min-height: calc(100dvh - 150px - clamp(48px, 10vh, 80px)); }
/* Three auto margins split the free space evenly: above the logo, logo-to-headline, headline-to-button,
   so the headline sits centered between the logo and the button. */
.view.landing .logo { margin-top: auto; }
.view.landing .hero-title { margin-top: auto; }
.view.landing .hero-sub { margin-bottom: auto; }
.handle-form { margin-top: auto; display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch; gap: 10px; width: min(100%, 520px); }
.handle-field { flex: 1 1 240px; display: flex; align-items: center; gap: 8px; min-height: 56px; padding: 0 16px; border-radius: 8px; background: rgba(8, 11, 21, 0.86); border: 1px solid #3a3320; box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 10px 30px rgba(0,0,0,0.4); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); cursor: text; }
.handle-field:focus-within { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(212,175,90,0.22); }
.handle-field .x-logo { width: 18px; height: 18px; fill: var(--muted); flex: none; }
.handle-at { color: var(--gold-2); font-weight: 700; font-size: 18px; }
.handle-field input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: #fff; font: 500 18px/1 var(--sans); letter-spacing: 0.01em; }
.handle-field input::placeholder { color: #6f6a5c; }
.btn-connect { flex: 0 0 auto; }
.fine { margin: 14px auto 0; color: var(--muted); font-size: 13px; letter-spacing: 0.04em; }

@keyframes chip-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Loading */
.loading { max-width: 640px; }
.loading-user { display: flex; justify-content: center; align-items: center; gap: 10px; color: #d6d3c8; font-size: 15px; margin-bottom: 18px; text-shadow: 0 1px 6px rgba(0,0,0,0.8); }
.loading-user b { color: #fff; font-weight: 600; }
.avatar { width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid var(--gold); object-fit: cover; }
.loading-title { position: relative; display: table; margin-left: auto; margin-right: auto; font-size: clamp(28px, 5vw, 40px); color: var(--gold-2); text-shadow: 0 2px 20px rgba(0,0,0,0.7); margin-bottom: 22px; }
/* The dots hang off the end of the word so "Loading" itself is what gets centered. */
.dots { position: absolute; left: 100%; top: 0; }
.dots i { font-style: normal; animation: dot 1.4s infinite; opacity: 0; }
.dots i:nth-child(2) { animation-delay: 0.2s; }
.dots i:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot { 0%, 60%, 100% { opacity: 0; } 30% { opacity: 1; } }
.bar {
  position: relative; height: 26px; border-radius: 4px; overflow: hidden;
  background: linear-gradient(180deg, #05070d, #0f1320); border: 2px solid var(--gold-dim);
  box-shadow: 0 0 0 1px #000, inset 0 2px 8px rgba(0,0,0,0.9), 0 6px 30px rgba(0,0,0,0.6);
}
.bar-fill {
  height: 100%; width: 0%;
  background: linear-gradient(180deg, #ffe9a8 0%, #e3b558 35%, #b98a2e 65%, #8d641d 100%);
  box-shadow: 0 0 20px rgba(227,181,88,0.7), inset 0 1px 0 rgba(255,255,255,0.6);
  transition: width 400ms var(--ease-out);
}
.bar-sheen { position: absolute; inset: 0; background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.25) 50%, transparent 100%); background-size: 40% 100%; background-repeat: no-repeat; animation: sheen 2.2s linear infinite; mix-blend-mode: screen; }
@keyframes sheen { from { background-position: -60% 0; } to { background-position: 160% 0; } }
.tip { min-height: 48px; margin: 18px auto 0; color: #fff3cf; font-size: 16px; text-shadow: 0 1px 8px rgba(0,0,0,0.85); max-width: 520px; text-wrap: pretty; }
.tip.swap { animation: tip-in 450ms var(--ease-out) both; }
@keyframes tip-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Class frame */
.frame {
  --size: 200px;
  position: relative; width: var(--size); height: var(--size); margin: 0 auto; border-radius: 50%;
  border: calc(var(--size) * 0.035) solid var(--class);
  background: radial-gradient(circle at 50% 38%, #1c2438 0%, #0a0d16 72%);
  box-shadow: 0 0 0 2px #000, 0 0 calc(var(--size) * 0.3) color-mix(in srgb, var(--class) 45%, transparent), inset 0 0 calc(var(--size) * 0.2) rgba(0,0,0,0.8);
  display: grid; place-items: center; color: var(--class);
  transition: border-color 120ms, box-shadow 120ms, color 120ms;
}
.frame-icon { width: 58%; height: 58%; display: grid; place-items: center; filter: drop-shadow(0 4px 10px rgba(0,0,0,0.7)); }
.frame-icon svg { width: 100%; height: 100%; }
.frame-xl { --size: clamp(190px, 44vw, 260px); }
.frame-lg { --size: clamp(110px, 26vw, 150px); }
.frame-ring { position: absolute; inset: -6px; border-radius: 50%; border: 3px solid var(--class); opacity: 0; pointer-events: none; }
.frame.land { animation: land 700ms var(--ease-out) both; }

/* Reveal reel: class frames on the faces of a cylinder, spun around the vertical axis */
/* Sized so the whole cylinder (about 4x the face) fits inside the narrowest viewport: nothing gets clipped. */
.reel-stage { --reel-size: clamp(76px, 18vw, 140px); perspective: 900px; perspective-origin: 50% 50%; width: 100%; height: calc(var(--reel-size) + 16px); display: grid; place-items: center; margin: 0 auto; overflow: visible; }
.reel-stage.land { animation: land 700ms var(--ease-out) both; }
.reel { position: relative; width: var(--reel-size); height: var(--reel-size); transform-style: preserve-3d; will-change: transform; }
.reel-face { position: absolute; inset: 0; margin: 0; --size: var(--reel-size); backface-visibility: hidden;
  transform: rotateY(calc(var(--i) * 360deg / var(--n))) translateZ(calc(var(--reel-size) * 1.95)); transition: none; }
.reel-face.land { animation: none; }
.reel-face.land .frame-ring { animation: ring 900ms ease-out 80ms both; }
.frame.land .frame-ring { animation: ring 900ms ease-out 80ms both; }
.frame.spin .frame-icon { animation: icon-tick 120ms linear; }
@keyframes icon-tick { from { transform: translateY(-14%) scale(0.9); opacity: 0.3; } to { transform: none; opacity: 1; } }
@keyframes land { 0% { transform: scale(0.8); } 55% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes ring { 0% { opacity: 0.9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.9); } }

/* Reveal */
.reveal { max-width: 720px; position: relative; }
.reveal .reel-stage, .reveal-eyebrow, .reveal-name, .reveal-tag { position: relative; z-index: 1; }
/* Shuffle-and-throw: the person's posts as X cards in a deck, riffled, then grabbed and flung off-screen. */
.toss-stage { position: absolute; left: 50%; top: calc(100% + clamp(80px, 16vh, 220px)); width: 0; height: 0; pointer-events: none; z-index: 0; }
.toss-card { --w: min(340px, 82vw); position: absolute; left: calc(var(--w) / -2); top: 0; width: var(--w); text-align: left; z-index: 0;
  transform: translate(var(--jx, 0px), calc(var(--i) * -2px)) rotate(var(--jr, 0deg)); box-shadow: 0 12px 34px rgba(0,0,0,0.65); transition: transform 150ms var(--ease-out); will-change: transform; }
.toss-card .xpost-link { padding: 10px 12px 8px; }
.toss-card .xpost-text { font-size: 13.5px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.toss-card .xpost-actions { font-size: 12px; margin-top: 8px; }
.toss-card .xa svg { width: 16px; height: 16px; }
.toss-stage.shuffle .toss-card { animation: riffle 900ms ease-in-out both; animation-delay: calc(var(--i) * 40ms); }
@keyframes riffle {
  0%, 100% { transform: translate(var(--jx, 0px), calc(var(--i) * -2px)) rotate(var(--jr, 0deg)); }
  35% { transform: translate(calc(var(--jx, 0px) - 90px), calc(var(--i) * -2px - 12px)) rotate(-10deg); }
  70% { transform: translate(calc(var(--jx, 0px) + 70px), calc(var(--i) * -2px + 6px)) rotate(8deg); }
}
.toss-card.grab { transform: translate(var(--jx, 0px), calc(var(--i) * -2px - 30px)) scale(1.08) rotate(-6deg); z-index: 3; box-shadow: 0 30px 50px rgba(0,0,0,0.7); transition: transform 300ms var(--ease-out), box-shadow 300ms; }
.toss-card.throw { animation: toss 1200ms cubic-bezier(0.22, 0.6, 0.3, 1) forwards; z-index: 3; }
@keyframes toss {
  0% { transform: translate(var(--jx, 0px), calc(var(--i) * -2px - 30px)) scale(1.08) rotate(-6deg); opacity: 1; }
  75% { opacity: 1; }
  100% { transform: translate(var(--tx, 60vw), var(--ty, -40vh)) scale(0.8) rotate(var(--rot, 40deg)); opacity: 0; }
}
.reveal-eyebrow { margin-bottom: 26px; font-size: 14px; }
.reveal-name { font-size: clamp(42px, 10vw, 84px); margin-top: 26px; opacity: 0; min-height: 1.1em; }
.reveal-name.stamp { animation: stamp 650ms var(--ease-out) both; }
@keyframes stamp { 0% { opacity: 0; transform: scale(1.8); filter: blur(6px); } 60% { opacity: 1; transform: scale(0.98); filter: blur(0); } 100% { opacity: 1; transform: scale(1); } }
.reveal-tag { font-family: var(--serif); font-weight: 700; font-size: clamp(18px, 3.4vw, 26px); color: #f3e7cb; margin: 10px 0 0; opacity: 0; min-height: 1.4em; }
.reveal-tag.in { animation: tip-in 500ms var(--ease-out) both; }

/* Result: three floating columns */
.view.result { max-width: 1340px; text-align: left; }
.sheet {
  display: grid; align-items: start; gap: clamp(18px, 2vw, 28px);
  grid-template-columns: minmax(0, 0.9fr) minmax(340px, 1.15fr) minmax(0, 1fr);
}
.panel {
  position: relative; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.8), 0 30px 80px rgba(0,0,0,0.55), 0 2px 0 rgba(255,255,255,0.03) inset;
  backdrop-filter: blur(12px) saturate(1.1); -webkit-backdrop-filter: blur(12px) saturate(1.1);
}
.panel::before { content: ""; position: absolute; inset: 5px; border-radius: 7px; border: 1px solid rgba(212,175,90,0.16); pointer-events: none; }
.panel::after { content: ""; position: absolute; left: 12px; right: 12px; top: -1px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--class), transparent); }
.col-desc, .col-sheet { padding: clamp(20px, 2.4vw, 30px); }
.col-desc { animation: col-left 800ms var(--ease-out) 120ms both; }
/* Race / gender picker floats under the description; the other two columns span both rows. */
.col-portrait, .col-sheet { grid-row: 1 / span 2; }
/* Row 1 hugs the description; the tall spanning columns push their extra height into row 2 only. */
.sheet { grid-template-rows: auto 1fr; }
.col-char { grid-column: 1; grid-row: 2; align-self: start; padding: clamp(16px, 2vw, 22px); animation: col-left 800ms var(--ease-out) 240ms both; }
.char-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.char-field { display: grid; gap: 6px; font-family: var(--serif); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }
.select { width: 100%; font: 500 14px/1.2 var(--sans); color: #f3e7cb; background: #0d1119; border: 1px solid #3a3320; border-radius: 6px; padding: 8px 10px; cursor: pointer; }
.select:focus { outline: 2px solid var(--gold); outline-offset: 1px; }
.col-sheet { animation: col-right 800ms var(--ease-out) 220ms both; }
.col-portrait { position: sticky; top: 24px; animation: col-up 800ms var(--ease-out) both; }
@keyframes col-left { from { opacity: 0; transform: translate3d(-28px, 12px, 0); } to { opacity: 1; transform: none; } }
@keyframes col-right { from { opacity: 0; transform: translate3d(28px, 12px, 0); } to { opacity: 1; transform: none; } }
@keyframes col-up { from { opacity: 0; transform: translate3d(0, 28px, 0) scale(0.98); } to { opacity: 1; transform: none; } }

.col .section-title:first-child { margin-top: 0; }

/* Portrait: an isolated class cutout floating on the background (no panel) */
.portrait { margin: 0; padding: 0; animation: float 7s ease-in-out 900ms infinite; }
@keyframes float { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(0, -7px, 0); } }
.portrait-art { position: relative; width: 100%; aspect-ratio: 3 / 4; max-width: 100%; display: grid; place-items: end center; }
.portrait-glow { display: none; }
.portrait-ground { position: absolute; left: 14%; right: 14%; bottom: 0.5%; height: 8%; border-radius: 50%; pointer-events: none; background: radial-gradient(closest-side, rgba(0,0,0,0.8), rgba(0,0,0,0.35) 55%, transparent 80%); }
.portrait-art img { position: relative; z-index: 1; height: 100%; width: auto; max-width: 100%; object-fit: contain; object-position: bottom center; filter: drop-shadow(0 26px 34px rgba(0,0,0,0.75)) drop-shadow(0 0 2px rgba(0,0,0,0.6)); }
.portrait-fallback { position: absolute; inset: 0; display: grid; place-items: center; z-index: 1; }
.portrait-fallback .frame { --size: clamp(160px, 66%, 260px); }
.portrait-fallback .frame.has-img { --size: clamp(170px, 70%, 280px); }
.nameplate { padding: 20px 8px 0; text-align: center; }
.nameplate .eyebrow { margin-bottom: 6px; }
.card-class { font-size: clamp(40px, 4.6vw, 66px); }
.card-spec { font-family: var(--serif); font-weight: 700; font-size: clamp(14px, 1.3vw, 17px); color: #f3e7cb; margin: 8px 0 0; }

.actions { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 14px; }
.actions .btn-x, .actions #btn-yours { grid-column: 1 / -1; }
.actions .btn { padding: 0 16px; font-size: 14px; }
.actions .btn:not(.btn-primary) { background: rgba(8, 11, 21, 0.82); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }

/* Description column */
/* Verdict: a clean pull quote. Cinzel has no lowercase, so long verdicts go in the sans, with a class-colored quote mark. */
.verdict { position: relative; font-family: var(--sans); font-weight: 600; font-size: clamp(17px, 1.45vw, 20px); line-height: 1.4; color: #fff; margin: 0 0 22px; padding: 4px 0 20px 30px; border-bottom: 1px solid var(--line); text-wrap: pretty; }
.verdict::before { content: "\201C"; position: absolute; left: 0; top: -6px; font-family: var(--serif); font-weight: 900; font-size: 44px; line-height: 1; color: var(--class); }
.roast { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.roast li { position: relative; padding-left: 22px; font-size: 16px; line-height: 1.45; color: var(--text); text-wrap: pretty; }
.roast li::before { content: "◆"; position: absolute; left: 2px; top: 0.45em; font-size: 9px; color: var(--class); }
.section-title { font-size: 13px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--gold); margin: 28px 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }

/* Character sheet column */
.sheet-level { margin: -4px 0 14px; font-family: var(--serif); font-weight: 700; font-size: 15px; color: #f3e7cb; }
.sheet-level b { color: var(--class); font-weight: 700; }
.stats { margin: 0; display: grid; gap: 0; border: 1px solid rgba(255,255,255,0.07); border-radius: 6px; overflow: hidden; }
.stats div { display: flex; flex-direction: column; gap: 3px; padding: 11px 14px; background: rgba(255,255,255,0.025); }
.stats div:nth-child(even) { background: rgba(255,255,255,0.05); }
.stats dt { font-family: var(--serif); font-weight: 700; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--gold); }
.stats dd { margin: 0; color: #fff; font-size: 15px; }
.evidence { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.evidence .xpost-text { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
/* X post card, laid out like the real timeline: avatar left, name/handle/time line, text, action row. */
.xpost { background: #000; border: 1px solid #2f3336; border-radius: 16px; color: #e7e9ea; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; transition: border-color 150ms, transform 150ms, box-shadow 150ms; }
.xpost-link { display: flex; gap: 10px; padding: 12px 14px 10px; color: inherit; text-decoration: none; border-radius: 16px; }
.xpost:has(a.xpost-link):hover { border-color: #6b7280; transform: translateY(-1px); box-shadow: 0 8px 24px rgba(0,0,0,0.5); }
.xpost a.xpost-link:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.xpost-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none; }
.xpost-avatar-fallback { display: grid; place-items: center; background: linear-gradient(180deg, #3a4150, #1b1f28); color: #fff; font-weight: 600; font-size: 16px; }
.xpost-body { flex: 1; min-width: 0; }
.xpost-head { display: flex; align-items: center; gap: 4px; font-size: 15px; line-height: 1.3; white-space: nowrap; min-width: 0; }
.xpost-name { font-weight: 700; color: #e7e9ea; overflow: hidden; text-overflow: ellipsis; }
.xpost-handle, .xpost-dot, .xpost-time { color: #71767b; font-weight: 400; }
.xpost-handle { overflow: hidden; text-overflow: ellipsis; }
.xpost-more { margin-left: auto; padding-left: 8px; color: #71767b; letter-spacing: 1px; font-size: 13px; }
.xpost-text { margin: 2px 0 0; font-size: 15px; line-height: 1.35; color: #e7e9ea; white-space: pre-wrap; overflow-wrap: anywhere; }
.xpost-actions { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; color: #71767b; font-size: 13px; }
.xa { display: inline-flex; align-items: center; gap: 5px; }
.xa svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; display: block; }
.xa i { font-style: normal; }
.xa-right { display: inline-flex; gap: 14px; }
.toss-stage.shuffle .toss-card { animation: riffle 900ms ease-in-out both; animation-delay: calc(var(--i) * 40ms); }
@keyframes riffle {
  0%, 100% { transform: translate(var(--jx, 0px), calc(var(--i) * -2px)) rotate(var(--jr, 0deg)); }
  35% { transform: translate(calc(var(--jx, 0px) - 90px), calc(var(--i) * -2px - 12px)) rotate(-10deg); }
  70% { transform: translate(calc(var(--jx, 0px) + 70px), calc(var(--i) * -2px + 6px)) rotate(8deg); }
}
.toss-card.grab { transform: translate(var(--jx, 0px), calc(var(--i) * -2px - 30px)) scale(1.08) rotate(-6deg); z-index: 3; box-shadow: 0 30px 50px rgba(0,0,0,0.7); transition: transform 300ms var(--ease-out), box-shadow 300ms; }
.toss-card.throw { animation: toss 1200ms cubic-bezier(0.22, 0.6, 0.3, 1) forwards; z-index: 3; }
@keyframes toss {
  0% { transform: translate(var(--jx, 0px), calc(var(--i) * -2px - 30px)) scale(1.08) rotate(-6deg); opacity: 1; }
  75% { opacity: 1; }
  100% { transform: translate(var(--tx, 60vw), var(--ty, -40vh)) scale(0.8) rotate(var(--rot, 40deg)); opacity: 0; }
}
.reveal-eyebrow { margin-bottom: 26px; font-size: 14px; }
.reveal-name { font-size: clamp(42px, 10vw, 84px); margin-top: 26px; opacity: 0; min-height: 1.1em; }
.reveal-name.stamp { animation: stamp 650ms var(--ease-out) both; }
@keyframes stamp { 0% { opacity: 0; transform: scale(1.8); filter: blur(6px); } 60% { opacity: 1; transform: scale(0.98); filter: blur(0); } 100% { opacity: 1; transform: scale(1); } }
.reveal-tag { font-family: var(--serif); font-weight: 700; font-size: clamp(18px, 3.4vw, 26px); color: #f3e7cb; margin: 10px 0 0; opacity: 0; min-height: 1.4em; }
.reveal-tag.in { animation: tip-in 500ms var(--ease-out) both; }

/* Result: three floating columns */
.view.result { max-width: 1340px; text-align: left; }
.sheet {
  display: grid; align-items: start; gap: clamp(18px, 2vw, 28px);
  grid-template-columns: minmax(0, 0.9fr) minmax(340px, 1.15fr) minmax(0, 1fr);
}
.panel {
  position: relative; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.8), 0 30px 80px rgba(0,0,0,0.55), 0 2px 0 rgba(255,255,255,0.03) inset;
  backdrop-filter: blur(12px) saturate(1.1); -webkit-backdrop-filter: blur(12px) saturate(1.1);
}
.panel::before { content: ""; position: absolute; inset: 5px; border-radius: 7px; border: 1px solid rgba(212,175,90,0.16); pointer-events: none; }
.panel::after { content: ""; position: absolute; left: 12px; right: 12px; top: -1px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--class), transparent); }
.col-desc, .col-sheet { padding: clamp(20px, 2.4vw, 30px); }
.col-desc { animation: col-left 800ms var(--ease-out) 120ms both; }
/* Race / gender picker floats under the description; the other two columns span both rows. */
.col-portrait, .col-sheet { grid-row: 1 / span 2; }
/* Row 1 hugs the description; the tall spanning columns push their extra height into row 2 only. */
.sheet { grid-template-rows: auto 1fr; }
.col-char { grid-column: 1; grid-row: 2; align-self: start; padding: clamp(16px, 2vw, 22px); animation: col-left 800ms var(--ease-out) 240ms both; }
.char-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.char-field { display: grid; gap: 6px; font-family: var(--serif); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }
.select { width: 100%; font: 500 14px/1.2 var(--sans); color: #f3e7cb; background: #0d1119; border: 1px solid #3a3320; border-radius: 6px; padding: 8px 10px; cursor: pointer; }
.select:focus { outline: 2px solid var(--gold); outline-offset: 1px; }
.col-sheet { animation: col-right 800ms var(--ease-out) 220ms both; }
.col-portrait { position: sticky; top: 24px; animation: col-up 800ms var(--ease-out) both; }
@keyframes col-left { from { opacity: 0; transform: translate3d(-28px, 12px, 0); } to { opacity: 1; transform: none; } }
@keyframes col-right { from { opacity: 0; transform: translate3d(28px, 12px, 0); } to { opacity: 1; transform: none; } }
@keyframes col-up { from { opacity: 0; transform: translate3d(0, 28px, 0) scale(0.98); } to { opacity: 1; transform: none; } }

.col .section-title:first-child { margin-top: 0; }

/* Portrait: an isolated class cutout floating on the background (no panel) */
.portrait { margin: 0; padding: 0; animation: float 7s ease-in-out 900ms infinite; }
@keyframes float { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(0, -7px, 0); } }
.portrait-art { position: relative; width: 100%; aspect-ratio: 3 / 4; max-width: 100%; display: grid; place-items: end center; }
.portrait-glow { display: none; }
.portrait-ground { position: absolute; left: 14%; right: 14%; bottom: 0.5%; height: 8%; border-radius: 50%; pointer-events: none; background: radial-gradient(closest-side, rgba(0,0,0,0.8), rgba(0,0,0,0.35) 55%, transparent 80%); }
.portrait-art img { position: relative; z-index: 1; height: 100%; width: auto; max-width: 100%; object-fit: contain; object-position: bottom center; filter: drop-shadow(0 26px 34px rgba(0,0,0,0.75)) drop-shadow(0 0 2px rgba(0,0,0,0.6)); }
.portrait-fallback { position: absolute; inset: 0; display: grid; place-items: center; z-index: 1; }
.portrait-fallback .frame { --size: clamp(160px, 66%, 260px); }
.portrait-fallback .frame.has-img { --size: clamp(170px, 70%, 280px); }
.nameplate { padding: 20px 8px 0; text-align: center; }
.nameplate .eyebrow { margin-bottom: 6px; }
.card-class { font-size: clamp(40px, 4.6vw, 66px); }
.card-spec { font-family: var(--serif); font-weight: 700; font-size: clamp(14px, 1.3vw, 17px); color: #f3e7cb; margin: 8px 0 0; }

.actions { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 14px; }
.actions .btn-x, .actions #btn-yours { grid-column: 1 / -1; }
.actions .btn { padding: 0 16px; font-size: 14px; }
.actions .btn:not(.btn-primary) { background: rgba(8, 11, 21, 0.82); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }

/* Description column */
/* Verdict: a clean pull quote. Cinzel has no lowercase, so long verdicts go in the sans, with a class-colored quote mark. */
.verdict { position: relative; font-family: var(--sans); font-weight: 600; font-size: clamp(17px, 1.45vw, 20px); line-height: 1.4; color: #fff; margin: 0 0 22px; padding: 4px 0 20px 30px; border-bottom: 1px solid var(--line); text-wrap: pretty; }
.verdict::before { content: "\201C"; position: absolute; left: 0; top: -6px; font-family: var(--serif); font-weight: 900; font-size: 44px; line-height: 1; color: var(--class); }
.roast { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.roast li { position: relative; padding-left: 22px; font-size: 16px; line-height: 1.45; color: var(--text); text-wrap: pretty; }
.roast li::before { content: "◆"; position: absolute; left: 2px; top: 0.45em; font-size: 9px; color: var(--class); }
.section-title { font-size: 13px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--gold); margin: 28px 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }

/* Character sheet column */
.sheet-level { margin: -4px 0 14px; font-family: var(--serif); font-weight: 700; font-size: 15px; color: #f3e7cb; }
.sheet-level b { color: var(--class); font-weight: 700; }
.stats { margin: 0; display: grid; gap: 0; border: 1px solid rgba(255,255,255,0.07); border-radius: 6px; overflow: hidden; }
.stats div { display: flex; flex-direction: column; gap: 3px; padding: 11px 14px; background: rgba(255,255,255,0.025); }
.stats div:nth-child(even) { background: rgba(255,255,255,0.05); }
.stats dt { font-family: var(--serif); font-weight: 700; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--gold); }
.stats dd { margin: 0; color: #fff; font-size: 15px; }
.evidence { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.evidence .xpost-text { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.xpost { background: #000; border: 1px solid #2f3336; border-radius: 14px; color: #e7e9ea; font-family: var(--sans); transition: border-color 150ms, transform 150ms, box-shadow 150ms; }
.xpost-link { display: block; padding: 12px 14px; color: inherit; text-decoration: none; border-radius: 14px; }
.xpost:has(a.xpost-link):hover { border-color: #6b7280; transform: translateY(-1px); box-shadow: 0 8px 24px rgba(0,0,0,0.5); }
.xpost a.xpost-link:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.xpost-head { display: flex; align-items: center; gap: 10px; }
.xpost-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none; }
.xpost-avatar-fallback { display: grid; place-items: center; background: linear-gradient(180deg, #3a4150, #1b1f28); color: #fff; font-weight: 600; font-size: 16px; }
.xpost-names { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.xpost-names b { font-weight: 700; font-size: 15px; color: #e7e9ea; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.xpost-names span { font-size: 14px; color: #71767b; }
.xpost-logo { margin-left: auto; width: 20px; height: 20px; flex: none; }
.xpost-logo svg { width: 100%; height: 100%; fill: #e7e9ea; display: block; }
.xpost-text { margin: 10px 0 0; font-size: 15px; line-height: 1.4; color: #e7e9ea; white-space: pre-wrap; overflow-wrap: anywhere; }
.xpost-reply { margin-top: 12px; padding-top: 10px; border-top: 1px solid #2f3336; display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.4; color: #b9bec8; }
.xpost-reply-who { flex: none; font-family: var(--serif); font-weight: 700; font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--class); padding-top: 3px; }

@media (max-width: 1080px) {
  .sheet { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .col-portrait { grid-column: 1 / -1; grid-row: auto; position: static; width: min(100%, 420px); justify-self: center; }
  .col-sheet { grid-row: auto; }
  .col-char { grid-column: auto; grid-row: auto; }
  .sheet { grid-template-rows: none; }
}
@media (max-width: 720px) {
  .sheet { grid-template-columns: minmax(0, 1fr); }
  .col-desc { order: 2; } .col-char { order: 3; } .col-sheet { order: 4; }
}

/* Share modal */
.modal { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; padding: 16px; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(3, 5, 10, 0.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.modal-box { position: relative; width: min(100%, 420px); max-height: calc(100vh - 32px); overflow: auto; padding: 18px 18px 20px; border-radius: 12px;
  background: linear-gradient(180deg, #151a26, #0b0e16); border: 1px solid #3a3320; box-shadow: 0 30px 90px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,255,255,0.06);
  animation: modal-in 260ms var(--ease-out) both; }
@keyframes modal-in { from { opacity: 0; transform: translateY(14px) scale(0.98); } to { opacity: 1; transform: none; } }
.modal-close { position: absolute; top: 8px; right: 10px; width: 36px; height: 36px; border: 0; border-radius: 50%; background: transparent; color: var(--muted); font-size: 26px; line-height: 1; cursor: pointer; }
.modal-close:hover { color: var(--gold-2); background: rgba(255,255,255,0.06); }
.share-frame { position: relative; border-radius: 8px; overflow: hidden; border: 1px solid #2a2416; background: #05070c; aspect-ratio: 4 / 5; }
.share-frame img { display: block; width: 100%; height: 100%; object-fit: contain; }
.share-frame img[src=""] { visibility: hidden; }
.share-wait { position: absolute; inset: 0; display: grid; place-items: center; color: var(--gold-2); font-family: var(--serif); letter-spacing: 0.1em; font-size: 13px; text-transform: uppercase; }
.share-hint { margin: 10px 0 0; color: var(--muted); font-size: 12.5px; text-align: center; }
.modal-actions { grid-template-columns: 1fr; }

/* Live ticker: recent results popping up bottom-right, sonner style. Landing page only. */
/* Sonner-style pile anchored to the corner: the oldest card sits at the bottom, each newer one
   stacks 46px above it, so the newest is on top at full size and the older ones peek out below,
   smaller and fainter. --n is 0 for the newest, --count is how many are in the pile. */
.ticker { position: fixed; right: 18px; bottom: 18px; z-index: 55; width: min(340px, calc(100vw - 36px)); height: 220px; pointer-events: none; }
/* Hover: fan the pile out so every card is readable (app.js pauses the rotation meanwhile). The
   ::before pad keeps :hover alive while the pointer crosses the gaps between fanned cards. */
.ticker:hover::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; top: -120px; pointer-events: auto; }
.ticker:hover .tick { transform: translateY(calc(var(--lift) * (var(--tick-h, 60px) + 8px))) scale(1); opacity: 1; }
.tick { --n: 0; position: absolute; left: 0; right: 0; bottom: 0; box-sizing: border-box; display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px; background: rgba(8, 11, 21, 0.94); border: 1px solid #2a2e3a; border-left: 3px solid var(--class, var(--gold)); box-shadow: 0 12px 34px rgba(0,0,0,0.55); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  color: var(--text); text-decoration: none; font-size: 13.5px; line-height: 1.3; pointer-events: auto; z-index: calc(10 - var(--n));
  --lift: calc((var(--count, 1) - 1 - var(--n)) * -1);
  transform: translateY(calc(var(--lift) * 46px)) scale(calc(1 - var(--n) * 0.04)); transform-origin: bottom center; opacity: calc(1 - var(--n) * 0.15);
  transition: transform 380ms var(--ease-out), opacity 380ms; animation: tick-in 420ms var(--ease-out); }
.tick.out { animation: tick-out 320ms ease-in forwards; }
.tick:hover { border-color: var(--class, var(--gold)); }
.tick-avatar { width: 32px; height: 32px; border-radius: 50%; flex: none; object-fit: cover; background: #1b1f28; display: grid; place-items: center; color: #fff; font-weight: 600; font-size: 13px; }
.tick-body { min-width: 0; flex: 1; }
.tick-body b { color: #fff; font-weight: 600; }
.tick-body em { font-style: normal; color: var(--class, var(--gold-2)); font-weight: 700; }
.tick-live { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.tick-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #e0443e; box-shadow: 0 0 0 0 rgba(224,68,62,0.6); animation: live-pulse 1.6s infinite; }
@keyframes live-pulse { 0% { box-shadow: 0 0 0 0 rgba(224,68,62,0.6); } 70% { box-shadow: 0 0 0 6px rgba(224,68,62,0); } 100% { box-shadow: 0 0 0 0 rgba(224,68,62,0); } }
/* No `to` frames on purpose: the card animates from here to its own pile position (transform/opacity
   from --n above). A filled `to { transform: none }` would pin every card to the front slot forever. */
@keyframes tick-in { from { opacity: 0; transform: translateY(calc(var(--lift) * 46px - 24px)) scale(0.96); } }
@keyframes tick-out { to { opacity: 0; transform: translateY(calc(var(--lift) * 46px + 12px)) scale(calc(1 - var(--n) * 0.04)); } }
@media (max-width: 720px) { .ticker { display: none; } }

/* Footer, toast */
.foot { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 18px 16px 34px; color: var(--muted); font-size: 13px; }
.foot p { margin: 0 0 8px; max-width: 680px; text-wrap: pretty; }
.foot strong { color: var(--gold-2); font-weight: 600; }
.foot a { color: var(--gold-2); text-decoration: none; border-bottom: 1px solid rgba(243,220,149,0.4); transition: border-color 150ms; }
.foot a:hover { border-color: var(--gold-2); }
.foot-credit { font-family: var(--serif); font-weight: 700; font-size: 13px; letter-spacing: 0.08em; color: var(--text); margin-bottom: 12px; }
.foot-fine { font-size: 11.5px; opacity: 0.75; }
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 60;
  max-width: min(92vw, 520px); padding: 12px 18px; border-radius: 8px;
  background: #1a1408; color: #fff3cf; border: 1px solid var(--gold); box-shadow: 0 10px 40px rgba(0,0,0,0.6);
  font-size: 14px; animation: toast-in 350ms var(--ease-out) both;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .bg-img { animation: none; }
}

/* Permanent Underclass */
.reveal-name.underclass { font-size: clamp(34px, 7.5vw, 64px); }
.reveal-name.underclass, .is-underclass .card-class {
  background: linear-gradient(180deg, #f2f2f2 0%, #b9b9b9 45%, #8a8a8a 75%, #5e5e5e 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.is-underclass .card-class { font-size: clamp(30px, 3.2vw, 44px); }

@media (max-width: 420px) {
  .btn { font-size: 13px; letter-spacing: 0.06em; padding: 0 18px; }
  .hero-title { font-size: 34px; }
}

.btn-connect { min-height: 56px; padding: 0 34px; font-size: 17px; letter-spacing: 0.14em; }
.btn-connect .x-logo { width: 20px; height: 20px; margin-left: 2px; }

/* Real class icons fill the frame (they carry their own ring) */
.frame.has-img { border-color: transparent; background: none; box-shadow: none; }
.frame.has-img .frame-icon { width: 100%; height: 100%; filter: drop-shadow(0 6px 14px rgba(0,0,0,0.7)); }
.frame-icon img { width: 100%; height: 100%; object-fit: contain; display: block; }
.portrait-fallback .frame.has-img { --size: clamp(150px, 62%, 220px); }

.card-class { text-wrap: balance; }
.card-class.long { font-size: clamp(30px, 3.2vw, 46px); }


/* 3D character */
/* !important: the viewer writes position:relative and a pixel height inline, which would collapse the host. */
.model3d { position: absolute !important; inset: 0; height: auto !important; z-index: 2; cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none; }
.model3d:active { cursor: grabbing; }
.model3d canvas { display: block; width: 100% !important; height: 100% !important; outline: none; }
.model3d .progress, .model3d .loading { display: none !important; }
.portrait-art.has-model .portrait-fallback { opacity: 0; transition: opacity 400ms; pointer-events: none; }
.model-hint { position: absolute; left: 0; right: 0; bottom: 2%; z-index: 3; text-align: center; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); opacity: 0; transition: opacity 400ms; pointer-events: none; }
.portrait-art.has-model .model-hint { opacity: 0.8; }
.portrait-art.has-model:hover .model-hint { opacity: 0; }
