/*
 * The game is a courtroom: the two parties at their lecterns facing the
 * bench, their statements, then the arbitrator's pad. The page is the
 * scene's own off-white, so the art blends into it. It keeps its colors in
 * light and dark mode, so text on it uses the room's ink, not the app's
 * colors.
 */
:root {
  /* The courtroom's palette, set on the kit's names so its sheets and buttons share it. */
  --gk-ink: #1d1b19;
  --gk-muted: #625b51;
  --gk-card: #fffdf7;
  --gk-line: #dcd8d0;
  --gk-radius: 6px;
  --gk-menu-ink: var(--gk-ink);
  /* What the kit has no name for. */
  --cg-wall: #f6f1e7;
  --cg-plate: #e3d9c4;
  --cg-pad: #fbf0a6;
  --cg-right: #2f7a4a;
  --cg-wrong: #b33a2e;
}

html,
body {
  background: var(--cg-wall);
}

#game {
  padding: 0;
}

/* The page holds a hidden copy of stage.svg for <use>; it must stay rendered for its patterns and filter. */
.cg-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}
.cg-defs svg {
  width: 0;
  height: 0;
}

.cg-inner {
  max-width: 640px;
  margin: 0 auto;
  padding: 0 16px;
}
.cg-inner.cg-wide {
  max-width: 920px;
}

/* The page: header, title, the courtroom with the statements, then the pad */
.cg-room {
  color: var(--gk-ink);
  padding: 16px 0 28px;
}
.cg-bar {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 4px;
}
.cg-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--gk-muted);
}
.cg-heading {
  margin: 0 0 6px;
  font-size: 28px;
  line-height: 1.15;
  color: var(--gk-ink);
}
.cg-heading {
  font-size: 34px;
}

/*
 * The courtroom: the lecterns at the two sides, the statements stacked
 * between them, the first speaker's on top. Sizes are in container units
 * (cqw), so the lecterns, the rail and the wall stay in proportion at any
 * width. The gap between the two bubbles is pinned at head height (24.4cqw
 * above the floor): the first bubble grows upward from it and the second
 * downward over the rail, so both tails meet the heads at any length.
 */
.cg-court-wrap {
  position: relative;
  container-type: inline-size;
  max-width: 880px;
  margin: 0 auto 14px;
}
/*
 * What people say over the courtroom (the ruling, a reply, an outburst)
 * sits on its own layer over it, outside the
 * courtroom's clipped edges, so a long line near a side or the top shows
 * in full.
 */
.cg-court-say {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
/*
 * The TV-court set (plaque, flags, a bench of onlookers): as wide as the
 * courtroom and 46cqw tall from the floor; on a phone, where the wide shot
 * is taller, it grows to match and crops at the sides.
 */
.cg-set {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 46cqw;
}
/*
 * The audience's lines, each over an onlooker's head in the pews. The pews
 * drawing is 720 units across and anchored at the floor; --s is one unit in
 * cqw and --ox where the drawing starts (on a phone it's drawn larger and
 * centered, cropping at the sides). Each line pops in after its delay (--d),
 * holds, and fades.
 */
.cg-crowd-say {
  --s: calc(100cqw / 720);
  --ox: 0cqw;
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}
.cg-crowd-line {
  position: absolute;
  left: calc(var(--ox) + var(--x) * var(--s));
  bottom: calc(130 * var(--s));
  translate: -50% 0;
  width: max-content;
  max-width: 180px;
  margin: 0;
  padding: 3px 10px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  font-style: italic;
  color: var(--gk-ink);
  background: var(--gk-card);
  border: 1.5px solid var(--gk-ink);
  border-radius: 10px;
  opacity: 0;
  animation: cg-crowd 3.4s var(--d, 0s) ease-out both;
}
/* Speech-bubble tails: a small square turned 45°, outlined on its two lower sides, half over the bubble's edge so the edge runs into the point. */
.cg-crowd-line::after {
  content: "";
  position: absolute;
  top: calc(100% - 5px);
  left: 50%;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  box-sizing: border-box;
  background: var(--gk-card);
  border-right: 1.5px solid var(--gk-ink);
  border-bottom: 1.5px solid var(--gk-ink);
  rotate: 45deg;
}
@keyframes cg-crowd {
  0% {
    opacity: 0;
    transform: translateY(6px) scale(0.85);
  }
  10% {
    opacity: 1;
    transform: none;
  }
  80% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* The show's name on the sign, in the game's serif. */
.cg-sign {
  font-family: var(--gk-serif, var(--font-serif, Georgia, serif));
  font-size: 23px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.cg-court {
  position: relative;
  display: grid;
  border-radius: 10px;
  grid-template-columns: 21cqw 1fr 21cqw;
  gap: 0 1.5cqw;
  align-items: end;
  overflow: hidden;
}
.cg-wall,
.cg-rail {
  position: absolute;
  left: 0;
  width: 100%;
}
.cg-wall {
  top: 0;
  height: 100%;
}
/* The rail runs 100 lectern units up from the floor: 100/224 of a lectern's width. */
.cg-rail {
  bottom: 0;
  height: 9.4cqw;
}
.cg-stand {
  position: relative;
}
.cg-stand.is-left {
  grid-column: 1;
}
.cg-stand.is-right {
  grid-column: 3;
}
.cg-lectern {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
.cg-talk {
  grid-column: 2;
  position: relative;
  z-index: 1;
  align-self: stretch;
  display: grid;
  grid-template-rows: 1fr minmax(24.4cqw, auto);
  row-gap: 14px;
  padding: 3cqw 0 2cqw;
}
.cg-bubble {
  position: relative;
  background: var(--bubble-fill, var(--gk-card));
  border: 2px solid var(--gk-ink);
  border-radius: 16px;
  padding: 9px 12px 11px;
}
.cg-bubble.is-left {
  align-self: end;
}
.cg-bubble.is-right {
  align-self: start;
}
.cg-bubble.is-unheard {
  visibility: hidden;
}
.cg-tail {
  position: absolute;
  width: 30px;
  height: 30px;
  overflow: visible;
}
.cg-bubble.is-left .cg-tail {
  left: -28px;
  bottom: 6px;
}
.cg-bubble.is-right .cg-tail {
  right: -28px;
  top: 6px;
}
.cg-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 6px;
  margin: 0 0 3px;
  font-size: 15px;
}
.cg-role {
  color: var(--gk-muted);
  font-size: 13px;
}
.cg-says {
  margin: 0;
  font-size: 16px;
  line-height: 1.5;
}
.cg-face {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid var(--gk-ink);
  background: var(--gk-card);
  box-sizing: border-box;
}

/*
 * A method question is about one speaker: their statement takes the pad's
 * yellow, as if the arbitrator ran a highlighter over it, and the question
 * on the pad carries their face.
 */
.cg-bubble,
.cg-card {
  transition: background-color 0.3s ease;
}
.cg-scene.is-asking-0 .is-left,
.cg-scene.is-asking-1 .is-right {
  --bubble-fill: var(--cg-pad);
}
.cg-point-text.cg-asking {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* The loser's reply to your line comes a beat after it (Kevin, 2026-10-26: you speak first, then they react). */
.cg-scene.is-closed .cg-insult.is-reply {
  animation-delay: 0.9s;
}
/*
 * Once the case is closed, the statements fade where they are (so nothing
 * changes size), and the loser's outburst (two or three lines) sits over
 * their head, inside the courtroom's faded edges.
 */
.cg-talk,
.cg-card {
  transition: opacity 0.4s ease;
}
.cg-scene.is-closed .cg-talk,
.cg-scene.is-closed .cg-card {
  opacity: 0;
}
.cg-insult.is-outburst {
  white-space: normal;
  width: max-content;
  max-width: 27cqw;
  translate: 0 0;
}
.cg-insult.is-outburst.is-left {
  left: 5cqw;
  translate: none;
}
.cg-insult.is-outburst.is-right {
  left: auto;
  right: 5cqw;
  translate: none;
}
.cg-insult.is-outburst::after {
  left: 45%;
  right: auto;
}

/*
 * What the player says with the ruling: a dark speech bubble labeled YOU,
 * its tail pointing down to the bench, where the player sits (Kevin,
 * 2026-10-25: not across the top of the room, and not inside the card). On
 * a wide screen it sits under the statements over the rail, with the card
 * under it. On a phone it rises from the docked card at the bottom, the
 * player's side of the screen (Kevin, 2026-10-26), and the loser's reply
 * stands just under the courtroom, under their lectern. The loser answers a
 * beat later.
 */
.cg-you-say {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: center;
  margin: 0 auto 18px;
}
/* Your line and the card share a dock on a phone; on a wide screen it adds no box. */
.cg-dock {
  display: contents;
}
.cg-insult-name {
  display: none;
}
.cg-judge-line.is-bubble {
  position: relative;
  max-width: 62%;
  border-radius: 16px;
}
.cg-judge-line.is-bubble::after {
  content: "";
  position: absolute;
  top: calc(100% - 7px);
  left: 50%;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  background: var(--gk-ink);
  rotate: 45deg;
}
.cg-judge-line {
  margin: 0;
  padding: 8px 14px 10px;
  background: var(--gk-ink);
  color: var(--gk-card);
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  animation: cg-pop 0.28s ease-out both;
}
.cg-judge-line b {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.7;
}
.cg-scene.is-closed .cg-insult.is-outburst {
  animation-delay: 0.9s;
}

/* The ruling on the pad, under the case's marks */
.cg-ruling {
  margin: 16px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--gk-line);
}
.cg-bins.is-two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.cg-ruled-panel {
  text-align: center;
}
.cg-ruled {
  margin: 0 0 12px;
  font-size: 16px;
}

/*
 * The announcer's card as the parties walk in: "Up next:" and the case's
 * topic, with the button to go on.
 */
.cg-narration {
  max-width: 600px;
  margin: 0 auto 12px;
  background: var(--gk-card);
  border: 2px solid var(--gk-ink);
  border-radius: 12px;
  padding: 12px 16px 14px;
}
.cg-narration.is-arriving {
  animation: cg-rise 0.4s 0.35s ease-out both;
}
/* The announcer's line for the case. */
.cg-up-next {
  margin: 0;
  font-size: 17px;
  line-height: 1.4;
}
.cg-up-next b {
  font-weight: 700;
}
/* The part of an announcer's line not typed yet: laid out, so nothing moves, but unseen. */
.cg-untyped {
  color: transparent;
}
.cg-typed {
  cursor: pointer;
}

/* The announcer's intro after "Start the hearing", in the dark caption the ruling uses. */
.cg-announcer {
  max-width: 600px;
  margin: 0 auto 14px;
  padding: 10px 16px 12px;
  background: var(--gk-ink);
  color: var(--gk-card);
  border-radius: 12px;
  font-size: 16px;
  line-height: 1.45;
  text-align: center;
}
.cg-announcer + .cg-continue {
  text-align: center;
}
/* The announcer's intro types in a typewriter face, to go with the key clicks; the ANNOUNCER label stays in the app's sans. */
.cg-announcer {
  font-family: "Courier Prime", "Courier New", Courier, monospace;
}
.cg-announcer b {
  font-family: var(--font-sans, "Lexend", sans-serif);
  display: block;
  margin-bottom: 2px;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.7;
}

/* After the first statement, only the button: no card around it. */
.cg-narration.is-continuing {
  background: none;
  border: 0;
  padding: 0;
}
.cg-narration .cg-continue {
  margin-top: 10px;
}

/* The phone parts (cards, the strip) stay out of the desktop layout. */
.cg-cards,
.cg-strip {
  display: none;
}

/* A small argument, unless motion is reduced */
.cg-figure {
  transform-box: fill-box;
  transform-origin: 50% 90%;
  animation: cg-argue 1.8s ease-in-out infinite;
}
.cg-figure-1 {
  animation-delay: -0.9s;
}
@keyframes cg-argue {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(1.5deg);
  }
}

/*
 * The reaction moment after a point is filed: the reaction face shows for
 * about two seconds, with a nod, a shake or a tilt, then the usual angry
 * face comes back. Under reduced motion the reaction face simply stays.
 */
.cg-usual-face {
  animation: cg-usual-face 2.4s ease forwards;
}
.cg-react-face {
  animation: cg-react-face 2.4s ease forwards;
}
@keyframes cg-usual-face {
  0%,
  85% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes cg-react-face {
  0%,
  85% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
.cg-react {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}
.cg-react-nod {
  animation: cg-nod 0.8s ease-in-out 2;
}
.cg-react-shake {
  animation: cg-shake 0.7s ease-in-out 2;
}
.cg-react-tilt {
  animation: cg-tilt 1.4s ease-in-out;
}
@keyframes cg-nod {
  0%,
  50%,
  100% {
    transform: translateY(0);
  }
  25% {
    transform: translateY(6px);
  }
  75% {
    transform: translateY(4px);
  }
}
@keyframes cg-shake {
  0%,
  100% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(-5px);
  }
  75% {
    transform: translateX(5px);
  }
}
@keyframes cg-tilt {
  0%,
  100% {
    transform: rotate(0deg);
  }
  30%,
  70% {
    transform: rotate(-10deg);
  }
}

/*
 * Opening a dispute: each statement pops in as its person speaks, and the
 * pad slides up when the player is ready to take notes. Statements not yet spoken keep their
 * space so nothing jumps when they arrive.
 */
.cg-bubble.is-arriving,
.cg-card.is-arriving {
  animation: cg-pop 0.28s ease-out;
}
.cg-pad.is-arriving {
  animation: cg-rise 0.32s ease-out;
}
@keyframes cg-pop {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes cg-rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/*
 * The entrance: each person walks in from their side of the courtroom,
 * bobbing, and steps up behind their lectern. Between cases the last two
 * walk back out the same way first.
 */
.cg-enter-0 {
  animation: cg-enter-left 1.1s ease-out both;
}
.cg-enter-1 {
  animation: cg-enter-right 1.1s ease-out both;
}
@keyframes cg-enter-left {
  0% {
    opacity: 0;
    transform: translateX(-230px);
  }
  18% {
    opacity: 1;
  }
  82%,
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}
@keyframes cg-enter-right {
  0% {
    opacity: 0;
    transform: translateX(230px);
  }
  18% {
    opacity: 1;
  }
  82%,
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}
.cg-exit-0 {
  animation: cg-exit-left 1s ease-in both;
}
.cg-exit-1 {
  animation: cg-exit-right 1s ease-in both;
}
@keyframes cg-exit-left {
  to {
    opacity: 0;
    transform: translateX(-230px);
  }
}
@keyframes cg-exit-right {
  to {
    opacity: 0;
    transform: translateX(230px);
  }
}
.cg-exit .cg-bob,
.cg-enter .cg-bob {
  animation: cg-bob 0.2s ease-in-out 4 alternate;
}
@keyframes cg-bob {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-10px);
  }
}
/* The insults sit on their own layer over the courtroom, just above each head (27.9cqw above the floor). */
.cg-insults {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.cg-insult {
  position: absolute;
  bottom: 29cqw;
  margin: 0;
  padding: 4px 11px;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 700;
  color: var(--gk-ink);
  background: var(--gk-card);
  border: 2px solid var(--gk-ink);
  border-radius: 12px;
  animation: cg-pop 0.28s ease-out both;
}
.cg-insult.is-left {
  left: 10.5cqw;
  translate: -25% 0;
}
.cg-insult.is-right {
  left: calc(100% - 10.5cqw);
  translate: -75% 0;
  animation-delay: 0.6s;
}
.cg-insult::after {
  content: "";
  position: absolute;
  top: calc(100% - 6.5px);
  width: 13px;
  height: 13px;
  box-sizing: border-box;
  background: var(--gk-card);
  border-right: 2px solid var(--gk-ink);
  border-bottom: 2px solid var(--gk-ink);
  rotate: 45deg;
}
.cg-insult.is-left::after {
  left: 22%;
}
.cg-insult.is-right::after {
  right: 22%;
}

.cg-continue {
  display: flex;
  justify-content: center;
  min-height: 44px;
  margin: 4px 0 0;
}

/*
 * Phone (under 600px): the courtroom is a wide shot of both lecterns side
 * by side, and the statements follow it as speaker cards at full width.
 * Once the courtroom scrolls away, a strip with both faces sticks to the
 * top; the pad docks at the bottom of the screen, so the point and its
 * choices stay in thumb reach while the statements scroll above.
 */
@media (max-width: 599px) {
  .cg-court {
    display: flex;
    justify-content: center;
    gap: 18%;
    padding-top: 10px;
  }
  .cg-stand {
    width: 32%;
  }
  .cg-talk {
    display: none;
  }
  .cg-court .cg-rail {
    height: 14.3cqw;
  }
  /* Heads stand 42.6cqw above the floor, centered on each lectern (25% and 75% across). */
  .cg-insult {
    bottom: 43.5cqw;
    font-size: 14px;
  }
  .cg-insult.is-left {
    left: 25cqw;
  }
  .cg-insult.is-right {
    left: 75cqw;
  }
  .cg-insult.is-outburst {
    max-width: 42cqw;
  }
  .cg-insult.is-outburst.is-left {
    left: 4cqw;
  }
  .cg-insult.is-outburst.is-right {
    right: 4cqw;
  }
  /*
   * On a phone the heads sit at the top of the wide shot with no room
   * above them, so your ruling and the loser's outburst sit over the faded
   * cards under the courtroom, tails up (the outburst on the loser's side).
   */
  .cg-court-say {
    display: none;
  }
  .cg-set {
    height: 70cqw;
  }
  .cg-crowd-say {
    --s: calc(70cqw / 331);
    --ox: calc(50cqw - 360 * 70cqw / 331);
  }
  /*
   * Once the first speaker is heard the courtroom folds away to make room
   * for the statements and the pad, and the strip with both faces takes its
   * place; it opens again for the ruling and stays through the next walk-in.
   */
  .cg-court-wrap {
    max-height: 120vw;
    overflow: hidden;
    transition:
      max-height 0.45s ease,
      margin-bottom 0.45s ease;
  }
  /* The button to go on follows the statement cards, so it comes after reading. */
  .cg-scene {
    display: flex;
    flex-direction: column;
  }
  /* In the column, auto side margins would shrink these to their content (the courtroom to nothing), so they keep the full width. */
  .cg-scene > .cg-court-wrap,
  .cg-scene > .cg-narration {
    width: 100%;
  }
  .cg-scene > .cg-narration.is-continuing {
    order: 1;
    margin: 4px 0 16px;
  }
  /* A statement not yet heard takes no space here, so the button sits right under the last one heard. */
  .cg-card.is-unheard {
    display: none;
  }
  .cg-scene.is-folded .cg-court-wrap {
    max-height: 0;
    margin-bottom: 0;
  }
  /* With the courtroom folded, the strip takes its own row at the top instead of covering the header. */
  .cg-inner:has(.cg-scene.is-folded) > .cg-strip {
    margin-bottom: 10px;
  }
  /* The two sides face off across the strip; the gallery's line hangs just under its middle. */
  .cg-vs {
    font-family: var(--gk-serif, var(--font-serif, Georgia, serif));
    font-size: 17px;
    font-weight: 700;
    font-style: italic;
    color: var(--gk-muted);
  }
  /* With the courtroom folded, the speakers' roles step aside for the statements. */
  .cg-scene.is-folded .cg-card .cg-role {
    display: none;
  }

  /* On a phone the parties' heads stand where the sign is, so it shows only while the lecterns are empty. */
  .cg-court.has-people .cg-set-sign {
    display: none;
  }
  /* Your line and the card dock together at the bottom, your line just above the card. */
  .cg-dock {
    display: block;
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin-top: 18px;
  }
  .cg-dock .cg-pad.is-docked {
    position: relative;
    margin-top: 0;
  }
  .cg-you-say {
    margin: 0 0 14px;
  }
  .cg-you-say .cg-judge-line {
    max-width: 92%;
    font-size: 15px;
  }
  .cg-cards-say {
    position: absolute;
    z-index: 2;
    top: 4px;
    left: 0;
    right: 0;
    display: grid;
    gap: 8px;
  }
  /* The reply, named, centered under its speaker's lectern (a quarter in from their side), tail pointing up at them. */
  .cg-insult.is-under {
    position: relative;
    bottom: auto;
    justify-self: start;
    left: 25%;
    translate: -50% 0;
    width: max-content;
    max-width: 50%;
    white-space: normal;
  }
  .cg-insult.is-under.is-right {
    left: 75%;
  }
  .cg-insult.is-under::after {
    top: auto;
    bottom: calc(100% - 6.5px);
    border: 0;
    border-left: 2px solid var(--gk-ink);
    border-top: 2px solid var(--gk-ink);
  }
  .cg-insult.is-under.is-left::after,
  .cg-insult.is-under.is-right::after {
    left: calc(50% - 6.5px);
    right: auto;
  }
  .cg-insult-name {
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--gk-muted);
  }

  .cg-cards {
    position: relative;
    display: grid;
    gap: 12px;
    margin: 0 0 4px;
  }
  .cg-card {
    display: flow-root;
    background: var(--bubble-fill, var(--gk-card));
    border: 2px solid var(--gk-ink);
    border-radius: 12px;
    padding: 9px 11px 11px 9px;
  }
  .cg-card.is-right {
    padding: 9px 9px 11px 11px;
  }
  .cg-card.is-unheard {
    visibility: hidden;
  }
  .cg-card-scene {
    position: relative;
    float: left;
    width: 30%;
    margin: 0 11px 4px 0;
    border: 1.5px solid var(--gk-ink);
    border-radius: 8px;
    overflow: hidden;
  }
  .cg-card.is-right .cg-card-scene {
    float: right;
    margin: 0 0 4px 11px;
  }
  .cg-card-scene .cg-rail {
    height: 30%;
  }
  .cg-card-scene .cg-lectern {
    position: relative;
  }
  .cg-card.is-flash {
    animation: cg-flash 1.2s ease;
  }
  @keyframes cg-flash {
    0%,
    100% {
      box-shadow: 0 0 0 0 rgba(240, 214, 90, 0);
    }
    30% {
      box-shadow: 0 0 0 7px rgba(240, 214, 90, 0.9);
    }
  }

  .cg-strip {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 56px;
    margin: 0 -16px -56px;
    padding: 0 12px;
    background: #ebe1cc;
    border-bottom: 2px solid var(--gk-ink);
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition:
      opacity 0.2s ease,
      transform 0.2s ease;
  }
  .cg-strip.is-shown {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .cg-jump {
    display: flex;
    align-items: center;
    gap: 6px;
    font: inherit;
    font-size: 14px;
    font-weight: 700;
    color: var(--gk-ink);
    background: var(--gk-card);
    border: 2px solid var(--gk-ink);
    border-radius: 999px;
    padding: 3px 12px 3px 3px;
    min-height: 44px;
    cursor: pointer;
  }
  .cg-jump.is-right {
    flex-direction: row-reverse;
    padding: 3px 3px 3px 12px;
  }

  /* The docked pad keeps one height whatever it holds (a long one scrolls inside), so the screen doesn't jump. */
  .cg-pad.is-docked {
    position: sticky;
    bottom: 0;
    z-index: 2;
    max-height: 420px;
    overflow-y: auto;
    margin: 18px -16px 0;
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.16);
  }
  .cg-room {
    padding-bottom: 0;
  }
}

@media (min-width: 600px) {
  .cg-wide .cg-pad {
    max-width: 880px;
    margin: 0 auto;
  }
  /* The bench: as wide as the statements' column, between the lecterns, lifted over the rail by tuckPad. */
  .cg-wide .cg-pad.is-bench {
    z-index: 5;
    width: 56%;
    max-width: none;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cg-figure,
  .cg-react,
  .cg-narration.is-arriving,
  .cg-enter,
  .cg-enter .cg-bob,
  .cg-exit,
  .cg-exit .cg-bob,
  .cg-insult,
  .cg-bubble.is-arriving,
  .cg-card.is-arriving,
  .cg-card.is-flash,
  .cg-pad.is-arriving {
    animation: none;
  }
  .cg-usual-face {
    animation: none;
    opacity: 0;
  }
  .cg-react-face {
    animation: none;
    opacity: 1;
  }
  .cg-court-wrap {
    transition: none;
  }
  .cg-strip {
    transition: none;
  }
}

/*
 * The arbitrator's panel (Kevin, 2026-10-25): no prop, a white card like
 * the prompts in 7Sage's other games, with thin gray borders and the app's
 * blue for the main button and a picked choice. Fixed light colors, since
 * the courtroom keeps its light colors in dark mode too.
 */
.cg-pad {
  position: relative;
  z-index: 1;
  background: #fff;
  border: 1px solid var(--gk-line);
  border-radius: 14px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  padding: 20px;
}
.cg-pad-lead {
  margin: 0 0 16px;
  font-size: 17px;
  line-height: 1.5;
}
.cg-point-label {
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--gk-muted);
}
.cg-point-text {
  margin: 0 0 18px;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.35;
}
.cg-bins {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.cg-bin {
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--gk-ink);
  background: var(--gk-card);
  border: 1.5px solid var(--gk-ink);
  border-radius: 6px;
  padding: 11px 8px;
  cursor: pointer;
}
.cg-bin:hover,
.cg-option:hover,
.cg-who-pick:hover {
  background: var(--cg-wall);
}
/* Settling a case: the question options, and the stamp that closes it */
.cg-options {
  display: grid;
  gap: 8px;
}
.cg-option {
  font: inherit;
  font-size: 16px;
  text-align: left;
  color: var(--gk-ink);
  background: var(--gk-card);
  border: 1.5px solid var(--gk-ink);
  border-radius: 6px;
  padding: 10px 14px;
  cursor: pointer;
}

.cg-ask {
  margin: 0 0 12px;
  font-size: 15px;
}
.cg-link {
  font: inherit;
  font-size: 14px;
  color: var(--gk-ink);
  background: none;
  border: none;
  padding: 0 0 0 4px;
  text-decoration: underline;
  cursor: pointer;
}

/* In the game's own flow a button is as wide as its label; the kit's sheets keep theirs full width. */
#game .gk-button {
  width: auto;
  padding: 10px 20px;
}

/* The courtroom's primary button: a parchment plate with an ink outline, like the sign. */
.gk-button-primary,
.gk-button-primary:hover {
  font-family: var(--gk-serif, var(--font-serif, Georgia, serif));
  color: var(--gk-ink);
  background: var(--cg-plate);
  border: 2px solid var(--gk-ink);
  box-shadow: 3px 3px 0 var(--gk-ink);
  filter: none;
}
.gk-button-primary:hover {
  background: var(--gk-card);
}
.gk-button-primary:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--gk-ink);
}

/* Feedback */
.cg-verdict {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 600;
}
.cg-feedback.is-right .cg-verdict {
  color: var(--cg-right);
}
.cg-feedback.is-wrong .cg-verdict {
  color: var(--cg-wrong);
}
.cg-why {
  margin: 12px 0 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--gk-muted);
}

/* On a phone the three choices stay in one row, so the docked pad stays short. */
@media (max-width: 480px) {
  .cg-bins {
    gap: 6px;
  }
  .cg-bin {
    font-size: 14px;
    padding: 8px 4px;
    min-height: 48px;
  }
  .cg-heading {
    font-size: 30px;
  }
}

/* Where each view comes from, marked in the statements once the notes are filed. */
.cg-view {
  background: #ffe27a;
  color: inherit;
  border-radius: 3px;
  padding: 0 2px;
  box-decoration-break: clone;
}
.cg-view.is-near {
  background: none;
  text-decoration: underline dashed #8a7f6c;
  text-underline-offset: 3px;
}
.cg-view-tag {
  margin-left: 8px;
  padding: 1px 8px;
  line-height: 1;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  border: 1.5px solid currentColor;
}
.cg-view-tag.is-yes {
  color: #2f6b3a;
}
.cg-view-tag.is-no {
  color: #a2382b;
}
.cg-view-tag.is-none {
  color: #6f675b;
}
.cg-view-key {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--gk-muted);
}

/*
 * The sheet, one point at a time: the point written straight on the pad,
 * its three choices, then a dot per point with the count. Each point is
 * graded as soon as it's answered: its dot takes a check or a cross, and
 * the pad shows right or not with the answer (and, on a miss, why).
 */
.cg-step-row {
  margin: 0;
}
.cg-step-text {
  margin: 0 0 10px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.35;
}
.cg-sheet-bins {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.cg-sheet-bins .cg-bin {
  min-height: 40px;
  padding: 6px 8px;
  font-size: 14px;
}
.cg-bin.is-picked,
.cg-who-pick.is-picked {
  background: var(--cg-plate);
  box-shadow: inset 0 0 0 1px var(--gk-ink);
}
.cg-sheet-who {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin-top: 8px;
  font-size: 14px;
}
.cg-who-pick {
  font: inherit;
  font-weight: 600;
  min-height: 34px;
  padding: 4px 12px;
  border: 1.5px solid var(--gk-ink);
  border-radius: 999px;
  background: var(--gk-card);
  color: var(--gk-ink);
  cursor: pointer;
}
/*
 * The case's points as a row of small dots at the top of the card, all one
 * size: green or red once graded, ink for the one being answered, hollow
 * for those to come; the one on show has a ring. At the ruling the score
 * sits to their right.
 */
.cg-step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: -6px 0 2px -10px;
}
.cg-dots {
  display: flex;
}
.cg-dot {
  position: relative;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.cg-dot::after {
  content: "";
  position: absolute;
  top: 10px;
  left: 10px;
  width: 12px;
  height: 12px;
  box-sizing: border-box;
  border: 1.5px solid #b9b2a6;
  border-radius: 50%;
}
.cg-dot.is-current::after {
  background: var(--gk-ink);
  border-color: var(--gk-ink);
}
.cg-dot.is-right::after {
  background: var(--cg-right);
  border-color: var(--cg-right);
}
.cg-dot.is-wrong::after {
  background: var(--cg-wrong);
  border-color: var(--cg-wrong);
}
.cg-dot.is-showing.is-right::after,
.cg-dot.is-showing.is-wrong::after {
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 3.5px currentColor;
}
.cg-dot.is-right {
  color: var(--cg-right);
}
.cg-dot.is-wrong {
  color: var(--cg-wrong);
}
.cg-step-count {
  font-size: 13px;
  color: var(--gk-muted);
}
.cg-result {
  margin: 0;
}
/*
 * A graded point: the three answers stay where they were and show the
 * result (the right one green with a check, a wrong pick red with a cross,
 * the third dimmed), then the explanation, led by Right or Not quite, in
 * lines of about 64 characters, with the button at the right.
 */
.cg-sheet-bins.is-graded .cg-bin {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: default;
}
.cg-sheet-bins.is-graded .cg-bin.is-answer {
  background: #e8f3ec;
  border-color: var(--cg-right);
  color: #1f5a35;
}
.cg-sheet-bins.is-graded .cg-bin.is-miss {
  background: #fbecea;
  border-color: var(--cg-wrong);
  color: var(--cg-wrong);
}
.cg-sheet-bins.is-graded .cg-bin.is-other {
  opacity: 0.45;
}
/* "Your pick" sits on the top edge of the answer you chose (Kevin, 2026-10-25). */
.cg-sheet-bins.is-graded {
  margin-top: 6px;
}
.cg-sheet-bins.is-graded .cg-bin {
  position: relative;
}
.cg-pick-badge {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -55%;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--gk-ink);
  color: var(--gk-card);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.cg-result-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-top: 14px;
}
.cg-result-why {
  margin: 0;
  max-width: 64ch;
  font-size: 15px;
  line-height: 1.5;
  color: var(--gk-muted);
}
.cg-result-foot .gk-button-primary {
  flex: none;
  margin-left: auto;
}
.cg-result-why .cg-verdict {
  font-size: inherit;
}
.cg-verdict.is-right {
  color: var(--cg-right);
}
.cg-verdict.is-wrong {
  color: var(--cg-wrong);
}
/* The question under the point (Kevin, 2026-10-25: the point first, so "that" points back to it). */
.cg-step-ask {
  margin: 0 0 16px;
  font-size: 14px;
  color: var(--gk-muted);
}
.cg-step-text:has(+ .cg-step-ask) {
  margin-bottom: 4px;
}

/* Phone: a tighter sheet, after the sheet's own rules so these win. */
@media (max-width: 599px) {
  .cg-step-text {
    font-size: 15.5px;
    margin-bottom: 8px;
  }
  .cg-sheet-bins {
    display: flex;
    gap: 6px;
  }
  .cg-sheet-bins .cg-bin {
    flex: 1 1 auto;
    min-height: 36px;
    padding: 4px 3px;
    font-size: 13px;
    white-space: nowrap;
  }
  .cg-sheet-who {
    margin-top: 6px;
  }
  .cg-sheet-who span {
    flex-basis: 100%;
  }
  .cg-who-pick {
    min-height: 32px;
  }
  .cg-result-why {
    font-size: 14px;
  }
  .cg-result-foot {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .cg-result-foot .gk-button-primary {
    width: 100%;
  }
  /* A long explanation scrolls inside the docked card; the button to go on stays in reach at its bottom. */
  .cg-pad.is-docked .cg-result-foot .gk-button-primary {
    position: sticky;
    bottom: 0;
    box-shadow: 0 -14px 12px 2px #fff;
  }
  .cg-sheet-bins.is-graded .cg-bin {
    white-space: normal;
  }
  .cg-step-ask {
    margin-bottom: 14px;
    font-size: 13px;
    line-height: 1.3;
  }
  .cg-step-text:has(+ .cg-step-ask) {
    margin-bottom: 2px;
  }
}

/*
 * The title card (the start screen, and the announcer's intro after it):
 * the game's name small and centered, the courtroom framed as one picture
 * (a thin border, rounded on all four corners, a floor under the rail), then
 * the button, all centered.
 */
.cg-title-card .cg-inner {
  text-align: center;
}
/* The page's heading, for screen readers only: the sign in the courtroom is the visible title. */
.cg-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.cg-scene.is-title .cg-court-wrap {
  margin-bottom: 28px;
}
.cg-scene.is-title .cg-court {
  /* An outline, not a border, so the frame takes no room and the courtroom keeps the first case's exact size. */
  outline: 1.5px solid var(--gk-ink);
  outline-offset: -1.5px;
  border-radius: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
}
/* The floor under the rail, a shade darker than the page, so the lecterns stand on something. */
.cg-scene.is-title .cg-rail rect:first-child {
  fill: #e6dcc6;
}
.cg-title-start {
  min-width: 220px;
}
.cg-title-card .cg-announcer {
  text-align: center;
}
@media (max-width: 599px) {
  .cg-title-start,
  .cg-title-card .cg-continue .gk-button-primary {
    width: 100%;
  }
}

/*
 * The end of a run: a short card (score, the three answers, the weak spot,
 * the buttons), and a review screen of point cards with Missed / Got right
 * tabs (Kevin, 2026-10-25, after Alexandru's Logic Blitz end screens).
 */
.cg-end .cg-inner {
  max-width: 600px;
}
.cg-final {
  margin: 8px 0 0;
  padding: 28px 24px 24px;
  text-align: center;
  background: #fff;
  border: 1px solid var(--gk-line);
  border-radius: 14px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
}
.cg-final-how {
  margin: 0;
  font-family: var(--gk-serif, var(--font-serif, Georgia, serif));
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gk-muted);
}
.cg-final-score {
  margin: 10px 0 0;
  font-family: var(--gk-serif, var(--font-serif, Georgia, serif));
  font-size: 64px;
  font-weight: 600;
  line-height: 1;
}
.cg-final-score span {
  font-size: 28px;
  color: var(--gk-muted);
}
.cg-final-unit {
  margin: 6px 0 0;
  font-size: 15px;
  color: var(--gk-muted);
}
.cg-final-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 22px 0 0;
  padding: 14px 0;
  border-top: 1px solid var(--gk-line);
  border-bottom: 1px solid var(--gk-line);
}
.cg-final-stat + .cg-final-stat {
  border-left: 1px solid var(--gk-line);
}
.cg-final-stat b {
  display: block;
  font-size: 20px;
}
.cg-final-stat span {
  font-size: 13px;
  color: var(--gk-muted);
}
.cg-spot {
  margin: 20px 0 0;
  padding: 14px 16px;
  text-align: left;
  background: #fbf7ef;
  border-radius: 12px;
}
.cg-spot.is-clean {
  background: #e8f3ec;
}
.cg-spot-label {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gk-muted);
}
.cg-spot-title {
  margin: 2px 0 0;
  font-size: 18px;
  font-weight: 700;
}
.cg-spot-meter {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 0;
}
.cg-spot-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: #e6dfd2;
  overflow: hidden;
}
.cg-spot-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--cg-wrong);
}
.cg-spot-count {
  font-size: 13px;
  color: var(--gk-muted);
  white-space: nowrap;
}
.cg-final-actions {
  display: grid;
  justify-items: center;
  gap: 12px;
  margin: 22px 0 0;
}
.cg-final-actions .gk-button-primary {
  min-width: 220px;
}
.cg-account:empty {
  display: none;
}

/* The review */
.cg-review-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 0 0 12px;
}
.cg-back {
  padding: 0;
  font-weight: 600;
  text-decoration: none;
}
.cg-review-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 20px;
}
.cg-review-title {
  margin: 0;
  font-size: 30px;
}
.cg-review-summary {
  margin: 4px 0 0;
  color: var(--gk-muted);
}
.cg-review-label {
  margin: 0 0 8px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gk-muted);
}
.cg-types {
  background: #fff;
  border: 1px solid var(--gk-line);
  border-radius: 12px;
}
.cg-type + .cg-type {
  border-top: 1px solid var(--gk-line);
}
.cg-type-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 12px 16px;
}
.cg-type-name {
  flex: 1;
  font-weight: 600;
}
.cg-type-score {
  font-size: 14px;
  color: var(--gk-muted);
}
.cg-tabs {
  display: flex;
  gap: 6px;
  margin: 24px 0 12px;
  border-bottom: 1px solid var(--gk-line);
}
.cg-tab {
  padding: 8px 12px;
  font: inherit;
  font-weight: 600;
  color: var(--gk-muted);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
}
.cg-tab[aria-selected="true"] {
  color: var(--gk-ink);
  border-bottom-color: var(--gk-ink);
}
.cg-tab-count {
  margin-left: 6px;
  padding: 0 7px;
  border-radius: 999px;
  background: #ece6da;
  font-size: 12px;
}
.cg-review-list {
  display: grid;
  gap: 12px;
  margin: 12px 0 0;
}
.cg-point-card {
  padding: 16px 18px;
  background: #fff;
  border: 1px solid var(--gk-line);
  border-radius: 12px;
}
.cg-point-case {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gk-muted);
}
.cg-point-line {
  margin: 4px 0 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
}
.cg-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
}
.cg-pill {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
}
.cg-pill.is-right {
  background: #e8f3ec;
  color: #1f5a35;
}
.cg-pill.is-wrong {
  background: #fbecea;
  color: var(--cg-wrong);
}
.cg-point-why {
  margin: 10px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--gk-muted);
}
.cg-point-toggle {
  margin: 8px 0 0;
  padding: 0;
  font-size: 13px;
}
.cg-point-says {
  margin: 10px 0 0;
  padding: 12px 14px;
  background: #fbf7ef;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.5;
}
.cg-point-says p {
  margin: 0;
}
.cg-point-says p + p {
  margin-top: 10px;
}
.cg-point-says .cg-view-tag {
  margin-left: 6px;
}
@media (max-width: 599px) {
  .cg-final {
    padding: 24px 16px 20px;
  }
  .cg-final-actions .gk-button-primary,
  .cg-review-head .gk-button-primary {
    width: 100%;
  }
  .cg-review-head {
    flex-direction: column;
    align-items: stretch;
  }
}

/*
 * Press feedback (Kevin, 2026-10-26): every button sinks a little and darkens
 * while it's held, so a tap feels acknowledged before anything changes; a
 * soft tick plays with it (SOUNDS.tap) unless the press makes its own sound.
 */
.cg-bin,
.cg-who-pick,
.cg-option,
.cg-tab,
.cg-jump,
.cg-link {
  transition:
    transform 0.08s ease,
    background-color 0.08s ease,
    box-shadow 0.08s ease;
  -webkit-tap-highlight-color: transparent;
}
.cg-bin:active,
.cg-who-pick:active,
.cg-option:active {
  transform: translateY(1px) scale(0.98);
  background: #f1ede5;
  border-color: var(--color-button-primary-default-fixed, #1f6f9c);
}
.cg-sheet-bins.is-graded .cg-bin:active {
  transform: none;
}
.cg-tab:active,
.cg-jump:active {
  transform: translateY(1px);
}
.cg-link:active {
  opacity: 0.6;
}
.cg-dot:active::after {
  transform: scale(0.8);
}
@media (prefers-reduced-motion: reduce) {
  .cg-bin:active,
  .cg-who-pick:active,
  .cg-option:active,
  .cg-tab:active,
  .cg-jump:active {
    transform: none;
  }
}

/*
 * Nameplates (Kevin, 2026-10-26): the party's name on the lectern. It turns
 * over onto the plate as the person arrives (the walk-in reaches the lectern
 * about 0.9s in) and turns away as they start to leave. Without the walk, as
 * under reduced motion, it's simply there.
 */
.cg-plate {
  transform-box: fill-box;
  transform-origin: 50% 50%;
}
.cg-plate.is-arriving {
  animation: cg-plate-in 1.3s ease-out both;
}
.cg-plate.is-leaving {
  animation: cg-plate-out 0.35s ease-in both;
}
@keyframes cg-plate-in {
  0%,
  70% {
    opacity: 0;
    transform: scaleY(0);
  }
  88% {
    opacity: 1;
    transform: scaleY(1.15);
  }
  100% {
    opacity: 1;
    transform: scaleY(1);
  }
}
@keyframes cg-plate-out {
  to {
    opacity: 0;
    transform: scaleY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .cg-plate.is-arriving,
  .cg-plate.is-leaving {
    animation: none;
  }
}

/* One courtroom height for the run on a wide screen (see fitCourt); a window resize eases to the new height. */
@media (min-width: 600px) {
  .cg-court {
    min-height: var(--cg-court-min, 0);
    transition: min-height 0.4s ease;
  }
}
.cg-court-probe {
  position: fixed;
  top: 0;
  left: -10000px;
  visibility: hidden;
  pointer-events: none;
}
.cg-final-sorted {
  margin: 14px 0 0;
  font-size: 17px;
  font-weight: 600;
}

/* The top row's right end: the score chip and the menu buttons. */
.cg-top-end {
  display: flex;
  align-items: center;
  gap: 12px;
}
.cg-score {
  min-width: 5ch;
  padding: 3px 11px;
  border-radius: 999px;
  background: var(--gk-ink);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.cg-score.is-bump {
  animation: cg-score-bump 0.38s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}
@keyframes cg-score-bump {
  40% {
    transform: scale(1.2);
  }
}
.cg-score-flyer {
  position: fixed;
  z-index: 30;
  padding: 3px 11px;
  border-radius: 999px;
  background: var(--cg-right);
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}
/* On a phone the top row stays pinned with the strip under it, so the score chip is always in view. */
@media (max-width: 599px) {
  .cg-top {
    position: sticky;
    top: 0;
    z-index: 4;
    margin: -16px -16px 0;
    padding: 12px 16px 6px;
    background: var(--cg-wall);
  }
  .cg-strip {
    top: 50px;
  }
}

/*
 * The beat (Kevin, 2026-10-26): 0.6 seconds between a pick and its
 * verdict. The pick keeps its badge, the other answers dim, and both
 * parties lean in (Kevin, 2026-10-26: no fill bar).
 */
.cg-sheet-bins.is-pending .cg-bin {
  position: relative;
  overflow: visible;
  cursor: default;
}
.cg-sheet-bins.is-pending .cg-bin:not(.is-picked) {
  opacity: 0.45;
}
.cg-inner.is-tense .cg-figure {
  animation: cg-lean var(--cg-beat, 600ms) ease-out both;
}
.cg-inner.is-tense .cg-jump .cg-face {
  animation: cg-lean-face var(--cg-beat, 600ms) ease-out both;
}
@keyframes cg-lean {
  to {
    transform: translateY(-2%) scale(1.05);
  }
}
@keyframes cg-lean-face {
  to {
    transform: scale(1.15);
  }
}

/*
 * One height for the whole game on a wide screen (Kevin, 2026-10-26): every
 * screen but the review holds the stage height set by fitStage, and the
 * answer card scrolls inside itself past its ceiling, its button pinned.
 */
@media (min-width: 600px) {
  .cg-room:not(.is-review) {
    min-height: var(--cg-stage-min, 0);
  }
  .cg-wide .cg-pad.is-bench {
    max-height: var(--cg-card-max, none);
    overflow-y: auto;
  }
  .cg-wide .cg-pad.is-bench .cg-result-foot .gk-button-primary {
    position: sticky;
    bottom: 0;
    box-shadow: 0 -14px 12px 2px #fff;
  }
}
/* The cards laid out for measuring keep their natural height. */
.cg-card-probe .cg-pad {
  max-height: none;
}

/* As the whole window, the docked pad keeps clear of half the screen. */
@media (max-width: 599px) {
  .gk-window .cg-pad.is-docked {
    max-height: min(52vh, 420px);
  }
}
