  .fs-line{fill:none;stroke:#dc2626;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
  .fs-volbar{fill:rgba(220,38,38,.34)}
  .fs-volbar.is-dn{fill:rgba(37,99,235,.32)}
  .fs-chart-dot{position:absolute;right:0;width:7px;height:7px;border-radius:50%;background:#dc2626;
    transform:translate(50%,-50%);box-shadow:0 0 0 3px rgba(220,38,38,.15),0 0 9px rgba(220,38,38,.5);
    transition:top .5s cubic-bezier(.2,.8,.2,1)}
  .fs-rail{position:relative;flex:none;width:34px}
  .fs-board .fs-ax{position:absolute;left:0;top:0;font-size:.5rem;font-weight:700;
    font-variant-numeric:tabular-nums;letter-spacing:.03em;color:rgba(26,26,31,.64);
    /* sits over the area fill, so give the glyphs a paper halo to stay legible */
    text-shadow:0 0 3px #fdf3f1,0 0 2px #fdf3f1;pointer-events:none}
  .fs-board .fs-ax--lo{top:67.5%}
  .fs-board .fs-chart-flag{position:absolute;right:0;padding:2px 4px;border-radius:4px;
    background:#dc2626;color:#fff;font-size:.58rem;font-weight:800;letter-spacing:0;
    font-variant-numeric:tabular-nums;transform:translateY(-50%);
    box-shadow:0 2px 8px rgba(220,38,38,.32);transition:top .5s cubic-bezier(.2,.8,.2,1)}
  .fs-board .fs-chart-flag.is-con{background:#2563eb;box-shadow:0 2px 8px rgba(37,99,235,.32)}
  /* Move since the round opened. Green when the room drifted toward Pro. */
  .fs-board .fs-delta{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border-radius:4px;
    font-size:.55rem;font-weight:800;letter-spacing:.02em;font-variant-numeric:tabular-nums;
    background:rgba(22,163,74,.12);color:#15803d}
  .fs-board .fs-delta.is-down{background:rgba(220,38,38,.1);color:#b91c1c}
  .fs-board .fs-delta.is-flat{background:rgba(26,26,31,.07);color:rgba(26,26,31,.64)}
  /* The first screen shows the simple audience read. The full price chart
     and credits ledger live on /predict, where visitors expect them. */
  .fs-chart,.fs-board .fs-delta{display:none}

  /* Market stats strip: audience, credits in play, leader's chance.
     Values tick with the price so the board reads as a live market. */
  /* A white fill read as nothing once the board itself went white
     (2026-07-23), so the strip recesses with a faint neutral tint. */
  .fs-mkt{display:flex;align-items:center;gap:0;margin-top:9px;border:1px solid rgba(26,26,31,.1);
    border-radius:10px;background:rgba(26,26,31,.025);overflow:hidden}
  .fs-mkt-cell{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px;padding:6px 5px;
    font-size:.56rem;font-weight:800;letter-spacing:.11em;text-transform:uppercase;color:rgba(26,26,31,.64);
    white-space:nowrap}
  .fs-mkt-cell + .fs-mkt-cell{border-left:1px solid rgba(26,26,31,.09)}
  /* The strip ships [hidden] until the board animation paints real values;
     the author display:flex above would beat the UA [hidden] rule (the
     documented /predict trap), so the guard is explicit. */
  .fs-mkt[hidden]{display:none}
  .fs-mkt-cell b{font-size:.88rem;font-weight:800;letter-spacing:0;font-variant-numeric:tabular-nums;color:#1a1a1f}
  .fs-mkt-cell--chance b{color:#dc2626}
  .fs-board .fs-mkt{display:none}

  /* Ballot payoff. */
  /* 2026-09-01: the odds strip is HIDDEN again (the founder, off a screenshot
     of the Owen/Grace percentage bar: it makes the page overwhelming). This
     re-retires the 2026-08-28 "spectator-heavy first screen" reveal. The
     engine stays live because its tick drives the board's clock, so hide it
     here rather than deleting markup or JS. Do not flip this back to
     display:block without a fresh founder call recorded in soul.md. */
  .fs-board .fs-odds{display:none}
  /* Reserves the scorecard's own height (2026-08-26). It was 88px, which
     was exactly one winner line plus a paragraph, and the scorecard is
     taller than that; without the reservation the link underneath jumps
     down every time a card settles. Re-measure this if the row metrics
     change: it wants to be the settled height and nothing more, or the
     waiting state pads the card out with dead space. */
  /* Reserve sized for the four-row card (2026-09-04), so the slot does
     not resize when the result lands and does not hold air before it. */
  .fs-ballot{border-top:1px solid rgba(245,239,231,.16);padding-top:11px;min-height:121px}
  /* 2026-09-07, the founder off a screenshot of the board: "make it just
     the resolution and judge eval taking less space on Y axis, never
     changing size". Under the tiles the card now holds exactly two
     things at fixed heights: a two-line resolution slot (clamped, never
     grows) and a 76px decision slot (label, winner, score; the speaker
     grid is off here as it already was on the phone). Challenge cards
     keep the same two slots so the card is the same height on every
     step of the rotator; their Start-a-round block is gone (Join a
     debate below is the door). Scoped to .fscreen so the phone home,
     which relocates this board into #mhome, keeps its own sizing. */
  .fscreen .fs-board h2.fs-motion{height:2.16em;min-height:0;margin-bottom:10px;overflow:hidden;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
  .fscreen .fs-board .fs-ballot{height:76px;min-height:0;padding-top:10px;overflow:hidden}
  .fscreen .fs-board .fs-ballot .fs-card{display:none !important}
  .fscreen .fs-board .fs-ballot-top{margin-bottom:0}
  .fscreen .fs-board.is-chal .fs-chal{display:none}
  .fscreen .fs-board.is-chal .fs-ballot{display:block}
  .fscreen .fs-board.is-chal .fs-ballot-wait .fs-wait-dot{display:none}
  /* Small label over the decision so the card names its own author: the
     AI judge. */
  .fs-ballot-k{display:block;margin-bottom:5px;font-size:.58rem;font-weight:800;letter-spacing:.13em;
    text-transform:uppercase;color:rgba(245,239,231,.68)}
  [data-theme="light"] .fs-ballot-k{color:rgba(26,26,31,.64)}
  [data-theme="light"] .fs-ballot{border-top-color:rgba(26,26,31,.12)}
  .fs-board .fs-ballot-wait{display:flex;align-items:center;gap:4px;font-size:.66rem;font-weight:800;
    letter-spacing:.1em;text-transform:uppercase;color:rgba(245,239,231,.68)}
  [data-theme="light"] .fs-board .fs-ballot-wait{color:rgba(26,26,31,.64)}
  .fs-board .fs-ballot-wait .fs-wait-dot{width:4px;height:4px;border-radius:50%;background:currentColor;animation:fsDot 1.3s infinite}
  .fs-board .fs-ballot-wait .d2{animation-delay:.18s}
  .fs-board .fs-ballot-wait .d3{animation-delay:.36s}
  @keyframes fsDot{0%,60%,100%{opacity:.3}30%{opacity:1}}
  .fs-ballot.is-in .fs-ballot-wait{display:none}
  .fs-ballot-card{display:none}
  .fs-ballot.is-in .fs-ballot-card{display:block;animation:fsRise .34s ease both}
  /* A paused entrance must never hide the decision after the waiting line clears. */
  @keyframes fsRise{from{transform:translateY(6px)}to{transform:none}}
  .fs-ballot-top{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:5px}
  .fs-board .fs-ballot-top b{font-family:var(--font-display);font-size:1.1rem;font-weight:700;color:#4ade80}
  [data-theme="light"] .fs-board .fs-ballot-top b{color:#16a34a}
  /* 2026-08-22, per the founder ("do it wins with points"): the speaker
     points are back on the verdict card. They were display:none'd in the
     07-25 prediction-layer de-emphasis, which left the card reading
     "X WINS" with no score at all. Name-attributed per side (set in JS)
     so a newcomer reads them as each person's points, not a sports line. */
  .fs-board .fs-ballot-top span{margin-left:auto;font-size:.78rem;font-weight:800;color:rgba(245,239,231,.78)}
  [data-theme="light"] .fs-board .fs-ballot-top span{color:rgba(26,26,31,.66)}
  .fs-board .fs-ballot-card p{margin:0;font-size:.78rem;line-height:1.5;color:rgba(245,239,231,.7)}
  [data-theme="light"] .fs-board .fs-ballot-card p{color:rgba(26,26,31,.64)}
  /* The scorecard. Five axes, one row each: label, the left seat's mark,
     a bar whose split is scaled off the margin between the two marks (the
     raw ratio makes a 9-6 axis look like a coin toss), the right seat's
     mark. The winner's name up top takes its own seat colour, so a red
     winner over a red-heavy card reads as one statement. It is ONE grid
     for the whole card rather than a grid per row, so the label column
     sizes itself to the longest label at any width and every bar still
     starts on the same line; per-row grids need a hardcoded label width
     and "Persuasion" outgrew it. */
  .fs-card{display:grid;grid-template-columns:auto 2.2ch 1fr 2.2ch;
    align-items:center;gap:3px 8px;margin-top:6px}
  /* line-height:1 on both text columns is what actually sets the row
     height: at the authored sizes the number's line box was taller than
     the bar, so every row carried about 6px of air it did not need and
     five rows of that was a third of the card. */
  .fs-board .fs-card-k{font-size:.6rem;font-weight:800;letter-spacing:.04em;line-height:1;
    color:rgba(245,239,231,.6);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  [data-theme="light"] .fs-board .fs-card-k{color:rgba(26,26,31,.58)}
  .fs-board .fs-card-n{font-family:var(--font-mono);font-variant-numeric:tabular-nums;
    font-size:.64rem;font-weight:700;letter-spacing:0;line-height:1;text-align:right;color:rgba(245,239,231,.5)}
  .fs-board .fs-card-n--b{text-align:left}
  [data-theme="light"] .fs-board .fs-card-n{color:rgba(26,26,31,.5)}
  /* The side that took the axis states its number at full strength; the
     other one stays quiet. Two numbers at equal weight would make every
     row look tied. */
  .fs-board .fs-card-n.is-up{color:#4ade80}
  .fs-board .fs-card-n--b.is-up{color:#f87171}
  [data-theme="light"] .fs-board .fs-card-n.is-up{color:#16a34a}
  [data-theme="light"] .fs-board .fs-card-n--b.is-up{color:#dc2626}
  .fs-card-bar{position:relative;height:5px;border-radius:999px;overflow:hidden;
    background:rgba(239,68,68,.4);display:block}
  [data-theme="light"] .fs-card-bar{background:rgba(220,38,38,.28)}
  .fs-card-bar i{position:absolute;left:0;top:0;bottom:0;border-radius:999px;
    background:rgba(74,222,128,.85);transition:width .5s ease}
  [data-theme="light"] .fs-card-bar i{background:rgba(22,163,74,.85)}
  /* The score line is the colour key: a dot per name in that seat's
     colour, which is why no legend row is needed above the axes. */
  .fs-board .fs-ballot-top span i{display:inline-block;width:6px;height:6px;border-radius:50%;
    margin-right:4px;vertical-align:baseline;background:#4ade80}
  .fs-board .fs-ballot-top span i.b{background:#f87171;margin-left:9px}
  [data-theme="light"] .fs-board .fs-ballot-top span i{background:#16a34a}
  [data-theme="light"] .fs-board .fs-ballot-top span i.b{background:#dc2626}
  .fs-board .fs-ballot-card.is-b .fs-ballot-top b{color:#f87171}
  [data-theme="light"] .fs-board .fs-ballot-card.is-b .fs-ballot-top b{color:#dc2626}
  @media(max-width:420px){
    .fs-card{gap:3px 6px}
    .fs-board .fs-card-k{font-size:.57rem}
    /* Narrow enough that the score line drops under the winner's name, so
       the settled card runs a line taller here than on desktop. */
    .fs-ballot{min-height:139px}
  }
  /* A judged example is proof, then an invitation. Keep the prompt in the
     site's oxblood action language instead of introducing a blue CTA. */
  .fs-bring{position:relative;z-index:4;display:inline-flex;align-items:center;gap:5px;margin-top:10px;
    color:#f87171;font-size:.72rem;font-weight:800;line-height:1.35;text-decoration:none}
  .fs-bring:hover{text-decoration:underline;text-underline-offset:3px}
  [data-theme="light"] .fs-bring{color:#b91c1c}
  .fs-board.is-chal .fs-bring{display:none}
  @media(prefers-reduced-motion:reduce){
    .fs-board .fs-tile-nm i,.fs-board .fs-odds-live i,.fs-board .fs-ballot-wait span{animation:none}
    .fs-open-fig svg,.fs-open-fig::before{animation:none}
    .fs-ballot.is-in .fs-ballot-card{animation:none}
    .fs-card-bar i{transition:none}
  }

  /* Challenge card (2026-08-24). A creator tile plus an empty seat, so the
     card has to LOSE the two things every other card carries: the ballot,
     because no round happened, and the clock, because nothing is running.
     Both are hidden on the state rather than removed from the DOM, so the
     next judged card in the rotation paints exactly as before. */
  .fs-chal{display:none}
  .fs-board.is-chal .fs-chal{display:block;border-top:1px solid rgba(245,239,231,.16);padding-top:11px;min-height:88px}
  [data-theme="light"] .fs-board.is-chal .fs-chal{border-top-color:rgba(26,26,31,.12)}
  .fs-board.is-chal .fs-ballot,.fs-board.is-chal .fs-clock{display:none}
  /* The speaking ring is a live signal. An unaccepted challenge has nobody
     speaking, so the ring comes off with the clock. */
  .fs-board.is-chal .fs-tile--speaking{box-shadow:none}
  .fs-board.is-chal .fs-tile-nm i{display:none}
  /* Creator portraits are head-and-shoulders press shots in a taller crop
     than the 16:9 tile, so centring them cuts the face at the chin. Bias the
     crop upward, which is where a head sits in all nineteen files. */
  .fs-board.is-chal .fs-tile--speaking img{object-position:50% 22%}
  .fs-board.is-chal.is-matched .fs-tile--speaking img{object-position:50% 50%}
  /* Empty seat: a dashed outline reading as a chair nobody is in, matching
     the .cs-claim dashed treatment further down the page. */
  .fs-board.is-chal .fs-tile--open{border:1px dashed rgba(245,239,231,.34);background:rgba(245,239,231,.05)}
  [data-theme="light"] .fs-board.is-chal .fs-tile--open{border-color:rgba(26,26,31,.3);background:rgba(255,255,255,.5)}
  .fs-board.is-chal .fs-tile--open img{opacity:0}
  /* The seat is not empty, it is UNTAKEN, and those read differently. A bare
     dashed rectangle read as a broken tile next to a live creator portrait;
     a figure sitting in the chair reads as the shape of the person who has
     not arrived yet. It is a flat anonymous silhouette on purpose: it must
     never be mistaken for a face, because nobody has accepted this
     challenge, and the standing rule is that no surface puts a picture of a
     person on a round that did not happen. Eight builds (hair, headwear,
     shoulder width) cycle across the ten challenge cards so the seat does
     not read as one stock person repeated. */
  .fs-open-fig{display:none;position:absolute;left:0;right:0;bottom:0;top:0;z-index:1;
    color:#f5efe7;pointer-events:none}
  [data-theme="light"] .fs-open-fig{color:#1a1a1f}
  .fs-you-avatar{display:none;position:absolute;inset:0;z-index:1;place-items:center;background:#171719}
  [data-theme="light"] .fs-you-avatar{background:#f1efeb}
  .fs-board.is-you .fs-you-avatar{display:grid}
  .fs-you-avatar > span{width:62% !important;max-width:140px;height:auto !important;aspect-ratio:1}
  .fs-you-avatar > svg{width:72%;height:100%;opacity:.35}
  .fs-board.is-chal .fs-tile--open .fs-open-fig{display:block}
  .fs-open-fig svg{position:absolute;left:50%;bottom:0;width:72%;height:auto;opacity:.3;
    transform:translateX(-50%);transform-origin:50% 100%;
    animation:fsSeatIdle 5.2s ease-in-out infinite}
  /* The halo is the waiting signal. It sits behind the figure and breathes
     on a slower cycle than the body, so the two never beat in lockstep. */
  .fs-open-fig::before{content:"";position:absolute;left:50%;top:52%;width:78%;aspect-ratio:1;
    transform:translate(-50%,-50%);border-radius:50%;
    background:radial-gradient(circle,rgba(220,38,38,.2),rgba(220,38,38,0) 68%);
    animation:fsSeatHalo 4.1s ease-in-out infinite}
  @keyframes fsSeatIdle{50%{transform:translateX(-50%) translateY(-2.5px) rotate(.8deg)}}
  @keyframes fsSeatHalo{0%,100%{opacity:.5;transform:translate(-50%,-50%) scale(.9)}
    50%{opacity:1;transform:translate(-50%,-50%) scale(1.06)}}
  .fs-chal-line{margin:0;font-size:.78rem;line-height:1.5;color:rgba(245,239,231,.78)}
  [data-theme="light"] .fs-chal-line{color:rgba(26,26,31,.7)}
  .fs-chal-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:10px}
  .fs-chal-cta{display:inline-flex;align-items:center;padding:9px 15px;border-radius:10px;
    background:#dc2626;color:#fff;font-size:.74rem;font-weight:800;text-decoration:none}
  .fs-chal-cta:hover{background:#b91c1c}
  .fs-chal-alt{font-size:.72rem;font-weight:700;color:rgba(245,239,231,.7);text-decoration:underline;
    text-underline-offset:3px}
  /* .fs-board-hit is an anchor at z-index 3 covering the whole card, so
     anything the visitor is meant to press has to clear it. Without this,
     both challenge buttons are dead: every click lands on the hit layer and goes to /spar, so
     "How the seat gets filled" never reaches #creator-sweepstakes and
     neither button ever shows its hover state. Lifted on the two
     anchors rather than on .fs-chal-row so the gaps around them still
     open the round like the rest of the card. */
  .fs-board .fs-chal-cta,
  .fs-board .fs-chal-alt{position:relative;z-index:4}
  [data-theme="light"] .fs-chal-alt{color:rgba(26,26,31,.62)}

  /* R01 (2026-09-25): the matched-you card's own action. Hidden on every
     other card; cleared above the .fs-board-hit layer like .fs-chal-cta. */
  .fs-board .fs-seat-cta{display:none;position:relative;z-index:4;align-items:center;gap:6px;
    margin-top:12px;padding:10px 16px;border-radius:11px;background:#dc2626;color:#fff;
    font-size:.78rem;font-weight:800;letter-spacing:-.01em;text-decoration:none;white-space:nowrap}
  .fs-board .fs-seat-cta:hover{background:#b91c1c}
  .fs-board.is-you .fs-seat-cta:not([hidden]){display:inline-flex}
  .fs-chal-note{margin:9px 0 0;font-size:.62rem;line-height:1.45;color:rgba(245,239,231,.5)}
  [data-theme="light"] .fs-chal-note{color:rgba(26,26,31,.5)}

  /* Swap fade. Everything that changes carries .is-swapping for one beat. */
  .fs-fade{transition:opacity .26s ease}
  .fs-board.is-swapping .fs-fade{opacity:.34}
  @media(prefers-reduced-motion:reduce){
    .fs-board.is-swapping .fs-fade{opacity:1}
    .fs-face,.fs-line{transition:none}
    .fs-board{transition:none}
    .fs-board:hover,.fs-board:focus-within{transform:none}
  }

  

/* The open seat's avatar clip (2026-10-11). Hidden until the file loads;
   shown only on the your-seat card, over the account avatar. */
.fs-board .fs-you-demo{display:none;position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:2;background:#e9e6df}
.fs-board.is-you.has-you-demo .fs-you-demo:not([hidden]){display:block}
.fs-board.is-you.has-you-demo .fs-you-avatar{display:none}
