/* ============================================================
   Tug of War — the first game that runs on this site rather than
   inside somebody else's iframe.
   ------------------------------------------------------------
   Everything here is sized for one screen at the front of a room,
   not for a phone in a hand. The numbers that look large are
   deliberate: the reader is a child four metres away, and the
   thing they press is being pressed by a finger, in a hurry,
   while the class shouts at them.

   Two surfaces, one page:
     .tow-setup  — an ordinary page, site chrome and all.
     .tow-stage  — the board. Fixed, full-bleed, no scrolling.
                   body.is-playing is what swaps them.

   Colours are scoped to this file. site.css owns one blue and one
   orange, and this game needs a blue team and a red team that are
   equals; borrowing the brand accent for one side would make the
   other look like the loser before a question was asked.
   ============================================================ */

/* Tug of War keeps one colour of its own. */
.tow { --tow-rope: #c08a3e; }
[data-theme="dark"] .tow { --tow-rope: #b98c4e; }

/* ---------- the board ---------- */

.tow-stage {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--cg-stage);
  color: var(--cg-ink);
  /* Three rows: the score strip, the rope, the two question panels.
     1fr on the panels is what keeps the board inside the screen on any
     shape of display — nothing here may scroll. */
  grid-template-rows: auto auto 1fr;
  gap: clamp(8px, 1.2vh, 16px);
  padding: clamp(10px, 1.6vh, 20px);
}
body.is-playing .tow-stage { display: grid; }

/* score strip */
.tow-score {
  display: grid;
  /* minmax(0, 1fr) rather than 1fr: a grid track sized 1fr will not shrink
     below its content, so a long team name pushed the clock and the tools off
     the strip instead of being cut short by the ellipsis it was given. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}
.tow-team {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  overflow: hidden;
  padding: 8px 16px;
  border-radius: 14px;
  font-weight: 700;
}
.tow-team.is-blue { background: var(--cg-blue-soft); color: var(--cg-blue-ink); }
.tow-team.is-red  { background: var(--cg-red-soft);  color: var(--cg-red-ink); justify-self: end; flex-direction: row-reverse; }
.tow-team-name {
  font-size: clamp(16px, 2.4vh, 26px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tow-team-pulls {
  font-size: clamp(22px, 3.6vh, 42px);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.tow-middle { display: flex; align-items: center; gap: clamp(6px, 1vw, 14px); }
.tow-clock {
  font-size: clamp(20px, 3.4vh, 38px);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  min-width: 3.4ch;
  text-align: center;
}
.tow-clock.is-low { color: var(--cg-red); }

.tow-tool {
  width: clamp(34px, 5vh, 44px);
  height: clamp(34px, 5vh, 44px);
  display: grid;
  place-items: center;
  border-radius: 11px;
  border: 1.5px solid var(--cg-line);
  background: var(--cg-panel);
  color: var(--cg-dim);
  cursor: pointer;
}
.tow-tool:hover { color: var(--cg-ink); border-color: var(--cg-dim); }
.tow-tool[aria-pressed="true"] { color: var(--cg-ink); border-color: var(--cg-ink); }
/* site.css gives every svg `display: block`, which outranks the `hidden`
   attribute — so the muted icon sat on top of the unmuted one and the button
   showed both at once. Specificity, not visibility, was the problem. */
.tow-tool svg[hidden] { display: none; }

/* the rope */
.tow-arena {
  position: relative;
  height: clamp(70px, 15vh, 150px);
  border-radius: 16px;
  background: var(--cg-panel);
  border: 1px solid var(--cg-line);
  overflow: hidden;
}
/* The pitch: a centre line and the two win lines, so the distance left to pull
   is visible rather than something to be told afterwards. */
.tow-arena::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 12%;
  bottom: 12%;
  width: 2px;
  margin-left: -1px;
  background: var(--cg-line);
}
.tow-goal {
  position: absolute;
  top: 8%;
  bottom: 8%;
  width: 3px;
  border-radius: 3px;
  opacity: .5;
}
/* Where the knot has to reach. Matched to --tow-shift below, so a team that has
   pulled the rope onto its line has won and is seen to have won. */
.tow-goal.is-blue { left: 20%; background: var(--cg-blue); }
.tow-goal.is-red  { right: 20%; background: var(--cg-red); }

/* Rope, knot and both teams move as one piece, because that is what a tug of
   war is: the winning side does not slide a marker, it drags everybody.
   --tow-pull is set from script as -1 … 1 and is the only thing that moves.

   It has to be one group. Offsetting each part on its own was the first
   attempt, and a percentage in `translateX` resolves against the element's own
   width — so the knot, being 50px wide, travelled 20 pixels for a whole match.
   On a group that fills the arena, the same percentage means what it reads as.

   Positive is blue, and blue is the left-hand team, so the shift is negative:
   the first version moved the rope to the loser's side. */
.tow-tug {
  position: absolute;
  inset: 0;
  /* 30% is the distance a winning team drags the rope, and it is why the goal
     lines above sit at 20%: 50% - 30% is where the knot stops.

     Written as one variable times a literal on purpose. The obvious version put
     the distance in a second custom property and multiplied the two, and
     `calc(var(--a) * var(--b))` does not resolve — the declaration is dropped
     and the rope simply never moves, with no error anywhere to say so. */
  transform: translateX(calc(var(--tow-pull, 0) * -30%));
  transition: transform .45s cubic-bezier(.34, 1.3, .5, 1);
}

.tow-rope {
  position: absolute;
  left: 26%;
  right: 26%;
  top: 50%;
  height: 8px;
  margin-top: -4px;
  border-radius: 4px;
  background: repeating-linear-gradient(115deg,
      var(--tow-rope) 0 9px, color-mix(in srgb, var(--tow-rope) 72%, #000) 9px 18px);
}

.tow-knot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(34px, 6vh, 58px);
  height: clamp(34px, 6vh, 58px);
  margin: calc(clamp(34px, 6vh, 58px) / -2) 0 0 calc(clamp(34px, 6vh, 58px) / -2);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: clamp(17px, 3vh, 28px);
  background: var(--cg-panel);
  border: 3px solid var(--tow-rope);
  box-shadow: 0 3px 14px rgba(0, 0, 0, .16);
}

.tow-pullers {
  position: absolute;
  top: 50%;
  font-size: clamp(22px, 4.4vh, 44px);
  line-height: 1;
  transform: translateY(-50%);
  user-select: none;
  white-space: nowrap;
}
.tow-pullers.is-blue { left: 32%; }
.tow-pullers.is-red  { right: 32%; }

.tow-arena.is-pulling-blue .tow-knot,
.tow-arena.is-pulling-red .tow-knot { animation: tow-jolt .45s ease; }
@keyframes tow-jolt {
  40% { box-shadow: 0 3px 22px rgba(0, 0, 0, .3); }
}

/* question panels */
.tow-panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(8px, 1.2vw, 18px);
  min-height: 0;
}

.tow-panel {
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.4vh, 16px);
  min-height: 0;
  padding: clamp(12px, 2vh, 24px);
  border-radius: 18px;
  background: var(--cg-panel);
  border: 3px solid transparent;
}
.tow-panel.is-blue { border-color: color-mix(in srgb, var(--cg-blue) 34%, transparent); }
.tow-panel.is-red  { border-color: color-mix(in srgb, var(--cg-red) 34%, transparent); }

.tow-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 10px;
  font-size: clamp(11px, 1.6vh, 15px);
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.tow-panel.is-blue .tow-panel-head { color: var(--cg-blue-ink); }
.tow-panel.is-red  .tow-panel-head { color: var(--cg-red-ink); }
.tow-panel-skill { text-transform: none; letter-spacing: 0; font-weight: 500; opacity: .72; }

/* The question takes the space above the options and sits in the middle of it,
   so a one-line question and a three-line one are read from the same place on
   the board instead of the shorter one hugging the top. */
.tow-prompt {
  flex: 1;
  display: grid;
  align-content: center;
  min-height: 0;
  font-size: clamp(19px, 3.4vh, 40px);
  font-weight: 600;
  line-height: 1.25;
  margin: 0;
  text-wrap: balance;
}

.tow-options {
  display: grid;
  gap: clamp(6px, 1vh, 12px);
  /* Two across once there is room for it: four stacked options on a wide
     board wastes the width and shrinks the type to fit the height. */
  grid-template-columns: 1fr;
  /* The options take the rest of the panel. Left at their natural height they
     sat in a line under the question with half the board empty below them; set
     to share the space equally they became four tall boxes with a word adrift
     in the middle of each. So they take a generous row height and the leftover
     is given back as space around the block. */
  flex: 0 0 auto;
  grid-auto-rows: minmax(clamp(52px, 9vh, 104px), auto);
  min-height: 0;
}
@media (min-aspect-ratio: 5/4) {
  .tow-options { grid-template-columns: 1fr 1fr; }
}

.tow-option {
  display: flex;
  align-items: center;
  gap: clamp(8px, 1.4vh, 14px);
  text-align: left;
  font: inherit;
  font-size: clamp(16px, 2.6vh, 30px);
  font-weight: 600;
  line-height: 1.2;
  padding: clamp(9px, 1.6vh, 18px) clamp(11px, 1.6vh, 20px);
  border-radius: 13px;
  border: 2.5px solid var(--cg-line);
  background: var(--cg-panel);
  color: var(--cg-ink);
  cursor: pointer;
  transition: transform .08s, border-color .12s, background .12s;
}
.tow-option:active { transform: scale(.985); }
.tow-panel.is-blue .tow-option:hover:not(:disabled) { border-color: var(--cg-blue); background: var(--cg-blue-soft); }
.tow-panel.is-red  .tow-option:hover:not(:disabled) { border-color: var(--cg-red);  background: var(--cg-red-soft); }

.tow-option.is-right {
  border-color: var(--cg-good);
  background: color-mix(in srgb, var(--cg-good) 14%, var(--cg-panel));
}
.tow-option.is-wrong {
  border-color: var(--cg-red);
  background: color-mix(in srgb, var(--cg-red) 14%, var(--cg-panel));
}
.tow-option:disabled { cursor: default; }

/* A team that answered wrongly waits, and is told so rather than left
   pressing a panel that has quietly stopped responding. */
.tow-panel.is-waiting { opacity: .62; }
.tow-wait {
  font-size: clamp(13px, 1.9vh, 18px);
  font-weight: 600;
  text-align: center;
  min-height: 1.3em;
}
.tow-panel.is-blue .tow-wait { color: var(--cg-blue-ink); }
.tow-panel.is-red  .tow-wait { color: var(--cg-red-ink); }

/* ---------- the overlay: paused, and won ---------- */

.tow-over {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  place-items: center;
  padding: 24px;
  background: color-mix(in srgb, var(--cg-stage) 88%, transparent);
  backdrop-filter: blur(3px);
}
.tow-over[data-open] { display: grid; }

.tow-over-card {
  width: min(680px, 100%);
  text-align: center;
  padding: clamp(24px, 5vh, 52px);
  border-radius: 22px;
  background: var(--cg-panel);
  border: 1px solid var(--cg-line);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .18);
}
.tow-over-crest { font-size: clamp(40px, 9vh, 76px); line-height: 1; }
.tow-over-card h2 {
  font-size: clamp(26px, 5vh, 46px);
  margin: 12px 0 6px;
  color: var(--cg-ink);
}
.tow-over-card h2.is-blue { color: var(--cg-blue); }
.tow-over-card h2.is-red  { color: var(--cg-red); }
.tow-over-line { font-size: clamp(15px, 2.2vh, 20px); color: var(--cg-dim); margin: 0 0 22px; }
.tow-over-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ---------- narrow screens ----------
   The board is built for a display at the front of a room, but a teacher will
   open it on a phone to see what it is before the lesson, and it must not be
   unusable there. Panels stack; the rope stays, because it is the game. */
/* A phone. The board is built for a display at the front of a room, and two
   panels side by side do not fit here — so they stack, and once they stack the
   board is taller than the screen. It is allowed to scroll rather than being
   squeezed until the questions are unreadable: a teacher looking at this before
   the lesson needs to see what it says, not a miniature of the real thing. */
@media (max-width: 720px), (max-height: 420px) {
  /* Written against body.is-playing on purpose. The rule that turns the board
     on is `body.is-playing .tow-stage`, and a bare `.tow-stage` here loses to
     it on specificity however far down the file it sits — which left the third
     row at 1fr, the panels sharing a fixed height, and the last option hanging
     through the panel's own border.

     Rows then take their content and the board scrolls. align-content is the
     other half of it: a grid stretches its rows to fill a fixed container
     unless it is told to stack them from the top. */
  body.is-playing .tow-stage {
    grid-template-rows: auto auto auto;
    align-content: start;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* min-height back to auto, which is the whole fix. The wide layout sets it
     to 0 so a panel may shrink to fit a fixed board; carried into the stacked
     layout, that same permission let each panel shrink below its own options
     and the last one hung through the panel's border. Here the content decides
     the height and the board scrolls instead. */
  .tow-panels { grid-template-columns: 1fr; align-content: start; min-height: auto; }
  .tow-panel { min-height: auto; }
  .tow-options { min-height: auto; }

  /* There is no room for a name beside a number and three buttons on a phone,
     and a name cut to nothing is worse than no name: each panel is headed with
     its team anyway, a few centimetres below. */
  .tow-score .tow-team-name { display: none; }
  .tow-team-pulls { font-size: 22px; }

  .tow-prompt { font-size: 20px; flex: 0 0 auto; }
  .tow-options { grid-auto-rows: minmax(52px, auto); }
  .tow-option { font-size: 17px; }
  .tow-arena { height: 84px; }
  .tow-panel-skill { display: none; }
  .cg-key { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tow-tug { transition: none; }
  .tow-arena.is-pulling-blue .tow-knot,
  .tow-arena.is-pulling-red .tow-knot { animation: none; }
}
