@charset "UTF-8";
/* Comic World Engine — original static-site styling.
   A col-N float grid, a type scale, and a row rhythm; dual villain/hero
   dark theme (--biz red <-> --hum green, gold accent). */


:root{
  --ink:#0d0d12;
  --panel:#15151f;
  --panel-2:#1d1d2b;
  --line:rgba(255,255,255,.14);
  --text:#ecebf2;
  --muted:#9b9ab0;
  --biz:#e0484d;      /* Bizarro / villain */
  --biz-dim:#7d2529;
  --hum:#4dc9a6;      /* Humanity / hero */
  --hum-dim:#215c4e;
  --gold:#e8c35a;
}

*{box-sizing:border-box}
body{
  margin:14px 15px 0 15px;padding:0;background:var(--ink);color:var(--text);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-style:normal;font-weight:400;-webkit-font-smoothing:antialiased;
}
.mainContainer{max-width:1470px;margin:0 auto}

/* ---- source grid system, preserved ---- */
.col-1{width:8.33%}.col-2{width:16.66%}.col-3{width:25%}.col-4{width:33.33%}
.col-5{width:41.66%}.col-6{width:50%}.col-7{width:58.33%}.col-8{width:66.66%}
.col-9{width:75%}.col-10{width:83.33%}.col-11{width:91.66%}.col-12{width:100%}
[class*="col-"]{float:left;padding:15px}
.row::after{content:"";clear:both;display:table}
.col-noPadding{padding:0}
sup{vertical-align:top;font-size:1em}

a{text-decoration:none;color:var(--text)}
div.rightRow a{text-decoration:underline}
div.rightRow a:hover{text-decoration:none}

h1{font-weight:500;font-size:40px;line-height:100%;letter-spacing:-.03em;margin:0}
h2{font-weight:500;font-size:30px;line-height:110%;letter-spacing:-.03em;margin:0}
h3{font-weight:500;font-size:20px;line-height:120%;letter-spacing:-.02em;margin:0}
p{line-height:150%}

/* ---- header / nav ---- */
header{padding-bottom:24px}
.siteHead{display:flex;align-items:center;justify-content:space-between;
  border-bottom:1px solid var(--line);padding:18px 15px}
.brand{font-weight:700;font-size:22px;letter-spacing:-.02em}
.brand .biz{color:var(--biz)}
.brand .hum{color:var(--hum)}
.brandTag{color:var(--muted);font-size:12px;letter-spacing:.14em;text-transform:uppercase}

nav.engineNav{border-bottom:1px solid var(--line);margin-bottom:10px}
.navRow{cursor:pointer;border-top:1px solid var(--line);font-weight:500;font-size:18px}
/* Nav rows and cards are real <a> elements now, so they are keyboard
   reachable. Anchors bring their own colour and underline; strip those and
   restore a VISIBLE focus ring, because a focus outline a sighted keyboard
   user cannot see is the same defect in a different coat. */
a.navRow,a.typeCard,a.card{color:inherit;text-decoration:none;display:flex}
a.navRow{align-items:center}
a.typeCard,a.card{flex-direction:column}
a.navRow:focus-visible,a.typeCard:focus-visible,a.card:focus-visible,
.btn:focus-visible,a:focus-visible,button:focus-visible,
.qpScen:focus-visible,.qpOpt:focus-visible{
  outline:3px solid var(--gold);outline-offset:2px;border-radius:6px}
/* The home card's secondary action sits beside the card, not inside it:
   nesting an interactive element in an anchor is invalid and traps focus. */
.cardAside{display:inline-block;margin-top:12px;text-align:center}
.navRow:hover{background:var(--panel)}
.navRow .col-1{text-align:right;color:var(--muted)}
.subNavRow{background:var(--panel);font-size:15px}
.subNavRow:hover{background:var(--panel-2)}
.subNavCol a{color:var(--muted)}
.subNavCol a:hover{color:var(--text)}

/* Legal information stays in navigation and the footer, not the play surface. */
.navLegal{border-top:1px solid var(--line);padding:4px 15px}
.navLegal a{display:inline-flex;align-items:center;min-height:44px;
  color:var(--muted);font-size:14px}
.navLegal a:hover,.navLegal a[aria-current="page"]{color:var(--gold)}
.navInfo,.footerInfo{display:flex;flex-wrap:wrap;gap:8px 24px;padding:8px 15px}
.navInfo{border-top:1px solid var(--line)}
.navInfo a,.footerInfo a{display:inline-flex;align-items:center;min-height:44px;font-size:14px}
.navInfo a[aria-current="page"]{color:var(--gold)}
.skipLink{position:fixed;left:15px;top:-100px;z-index:100;
  background:var(--gold);color:var(--ink);padding:14px}
.skipLink:focus{top:10px}
/* A public front door, not a table of contents above every page. */
@media screen and (min-width:821px){
  .siteHead .navToggle{display:flex}
  nav.engineNav{display:none}
  body.navOpen nav.engineNav{display:block}
  header{padding-bottom:0}
}
.legalNotice{max-width:760px;margin:32px auto;padding:0 15px}
.legalNotice h1{line-height:1.15}
.legalNotice p{line-height:1.7;margin:24px 0}

.navToggle{display:none;background:transparent;border:1px solid var(--line);
  color:var(--text);font:inherit;font-size:14px;font-weight:500;padding:10px 16px;
  border-radius:8px;cursor:pointer;min-height:44px}
.navToggle:hover{border-color:var(--gold);color:var(--gold)}
/* Icon + word sit on one line; the word stays so the control is readable if
   the sprite fails and is announced correctly by a screen reader. */
.navToggle{align-items:center;gap:7px;min-height:44px}
.navToggle .ico{width:18px;height:18px;margin:0}
body.navOpen .navToggle{border-color:var(--gold);color:var(--gold)}

/* ---- backlink bar (primary "up" affordance on phones) ---- */
.crumbBar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 15px;border-bottom:1px solid var(--line);margin-bottom:10px}
.crumbUp{color:var(--gold);font-size:14px;font-weight:500;padding:6px 0}
.crumbUp:hover{text-decoration:underline}
.crumbHere{color:var(--muted);font-size:13px}

/* ---- phone bottom tab bar ---- */
.tabBar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:40;
  background:rgba(13,13,18,.97);border-top:1px solid var(--line)}
.tabItem{flex:1;text-align:center;padding:12px 4px calc(12px + env(safe-area-inset-bottom));
  color:var(--muted);font-size:12px;font-weight:500;letter-spacing:.04em;min-height:52px}
.tabItem.on{color:var(--gold)}

/* ---- home cards ---- */
.homeContent{display:grid;grid-template-columns:repeat(2,1fr);grid-gap:15px}
.homeContent_right{display:grid;grid-template-rows:auto auto;grid-gap:15px}
.card{border-radius:10px;padding:25px;display:flex;flex-direction:column;
  justify-content:space-between;min-height:180px}
.card1{min-height:420px;
  background:linear-gradient(145deg,var(--biz-dim) 0%,#140d12 55%,var(--hum-dim) 100%);
  border:1px solid var(--line)}
.card1 h1{max-width:18ch}
.card2{background:var(--panel);border:1px solid var(--line)}
.card3{background:var(--panel-2);border:1px solid var(--line)}
.cardHeadText{font-weight:500;font-size:12px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gold);margin-bottom:14px}
.insightsQuoteText{font-weight:500;font-size:26px;line-height:112%;letter-spacing:-.03em}
.insightsQuoteCite{font-weight:500;font-size:16px;color:var(--muted)}
.btn{display:inline-block;margin-top:22px;padding:16px 22px;border-radius:8px;border:0;
  background:var(--text);color:var(--ink);font-family:inherit;font-weight:500;
  font-size:16px;cursor:pointer;text-align:center}
.btn:hover{background:var(--gold)}
.btn-ghost{background:transparent;color:var(--text);border:1px solid var(--line)}
.btn-ghost:hover{background:var(--panel-2);color:var(--text)}

/* ---- content rows (mirrors source contentTopRow / leftRow / rightRow) ---- */
.contentTopRow{border-bottom:1px solid var(--line)}
.lightTopBorder{border-top:1px solid var(--line)}
.leftRow{color:var(--muted)}
.rightRow p{color:#cfcee0}

/* ---- illustrated Engine guide: static art, protected reading surface ----
   Scoped to the guide so quiz/results and their earned worlds do not change.
   CSS backgrounds are decorative; all meaning stays in the HTML text. */
.engineGuide{--guide-art:url("../_art/metropolitan.webp")}
.engineGuide > .row{
  border:1px solid var(--line);border-radius:12px;margin:0 0 20px;
  background-color:var(--ink);
  background-image:linear-gradient(90deg,rgba(13,13,18,.38),rgba(13,13,18,.72) 42%,rgba(13,13,18,.9)),var(--guide-art);
  background-size:cover;background-position:center;
}
.engineGuide > .contentTopRow{
  display:flex;align-items:flex-end;min-height:240px;
  background-image:linear-gradient(0deg,rgba(13,13,18,.94),rgba(13,13,18,.18)),var(--guide-art);
}
.engineGuide > .row > [class*="col-"]{padding:28px}
.engineGuide > .row:not(.contentTopRow){display:flow-root}
.engineGuide .leftRow{color:var(--text)}
.engineGuide .leftRow h2{
  display:inline-block;max-width:100%;padding:14px 16px;
  background:rgba(13,13,18,.88);border-left:3px solid var(--gold);border-radius:0 8px 8px 0;
}
.engineGuide .rightRow{background:rgba(13,13,18,.94);border-radius:0 12px 12px 0}
.engineGuide .rightRow p,.engineGuide .rightRow li{color:var(--text);line-height:1.65}
.engineGuide .rightRow > :first-child{margin-top:0}
.engineGuide .rightRow > :last-child{margin-bottom:0}
.engineGuide .axisTable{width:100%}
.engineGuide #axes{--guide-art:url("../_art/industrial.webp")}
.engineGuide #scoring{--guide-art:url("../_art/justice.webp")}
.engineGuide #reading{--guide-art:url("../_art/metropolitan.webp")}
.engineGuide #tether{--guide-art:url("../_art/family.webp")}
.engineGuide #thesis{--guide-art:url("../_art/agricultural.webp")}
@media screen and (max-width:820px){
  .engineGuide > .row{margin:0 12px 16px;background-size:auto 260px;
    background-repeat:no-repeat;background-position:center top}
  .engineGuide > .contentTopRow{display:block;min-height:220px;padding-top:65px;
    background-size:cover}
  .engineGuide > .row > [class*="col-"]{padding:20px}
  .engineGuide .leftRow{min-height:150px;display:flex;align-items:flex-end}
  .engineGuide .leftRow h2{font-size:25px}
  .engineGuide .rightRow{border-radius:0 0 12px 12px}
}
@media screen and (max-width:540px){
  .engineGuide .axisTable{table-layout:auto;overflow-wrap:anywhere}
  .engineGuide .axisTable th,.engineGuide .axisTable td{padding:8px 3px;font-size:12px}
  .engineGuide .axisTable th{font-size:10px;letter-spacing:.03em}
  .engineGuide .axisTable :is(th,td):first-child,
  .engineGuide .axisTable :is(th,td):last-child{white-space:nowrap}
}
@media print{
  .engineGuide > .row,.engineGuide > .contentTopRow{background-image:none}
}

/* ---- archetype + realm grids ---- */
.typeGrid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;padding:15px}
.typeCard{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:16px}
.typeCard:hover{border-color:var(--gold)}
.typeCode{font-weight:700;font-size:13px;letter-spacing:.22em;color:var(--gold)}
.typeBiz{font-weight:500;font-size:19px;color:var(--biz);margin-top:8px}
.typeSwap{color:var(--muted);font-size:12px;margin:4px 0}
.typeHum{font-weight:500;font-size:19px;color:var(--hum)}
.typeAbility{font-size:13px;color:var(--muted);margin-top:10px;line-height:145%}
.typeAxes{font-size:12px;color:var(--muted);margin-top:10px;border-top:1px solid var(--line);padding-top:10px}

/* ---- friend reading (A7) ----
   Optional layer: only some codes have a profile written, so these rules
   must never assume the section is present. Three columns rather than the
   four of .typeGrid, because these cards hold list copy, not a single line. */
.friendGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;padding:15px}
.friendGrid ul{margin:10px 0 0;padding-left:18px}
.friendGrid li.typeAbility{margin-top:6px}
.poleNote{font-size:12px;color:var(--gold);margin-top:8px;line-height:140%;
  border-top:1px solid var(--line);padding-top:8px}
.friendQuote{font-style:italic;color:#cfcee0;font-size:16px;line-height:150%;
  border-left:2px solid var(--line);padding-left:12px;margin:14px 0}
.friendClose{font-size:18px;line-height:140%;font-weight:500}
.friendClose.hw{color:var(--hum)}
.friendClose.bw{color:var(--biz)}
@media (max-width:860px){.friendGrid{grid-template-columns:1fr}}

/* ---- cast faces ----
   Partial by design: only some arcs have generated portraits, so .castInit
   is the monogram fallback and the row must read correctly either way. */
.castStrip{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.castOne{display:flex;align-items:center;gap:10px}
/* The monogram lives on the WRAPPER, drawn behind the portrait. A loaded
   image hides it; a missing one lets it show through. No JS, no onerror,
   no load event -- the two earlier versions of this both failed on one
   of those. */
.faceWrap{position:relative;display:inline-flex;flex:0 0 38px;
  width:38px;height:38px;border-radius:50%;overflow:hidden;
  background:var(--panel-2);border:1px solid var(--line)}
.faceWrap::before{content:attr(data-initial);position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:15px;color:var(--gold)}
.castFace{position:relative;width:100%;height:100%;
  object-fit:cover;display:block;border:0}
/* Full portraits keep the original 3:4 framing, not the cast's round crop.
   Reuse the handler-free monogram layer beneath each decorative image. */
.faceWrap.archetypePortrait{display:flex;width:min(100%,300px);height:auto;
  aspect-ratio:3/4;flex:none;border-radius:12px;margin:16px 0 0}
.archetypePortrait::before{font-size:28px;letter-spacing:.12em}
.archetypePortrait .castFace{position:absolute;inset:0}
.qpIdentity{display:flex;align-items:flex-start;gap:24px}
.qpIdentity .archetypePortrait{width:180px;max-width:35%;margin:0}
.qpIdentityText{min-width:0;flex:1}
@media(max-width:540px){
  .qpIdentity{flex-direction:column;gap:18px}
  .qpIdentity .archetypePortrait{width:180px;max-width:100%;align-self:center}
}
.castWho{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.castWho b{font-size:14px;font-weight:600}
.castWho span{color:var(--muted);font-size:12px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* On the beat screen the faces are a compact row above the setup line:
   who is in the room, without pushing the dilemma off the first screen. */
.beatCast{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 10px}
.beatWho{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;
  color:var(--muted)}
.beatWho .faceWrap{width:30px;height:30px;flex:0 0 30px}
.beatWho .faceWrap::before{font-size:12px}

/* ---- folded jargon + its mandatory explainer link ----
   Engine notation ("V 2 vs O 3 · margin -1", "motive tension") is folded
   away by default and ALWAYS carries a link to the page that defines it.
   <details>/<summary> so it is keyboard-operable and works with no JS. */
.jargonFold{border-top:1px solid var(--line);margin:0}
.jargonFold>summary{cursor:pointer;list-style:none;padding:12px 0;
  color:var(--muted);font-size:13px;letter-spacing:.04em;
  display:flex;align-items:center;gap:8px}
.jargonFold>summary::-webkit-details-marker{display:none}
.jargonFold>summary::after{content:"+";margin-left:auto;color:var(--gold);
  font-size:16px;line-height:1}
.jargonFold[open]>summary::after{content:"\2212"}
.jargonFold>summary:hover{color:var(--text)}
.jargonFold>summary:focus-visible{outline:2px solid var(--gold);
  outline-offset:3px;border-radius:4px}
.jargonBody{padding:2px 0 14px}
.methodNote{margin:12px 0 0;font-size:13px}
a.methodRef{color:var(--gold);text-decoration:underline;
  text-underline-offset:2px}
a.methodRef:hover{color:var(--text)}

/* ---- influence tally (tether arcs only) ----
   Four peer cells. Deliberately NOT ordered best-to-worst and deliberately
   without a total: the report is explicit that resisting influence is not
   automatically virtuous. The h/b tint marks which WORLD the suggestion
   came from, not whether the player did well. */
.inflGrid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.inflCell{background:var(--panel-2);border:1px solid var(--line);
  border-radius:10px;padding:14px 12px}
.inflCell.h{border-left:3px solid var(--hum)}
.inflCell.b{border-left:3px solid var(--biz)}
.inflN{font-size:28px;font-weight:700;line-height:1}
.inflLbl{color:var(--muted);font-size:12.5px;line-height:140%;margin-top:4px}
@media (max-width:620px){.inflGrid{grid-template-columns:1fr}}

.realmGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;padding:15px}

.realmCard{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:18px}
.realmCard h3{color:var(--gold)}
.realmCtx{color:var(--muted);font-size:14px;margin:8px 0 14px}
.viewRow{border-left:3px solid var(--hum);padding-left:12px;margin-bottom:10px;font-size:14px}
.viewRow.biz{border-left-color:var(--biz)}
.viewLabel{font-weight:500;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);display:block;margin-bottom:3px}
.realmQ{font-style:italic;color:#cfcee0;font-size:14px;border-top:1px solid var(--line);
  padding-top:12px}

/* ---- quiz ---- */
.quizBar{position:sticky;top:0;z-index:5;background:var(--ink);border-bottom:1px solid var(--line);
  padding:14px 15px;display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.progressTrack{flex:1;min-width:180px;height:6px;background:var(--panel-2);border-radius:3px;overflow:hidden}
.progressFill{height:100%;width:0;background:linear-gradient(90deg,var(--biz),var(--gold),var(--hum));
  transition:width .18s ease}
.progressText{color:var(--muted);font-size:13px;white-space:nowrap}
.qCard{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:22px;margin:0 15px 14px}
.qNum{font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.qPrompt{font-weight:500;font-size:21px;line-height:124%;letter-spacing:-.02em;margin:10px 0 18px}
.qOpts{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.qOpt{background:var(--panel-2);border:1px solid var(--line);border-radius:8px;padding:16px;
  cursor:pointer;font-size:15px;line-height:145%;color:var(--text);text-align:left;
  font-family:inherit;transition:border-color .12s ease,background .12s ease}
.qOpt:hover{border-color:var(--muted)}
.qOpt.sel{border-color:var(--gold);background:#2a2616}
.qOpt .optTag{display:block;font-weight:700;font-size:11px;letter-spacing:.2em;
  color:var(--gold);margin-bottom:7px}
.quizNav{display:flex;gap:12px;padding:0 15px 30px;flex-wrap:wrap;align-items:center}
.lensRow{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:0 15px 10px}
select,.lensRow label{font-family:inherit;font-size:14px}
select{background:var(--panel-2);color:var(--text);border:1px solid var(--line);
  border-radius:6px;padding:9px 12px}
.toggle{display:inline-flex;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.toggle button{background:var(--panel-2);color:var(--muted);border:0;padding:9px 16px;
  font-family:inherit;font-size:14px;cursor:pointer}
.toggle button.on[data-o="bizarro"]{background:var(--biz);color:#fff}
.toggle button.on[data-o="humanity"]{background:var(--hum);color:#06201a}

/* ---- result ---- */
.resultHero{border:1px solid var(--line);border-radius:10px;padding:28px;margin:15px;
  background:linear-gradient(145deg,#1a1020,#101018)}
.resultCode{font-weight:700;font-size:14px;letter-spacing:.4em;color:var(--gold)}
.resultName{font-weight:500;font-size:46px;line-height:104%;letter-spacing:-.03em;margin:10px 0}
.resultName.bizarro{color:var(--biz)}
.resultName.humanity{color:var(--hum)}
.resultFlip{color:var(--muted);font-size:15px}
.axisTable{width:calc(100% - 30px);border-collapse:collapse;margin:15px}
.axisTable th,.axisTable td{border-bottom:1px solid var(--line);padding:12px 10px;
  text-align:left;font-size:14px}
.axisTable th{color:var(--muted);font-weight:500;font-size:11px;letter-spacing:.14em;
  text-transform:uppercase}
.axisTable .marg{font-variant-numeric:tabular-nums;font-weight:500}
.flag{display:inline-block;font-size:11px;padding:2px 8px;border-radius:99px;
  background:var(--panel-2);color:var(--muted);margin-left:8px}
.hidden{display:none!important}

/* ---------- Quick Play (phone-first) ---------- */
.qpWrap{max-width:620px;margin:0 auto}
.qpScenarios{display:grid;gap:14px;margin:22px 0}
.qpScen{background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:20px;text-align:left;color:var(--text);font:inherit;cursor:pointer}
/* Hover only. This rule once carried `:focus{outline:none}`, which has the
   SAME specificity (0,2,0) as the :focus-visible ring above and comes later,
   so it won — a keyboard user tabbing the scenario picker saw no ring at all.
   :focus-visible is a subset of :focus, so never suppress the outline here. */
.qpScen:hover{border-color:var(--gold)}
.qpScen h3{margin:0 0 6px;font-size:20px;letter-spacing:-.02em}
.qpScen p{margin:0;color:var(--muted);font-size:14px;line-height:140%}
.qpScen .qpRealm{display:inline-block;margin-top:10px;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--gold)}
.qpDots{display:flex;gap:5px;flex-wrap:wrap;margin:18px 0 10px}
.qpDot{width:100%;max-width:22px;height:5px;border-radius:3px;background:var(--panel-2);flex:1}
.qpDot.done{background:var(--gold)}
.qpDot.now{background:var(--text)}
.qpStep{color:var(--muted);font-size:13px;letter-spacing:.04em}
.qpCard{background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:22px;margin:12px 0 18px}
.qpSetup{color:var(--muted);font-size:15px;line-height:152%;margin:0 0 14px;
  padding-left:12px;border-left:2px solid var(--line)}
.qpEcho{color:var(--gold)}
.qpPrompt{font-weight:500;font-size:23px;line-height:126%;letter-spacing:-.02em;margin:0 0 20px}
.qpArcTitle{font-weight:700;font-size:15px;letter-spacing:.02em;color:var(--gold);margin-bottom:4px}
.qpCast{color:var(--muted);font-size:13px;line-height:160%;margin-top:10px}
.qpCast b{color:var(--text);font-weight:500}
.qpRecap{margin:0;padding:0;list-style:none}
.qpRecap li{border-left:2px solid var(--line);padding:0 0 14px 14px;margin:0}
.qpRecap li.h{border-left-color:var(--hum)}
.qpRecap li.b{border-left-color:var(--biz)}
.qpRecap .rChose{font-size:15px;line-height:145%}
.qpRecap .rCons{color:var(--muted);font-size:13.5px;line-height:150%;margin-top:3px}
.qpOpts{display:grid;gap:12px}
.qpOpt{background:var(--panel-2);border:1px solid var(--line);border-radius:10px;
  padding:18px 16px;text-align:left;color:var(--text);font:inherit;font-size:17px;
  line-height:138%;cursor:pointer;min-height:64px;width:100%}
/* Hover only — see the note on .qpScen. These two buttons ARE the game; they
   were the only controls in the package still suppressing their focus ring. */
.qpOpt:hover{border-color:var(--gold)}
.qpOpt.sel{border-color:var(--gold);background:#2a2616}
.qpBack{background:transparent;border:0;color:var(--muted);font:inherit;font-size:14px;
  cursor:pointer;padding:8px 0}
.qpBack:hover{color:var(--text)}
.worldBadge{display:inline-block;padding:7px 14px;border-radius:999px;font-size:12px;
  font-weight:700;letter-spacing:.18em;text-transform:uppercase}
.worldBadge.hw{background:var(--hum-dim);color:#d6fff1;border:1px solid var(--hum)}
.worldBadge.bw{background:var(--biz-dim);color:#ffe1e2;border:1px solid var(--biz)}
.worldBar{display:flex;height:10px;border-radius:5px;overflow:hidden;margin:14px 0 8px;
  background:var(--panel-2)}
.worldBar i{display:block;height:100%}
.worldBar i.h{background:var(--hum)}
.worldBar i.b{background:var(--biz)}
.qpCode{font-size:40px;font-weight:700;letter-spacing:.12em;margin:6px 0}
.builtWorld{font-size:34px;font-weight:700;line-height:112%;letter-spacing:-.02em;margin:4px 0 12px}
.builtWorld.hw{color:var(--hum)}
.builtWorld.bw{color:var(--biz)}
@media (max-width:620px){
  .qpPrompt{font-size:20px}
  .qpOpt{font-size:16px}
  .qpCode{font-size:32px}
  .builtWorld{font-size:27px}
}

/* ---------- A8: realm art, atmosphere, icons ----------
   The art is a BACKGROUND LAYER, never a control. Every interactive element
   stays a real <button>/<a> with its own focus ring; see ART/BUTTONS.md. */

/* Icon sprite. Size and colour live here, never on the asset, so one symbol
   serves every context and inherits the muted -> gold active state. */
.ico{width:22px;height:22px;display:block;margin:0 auto 4px;
  fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.tabItem .ico{color:inherit}
.qpBack .ico,.btn .ico{display:inline-block;width:16px;height:16px;
  margin:0 6px 0 0;vertical-align:-3px}

/* Scenario cards carry their realm image behind a scrim that protects text.
   --art is set per card from the realm key; --scrim darkens enough for AA
   contrast on the title and body copy. */
.qpScen{position:relative;overflow:hidden;isolation:isolate;min-height:208px}
.qpScen::before{content:"";position:absolute;inset:0;z-index:-2;
  background-image:var(--art);background-size:cover;background-position:center;
  opacity:.55}
.qpScen::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to bottom,
    rgba(13,13,18,.35) 0%, rgba(13,13,18,.72) 55%, rgba(13,13,18,.94) 100%)}
.qpScen:hover::before{opacity:.7}

/* The play screen: same realm image, plus TWO atmosphere layers whose opacity
   is driven by the running tally. This is the accumulation effect -- the world
   changes as choices are made, rather than toggling at the end. */
.qpStage{position:relative;border-radius:14px;overflow:hidden;isolation:isolate;
  margin:14px 0 0}
.qpStage>.qpStageArt,.qpStage>.qpStageHum,.qpStage>.qpStageBiz,
.qpStage>.qpStageScrim{position:absolute;inset:0;z-index:-1;pointer-events:none}
/* Opacity raised from .5 once per-beat scene art landed: a realm texture
   could sit at half strength behind text, but a composed frame with faces
   in it is the subject and reads as mud at .5. The scrim below still
   guarantees text contrast. Transitioned so a beat change is a cut, not
   a jolt. */
.qpStageArt{background-image:var(--art);background-size:cover;
  background-position:center;opacity:.78;transition:opacity .35s ease}
.qpStageHum{background-image:url("../_art/humanity-atmosphere.webp");
  background-size:cover;mix-blend-mode:screen;opacity:var(--hum-mix,0);
  transition:opacity .5s ease}
.qpStageBiz{background-image:url("../_art/bizarro-atmosphere.webp");
  background-size:cover;mix-blend-mode:screen;opacity:var(--biz-mix,0);
  transition:opacity .5s ease}
.qpStageScrim{background:linear-gradient(to bottom,
  rgba(13,13,18,.55) 0%, rgba(13,13,18,.78) 60%, rgba(13,13,18,.9) 100%)}
.qpStage .qpCard{background:rgba(21,21,31,.55);backdrop-filter:blur(7px);
  -webkit-backdrop-filter:blur(7px);margin:0}
.qpStage .qpOpt{background:rgba(29,29,43,.72);backdrop-filter:blur(4px);
  -webkit-backdrop-filter:blur(4px)}

/* Live direction meter. Shows WHICH WAY the world is tipping, with no number,
   because a score would turn a story into a test. */
.qpTilt{display:flex;align-items:center;gap:10px;margin:12px 0 2px}
.qpTiltBar{flex:1;height:6px;border-radius:3px;overflow:hidden;position:relative;
  background:var(--panel-2)}
.qpTiltBar i{position:absolute;top:0;bottom:0;transition:width .45s ease}
.qpTiltBar i.h{left:0;background:var(--hum)}
.qpTiltBar i.b{right:0;background:var(--biz)}
.qpTiltEnd{font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted)}

/* ---------- consequence layer ----------
   One bar per affected metric, same shape as the tilt meter above so the
   player reads them as the same kind of object. A bar is drawn ONLY for a
   cell the running arc actually puts to the player, which is why an arc
   declares its scope: a bar that appears in one story and not another would
   mean nothing. */
.qpGoal{display:flex;align-items:baseline;gap:8px;margin:10px 0 0;
  font-size:12px;line-height:1.35}
.qpGoal b{color:var(--gold);font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;font-size:10px;flex:0 0 auto}
.qpGoal span{color:var(--text)}

.qpBars{margin:10px 0 2px;display:flex;flex-direction:column;gap:6px}
.qpBarRow{display:flex;align-items:center;gap:8px}
/* The label must stay READABLE, not merely present. A fixed 92px column
   clipped "Colleague trust" and "Colleague agency" to the same
   "COLLEAGUE ..." at 390px, so the two most important bars could not be
   told apart -- found by screenshot, invisible to a DOM test. Sized to the
   longest real label instead, with the ellipsis kept only as a backstop. */
.qpBarName{font-size:10px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);flex:0 0 118px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.qpBarName.authored{white-space:normal;overflow:visible;overflow-wrap:anywhere;line-height:1.35}
.qpBarTrack{flex:1;height:6px;border-radius:3px;overflow:hidden;
  position:relative;background:var(--panel-2);min-width:0}
/* Fill grows from the left. Colour is a HINT, never the only signal: the
   caption text and aria-label carry the same information for anyone who
   cannot see it. */
.qpBarTrack i{position:absolute;left:0;top:0;bottom:0;border-radius:3px;
  transition:width .45s ease,background .45s ease}
.qpBarTrack i.low{background:var(--biz)}
.qpBarTrack i.mid{background:var(--gold)}
.qpBarTrack i.high{background:var(--hum)}
/* A cell decided by fewer than three beats is real but weakly evidenced.
   It is drawn faintly so it cannot pose as a verdict. */
.qpBarRow.thin .qpBarTrack i{opacity:.45}
.qpBarRow.thin .qpBarName{opacity:.6}

/* Art must never be the only way to understand the page, and motion must be
   optional. This block was absent before the art landed. */
@media (prefers-reduced-motion:reduce){
  .qpStageHum,.qpStageBiz,.qpTiltBar i,.worldBar i,.qpBarTrack i{transition:none}
  *{scroll-behavior:auto}
}

/* ---------- A8 phone pass ----------
   The art made three existing phone problems worse, so they are fixed here
   rather than left for a handset to discover. */
@media screen and (max-width:820px){
  /* 1. The bottom tab bar is position:fixed, so it floats OVER the end of the
     page. Nothing reserved space for it. That was survivable with short
     panels; with taller art cards the last scenario card sat underneath it.
     env() keeps the gap correct on notched phones. */
  /* Side padding too: at <=820px the body margin is removed (body{margin:0}
     further down), so without this the Quick Play column runs edge to edge.
     The dots row and the tilt meter were being clipped off-screen right. */
  .qpWrap{padding:0 15px calc(76px + env(safe-area-inset-bottom))}

  /* 2. A 208px card is most of a phone screen. Shorter cards mean the player
     can see two scenarios at once and understands it is a list. */
  .qpScen{min-height:168px}

  /* 3. The stage art is behind a scrim and a blurred panel; at phone width it
     only has to cover ~360px, so lift the scrim slightly to keep the prompt
     at comfortable contrast on a bright-sunlight screen. */
  .qpStageScrim{background:linear-gradient(to bottom,
    rgba(13,13,18,.62) 0%, rgba(13,13,18,.82) 60%, rgba(13,13,18,.92) 100%)}

  /* 4. backdrop-filter is expensive to composite on mid-range phones and the
     panel is already translucent over a dark scrim. Drop the blur and raise
     the opacity instead: same legibility, far cheaper to paint. */
  .qpStage .qpCard{backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(21,21,31,.74)}
  .qpStage .qpOpt{backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(29,29,43,.86)}

  /* 5. The tilt meter. The two end words ate most of a 390px row and pushed
     the bar off-screen. Shrink them, kill the letter-spacing that was adding
     invisible width, and stop them shrinking the bar below usefulness. */
  .qpTiltEnd{font-size:9px;letter-spacing:.04em;white-space:nowrap;flex:0 0 auto}
  .qpTilt{gap:8px}
  .qpTiltBar{min-width:0}

  /* The 20 progress dots wrapped to a second row and collided with the tilt
     meter. Let them shrink instead of wrapping: 20 dots across 360px is
     ~13px each, still a clear progress read. */
  .qpDots{flex-wrap:nowrap;gap:3px}
  .qpDot{max-width:none;min-width:0}

  /* 6. WEIGHT. The two atmosphere overlays are 459K at desktop size, and a
     phone never shows them wider than ~390px. These -sm variants are 640px
     wide and total 133K -- a 326K saving on the exact connection least able
     to afford it. They are blurred haze, so the resolution drop is invisible.
     Declared INSIDE the media query so a phone never fetches the large pair. */
  .qpStageHum{background-image:url("../_art/humanity-atmosphere-sm.webp")}
  .qpStageBiz{background-image:url("../_art/bizarro-atmosphere-sm.webp")}

  /* 7. THE OPEN MENU IS TOO LONG. When expanded, the nav listed 5 sections
     PLUS 7 sub-rows -- 12 rows, more than a phone screen, so the player
     scrolled a table of contents to reach the game. The sub-rows are
     wayfinding for a desktop reader; on a phone the five sections plus the
     bottom tab bar are enough. Hide the sub-rows and let the menu fit. */
  body.navOpen .subNavRow{display:none}

  /* Make the open menu a scrollable overlay instead of pushing the page down,
     so opening it never moves the content a player was reading. */
  body.navOpen nav.engineNav{position:fixed;left:0;right:0;
    top:var(--headH,52px);bottom:0;z-index:50;overflow-y:auto;
    background:var(--ink);border-top:1px solid var(--line);margin:0;
    padding-bottom:calc(76px + env(safe-area-inset-bottom))}
  body.navOpen{overflow:hidden}

  /* The page heading is the first thing under the header: keep it tight so the
     game, not the title, occupies the first screen. */
  .contentTopRow h1{font-size:26px;margin:0}
  .pageLede{color:var(--muted);font-size:14px;line-height:150%;margin:6px 0 0}

  /* "Act 4 - The Reversal - beat 15 of 20" is one long line that wrapped and
     collided with the dots. Let it wrap deliberately and sit tighter. */
  #qpStep{font-size:12px;line-height:145%}

  /* The stage stretched to the viewport while the card inside was short,
     leaving a band of bare artwork under the options. Let it hug content. */
  .qpStage{margin-top:10px}

  /* Once play starts the intro copy is noise; the picker still shows it. */
  #qpPlay .qpBack{padding:10px 0 2px}

  /* RECLAIM THE FIRST SCREEN.
     On a 390x844 phone the brand bar plus the page heading and lede consumed
     the top ~175px on EVERY beat -- a quarter of the screen spent re-reading
     a title the player has already acted on. The heading matters when
     choosing a world; during play the story should own the screen.
     body.playing is set by quickplay.js only while a round is in progress. */
  body.playing .contentTopRow{display:none}
  body.playing header{position:sticky;top:0;z-index:30;
    background:rgba(13,13,18,.96);border-bottom:1px solid var(--line)}
  body.playing .siteHead{padding:8px 15px}
  body.playing .brand{font-size:15px}

  /* The site footer (sitemap, legal, disclaimer) appeared directly beneath the
     choices mid-beat, so the screen read "make a decision ... Four Axes,
     Scoring Contract". It belongs on the picker and the result, not inside a
     story. The disclaimer is still shown in both of those places. */
  body.playing footer,body.playing .disclaimer{display:none}
}

/* Very small phones: the realm art is decoration, and at this width the
   scenario cards are better as readable text than as thumbnails. */
@media screen and (max-width:360px){
  .qpScen{min-height:0}
  .qpScen::before{opacity:.38}
  /* Below 360 there is not enough room for a label column AND a usable bar.
     Stack instead: the label sits above its own bar, full width. Taller,
     but every bar stays identifiable, which is the whole point of drawing
     them separately. */
  .qpBarRow{flex-direction:column;align-items:stretch;gap:2px}
  .qpBarName{flex:none;letter-spacing:.06em}
  /* Switching to column turns flex:1 into a HEIGHT grow from a 0 basis,
     which collapsed the 6px track to nothing. Pin height, grow width. */
  .qpBarTrack{flex:none;width:100%;height:6px}
  .qpBars{gap:8px}
}

/* ---- disclaimer / footer ---- */
.disclaimer{border:1px solid var(--line);border-left:3px solid var(--gold);
  background:var(--panel);border-radius:8px;padding:16px 18px;margin:15px;
  color:var(--muted);font-size:13px;line-height:155%}
footer{border-top:1px solid var(--line);margin-top:40px}
.footerCol_Header{font-weight:500;margin-bottom:10px}
footer a{color:var(--muted);font-size:14px;line-height:200%}
footer a:hover{color:var(--text)}
#rightsMsg_top{color:var(--muted);font-size:13px}
#rightsMsg_top a{font-size:inherit}

@media screen and (max-width:1100px){
  .typeGrid{grid-template-columns:repeat(2,1fr)}
  .realmGrid{grid-template-columns:repeat(2,1fr)}
}
@media screen and (max-width:820px){
  [class*="col-"]{width:100%}
  .homeContent{grid-template-columns:1fr}
  .typeGrid,.realmGrid{grid-template-columns:1fr}
  .qOpts{grid-template-columns:1fr}
  h1{font-size:30px}.resultName{font-size:34px}

  /* Collapse the deep section nav behind a Menu button. */
  body{margin:0;padding:0 0 64px 0}
  /* flex, not block: the toggle holds an icon and a word side by side. */
  .navToggle{display:flex}
  .brandTag{display:none}
  .siteHead{padding:12px 15px}
  header{padding-bottom:0}
  nav.engineNav{display:none}
  body.navOpen nav.engineNav{display:block}
  .navRow,.subNavRow{font-size:16px}
  [class*="col-"]{padding:12px 15px}
  .navRow .col-5,.subNavRow .col-5{display:none}
  .navRow .col-6,.subNavRow .col-6{width:85%}
  .navRow .col-1,.subNavRow .col-1{width:15%}

  /* Bottom tabs replace the nav for the common journeys. */
  .tabBar{display:flex}
  .typeGrid,.realmGrid{padding:0 15px}
  .contentTopRow .col-5{padding-bottom:0}
  .contentTopRow .col-7{padding-top:4px}
  footer{margin-top:28px}
  .disclaimer{margin:15px 0}
}

/* ---- A3 result share: shared page + share card ---- */
.shNum{border-top:1px solid var(--line);margin-top:16px;padding-top:12px}
.shNumName{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--gold);margin-bottom:6px}
.shNumVal{font-size:15px;line-height:150%}
.shNumWhat{color:var(--muted);font-size:13px;line-height:150%;margin-top:6px}
.shNot{color:var(--muted);font-size:14px;line-height:152%;border-left:3px solid var(--gold)}
.shNot strong{color:var(--text)}
.shLink{width:100%;background:var(--panel-2);color:var(--text);border:1px solid var(--line);
  border-radius:8px;padding:12px;font:inherit;font-size:13px;margin:10px 0 0}
.shActions{display:flex;gap:8px;flex-wrap:wrap}
.shActions .btn{margin-top:12px}
