@thebattlearena/corner 0.9.1-beta.70 → 0.10.1-beta.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +46 -26
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/ring/agents/cornerman.md +32 -6
  5. package/ring/agents/rudo.md +2 -1
  6. package/ring/agents/wrestler.md +19 -4
  7. package/ring/hooks/hooks.json +42 -0
  8. package/ring/scripts/bout-stats-render.mjs +366 -0
  9. package/ring/scripts/bout-stats.mjs +360 -0
  10. package/ring/scripts/brief-build.mjs +130 -0
  11. package/ring/scripts/brief-guard.mjs +154 -0
  12. package/ring/scripts/brief.mjs +272 -0
  13. package/ring/scripts/compact-hook.mjs +110 -0
  14. package/ring/scripts/config.mjs +25 -1
  15. package/ring/scripts/contract-endpoints.mjs +163 -0
  16. package/ring/scripts/contract-preview.mjs +34 -14
  17. package/ring/scripts/fight.mjs +27 -0
  18. package/ring/scripts/findings.mjs +82 -3
  19. package/ring/scripts/format-gate.mjs +723 -0
  20. package/ring/scripts/format-worker.mjs +120 -0
  21. package/ring/scripts/front-routes.mjs +345 -0
  22. package/ring/scripts/judges-card.mjs +324 -3
  23. package/ring/scripts/lookout.mjs +22 -4
  24. package/ring/scripts/mask-guard.mjs +34 -1
  25. package/ring/scripts/page-embed.mjs +112 -0
  26. package/ring/scripts/play-by-play.mjs +155 -7
  27. package/ring/scripts/preparation-collect.mjs +177 -0
  28. package/ring/scripts/preparation.mjs +547 -0
  29. package/ring/scripts/round-bell.mjs +9 -2
  30. package/ring/scripts/rule-ids.mjs +124 -0
  31. package/ring/scripts/tech-plan-log.mjs +81 -0
  32. package/ring/scripts/tech-plan.mjs +191 -0
  33. package/ring/scripts/verdicts-log.mjs +75 -0
  34. package/ring/scripts/verdicts.mjs +205 -0
  35. package/ring/skills/play-by-play/SKILL.md +235 -33
  36. package/ring/skills/play-by-play/templates/blocks.css +196 -0
  37. package/ring/skills/play-by-play/templates/chronicle.html +358 -55
  38. package/ring/skills/play-by-play/templates/endpoints-view.js +1153 -0
  39. package/ring/skills/play-by-play/templates/interview-form.js +516 -0
  40. package/ring/skills/play-by-play/templates/now-panel.js +719 -0
  41. package/ring/skills/referee/SKILL.md +181 -56
  42. package/ring/skills/referee/references/api-diagram.md +56 -0
  43. package/ring/skills/referee/references/precedents.md +11 -0
  44. package/ring/skills/referee/references/rulebook.md +97 -6
  45. package/ring/skills/referee/templates/api-diagram.html +115 -0
  46. package/ring/skills/referee/templates/cornerman-batch.md +17 -11
  47. package/ring/skills/referee/templates/cornerman-concept.md +28 -30
  48. package/ring/skills/referee/templates/cornerman-range.md +16 -11
  49. package/ring/skills/referee/templates/escalation.md +7 -1
  50. package/ring/skills/referee/templates/round-bell-body.md +4 -0
  51. package/ring/skills/referee/templates/wrestler-brief.md +28 -41
  52. package/ring/skills/referee/templates/wrestler-cutoff.md +4 -0
  53. package/ring/skills/referee/templates/wrestler-resume.md +4 -0
  54. package/ring/skills/sparring/SKILL.md +13 -4
  55. package/ring/skills/sparring/templates/contrato.md +29 -0
  56. package/ring/skills/sparring/templates/rudo-brief.md +7 -0
  57. package/ring/skills/title-defense/SKILL.md +2 -2
  58. package/ring/skills/weigh-in/SKILL.md +6 -0
@@ -6,21 +6,22 @@
6
6
  :root{
7
7
  --canvas:#f3f2ec; --paper:#ffffff; --ink:#16151c; --muted:#62616e; --rule:#d9d8df;
8
8
  --red:#c4142c; --red-soft:#fbe4e7; --gold:#a87c00; --gold-soft:#faf0d0; --green:#1d7a43; --green-soft:#e1f3e8;
9
- --blue:#1f4fb3; --blue-soft:#e3ebfb; --navy:#1b2f5a; --navy-soft:#e3e8f3; --grey-soft:#ebebef;
9
+ --blue:#1f4fb3; --blue-soft:#e3ebfb; --navy:#1b2f5a; --navy-soft:#e3e8f3; --grey-soft:#ebebef; --diagram-filter:none;
10
10
  --f-display:"Anton", Impact, "Arial Narrow", sans-serif; --f-label:"Barlow Condensed", "Arial Narrow", sans-serif;
11
11
  --f-body:"Literata", Georgia, "Times New Roman", serif; --f-mono:"JetBrains Mono", ui-monospace, Menlo, monospace;
12
12
  }
13
13
  @media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
14
14
  --canvas:#111017; --paper:#1a1922; --ink:#ecebf2; --muted:#a4a3b1; --rule:#2e2d39;
15
15
  --red:#ff5a6e; --red-soft:#3a1a20; --gold:#e8b62f; --gold-soft:#332a12; --green:#5fd08e; --green-soft:#16301f;
16
- --blue:#7aa3ff; --blue-soft:#1a2440; --navy:#a9bde6; --navy-soft:#1c2638; --grey-soft:#24232d; color-scheme:dark}}
16
+ --blue:#7aa3ff; --blue-soft:#1a2440; --navy:#a9bde6; --navy-soft:#1c2638; --grey-soft:#24232d; --diagram-filter:invert(.9) hue-rotate(180deg); color-scheme:dark}}
17
17
  :root[data-theme="dark"]{
18
18
  --canvas:#111017; --paper:#1a1922; --ink:#ecebf2; --muted:#a4a3b1; --rule:#2e2d39;
19
19
  --red:#ff5a6e; --red-soft:#3a1a20; --gold:#e8b62f; --gold-soft:#332a12; --green:#5fd08e; --green-soft:#16301f;
20
- --blue:#7aa3ff; --blue-soft:#1a2440; --navy:#a9bde6; --navy-soft:#1c2638; --grey-soft:#24232d; color-scheme:dark}
20
+ --blue:#7aa3ff; --blue-soft:#1a2440; --navy:#a9bde6; --navy-soft:#1c2638; --grey-soft:#24232d; --diagram-filter:invert(.9) hue-rotate(180deg); color-scheme:dark}
21
21
  *{box-sizing:border-box}
22
22
  body{background:var(--canvas);color:var(--ink);font-family:var(--f-body);font-size:17px;line-height:1.7;padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
23
- .wrap{max-width:820px;margin:0 auto;padding-block:32px 80px}
23
+ .wrap{max-width:80%;margin:0 auto;padding-block:32px 80px}
24
+ @media (max-width:620px){.wrap{max-width:none}}
24
25
  .masthead{display:flex;justify-content:space-between;align-items:baseline;flex-wrap:wrap;gap:6px 16px;border-bottom:3px solid var(--ink);padding-bottom:8px;font-family:var(--f-label);font-weight:700;letter-spacing:.08em;text-transform:uppercase;font-size:14px}
25
26
  .masthead .live{color:var(--red);display:inline-flex;align-items:center;gap:8px}
26
27
  .masthead .live i{width:9px;height:9px;border-radius:50%;background:var(--red)}
@@ -67,75 +68,377 @@ th{font-size:12.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--mu
67
68
  tr:last-child td{border-bottom:0}
68
69
  td.n{font-family:var(--f-mono);font-weight:700;font-variant-numeric:tabular-nums}
69
70
  code{font-family:var(--f-mono);font-size:.82em;background:var(--grey-soft);padding:1px 5px;border-radius:3px}
71
+ a{color:var(--blue)}
72
+ /* The preparation: «el pesaje del contrato» and «la entrevista», before the first round */
73
+ .prep{margin-top:44px}
74
+ .prep h2{font-family:var(--f-display);font-weight:400;font-size:30px;text-transform:uppercase;margin:0}
75
+ .prep .when{font-family:var(--f-mono);font-size:13px;color:var(--muted);margin:2px 0 14px}
76
+ .facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 14px;margin:0 0 16px;font-family:var(--f-label);font-size:15.5px}
77
+ .facts dt{color:var(--muted);letter-spacing:.04em;text-transform:uppercase;font-size:13px;padding-top:2px}
78
+ .facts dd{margin:0;overflow-wrap:anywhere}
79
+ @media (max-width:560px){.facts{grid-template-columns:minmax(0,1fr)}.facts dd{margin-bottom:6px}}
80
+ .scale{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;margin:18px 0;padding:14px 18px;border:2px solid currentColor;font-family:var(--f-label);font-size:16px}
81
+ .scale b{font-family:var(--f-display);font-weight:400;font-size:26px;text-transform:uppercase;line-height:1;white-space:nowrap}
82
+ .scale span{flex:1 1 16ch;min-width:0}
83
+ .scale span{color:var(--ink)}
84
+ .scale.red{color:var(--red);background:var(--red-soft)} .scale.green{color:var(--green);background:var(--green-soft)}
85
+ .sev{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 16px}
86
+ .sev span{font-family:var(--f-label);font-weight:700;font-size:14px;letter-spacing:.06em;text-transform:uppercase;padding:3px 10px;border-radius:3px;background:var(--grey-soft)}
87
+ .sev .blocker{background:var(--red);color:var(--paper)} .sev .fix{background:var(--gold-soft);color:var(--gold)}
88
+ h3.bout{font-family:var(--f-display);font-weight:400;font-size:26px;text-transform:uppercase;margin:40px 0 0;padding-top:8px;border-top:1px solid var(--rule)}
89
+ h3.bout a{text-decoration:none}
90
+ ol.qa{list-style:none;padding:0;margin:0;counter-reset:q}
91
+ ol.qa>li{margin:0 0 22px;padding:0 0 18px;border-bottom:1px solid var(--rule)}
92
+ ol.qa .q{font-weight:600;margin:0 0 6px}
93
+ ol.qa .q time{font-family:var(--f-mono);font-size:13px;color:var(--muted);font-weight:500;margin-left:6px}
94
+ ol.qa ul{list-style:none;padding:0;margin:0 0 8px}
95
+ ol.qa ul li{padding:4px 0 4px 34px;position:relative;font-size:16px;line-height:1.55}
96
+ ol.qa ul li i{position:absolute;left:0;top:4px;font-family:var(--f-mono);font-style:normal;font-weight:700;color:var(--muted)}
97
+ ol.qa ul li.rec i{color:var(--blue)}
98
+ ol.qa ul li.rec::after{content:"recomienda el réferi";font-family:var(--f-label);font-size:12.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--blue);background:var(--blue-soft);padding:0 6px;border-radius:3px;margin-left:8px;white-space:nowrap}
99
+ ol.qa ul li.picked{background:var(--navy-soft);border-radius:3px}
100
+ .answer{font-family:var(--f-label);font-size:16px;padding:6px 12px;border-left:4px solid var(--navy);background:var(--navy-soft);color:var(--navy)}
101
+ .answer b{color:var(--ink)}
102
+ .answer.pending{border-left-color:var(--red);background:var(--red-soft);color:var(--red)}
103
+ .byref{margin:28px 0 0;padding:14px 18px;background:var(--blue-soft);border-left:4px solid var(--blue)}
104
+ .byref h4{font-family:var(--f-label);font-weight:700;font-size:14px;letter-spacing:.1em;text-transform:uppercase;color:var(--blue);margin:0 0 8px}
105
+ .byref ul{margin:0;padding-left:18px}
106
+ .byref li{margin:0 0 6px;font-size:16px}
107
+ h4.sub{font-family:var(--f-label);font-weight:700;font-size:14px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:18px 0 4px}
108
+ /* Alternative B: the bill, «Qué necesita de ti ahora» (now-panel.js, styled in blocks.css) and «La crónica», one folded row per stage */
109
+ .headline{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:4px 24px;margin:20px 0 6px}
110
+ .headline h1{margin:0;font-size:clamp(36px,5.5vw,60px)}
111
+ .headline .meta{font-family:var(--f-label);font-size:16px;color:var(--muted);letter-spacing:.02em;padding-bottom:6px}
112
+ section.now:not(:has(.now-head)) .now-status{font-size:18px}
113
+ .chronicle{margin-top:44px}
114
+ .chron-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 16px;border-bottom:3px solid var(--ink);padding-bottom:10px}
115
+ .chron-head h2{font-family:var(--f-display);font-weight:400;font-size:36px;text-transform:uppercase;margin:0;line-height:1}
116
+ .chron-head span{font-family:var(--f-label);font-size:15px;color:var(--muted)}
117
+ .chron-head button{margin-left:auto;font:inherit;font-family:var(--f-label);font-weight:700;font-size:15px;color:var(--blue);background:none;border:0;cursor:pointer;padding:0}
118
+ details.stage{border-bottom:1px solid var(--rule)}
119
+ details.stage>summary{cursor:pointer;list-style:none;display:grid;grid-template-columns:18px 22px auto auto minmax(0,1fr);align-items:center;gap:6px 12px;padding:16px 4px}
120
+ details.stage>summary::-webkit-details-marker{display:none}
121
+ details.stage>summary::before{content:"›";font-family:var(--f-label);font-weight:700;font-size:22px;line-height:1;color:var(--muted);transition:transform .15s}
122
+ details.stage[open]>summary::before{transform:rotate(90deg)}
123
+ details.stage>summary .ico{width:22px;height:22px;display:grid;place-items:center;border:2px solid currentColor;border-radius:50%;font-family:var(--f-label);font-weight:700;font-size:12px;line-height:1;color:var(--muted)}
124
+ details.stage[data-state="done"]>summary .ico{color:var(--green)} details.stage[data-state="live"]>summary .ico{color:var(--red)} details.stage[data-state="todo"]>summary{color:var(--muted)}
125
+ details.stage>summary b{font-family:var(--f-display);font-weight:400;font-size:26px;line-height:1.1;text-transform:uppercase}
126
+ details.stage>summary .chip{font-family:var(--f-label);font-weight:700;font-size:12.5px;letter-spacing:.08em;text-transform:uppercase;padding:2px 8px;border-radius:3px;white-space:nowrap;background:var(--grey-soft);color:var(--muted)}
127
+ details.stage[data-state="done"]>summary .chip{background:var(--green);color:var(--paper)} details.stage[data-state="live"]>summary .chip{background:var(--red);color:var(--paper)}
128
+ details.stage>summary .chip.count{background:var(--gold-soft);color:var(--gold)}
129
+ details.stage>summary .line{font-family:var(--f-label);font-size:15px;color:var(--muted);min-width:0}
130
+ details.stage>.inner{padding:0 0 28px 70px}
131
+ @media (max-width:620px){details.stage>summary{grid-template-columns:18px 22px minmax(0,1fr)}details.stage>summary .chip{grid-column:3;justify-self:start}details.stage>summary .line{grid-column:2 / -1}details.stage>.inner{padding-left:0}}
132
+ details.stage>.inner>.prep:first-child,details.stage>.inner>.round:first-child{margin-top:16px}
70
133
  footer{margin-top:44px;font-family:var(--f-label);font-size:14px;color:var(--muted);letter-spacing:.02em;border-top:1px solid var(--rule);padding-top:14px}
134
+ /* "El cierre en números" (final edition only): classes cn-*, drawn by scripts/bout-stats-render.mjs.
135
+ Colors of the Lotería (web LOTTERY_ACCENTS without its purple): papel crema by day, noche de feria
136
+ by night. Fixed order: rosa, azul, naranja, verde, ámbar. */
137
+ .cn{--lot-0:#D11F66;--lot-1:#0E76A8;--lot-2:#C2410C;--lot-3:#0F7A55;--lot-4:#A16207;--lot-rojo:#B91C1C;--lot-oro:#F6C443;
138
+ --lot-paper:#FFFCF5;--lot-cream:#FBF1DE;--lot-ink:#241509;--lot-muted:#8A6A4B;--lot-night:#26180F;--lot-night-ink:#FFF5E4;--lot-on:#FFFFFF}
139
+ @media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .cn{--lot-0:#FF5C9C;--lot-1:#4FC3F7;--lot-2:#FF9A52;--lot-3:#4ADEA0;--lot-4:#FACC15;--lot-rojo:#FF7A70;--lot-oro:#FFC940;
140
+ --lot-paper:#26180F;--lot-cream:#170D08;--lot-ink:#FFF5E4;--lot-muted:#B39675;--lot-night:#22140C;--lot-on:#1F1308}}
141
+ :root[data-theme="dark"] .cn{--lot-0:#FF5C9C;--lot-1:#4FC3F7;--lot-2:#FF9A52;--lot-3:#4ADEA0;--lot-4:#FACC15;--lot-rojo:#FF7A70;--lot-oro:#FFC940;
142
+ --lot-paper:#26180F;--lot-cream:#170D08;--lot-ink:#FFF5E4;--lot-muted:#B39675;--lot-night:#22140C;--lot-on:#1F1308}
143
+ .cn-picado{height:26px;margin:0 0 14px;background:
144
+ linear-gradient(135deg,var(--canvas) 25%,transparent 25%) 0 100%/26px 13px repeat-x,
145
+ linear-gradient(225deg,var(--canvas) 25%,transparent 25%) 0 100%/26px 13px repeat-x,
146
+ linear-gradient(90deg,var(--lot-0) 0 20%,var(--lot-4) 20% 40%,var(--lot-3) 40% 60%,var(--lot-1) 60% 80%,var(--lot-2) 80% 100%) 0 0/260px 100% repeat-x}
147
+ .cn .cn-h{font-family:var(--f-label);font-weight:700;font-size:16px;letter-spacing:.1em;text-transform:uppercase;margin:34px 0 2px}
148
+ .cn .cn-note{font-family:var(--f-label);font-size:15px;color:var(--muted);margin:0 0 10px}
149
+ .cn-fill-0{fill:var(--lot-0);background:var(--lot-0)} .cn-fill-1{fill:var(--lot-1);background:var(--lot-1)} .cn-fill-2{fill:var(--lot-2);background:var(--lot-2)}
150
+ .cn-fill-3{fill:var(--lot-3);background:var(--lot-3)} .cn-fill-4{fill:var(--lot-4);background:var(--lot-4)}
151
+ .cn-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin:14px 0 6px}
152
+ @media (max-width:620px){.cn-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
153
+ .cn-tiles div{background:var(--lot-paper);color:var(--lot-ink);padding:12px 14px;border:2px solid var(--lot-ink);border-top-width:8px;border-radius:8px}
154
+ .cn-tiles div:nth-child(1){border-top-color:var(--lot-0)} .cn-tiles div:nth-child(2){border-top-color:var(--lot-1)} .cn-tiles div:nth-child(3){border-top-color:var(--lot-3)} .cn-tiles div:nth-child(4){border-top-color:var(--lot-4)}
155
+ .cn-tiles b{display:block;font-family:var(--f-display);font-weight:400;font-size:32px;line-height:1;font-variant-numeric:tabular-nums}
156
+ .cn-tiles span{font-family:var(--f-label);font-size:14px;color:var(--lot-muted)}
157
+ .cn-chart{background:var(--lot-paper);border:2px solid var(--lot-ink);border-radius:10px;padding:12px}
158
+ .cn-chart svg{display:block;width:100%;height:auto}
159
+ .cn-weigh{background:var(--lot-night);color:var(--lot-night-ink);padding:18px 18px 14px;border-radius:10px;border:2px solid var(--lot-oro)}
160
+ .cn-weigh-top{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:end;gap:12px}
161
+ .cn-corner{display:flex;flex-direction:column;gap:2px}
162
+ .cn-corner.cn-blue{text-align:right;align-items:flex-end}
163
+ .cn-corner-label{font-family:var(--f-label);font-weight:700;font-size:13px;letter-spacing:.14em;text-transform:uppercase;padding:1px 8px;border-radius:3px;align-self:flex-start;color:var(--lot-on)}
164
+ .cn-blue .cn-corner-label{align-self:flex-end}
165
+ .cn-red .cn-corner-label{background:var(--lot-0)} .cn-blue .cn-corner-label{background:var(--lot-1)}
166
+ .cn-corner b{font-family:var(--f-display);font-weight:400;font-size:clamp(38px,8vw,64px);line-height:1;font-variant-numeric:tabular-nums}
167
+ .cn-red b{color:#FF5C9C} .cn-blue b{color:#4FC3F7}
168
+ .cn-corner span:last-child{font-family:var(--f-label);font-size:15px;opacity:.8}
169
+ .cn-vs{font-family:var(--f-display);font-size:30px;color:var(--lot-oro);padding-bottom:22px}
170
+ .cn-tape{display:flex;gap:3px;height:14px;margin:14px 0 8px}
171
+ .cn-tape i{display:block;height:100%}
172
+ .cn-tape-red{background:#FF5C9C;border-radius:4px 0 0 4px} .cn-tape-blue{background:#4FC3F7;border-radius:0 4px 4px 0}
173
+ .cn-dead{display:flex;flex-wrap:wrap;gap:4px 18px;font-family:var(--f-label);font-size:14px;opacity:.8}
174
+ .cn-dead span:first-child{letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--lot-oro)}
175
+ .cn-dead b{font-family:var(--f-mono);font-weight:500}
176
+ .cn-rope{stroke-width:2.5;opacity:.7} .cn-rope-0{stroke:var(--lot-1)} .cn-rope-1{stroke:var(--lot-4)} .cn-rope-2{stroke:var(--lot-0)}
177
+ .cn-post{fill:var(--lot-ink)} .cn-canvas-line{stroke:var(--lot-ink);stroke-width:3}
178
+ .cn-bar{stroke:var(--lot-ink);stroke-width:2} .cn-bar-star{stroke:var(--lot-oro);stroke-width:4}
179
+ g:hover>.cn-bar{opacity:.85}
180
+ .cn-val{font-family:var(--f-display);font-size:18px;fill:var(--lot-ink);text-anchor:middle}
181
+ .cn-axis{font-family:var(--f-mono);font-size:11px;fill:var(--lot-muted);text-anchor:middle;text-transform:uppercase}
182
+ .cn-star{font-family:var(--f-label);font-weight:700;font-size:12px;letter-spacing:.12em;text-transform:uppercase;fill:var(--lot-4);text-anchor:middle}
183
+ .cn-clock-wrap{display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:18px;align-items:center}
184
+ @media (max-width:620px){.cn-clock-wrap{grid-template-columns:minmax(0,1fr)}}
185
+ .cn-face{fill:var(--lot-cream)} .cn-night{fill:var(--lot-1);opacity:.16} .cn-hub{fill:var(--lot-paper);stroke:var(--lot-ink);stroke-width:2}
186
+ .cn-hour{stroke:var(--lot-paper);stroke-width:1.5} .cn-hour:hover{opacity:.8}
187
+ .cn-hour.cn-band-0{fill:var(--lot-1)} .cn-hour.cn-band-1{fill:var(--lot-4)} .cn-hour.cn-band-2{fill:var(--lot-0)} .cn-hour.cn-band-3{fill:var(--lot-3)}
188
+ .cn-hour-peak{stroke:var(--lot-ink);stroke-width:3}
189
+ .cn-clock-big{font-family:var(--f-display);font-size:30px;fill:var(--lot-ink);text-anchor:middle}
190
+ .cn-clock-sub{font-family:var(--f-label);font-size:12px;letter-spacing:.12em;text-transform:uppercase;fill:var(--lot-muted);text-anchor:middle}
191
+ .cn-clock-facts{display:grid;gap:14px;color:var(--lot-ink)}
192
+ .cn-clock-facts b{display:block;font-family:var(--f-display);font-weight:400;font-size:40px;line-height:1}
193
+ .cn-clock-facts span{font-family:var(--f-label);font-size:15px;color:var(--lot-muted)}
194
+ .cn-bands{list-style:none;margin:4px 0 0;padding:0;display:grid;gap:6px;font-family:var(--f-label);font-size:15px}
195
+ .cn-bands li{display:grid;grid-template-columns:16px minmax(0,1fr) auto;gap:8px;align-items:center}
196
+ .cn-bands i{width:16px;height:16px;border-radius:4px;border:2px solid var(--lot-ink)}
197
+ .cn-bands i.cn-band-0{background:var(--lot-1)} .cn-bands i.cn-band-1{background:var(--lot-4)} .cn-bands i.cn-band-2{background:var(--lot-0)} .cn-bands i.cn-band-3{background:var(--lot-3)}
198
+ .cn-bands b{font-family:var(--f-mono);font-weight:700;font-size:13px}
199
+ .cn-box{background:var(--lot-night);color:var(--lot-night-ink);border-color:var(--lot-oro);padding:14px 16px}
200
+ .cn-box{--lot-0:#FF5C9C;--lot-1:#4FC3F7;--lot-2:#FF9A52;--lot-3:#4ADEA0;--lot-4:#FACC15}
201
+ .cn-box-row{display:grid;grid-template-columns:minmax(0,190px) minmax(0,1fr) 54px 42px;gap:10px;align-items:center;padding:5px 0;border-bottom:1px solid rgba(255,245,228,.14);font-family:var(--f-label);font-size:16px}
202
+ .cn-box-row:last-child{border-bottom:0}
203
+ .cn-box-name code{background:transparent;color:inherit;opacity:.55;margin-left:6px}
204
+ .cn-box-track{height:14px}
205
+ .cn-box-track i{display:block;height:100%;border-radius:0 5px 5px 0}
206
+ .cn-box .cn-ink{background:var(--lot-night-ink);opacity:.45}
207
+ .cn-box-row b{font-family:var(--f-display);font-weight:400;font-size:20px;text-align:right}
208
+ .cn-box-pct{font-family:var(--f-mono);font-size:12px;opacity:.7;text-align:right}
209
+ @media (max-width:560px){.cn-box-row{grid-template-columns:minmax(0,1fr) 54px 42px}.cn-box-track{grid-column:1/-1;order:3}}
210
+ .cn-scores{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
211
+ .cn-score{background:var(--lot-paper);color:var(--lot-ink);border:2px solid var(--lot-ink);border-radius:10px;overflow:hidden;display:flex;flex-direction:column}
212
+ .cn-score-head{color:var(--lot-on);font-family:var(--f-label);font-weight:700;font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;padding:5px 10px}
213
+ .cn-head-0 .cn-score-head{background:var(--lot-0)} .cn-head-1 .cn-score-head{background:var(--lot-1)} .cn-head-2 .cn-score-head{background:var(--lot-2)}
214
+ .cn-head-3 .cn-score-head{background:var(--lot-3)} .cn-head-4 .cn-score-head{background:var(--lot-4)}
215
+ .cn-score b{font-family:var(--f-display);font-weight:400;font-size:40px;line-height:1;padding:10px 10px 2px}
216
+ .cn-score span:not(.cn-score-head){font-family:var(--f-label);font-size:14px;color:var(--lot-muted);padding:0 10px 10px}
217
+ .cn-score-foul{border-color:var(--lot-rojo)} .cn-score-foul .cn-score-head{background:var(--lot-rojo)} .cn-score-foul b{color:var(--lot-rojo)}
218
+ .cn-reel{background:var(--lot-paper);color:var(--lot-ink);border:2px solid var(--lot-ink);border-radius:10px;padding:16px 14px 8px}
219
+ .cn-reel-line{position:relative;height:34px;margin:0 6px 10px;border-bottom:3px dashed var(--lot-ink)}
220
+ .cn-bell{position:absolute;bottom:-15px;transform:translateX(-50%);width:28px;height:28px;border-radius:50%;color:var(--lot-on);font-family:var(--f-display);font-size:14px;display:grid;place-items:center;border:2px solid var(--lot-ink)}
221
+ .cn-reel ol{list-style:none;margin:20px 0 0;padding:0}
222
+ .cn-reel li{display:grid;grid-template-columns:30px 88px minmax(0,1fr);gap:10px;align-items:baseline;margin:0 0 12px}
223
+ .cn-reel-n{font-family:var(--f-display);font-size:20px;color:var(--lot-0)}
224
+ .cn-reel li:nth-child(5n+2) .cn-reel-n{color:var(--lot-1)} .cn-reel li:nth-child(5n+3) .cn-reel-n{color:var(--lot-2)} .cn-reel li:nth-child(5n+4) .cn-reel-n{color:var(--lot-3)} .cn-reel li:nth-child(5n+5) .cn-reel-n{color:var(--lot-4)}
225
+ .cn-reel time{font-family:var(--f-mono);font-size:12.5px;color:var(--lot-muted)}
226
+ .cn-reel li p{margin:0}
227
+ @media (max-width:560px){.cn-reel li{grid-template-columns:30px minmax(0,1fr)}.cn-reel time,.cn-reel li p{grid-column:2}}
228
+ @media (max-width:560px){.cn-chart .cn-axis{font-size:19px}.cn-chart .cn-val{font-size:28px}.cn-chart .cn-star{font-size:19px}.cn-clock .cn-axis{font-size:15px}}
229
+ .cn-changelog{margin:6px 0 0;padding-left:20px}
230
+ .cn-changelog li{margin:0 0 8px;max-width:64ch}
231
+ .cn-changelog li::marker{color:var(--lot-0)}
71
232
  </style>
72
233
  <!--
73
- ring play-by-play template. The skill fills every {{…}} from the play-by-play JSON and writes
74
- the prose in the human's language. Rules:
234
+ ring play-by-play template, alternative B «Tablero del ahora + historial»: the page opens with
235
+ the judge's queue, not with the story. The skill fills every {{…}} from the play-by-play JSON and
236
+ writes the prose in the human's language. Rules:
237
+ - order: masthead, the headline with its one-line meta, «Qué necesita de ti ahora»
238
+ (section.now), «La crónica» (one details.stage per stage), the sources footer;
239
+ - «Qué necesita de ti ahora» is drawn by now-panel.js; the skill writes only its frame: one
240
+ div.now-bout per bout with data-pr, data-label («El back», «El front») and data-frozen (empty,
241
+ or why the fight is frozen, e.g. «espera el SDK de #1212»), p.now-ball (who has the ball now
242
+ and what comes next, e.g. «El wrestler trabaja en el concepto 2; el próximo round-bell, ~18:00»)
243
+ and p.now-news (the latest event with its time). Each bout's own ball and news go inside its
244
+ div.now-bout (the script keeps them in that bout's card); the fight's, if any, after the
245
+ div.now-bouts. The script counts, live from the page's
246
+ `respuestas` and `veredictos`, the unanswered questions, the pending verdicts (endpoints and
247
+ routes without a current one), the red scales and the frozen fights; it shows per bout the
248
+ next question and the next endpoints or routes with their controls, «Ver la cola», and
249
+ «Aceptar las N recomendaciones del réferi», which saves nothing before a dialog that lists
250
+ every answer it will save. With nothing pending it says who has the ball and the news;
251
+ - «La crónica»: one details.stage per stage, in this order, skipping a stage the JSON does not
252
+ have: el rudo (the sparring's first and second falls, `fold`), el relevo (the hand-off: the
253
+ bouts opened from the KO), el pesaje (weighIn), la entrevista (interview), el plan del técnico
254
+ (plan-tecnico.md), la pelea del técnico (the card, the crew, the tally, the rounds and the
255
+ judges' card). Each summary has the icon, the name, the state chip and ONE line of facts.
256
+ data-state is done (chip: KO, HECHO, DA EL PESO…), live (EN CURSO; the stage the bout is in)
257
+ or todo (POR EMPEZAR); a count chip (the plan, 0 / 41) takes class "chip count". Every live
258
+ stage carries the open attribute; done and todo stages stay closed. With several bouts (one
259
+ per repo), each stage holds every bout, each part opening with h3.bout data-pr="<PR>" and no
260
+ id (it repeats per stage; an id, if any, must be unique: bout-<PR>-<stage>). The panel's link
261
+ to a bout goes to its h3.bout in an open stage;
75
262
  - every <time> comes from an event's `local` field; never write a time the JSON does not have;
76
263
  - a gap is written as a gap: the beat goes where it must have happened, with
77
264
  <time class="nohora">sin hora · 20:45–20:56</time>, and its prose says so;
78
265
  - tags map 1:1 to event types: t-reclamo, t-dado, t-recibido, t-falta, t-juez, t-arbitro,
79
266
  t-bateria, t-campana; a foul beat also gets class "falta";
80
267
  - .ref under each beat says where the time came from (decision id, sha, review, run);
81
- - exactly two blockquotes (pull quotes) in the whole chronicle;
82
- - a fight from a sparring (--sparring): one <h3 class="fall"> before the first round of each
83
- fall of the JSON (first fall: the rudo against the judge; second: the defense of the técnicos;
84
- third: the referee), the card is the rudo against the judge, and the first beat of each day
85
- says the day (the event's `day`) in its prose;
86
- - no scripts; only the Google Fonts stylesheet above loads from outside.
268
+ - at most two blockquotes (pull quotes) in the whole chronicle;
269
+ - a fight from a sparring: in «El rudo», one h3.fall before the first round of each fall
270
+ (first: the rudo against the judge; second: the defense of the técnicos); the first beat of
271
+ each day says the day (the event's `day`). Its summary line is the call (KO), its date and time
272
+ from `fold.at`, the rounds, the evidence of `fold.evidence` (as links) and the files of
273
+ `fold.media` (a video, a PDF) named as text. Before any bout opened, «El rudo» is the live
274
+ stage and the panel shows what the sparring waits on;
275
+ - «El pesaje del contrato» from `weighIn` (never just «El pesaje» inside the stage:
276
+ `/ring:weigh-in` is another thing). The diagram goes in as the placeholder comment
277
+ `ring:db-diagram #<pr>`, which `play-by-play.mjs embed` fills. The scale is red until
278
+ `weighIn.scale.madeWeight`, green from the judge's approval on (its time and quote). It carries
279
+ data-ring-scale="<PR>" and data-approved="true|false" (weighIn.scale.approvedByJudge): the
280
+ page turns it green only when every operation and route is approved with its current
281
+ fingerprint and the judge's approve-contract is on record;
282
+ - «Endpoints del contrato» in the weigh-in: the placeholder comment `ring:api-contract #<PR>`;
283
+ the page draws there the progress «N de M aprobados», «Pendientes del contrato», the filters
284
+ and a card per operation with the verdict buttons. «Rutas del frontend» in the weigh-in of a
285
+ frontend bout: the placeholder comment `ring:front-routes #<PR>`;
286
+ - «La entrevista» from `interview`, answered from the page: each `ol.qa` carries
287
+ data-escalation="pr<PR>-E<k>", each li its `.q` starting with the question's number, its `ul`
288
+ of options (`li.rec` the recommended one, `i` the key) and its `.answer` box («Julio, 22:40:
289
+ a»; unanswered: `.answer.pending`). Nothing comes picked, not even the recommended option (it
290
+ keeps its badge). A logged answer with attachments shows them as img src="/_blob/<asset id>".
291
+ A question with context gets «Ver más información» (`embed --interview`). The referee's
292
+ decisions go apart, under «Del réferi». Events with `stage` are told there, not in the rounds;
293
+ - «El plan del técnico»: the placeholder comment `ring:tech-plan #<PR>` (`embed --plan`);
294
+ - write no script and no capability code: `play-by-play.mjs embed` puts the page's scripts
295
+ (interview-form.js, endpoints-view.js, now-panel.js) and the styles of what they draw
296
+ (blocks.css) at the very end, after the placeholder comment `ring:page-scripts` (the last line
297
+ of the page), never by searching for a closing body tag. Only the Google Fonts stylesheet and
298
+ js-yaml (jsdelivr) load from outside.
299
+ - the final edition only: the "El cierre en números" block goes right before the judges' card,
300
+ exactly as `bout-stats.mjs <pr> --html` prints it, plus the changelog the skill writes in its
301
+ CHANGELOG slot. The cn-* styles draw it; do not restyle it by hand.
87
302
  -->
88
303
  <div class="wrap">
89
- <div class="masthead"><span>Battle Arena · {{SECTION, e.g. "Crónicas del ring"}}</span><span class="live"><i></i>{{STATUS, e.g. "En vivo · round 2 de 6" or "Final"}}</span></div>
304
+ <div class="masthead"><span>Battle Arena · {{SECTION, e.g. "Crónicas del ring"}}</span><span class="live"><i></i>{{STATUS, e.g. "En curso · esperando la respuesta del juez al contrato" or "Final"}}</span></div>
90
305
 
91
- <h1>{{HEADLINE with the PR number in <em>, e.g. "El campeón <em>#1060</em> defiende el cinturón"}}</h1>
92
- <p class="dek">{{DEK: two sentences, the story of the bout so far, only facts from the JSON}}</p>
93
- <div class="byline">{{PLACE AND DATE, in the JSON's timezone}} · narra el árbitro</div>
94
-
95
- <div class="card">
96
- <div><div class="who">{{CHAMPION LABEL, e.g. "El campeón"}}</div><div class="what">PR #{{PR}} · {{what the PR does}} · {{tier}}</div></div>
97
- <div class="vs">VS</div>
98
- <div class="right"><div class="who">{{CHALLENGER LABEL}}</div><div class="what">{{e.g. "Copilot · revisor automático de GitHub"}}</div></div>
306
+ <div class="headline">
307
+ <h1>{{HEADLINE with the PR number in <em>, e.g. "KO a la tira morada: <em>#1212</em> sube a la báscula"}}</h1>
308
+ <span class="meta">{{e.g. "8 d 8 h · 185 commits · 0 Copilot · 0 faltas"}}</span>
99
309
  </div>
100
- <p class="crew"><b>{{Juez}}:</b> {{the human}} · <b>{{Árbitro}}:</b> {{the referee session, effort high}} · <b>{{Luchador}}:</b> {{the wrestler, medium}} · <b>{{Esquineros}}:</b> {{read-only reviewers, high}} · <b>{{Prueba de fuego}}:</b> {{the host's validation, if any}}</p>
101
310
 
102
- <div class="tally">
103
- <div><b>{{DURATION}}</b><span>{{de pelea, first to last event}}</span></div>
104
- <div><b>{{N}}</b><span>{{Copilot findings in N rounds}}</span></div>
105
- <div><b>{{N}}</b><span>{{commits by the wrestler}}</span></div>
106
- <div><b>{{N}}</b><span>{{fouls marked, on the referee}}</span></div>
107
- </div>
311
+ <section class="now" data-ring-now>
312
+ <div class="now-bouts">
313
+ <div class="now-bout" data-pr="{{PR}}" data-label="{{El back}}" data-frozen="">
314
+ <p class="now-ball"><b>{{La pelota:}}</b> {{e.g. "el wrestler trabaja en el concepto 2; el próximo round-bell, ~18:00"}}</p>
315
+ <p class="now-news"><b>{{Última noticia · HH:MM}}</b> · {{this bout's latest event, one sentence}}</p>
316
+ </div>
317
+ <!-- one per bout, e.g. <div class="now-bout" data-pr="504" data-label="El front" data-frozen="espera el SDK de #1212"> with its own p.now-ball and p.now-news </div> -->
318
+ </div>
319
+ <!-- the whole fight's ball and news, when there is one for all the bouts:
320
+ <p class="now-ball"><b>Quién tiene la pelota:</b> …</p><p class="now-news"><b>Última noticia · HH:MM</b> · …</p> -->
321
+ </section>
108
322
 
109
- <div class="legend">
110
- <span class="tag t-reclamo">{{Reclamo de Copilot}}</span><span class="tag t-dado">{{Golpe dado}}</span><span class="tag t-recibido">{{Golpe recibido}}</span><span class="tag t-falta">{{Falta}}</span><span class="tag t-arbitro">{{Árbitro}}</span><span class="tag t-juez">{{Juez}}</span><span class="tag t-bateria">{{Batería}}</span><span class="tag t-campana">{{Campana}}</span>
111
- </div>
323
+ <section class="chronicle">
324
+ <div class="chron-head"><h2>La crónica</h2><span>lo que ya pasó, plegado · clic en una etapa para abrirla</span><button type="button" data-ring-open-all>Abrir todo</button></div>
112
325
 
113
- <!-- In a fight from a sparring, before the first round of each fall:
114
- <h3 class="fall">{{e.g. "Primera caída · el rudo contra el juez"}}</h3> -->
115
- <!-- One section per round of the JSON; round 0 is the preview ("La previa"). -->
116
- <section class="round">
117
- <h2>{{ROUND NAME, e.g. "Round 1 · siete golpes de entrada"}}</h2>
118
- <div class="when">{{START local}} a {{END local, or "ahora" while open}}</div>
326
+ <details class="stage" data-stage="rudo" data-state="done">
327
+ <summary><span class="ico">✓</span><b>El rudo</b><span class="chip">KO</span><span class="line">{{5 nov 22:01 · 2 rounds · 185 commits · sin equipo · evidencia: <a href="…">artifact v6</a> y video}}</span></summary>
328
+ <div class="inner">
329
+ <p>{{one paragraph: how the rudo's fight ended}}</p>
330
+ <h3 class="fall">{{Primera caída · el rudo contra el juez}}</h3>
331
+ <!-- the rounds of the first and second falls, as section.round, plus their round table -->
332
+ </div>
333
+ </details>
119
334
 
120
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-reclamo">{{Copilot}}</span>{{prose: what happened, one paragraph, plain sentences}}<span class="ref">{{source: review, file:line, decision id}}</span></p></div>
121
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-dado">{{Golpe dado}}</span>{{…}}<span class="ref">{{sha range}}</span></p></div>
122
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-recibido">{{Golpe recibido}}</span>{{…}}<span class="ref">{{rebound ids}}</span></p></div>
123
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-juez">{{Juez}}</span>{{…}}<span class="ref">{{D ids}}</span></p></div>
124
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-arbitro">{{Árbitro}}</span>{{…}}<span class="ref">{{D id}}</span></p></div>
125
- <div class="beat"><time class="nohora">sin hora · {{HH:MM}}–{{HH:MM}}</time><p><span class="tag t-arbitro">{{Árbitro}}</span>{{a gap from the JSON: what happened, said to have no recorded time}}<span class="ref">{{source}}</span></p></div>
126
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-bateria">{{Batería}}</span>{{… with SHA, command and result}}<span class="ref">{{run}}</span></p></div>
127
- <div class="beat falta"><time>{{HH:MM}}</time><p><span class="tag t-falta">{{Falta}}</span>{{the referee marks the foul on itself, with the evidence}}<span class="ref">{{D id}}</span></p></div>
128
- <blockquote>{{PULL QUOTE: one sentence that sums up the turn of the bout}}</blockquote>
129
- <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-campana">{{Campana}}</span>{{replies pushed, Copilot re-requested, the belt waits for the decision}}</p></div>
130
- </section>
335
+ <details class="stage" data-stage="relevo" data-state="done">
336
+ <summary><span class="ico">✓</span><b>El relevo</b><span class="chip">Hecho</span><span class="line">{{#1212 y #504 abiertos en 10 min · release/ + mainevent/}}</span></summary>
337
+ <div class="inner">{{the hand-off round: the bouts opened, their branches and worktrees}}</div>
338
+ </details>
131
339
 
132
- <h3 class="section">{{Tarjeta de los jueces}}</h3>
133
- <div class="tbl"><table>
134
- <thead><tr><th>{{Round}}</th><th>{{Tiempo}}</th><th>{{Golpes de Copilot}}</th><th>{{Golpes dados}}</th><th>{{Golpes recibidos}}</th><th>{{Faltas}}</th><th>{{Resultado}}</th></tr></thead>
135
- <tbody>
136
- <tr><td class="n">{{1}}</td><td>{{duration or "en curso"}}</td><td>{{…}}</td><td>{{…}}</td><td>{{…}}</td><td class="n">{{0}}</td><td>{{…}}</td></tr>
137
- </tbody>
138
- </table></div>
340
+ <details class="stage" data-stage="pesaje" data-state="live" open>
341
+ <summary><span class="ico">⚖</span><b>El pesaje del contrato</b><span class="chip">En curso</span><span class="line">{{6 BLOCKER · 13 FIX · diagrama ER · 0 de 34 endpoints aprobados}}</span></summary>
342
+ <div class="inner">
343
+ <h3 class="bout" data-pr="{{PR}}"><a href="{{PR url}}">#{{PR}}</a> · {{repo}}</h3>
344
+ <section class="prep">
345
+ <div class="when">{{opened local}} · PR #{{PR}}</div>
346
+ <p>{{one paragraph: what was promoted and what the judge has to sign}}</p>
347
+ <dl class="facts">
348
+ <dt>Entrega</dt><dd><a href="{{mainevent url}}">#{{PR}}</a> <code>{{mainevent}}</code> → <code>{{release}}</code></dd>
349
+ <dt>Borrador</dt><dd><a href="{{sparring url}}">#{{sparring pr}}</a> <code>{{sparring branch}}</code> (do-not-merge)</dd>
350
+ <dt>Worktrees</dt><dd><code>{{wrestler worktree}}</code></dd>
351
+ <dt>Peso</dt><dd>{{files}} archivos · +{{insertions}} / −{{deletions}} líneas (contra <code>{{base}}</code>, en <code>{{sha}}</code>)</dd>
352
+ </dl>
353
+ <div class="sev"><span class="blocker">{{N}} BLOCKER</span><span class="fix">{{N}} FIX</span><span>{{N}} en espera del juez</span></div>
354
+ <div class="scale red" data-ring-scale="{{PR}}" data-approved="{{weighIn.scale.approvedByJudge}}"><b>No da el peso</b><span>{{N de M endpoints aprobados, and what waits}}</span></div>
355
+ <h4 class="sub">Endpoints del contrato</h4>
356
+ <!-- ring:api-contract #{{PR}} -->
357
+ <!-- a frontend bout: <h4 class="sub">Rutas del frontend</h4> and the placeholder comment ring:front-routes #{{PR}} -->
358
+ <h4 class="sub">Base de datos</h4>
359
+ <!-- ring:db-diagram #{{PR}} -->
360
+ </section>
361
+ </div>
362
+ </details>
363
+
364
+ <details class="stage" data-stage="entrevista" data-state="live" open>
365
+ <summary><span class="ico">?</span><b>La entrevista</b><span class="chip">En curso</span><span class="line">{{las 11 preguntas con su contexto · Del réferi D1–D4}}</span></summary>
366
+ <div class="inner">
367
+ <section class="prep">
368
+ <div class="when">{{the escalation's local time}} · {{N}} preguntas</div>
369
+ <ol class="qa" data-escalation="pr{{PR}}-E{{k}}">
370
+ <li>
371
+ <p class="q">1. {{question}}<time>{{HH:MM}}</time></p>
372
+ <ul>
373
+ <li class="rec"><i>a</i>{{option}}</li>
374
+ <li><i>b</i>{{option}}</li>
375
+ </ul>
376
+ <div class="answer pending">Sin respuesta del juez todavía</div>
377
+ <!-- answered: <div class="answer"><b>{{Julio}}, {{HH:MM}}:</b> a</div> -->
378
+ </li>
379
+ </ol>
380
+ <div class="byref"><h4>Del réferi</h4><ul><li><b>D1</b> · {{HH:MM}} · {{decision}}</li></ul></div>
381
+ </section>
382
+ </div>
383
+ </details>
384
+
385
+ <details class="stage" data-stage="plan" data-state="live" open>
386
+ <summary><span class="ico">≡</span><b>El plan del técnico</b><span class="chip count">{{0 / 41}}</span><span class="line">{{back 0 de 23 (8 esperan al juez) · front 0 de 18 (3 esperan al juez)}}</span></summary>
387
+ <div class="inner">
388
+ <section class="prep">
389
+ <!-- ring:tech-plan #{{PR}} -->
390
+ </section>
391
+ </div>
392
+ </details>
393
+
394
+ <details class="stage" data-stage="pelea" data-state="todo">
395
+ <summary><span class="ico">✕</span><b>La pelea del técnico</b><span class="chip">Por empezar</span><span class="line">{{la previa: CI en rojo en la punta heredada 2aea458f1 · nadie ha empujado}}</span></summary>
396
+ <div class="inner">
397
+ <div class="card">
398
+ <div><div class="who">{{CHAMPION LABEL, e.g. "El campeón"}}</div><div class="what">PR #{{PR}} · {{what the PR does}} · {{tier}}</div></div>
399
+ <div class="vs">VS</div>
400
+ <div class="right"><div class="who">{{CHALLENGER LABEL}}</div><div class="what">{{e.g. "Copilot · revisor automático de GitHub"}}</div></div>
401
+ </div>
402
+ <p class="crew"><b>{{Juez}}:</b> {{the human}} · <b>{{Árbitro}}:</b> {{the referee session, effort high}} · <b>{{Luchador}}:</b> {{the wrestler, medium}} · <b>{{Esquineros}}:</b> {{read-only reviewers, high}} · <b>{{Prueba de fuego}}:</b> {{the host's validation, if any}}</p>
403
+ <div class="tally">
404
+ <div><b>{{DURATION}}</b><span>{{de pelea, first to last event}}</span></div>
405
+ <div><b>{{N}}</b><span>{{Copilot findings in N rounds}}</span></div>
406
+ <div><b>{{N}}</b><span>{{commits by the wrestler}}</span></div>
407
+ <div><b>{{N}}</b><span>{{fouls marked, on the referee}}</span></div>
408
+ </div>
409
+ <div class="legend">
410
+ <span class="tag t-reclamo">{{Reclamo de Copilot}}</span><span class="tag t-dado">{{Golpe dado}}</span><span class="tag t-recibido">{{Golpe recibido}}</span><span class="tag t-falta">{{Falta}}</span><span class="tag t-arbitro">{{Árbitro}}</span><span class="tag t-juez">{{Juez}}</span><span class="tag t-bateria">{{Batería}}</span><span class="tag t-campana">{{Campana}}</span>
411
+ </div>
412
+ <!-- One section per round of the JSON; round 0 is the preview ("La previa"). -->
413
+ <section class="round">
414
+ <h2>{{ROUND NAME, e.g. "Round 1 · siete golpes de entrada"}}</h2>
415
+ <div class="when">{{START local}} a {{END local, or "ahora" while open}}</div>
416
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-reclamo">{{Copilot}}</span>{{prose: what happened, one paragraph, plain sentences}}<span class="ref">{{source: review, file:line, decision id}}</span></p></div>
417
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-dado">{{Golpe dado}}</span>{{…}}<span class="ref">{{sha range}}</span></p></div>
418
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-recibido">{{Golpe recibido}}</span>{{…}}<span class="ref">{{rebound ids}}</span></p></div>
419
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-juez">{{Juez}}</span>{{…}}<span class="ref">{{D ids}}</span></p></div>
420
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-arbitro">{{Árbitro}}</span>{{…}}<span class="ref">{{D id}}</span></p></div>
421
+ <div class="beat"><time class="nohora">sin hora · {{HH:MM}}–{{HH:MM}}</time><p><span class="tag t-arbitro">{{Árbitro}}</span>{{a gap from the JSON: what happened, said to have no recorded time}}<span class="ref">{{source}}</span></p></div>
422
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-bateria">{{Batería}}</span>{{… with SHA, command and result}}<span class="ref">{{run}}</span></p></div>
423
+ <div class="beat falta"><time>{{HH:MM}}</time><p><span class="tag t-falta">{{Falta}}</span>{{the referee marks the foul on itself, with the evidence}}<span class="ref">{{D id}}</span></p></div>
424
+ <blockquote>{{PULL QUOTE: one sentence that sums up the turn of the bout}}</blockquote>
425
+ <div class="beat"><time>{{HH:MM}}</time><p><span class="tag t-campana">{{Campana}}</span>{{replies pushed, Copilot re-requested, the belt waits for the decision}}</p></div>
426
+ </section>
427
+ <!-- FINAL EDITION ONLY: the output of `bout-stats.mjs <pr> --html --moments <file>`, with the
428
+ changelog in its CHANGELOG slot:
429
+ <h4 class="cn-h">{{Lo que se libera · changelog}}</h4>
430
+ <ul class="cn-changelog"><li><b>{{Área}}.</b> {{what ships, from the PR body and the rounds}}</li></ul> -->
431
+ <h3 class="section">{{Tarjeta de los jueces}}</h3>
432
+ <div class="tbl"><table>
433
+ <thead><tr><th>{{Round}}</th><th>{{Tiempo}}</th><th>{{Golpes de Copilot}}</th><th>{{Golpes dados}}</th><th>{{Golpes recibidos}}</th><th>{{Faltas}}</th><th>{{Resultado}}</th></tr></thead>
434
+ <tbody>
435
+ <tr><td class="n">{{1}}</td><td>{{duration or "en curso"}}</td><td>{{…}}</td><td>{{…}}</td><td>{{…}}</td><td class="n">{{0}}</td><td>{{…}}</td></tr>
436
+ </tbody>
437
+ </table></div>
438
+ </div>
439
+ </details>
440
+ </section>
139
441
 
140
442
  <footer>{{Sources line: the ring ledgers (decisions and rebounds), the commits, Copilot's reviews, the thread replies, the CI runs and any provided times (marked). Times in TIMEZONE. Whether Copilot reviewed the last commit. "Se actualiza mientras dure la pelea" while the bout is active.}}</footer>
141
443
  </div>
444
+ <!-- ring:page-scripts -->