/* ============================================================
   CARD GAME ENGINE — stylesheet
   Extends engine/tt-engine.css, which must be loaded first.

   Two things are load-bearing here and should not be "tidied":

   1. A card is ONE piece of markup at two sizes. Everything inside
      scales off --cw (the card's width), so the ~110px thumbnail on
      a phone and the ~40%-of-the-screen card on the projector are
      the same element with a different --cw.

   2. Rarity is never colour alone. Frame colour AND the pip count
      say the same thing, so the tier survives a washed-out
      projector and a colourblind student.
   ============================================================ */

:root{
  --c-common:#9bb0cf;   --c-common-d:#4a5f85;
  --c-rare:#54c8ff;     --c-rare-d:#1b6e9c;
  --c-epic:#c08cff;     --c-epic-d:#6a3fa8;
  --c-legendary:#ffc861;--c-legendary-d:#9a7018;
}

/* ============================================================
   THE CARD
   ============================================================ */
.cgcard{
  --cw:110px;
  --tier:var(--c-common);
  --tierd:var(--c-common-d);
  width:var(--cw);
  aspect-ratio:120/172;
  border-radius:calc(var(--cw)*.075);
  border:calc(var(--cw)*.022) solid var(--tier);
  background:linear-gradient(168deg,#1d2942 0%,#0d1425 62%,#121b30 100%);
  display:flex;flex-direction:column;
  padding:calc(var(--cw)*.055);
  gap:calc(var(--cw)*.035);
  position:relative;overflow:hidden;
  box-shadow:0 calc(var(--cw)*.05) calc(var(--cw)*.14) rgba(0,0,0,.5);
  text-align:center;
}
.cgcard.r-common   {--tier:var(--c-common);   --tierd:var(--c-common-d)}
.cgcard.r-rare     {--tier:var(--c-rare);     --tierd:var(--c-rare-d)}
.cgcard.r-epic     {--tier:var(--c-epic);     --tierd:var(--c-epic-d)}
.cgcard.r-legendary{--tier:var(--c-legendary);--tierd:var(--c-legendary-d)}

/* the tier glow, drawn once behind everything — a static gradient, never
   an animated filter, because this is the biggest surface on the screen */
.cgcard::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 70% at 50% 0%, var(--tierd) 0%, transparent 62%);
  opacity:.55;
}
.cgcard > *{position:relative;z-index:1}

.cgcard .ctop{
  display:flex;align-items:center;gap:calc(var(--cw)*.04);
  font-size:calc(var(--cw)*.072);font-weight:900;letter-spacing:.08em;
  color:var(--tier);text-transform:uppercase;line-height:1;
}
.cgcard .ctop .les{
  color:#cfe0f7;background:rgba(255,255,255,.08);
  border-radius:999px;padding:calc(var(--cw)*.018) calc(var(--cw)*.05);
  letter-spacing:.06em;
}
.cgcard .ctop .pips{margin-left:auto;letter-spacing:.02em;font-size:calc(var(--cw)*.09)}

.cgcard .cart{
  height:calc(var(--cw)*.34);display:flex;align-items:center;justify-content:center;
}
/* A <use> shadow tree does NOT pick up presentation attributes from the
   symbol's original parent, so the stroke style has to arrive as inherited
   CSS from the <svg> the <use> sits in. Without this every glyph renders as
   a solid black blob. */
.cgcard .cart svg{
  height:100%;width:auto;color:var(--tier);opacity:.92;
  fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
}
/* effects need two lines at the bottom, so the art gives some back */
.cgcard.has-fx .cart{height:calc(var(--cw)*.27)}

.cgcard .cname{
  font-size:calc(var(--cw)*var(--nameFs,.115));font-weight:900;letter-spacing:.05em;
  color:#fff;line-height:1.05;text-transform:uppercase;
  text-wrap:balance;
}

/* THE LINE is the hero element after the name — this is an English game.
   --lineFs is set per card from the length of the line, because a
   Legendary can be three times as long as a Common and a single font
   size cannot serve both without clipping one of them. */
.cgcard .cline{
  flex:1;display:flex;align-items:center;justify-content:center;
  font-size:calc(var(--cw)*var(--lineFs,.098));font-weight:700;line-height:1.22;
  color:#eaf0fa;text-wrap:balance;overflow:hidden;
  padding:0 calc(var(--cw)*.01);
}
.cgcard.hideline .cline{
  color:var(--muted);font-style:italic;font-weight:600;
}

.cgcard .cfx{
  display:flex;flex-direction:column;gap:calc(var(--cw)*.018);
  font-size:calc(var(--cw)*.066);font-weight:800;letter-spacing:.03em;line-height:1.2;
  text-transform:uppercase;
}
.cgcard .cfx span{
  border-radius:calc(var(--cw)*.03);padding:calc(var(--cw)*.022) calc(var(--cw)*.03);
}
.cgcard .cfx .perk{color:#7ee2a8;background:rgba(61,220,132,.12)}
.cgcard .cfx .weak{color:#ff96a1;background:rgba(255,93,108,.12)}

/* the face-down back reuses the hub's existing #cardback symbol */
.cgcard.back{border-color:var(--line);background:none;padding:0}
.cgcard.back::before{display:none}
.cgcard.back svg{width:100%;height:100%;display:block;border-radius:calc(var(--cw)*.06)}

/* ============================================================
   THE TABLE — layout
   ============================================================ */
#board{grid-template-columns:1fr 330px}

#stage{justify-content:center;align-items:center;gap:14px}

#cardZone{
  display:flex;align-items:center;justify-content:center;gap:26px;
  min-height:0;flex:1;width:100%;
  /* size containment so the card can be sized from the zone's own height
     rather than from the viewport. The card is 120:172, so 68cqh of the
     zone's height is the widest it can be and still fit — a viewport-based
     width overflows the moment the task below it grows. */
  container-type:size;
}
#cardZone .cgcard{--cw:min(30vh,300px)}
@supports (width:1cqh){ #cardZone .cgcard{--cw:min(68cqh,96cqw,300px)} }

#playArea{
  width:100%;display:flex;flex-direction:column;gap:12px;align-items:center;min-width:0;
}
#taskZone{
  width:100%;display:flex;flex-direction:column;gap:12px;align-items:center;
  min-height:0;
}

/* ---------- the task is up: the card steps aside ---------- */
#stage.playing{flex-direction:row;align-items:stretch;gap:22px;justify-content:flex-start}
#stage.playing #cardZone{flex:0 0 clamp(155px,21%,250px)}
#stage.playing #playArea{flex:1;justify-content:center}
#prompt{
  color:var(--muted);font-size:clamp(13px,1.3vw,18px);font-style:italic;
  line-height:1.35;text-align:center;max-width:70ch;
}
#prompt b{color:#cfe0f7;font-style:normal}
#spec{
  font-size:clamp(16px,2.1vw,30px);font-weight:800;line-height:1.3;
  text-align:center;max-width:26ch;color:var(--text);text-wrap:balance;
}
#spec b{color:#ffd479}
#modelAnswer{
  font-size:clamp(14px,1.6vw,22px);font-weight:700;color:var(--good);
  text-align:center;max-width:60ch;line-height:1.3;
}
#modelAnswer small{display:block;font-size:.66em;color:var(--muted);
  letter-spacing:1.4px;text-transform:uppercase;font-weight:800;margin-bottom:4px}

/* ---------- the played-card stage, before a card is chosen ---------- */
#idleNote{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  color:var(--muted);text-align:center;max-width:44ch;
}
#idleNote .big{font-size:clamp(19px,2.6vw,34px);font-weight:900;letter-spacing:1px;color:var(--text)}
#idleNote .sm{font-size:clamp(13px,1.3vw,17px);line-height:1.45}

/* ============================================================
   THE CLOCK — a draining ring with the digits inside, so it reads
   from the back of the room and rush / slow are visible at a glance.
   ============================================================ */
#clock{position:relative;width:clamp(52px,5vw,74px);aspect-ratio:1;flex:none}
#clock svg{width:100%;height:100%;transform:rotate(-90deg);display:block}
#clock .track{fill:none;stroke:var(--line);stroke-width:7}
#clock .ring{fill:none;stroke:var(--good);stroke-width:7;stroke-linecap:round;
  transition:stroke-dashoffset .95s linear,stroke .3s}
#clock.warn  .ring{stroke:#ffc861}
#clock.danger .ring{stroke:var(--bad)}
#clock.paused .ring{stroke:var(--muted)}
#clock .digits{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-weight:900;font-size:clamp(17px,1.9vw,26px);font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;
}
#clock.danger .digits{color:var(--bad)}
#clock.warn .digits{color:#ffc861}
#clock.off .digits{font-size:clamp(10px,1vw,13px);letter-spacing:.06em;color:var(--muted)}
#clock.flash{animation:clockFlash .5s ease}
@keyframes clockFlash{0%,100%{transform:scale(1)}40%{transform:scale(1.18)}}

/* ============================================================
   SIDE PANEL — the card picker and the two discard stacks
   ============================================================ */
#sidePanel{
  background:linear-gradient(180deg,var(--panel) 0%,var(--bg2) 100%);
  border:2px solid var(--line);border-radius:20px;padding:12px;
  display:flex;flex-direction:column;gap:10px;min-height:0;
}
#sidePanel h3{
  margin:0;font-size:12px;letter-spacing:1.6px;color:var(--muted);
  text-transform:uppercase;text-align:center;
}
#pickSearch{
  font-family:inherit;font-size:15px;font-weight:700;padding:9px 12px;
  border-radius:11px;background:var(--panel2);color:var(--text);
  border:2px solid var(--line);width:100%;
}
#pickSearch:focus{outline:none;border-color:var(--t1)}
#pickList{
  flex:1;overflow:auto;display:flex;flex-direction:column;gap:5px;
  padding-right:2px;min-height:0;
}
.pickRow{
  display:flex;align-items:center;gap:8px;text-align:left;cursor:pointer;
  background:var(--panel2);border:2px solid transparent;border-left-width:5px;
  border-radius:10px;padding:7px 9px;font-family:inherit;color:var(--text);
  transition:background .12s,border-color .12s;
}
.pickRow:hover{background:#2c3b56}
.pickRow .pn{font-weight:800;font-size:13.5px;letter-spacing:.3px;line-height:1.15;flex:1}
.pickRow .pv{font-weight:900;font-size:15px;font-variant-numeric:tabular-nums}
.pickRow .pl{font-size:10.5px;font-weight:800;color:var(--muted);letter-spacing:.8px}
.pickRow.r-common   {border-left-color:var(--c-common)}    .pickRow.r-common .pv{color:var(--c-common)}
.pickRow.r-rare     {border-left-color:var(--c-rare)}      .pickRow.r-rare .pv{color:var(--c-rare)}
.pickRow.r-epic     {border-left-color:var(--c-epic)}      .pickRow.r-epic .pv{color:var(--c-epic)}
.pickRow.r-legendary{border-left-color:var(--c-legendary)} .pickRow.r-legendary .pv{color:var(--c-legendary)}
.pickRow.spent{opacity:.3;cursor:not-allowed}
.pickRow.spent .pn{text-decoration:line-through}
#pickNote{color:var(--muted);font-size:13px;text-align:center;line-height:1.4;padding:10px 4px}
#pickNote.hidden{display:none}

/* while a task is live, nobody is choosing a card */
#sidePanel.waiting #pickSearch{opacity:.35;pointer-events:none}
#sidePanel.waiting #pickList{opacity:.35;pointer-events:none}

#discards{display:flex;gap:10px;justify-content:space-between}
.dstack{
  flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;
  border-radius:12px;padding:8px 4px;background:rgba(255,255,255,.03);
}
.dstack .dlabel{font-size:10.5px;font-weight:800;letter-spacing:1px;color:var(--muted)}
.dstack.t1 .dlabel{color:var(--t1)} .dstack.t2 .dlabel{color:var(--t2)}
.dstack .pile{position:relative;width:44px;height:63px}
.dstack .pile .cgcard{--cw:44px;position:absolute;left:0;top:0}
.dstack .dleft{font-size:12px;font-weight:800;color:var(--muted)}

/* ============================================================
   EFFECT BANNER — the rule arrives exactly when it is needed
   ============================================================ */
#fxBanner{
  position:fixed;left:50%;top:18%;transform:translateX(-50%);
  z-index:640;pointer-events:none;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:6px;
}
#fxBanner.hidden{display:none}
#fxBanner .fxName{
  font-size:clamp(30px,6vw,76px);font-weight:900;letter-spacing:3px;line-height:1;
  animation:fxIn .4s cubic-bezier(.2,1.5,.4,1);
}
#fxBanner .fxDesc{
  font-size:clamp(15px,2vw,26px);font-weight:800;color:var(--text);
  max-width:24ch;line-height:1.3;text-wrap:balance;
}
#fxBanner.good .fxName{color:var(--good)}
#fxBanner.bad  .fxName{color:var(--bad)}
@keyframes fxIn{0%{transform:scale(.5);opacity:0}100%{transform:scale(1);opacity:1}}

/* a small permanent reminder while the task is on screen */
#fxStrip{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
#fxStrip .chip{
  font-size:clamp(11px,1.1vw,14px);font-weight:800;letter-spacing:.8px;
  border-radius:999px;padding:4px 12px;border:2px solid;text-transform:uppercase;
}
#fxStrip .chip.good{color:#7ee2a8;border-color:#2f7a52;background:rgba(61,220,132,.10)}
#fxStrip .chip.bad {color:#ff96a1;border-color:#8a3a44;background:rgba(255,93,108,.10)}

/* ============================================================
   REVEAL — the flourish scales with rarity (§7.2). Every step is
   transform or opacity only: a classroom PC driving a projector
   judders on an animated filter across a surface this big.
   ============================================================ */
#revealWrap{perspective:1400px;display:flex;align-items:center;justify-content:center}
#revealWrap .flip{transform-style:preserve-3d;position:relative}
#revealWrap .flip.go{animation:cgFlip var(--flipMs,550ms) cubic-bezier(.4,.05,.2,1) both}
@keyframes cgFlip{
  0%  {transform:rotateY(180deg) scale(.92)}
  55% {transform:rotateY(70deg)  scale(var(--popScale,1.06))}
  100%{transform:rotateY(0deg)   scale(1)}
}
#dimmer{
  position:fixed;inset:0;background:#04070e;opacity:0;z-index:430;pointer-events:none;
  transition:opacity .35s ease;
}
#dimmer.on{opacity:.72}
#rays{
  position:fixed;left:50%;top:50%;width:190vmax;height:190vmax;
  transform:translate(-50%,-50%) scale(.2);opacity:0;
  z-index:435;pointer-events:none;
  background:repeating-conic-gradient(from 0deg,
    rgba(255,200,97,.30) 0deg 5deg, transparent 5deg 15deg);
  border-radius:50%;
}
#rays.go{animation:rayBurst 1.25s ease-out both}
@keyframes rayBurst{
  0%  {transform:translate(-50%,-50%) scale(.15) rotate(0deg);opacity:0}
  30% {opacity:.9}
  100%{transform:translate(-50%,-50%) scale(1) rotate(42deg);opacity:0}
}
#cardZone .cgcard.lift{z-index:440}

/* ============================================================
   POINTS-FLY — the one animation that carries information.
   "You succeeded, so YOU take the attacker's points" is
   counter-intuitive; watching the value travel is what makes
   the rule legible without a word of explanation.
   ============================================================ */
.ptchip{
  position:fixed;z-index:900;pointer-events:none;
  min-width:56px;height:56px;padding:0 14px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;
  font-size:30px;font-weight:900;font-variant-numeric:tabular-nums;
  color:#06210f;background:linear-gradient(180deg,#6cf0ab,#22b268);
  box-shadow:0 8px 22px rgba(0,0,0,.55);
}
.ptchip.neg{color:#2a0308;background:linear-gradient(180deg,#ff9aa4,#e0384a)}

/* ============================================================
   BUILD-THE-LINE (task-widgets.js) — the tile tray on the table
   ============================================================ */
#builder{width:100%;display:flex;flex-direction:column;gap:12px;align-items:center;min-height:0}
#builder.silenced{opacity:.25;position:relative}
#builder.silenced::after{
  content:"";position:absolute;left:0;right:0;top:50%;height:4px;border-radius:2px;
  background:var(--bad);transform:rotate(-2deg);
}
#builder.silenced *{pointer-events:none}
#slots{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;align-items:center}
#wordTray{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;
  padding:8px;border-radius:12px;border:2px dashed transparent;max-width:100%}
#wordTray.over{border-color:#5b7099;background:rgba(255,255,255,.04)}

/* ============================================================
   OVERLAYS — the QR screen
   ============================================================ */
#qrRow{display:flex;gap:clamp(18px,4vw,56px);flex-wrap:wrap;justify-content:center;align-items:flex-start}
.qrBox{display:flex;flex-direction:column;align-items:center;gap:10px}
.qrBox .qrTeam{font-size:clamp(17px,2.2vw,28px);font-weight:900;letter-spacing:2px}
.qrBox.t1 .qrTeam{color:var(--t1)} .qrBox.t2 .qrTeam{color:var(--t2)}
.qrBox .qrImg{
  width:clamp(150px,22vh,240px);aspect-ratio:1;background:#fff;
  border-radius:14px;padding:8px;box-shadow:0 10px 30px rgba(0,0,0,.5);
}
.qrBox .qrImg svg{width:100%;height:100%;display:block}
.qrBox .qrUrl{font-size:11px;color:var(--muted);word-break:break-all;max-width:230px;
  text-align:center;font-family:ui-monospace,Consolas,monospace;line-height:1.3}
#seedBig{
  font-size:clamp(26px,4vw,52px);font-weight:900;letter-spacing:.28em;
  color:var(--gold,#e9bb55);font-family:ui-monospace,Consolas,monospace;
}

/* ============================================================
   END SCREEN — what each card was actually worth
   ============================================================ */
#endTable{display:flex;gap:20px;flex-wrap:wrap;justify-content:center;max-width:900px}
.endCol{flex:1;min-width:250px;text-align:left}
.endCol h4{margin:0 0 8px;font-size:13px;letter-spacing:1.6px;text-transform:uppercase}
.endCol.t1 h4{color:var(--t1)} .endCol.t2 h4{color:var(--t2)}
.endCol .row{display:flex;gap:8px;align-items:center;font-size:13.5px;
  color:var(--muted);padding:3px 0;border-bottom:1px solid var(--line)}
.endCol .row .nm{flex:1;font-weight:700;color:var(--text)}
.endCol .row .won{font-weight:900}
.endCol .row .won.us{color:var(--good)} .endCol .row .won.them{color:var(--bad)}

/* ============================================================
   SHORT VIEWPORTS — 1366x768 and 1280x720 classroom screens
   ============================================================ */
@media (max-height:820px){
  #board{grid-template-columns:1fr 290px}
  /* NOTE: --cw is deliberately not touched here. The @supports rule above
     sizes the card from the card zone's own height, which already handles
     a short screen; overriding it here would beat that rule on source
     order and put the top of the card back off the stage. */
  #stage{gap:10px}
  #taskZone{gap:9px}
  .qrBox .qrImg{width:clamp(130px,19vh,190px)}
}
@media (max-width:1100px){
  #board{grid-template-columns:1fr;grid-template-rows:1fr auto}
  #sidePanel{max-height:36vh}
  #discards{display:none}
}

/* ============================================================
   REDUCED MOTION — honoured in THIS engine only. The other five
   engines are in use and are deliberately left alone.
   Points-fly degrades to a fade rather than to nothing: it carries
   information and must survive.
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  #revealWrap .flip.go{animation:cgFade .25s ease both}
  @keyframes cgFade{from{opacity:0}to{opacity:1}}
  #rays{display:none}
  #dimmer{transition:none}
  #fxBanner .fxName{animation:none}
  #clock .ring{transition:none}
  #clock.flash{animation:none}
  .ptchip{transition:none}
  .pts.bump{animation:none}
  #stage.flash-good,#stage.flash-bad{animation:none}
  .confetti{display:none}
}
