build 122 - стартовые пятерки
This commit is contained in:
@@ -2597,7 +2597,9 @@ function startCustomTooltips() {
|
||||
// BUILD86: "Заготовки" is always the final top-level runtime tab.
|
||||
// Reorder it on every config normalisation as older published configs may
|
||||
// already contain the tab near "Игра" from BUILD84/85.
|
||||
state.config.tabs = state.config.tabs.filter((tab) => tab?.id !== "prepared_titles");
|
||||
state.config.tabs = state.config.tabs.filter((tab) => !["lines", "prepared_titles"].includes(tab?.id));
|
||||
// BUILD122: line/five sorting is a first-class operator workspace.
|
||||
state.config.tabs.push({ id: "lines", label: "Пятёрки" });
|
||||
state.config.tabs.push({ id: "prepared_titles", label: "Заготовки" });
|
||||
if (state.activeTab === "prematch") state.activeTab = state.config.tabs.find((tab) => tab.id === "main")?.id || state.config.tabs[0].id;
|
||||
}
|
||||
@@ -6817,6 +6819,10 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
name: get("nameField", `Игрок ${index + 1}`),
|
||||
position: get("positionField", ""),
|
||||
role: String(row?.role || ""),
|
||||
line: String(row?.line || row?.line_number || "").trim(),
|
||||
lineSortOrder: Number(row?.line_sort_order || 0),
|
||||
lineManual: Boolean(row?.line_manual),
|
||||
apiLine: String(row?.api_line || row?.api_line_number || "").trim(),
|
||||
raw: clone(row)
|
||||
};
|
||||
}
|
||||
@@ -6825,19 +6831,33 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
const props = component.props || {};
|
||||
const rows = getByPath(state.data, side === "home" ? props.homePlayersPath : props.awayPlayersPath);
|
||||
const limit = Math.max(1, Number(props.rosterLimit) || 40);
|
||||
return (Array.isArray(rows) ? rows : [])
|
||||
.map((row, index) => normalizeHockeyPlayer(component, row, side, index))
|
||||
.sort((left, right) => {
|
||||
const leftNumber = String(left.number || "").replace(/^#/, "");
|
||||
const rightNumber = String(right.number || "").replace(/^#/, "");
|
||||
if (!leftNumber && rightNumber) return 1;
|
||||
if (leftNumber && !rightNumber) return -1;
|
||||
return leftNumber.localeCompare(rightNumber, undefined, {
|
||||
numeric: true,
|
||||
sensitivity: "base",
|
||||
}) || left.name.localeCompare(right.name);
|
||||
})
|
||||
.slice(0, limit);
|
||||
const players = (Array.isArray(rows) ? rows : [])
|
||||
.map((row, index) => normalizeHockeyPlayer(component, row, side, index));
|
||||
const hasLineData = players.some((player) => String(player.line || "").trim());
|
||||
players.sort((left, right) => {
|
||||
if (hasLineData) {
|
||||
const lineValue = (player) => {
|
||||
const raw = String(player.line || "").trim();
|
||||
if (!raw) return 10000;
|
||||
const number = Number(raw);
|
||||
return Number.isFinite(number) ? number : 9000;
|
||||
};
|
||||
const lineDiff = lineValue(left) - lineValue(right);
|
||||
if (lineDiff) return lineDiff;
|
||||
const leftOrder = Number(left.lineSortOrder || 0) || 10000;
|
||||
const rightOrder = Number(right.lineSortOrder || 0) || 10000;
|
||||
if (leftOrder !== rightOrder) return leftOrder - rightOrder;
|
||||
}
|
||||
const leftNumber = String(left.number || "").replace(/^#/, "");
|
||||
const rightNumber = String(right.number || "").replace(/^#/, "");
|
||||
if (!leftNumber && rightNumber) return 1;
|
||||
if (leftNumber && !rightNumber) return -1;
|
||||
return leftNumber.localeCompare(rightNumber, undefined, {
|
||||
numeric: true,
|
||||
sensitivity: "base",
|
||||
}) || left.name.localeCompare(right.name);
|
||||
});
|
||||
return players.slice(0, limit);
|
||||
}
|
||||
|
||||
function hockeyRosterCounts(players) {
|
||||
@@ -6860,6 +6880,296 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
return `<em class="hpd-roster-count-breakdown" data-tooltip="${escapeHtml(tooltip)}" aria-label="${escapeHtml(tooltip)}"><b>${counts.total}</b><span>${counts.forwards}</span><span>${counts.defenders}</span><span>${counts.goalkeepers}</span></em>`;
|
||||
}
|
||||
|
||||
|
||||
// BUILD122 — operator line/five sorting.
|
||||
function hockeyLinesGame() {
|
||||
return getByPath(state.data, "hockey.selected_game") || null;
|
||||
}
|
||||
|
||||
function hockeyLinesPlayers(side) {
|
||||
const game = hockeyLinesGame();
|
||||
const rows = game?.[side]?.players;
|
||||
return Array.isArray(rows) ? rows : [];
|
||||
}
|
||||
|
||||
function hockeyLineNumericValue(value) {
|
||||
const raw = String(value || "").trim();
|
||||
if (!raw) return 10000;
|
||||
const number = Number(raw);
|
||||
return Number.isFinite(number) ? number : 9000;
|
||||
}
|
||||
|
||||
function hockeyLinePlayerNumberValue(player) {
|
||||
const raw = String(player?.number || "").replace(/^#/, "").trim();
|
||||
const number = Number(raw);
|
||||
return Number.isFinite(number) ? number : 10000;
|
||||
}
|
||||
|
||||
function hockeyLinePlayersSorted(side, lineNumber) {
|
||||
const line = String(lineNumber || "").trim();
|
||||
return hockeyLinesPlayers(side)
|
||||
.filter((player) => String(player?.line || "").trim() === line)
|
||||
.slice()
|
||||
.sort((left, right) => {
|
||||
const leftOrder = Number(left?.line_sort_order || 0) || 10000;
|
||||
const rightOrder = Number(right?.line_sort_order || 0) || 10000;
|
||||
return leftOrder - rightOrder
|
||||
|| hockeyLinePlayerNumberValue(left) - hockeyLinePlayerNumberValue(right)
|
||||
|| String(left?.name || "").localeCompare(String(right?.name || ""), undefined, { sensitivity: "base" });
|
||||
});
|
||||
}
|
||||
|
||||
function hockeyLineVisibleCount(side) {
|
||||
const key = `hockeyLinesVisible:${side}`;
|
||||
const maxAssigned = hockeyLinesPlayers(side).reduce((maximum, player) => {
|
||||
const value = Number(String(player?.line || "").trim());
|
||||
return Number.isFinite(value) ? Math.max(maximum, value) : maximum;
|
||||
}, 0);
|
||||
const current = Number(state.formValues[key] || 0);
|
||||
const next = Math.max(4, maxAssigned, current);
|
||||
state.formValues[key] = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
function hockeyReindexLine(side, lineNumber) {
|
||||
hockeyLinePlayersSorted(side, lineNumber).forEach((player, index) => {
|
||||
player.line_sort_order = index + 1;
|
||||
});
|
||||
}
|
||||
|
||||
function hockeyMoveLinePlayer(side, playerId, targetLine, beforePlayerId = "") {
|
||||
const players = hockeyLinesPlayers(side);
|
||||
const player = players.find((item) => String(item?.external_id || item?.id || "") === String(playerId || ""));
|
||||
if (!player) return false;
|
||||
const sourceLine = String(player.line || "").trim();
|
||||
const nextLine = String(targetLine || "").trim();
|
||||
const targetPlayers = hockeyLinePlayersSorted(side, nextLine).filter((item) => item !== player);
|
||||
let insertIndex = targetPlayers.length;
|
||||
if (beforePlayerId) {
|
||||
const found = targetPlayers.findIndex((item) => String(item?.external_id || item?.id || "") === String(beforePlayerId));
|
||||
if (found >= 0) insertIndex = found;
|
||||
}
|
||||
player.line = nextLine;
|
||||
targetPlayers.splice(insertIndex, 0, player);
|
||||
targetPlayers.forEach((item, index) => { item.line_sort_order = index + 1; });
|
||||
if (sourceLine !== nextLine) hockeyReindexLine(side, sourceLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function hockeySaveLineAssignments(side) {
|
||||
const game = hockeyLinesGame();
|
||||
const gameId = String(game?.external_id || game?.id || "").trim();
|
||||
if (!gameId) throw new Error("Сначала выберите матч");
|
||||
const assignments = hockeyLinesPlayers(side).map((player) => ({
|
||||
player_external_id: String(player?.external_id || player?.id || ""),
|
||||
line_number: String(player?.line || "").trim(),
|
||||
sort_order: Number(player?.line_sort_order || 0),
|
||||
})).filter((item) => item.player_external_id);
|
||||
const payload = await hockeyGameControlRequest(`/games/${encodeURIComponent(gameId)}/lines`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
side,
|
||||
assignments,
|
||||
language: hockeyGameControlLanguage(),
|
||||
}),
|
||||
});
|
||||
state.data.hockey ||= {};
|
||||
const current = state.data.hockey.selected_game || {};
|
||||
current[side] ||= {};
|
||||
current[side].players = Array.isArray(payload?.[side]?.players) ? payload[side].players : current[side].players;
|
||||
if (payload?.player_statistics) current.player_statistics = payload.player_statistics;
|
||||
if (payload?.season_player_statistics) current.season_player_statistics = payload.season_player_statistics;
|
||||
state.data.hockey.selected_game = current;
|
||||
return payload;
|
||||
}
|
||||
|
||||
async function hockeyResetLineAssignments(side) {
|
||||
const game = hockeyLinesGame();
|
||||
const gameId = String(game?.external_id || game?.id || "").trim();
|
||||
if (!gameId) throw new Error("Сначала выберите матч");
|
||||
const payload = await hockeyGameControlRequest(`/games/${encodeURIComponent(gameId)}/lines`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
side,
|
||||
assignments: [],
|
||||
reset: true,
|
||||
language: hockeyGameControlLanguage(),
|
||||
}),
|
||||
});
|
||||
state.data.hockey ||= {};
|
||||
const current = state.data.hockey.selected_game || {};
|
||||
current[side] ||= {};
|
||||
current[side].players = Array.isArray(payload?.[side]?.players) ? payload[side].players : current[side].players;
|
||||
if (payload?.player_statistics) current.player_statistics = payload.player_statistics;
|
||||
if (payload?.season_player_statistics) current.season_player_statistics = payload.season_player_statistics;
|
||||
state.data.hockey.selected_game = current;
|
||||
state.formValues[`hockeyLinesVisible:${side}`] = 0;
|
||||
return payload;
|
||||
}
|
||||
|
||||
function hockeyLinePlayerCard(side, player) {
|
||||
const node = div("hockey-line-player");
|
||||
const playerId = String(player?.external_id || player?.id || "");
|
||||
node.draggable = true;
|
||||
node.dataset.playerId = playerId;
|
||||
node.dataset.side = side;
|
||||
node.innerHTML = `
|
||||
<span class="hockey-line-drag">⋮⋮</span>
|
||||
<b>${escapeHtml(player?.number ? `#${player.number}` : "—")}</b>
|
||||
<strong>${escapeHtml(player?.name || "Игрок")}</strong>
|
||||
<small>${escapeHtml(player?.position || "")}</small>
|
||||
`;
|
||||
node.addEventListener("dragstart", (event) => {
|
||||
const payload = JSON.stringify({ side, playerId });
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
event.dataTransfer.setData("application/x-hockey-line-player", payload);
|
||||
event.dataTransfer.setData("text/plain", payload);
|
||||
node.classList.add("is-dragging");
|
||||
});
|
||||
node.addEventListener("dragend", () => node.classList.remove("is-dragging"));
|
||||
return node;
|
||||
}
|
||||
|
||||
function hockeyReadLineDrag(event) {
|
||||
try {
|
||||
const raw = event.dataTransfer?.getData("application/x-hockey-line-player") || event.dataTransfer?.getData("text/plain") || "";
|
||||
const payload = JSON.parse(raw);
|
||||
if (!payload?.side || !payload?.playerId) return null;
|
||||
return payload;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function hockeyLineDropZone(side, lineNumber, players) {
|
||||
const zone = div("hockey-line-dropzone");
|
||||
zone.dataset.side = side;
|
||||
zone.dataset.line = String(lineNumber || "");
|
||||
if (!players.length) zone.innerHTML = `<span>Перетащите игрока сюда</span>`;
|
||||
players.forEach((player) => {
|
||||
const card = hockeyLinePlayerCard(side, player);
|
||||
card.addEventListener("dragover", (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
card.classList.add("is-drop-before");
|
||||
});
|
||||
card.addEventListener("dragleave", () => card.classList.remove("is-drop-before"));
|
||||
card.addEventListener("drop", async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
card.classList.remove("is-drop-before");
|
||||
const dragged = hockeyReadLineDrag(event);
|
||||
if (!dragged || dragged.side !== side) return;
|
||||
if (!hockeyMoveLinePlayer(side, dragged.playerId, lineNumber, String(player?.external_id || player?.id || ""))) return;
|
||||
renderRuntime();
|
||||
try {
|
||||
await hockeySaveLineAssignments(side);
|
||||
renderRuntime();
|
||||
} catch (error) {
|
||||
toast(`Не удалось сохранить пятёрки: ${error.message}`, true);
|
||||
}
|
||||
});
|
||||
zone.appendChild(card);
|
||||
});
|
||||
zone.addEventListener("dragover", (event) => {
|
||||
const dragged = hockeyReadLineDrag(event);
|
||||
if (!dragged || dragged.side !== side) return;
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
zone.classList.add("is-over");
|
||||
});
|
||||
zone.addEventListener("dragleave", (event) => {
|
||||
if (!zone.contains(event.relatedTarget)) zone.classList.remove("is-over");
|
||||
});
|
||||
zone.addEventListener("drop", async (event) => {
|
||||
if (event.target.closest(".hockey-line-player")) return;
|
||||
event.preventDefault();
|
||||
zone.classList.remove("is-over");
|
||||
const dragged = hockeyReadLineDrag(event);
|
||||
if (!dragged || dragged.side !== side) return;
|
||||
if (!hockeyMoveLinePlayer(side, dragged.playerId, lineNumber)) return;
|
||||
renderRuntime();
|
||||
try {
|
||||
await hockeySaveLineAssignments(side);
|
||||
renderRuntime();
|
||||
} catch (error) {
|
||||
toast(`Не удалось сохранить пятёрки: ${error.message}`, true);
|
||||
}
|
||||
});
|
||||
return zone;
|
||||
}
|
||||
|
||||
function hockeyLineTeamColumn(side) {
|
||||
const game = hockeyLinesGame() || {};
|
||||
const team = game?.[side] || {};
|
||||
const column = div(`hockey-lines-team side-${side}`);
|
||||
const players = hockeyLinesPlayers(side);
|
||||
const manualCount = players.filter((player) => Boolean(player?.line_manual)).length;
|
||||
const header = div("hockey-lines-team-header");
|
||||
header.innerHTML = `
|
||||
<div><span>${side === "home" ? "ЛЕВАЯ КОМАНДА" : "ПРАВАЯ КОМАНДА"}</span><strong>${escapeHtml(team?.name || (side === "home" ? "Хозяева" : "Гости"))}</strong></div>
|
||||
<em>${manualCount ? `ручн. ${manualCount}` : "API"}</em>
|
||||
`;
|
||||
const actions = div("hockey-lines-actions");
|
||||
const addButton = document.createElement("button");
|
||||
addButton.type = "button";
|
||||
addButton.textContent = "+ Звено";
|
||||
addButton.addEventListener("click", () => {
|
||||
state.formValues[`hockeyLinesVisible:${side}`] = hockeyLineVisibleCount(side) + 1;
|
||||
renderRuntime();
|
||||
});
|
||||
const resetButton = document.createElement("button");
|
||||
resetButton.type = "button";
|
||||
resetButton.textContent = "Вернуть из API";
|
||||
resetButton.title = "Снять ручные назначения и вернуть последнее звено/порядок, полученные из API";
|
||||
resetButton.addEventListener("click", async () => {
|
||||
resetButton.disabled = true;
|
||||
try {
|
||||
await hockeyResetLineAssignments(side);
|
||||
toast(`Пятёрки ${side === "home" ? "HOME" : "AWAY"}: восстановлены из API`);
|
||||
renderRuntime();
|
||||
} catch (error) {
|
||||
resetButton.disabled = false;
|
||||
toast(`Не удалось вернуть пятёрки: ${error.message}`, true);
|
||||
}
|
||||
});
|
||||
actions.append(addButton, resetButton);
|
||||
column.append(header, actions);
|
||||
|
||||
const unassigned = div("hockey-line-card is-unassigned");
|
||||
const unassignedPlayers = hockeyLinePlayersSorted(side, "");
|
||||
unassigned.innerHTML = `<header><strong>Без звена</strong><span>${unassignedPlayers.length}</span></header>`;
|
||||
unassigned.appendChild(hockeyLineDropZone(side, "", unassignedPlayers));
|
||||
column.appendChild(unassigned);
|
||||
|
||||
const count = hockeyLineVisibleCount(side);
|
||||
for (let line = 1; line <= count; line += 1) {
|
||||
const linePlayers = hockeyLinePlayersSorted(side, String(line));
|
||||
const card = div("hockey-line-card");
|
||||
card.innerHTML = `<header><strong>Звено ${line}</strong><span>${linePlayers.length}</span></header>`;
|
||||
card.appendChild(hockeyLineDropZone(side, String(line), linePlayers));
|
||||
column.appendChild(card);
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
function renderHockeyLinesWorkspace() {
|
||||
const workspace = div("hockey-lines-workspace");
|
||||
const game = hockeyLinesGame();
|
||||
if (!game) {
|
||||
workspace.innerHTML = `<div class="hockey-lines-empty"><strong>Выберите матч</strong><span>После загрузки матча здесь появятся составы для сортировки по звеньям.</span></div>`;
|
||||
return workspace;
|
||||
}
|
||||
const intro = div("hockey-lines-intro");
|
||||
intro.innerHTML = `<div><strong>Пятёрки / звенья</strong><span>Перетаскивайте игроков между звеньями и меняйте порядок внутри звена. Изменения сохраняются в базе автоматически.</span></div><small>SQL: hockey_game_rosters.line_number + line_sort_order</small>`;
|
||||
workspace.append(intro);
|
||||
const teams = div("hockey-lines-columns");
|
||||
teams.append(hockeyLineTeamColumn("home"), hockeyLineTeamColumn("away"));
|
||||
workspace.appendChild(teams);
|
||||
return workspace;
|
||||
}
|
||||
|
||||
function hockeyTeamName(component, side) {
|
||||
const path = side === "home" ? component.props?.homeTeamPath : component.props?.awayTeamPath;
|
||||
return formatValue(getByPath(state.data, path), side === "home" ? "Хозяева" : "Гости");
|
||||
@@ -13272,7 +13582,7 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
}
|
||||
|
||||
function runtimeHasFixedHockeyCanvas() {
|
||||
if (state.activeTab === "prepared_titles") return true;
|
||||
if (["prepared_titles", "lines"].includes(state.activeTab)) return true;
|
||||
return state.config.components.some((component) =>
|
||||
[
|
||||
"hockey_penalty_dashboard",
|
||||
@@ -13382,6 +13692,8 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
if (state.preparedTitlesLoadedKey !== hockeyPreparedWorkspaceKey() && !state.preparedTitlesLoading) {
|
||||
setTimeout(() => hockeyLoadPreparedTitlesWorkspace({ force: true }).catch(() => {}), 0);
|
||||
}
|
||||
} else if (state.activeTab === "lines") {
|
||||
el.runtimeStage.appendChild(renderHockeyLinesWorkspace());
|
||||
} else {
|
||||
state.config.components.filter((component) => !component.hidden && component.props?.runtimeHidden !== true && state.runtimeVisibility[component.action_id] !== false && isEffectivelyOnActiveTab(component)).sort((a, b) => Number(a.z) - Number(b.z)).forEach((component) => {
|
||||
const wrapper = document.createElement("div"); wrapper.className = "runtime-component"; Object.assign(wrapper.style, { left: `${component.x}px`, top: `${component.y}px`, width: `${component.w}px`, height: `${component.h}px`, zIndex: String(component.z) }); wrapper.appendChild(renderComponent(component, true)); el.runtimeStage.appendChild(wrapper);
|
||||
|
||||
@@ -7778,3 +7778,26 @@ body.hockey-navigation-open .runtime-viewport.has-hockey-pbp { gap: 14px !import
|
||||
.quick-score-team{display:none}
|
||||
.quick-score-control{padding-inline:4px}
|
||||
}
|
||||
|
||||
/* BUILD122 — drag-and-drop hockey line/five sorter. */
|
||||
.hockey-lines-workspace{
|
||||
position:absolute;inset:0;display:grid;grid-template-rows:auto minmax(0,1fr);gap:10px;
|
||||
padding:14px;box-sizing:border-box;color:#dcecff;background:linear-gradient(180deg,#0a1522 0%,#09131f 100%);overflow:hidden;
|
||||
}
|
||||
.hockey-lines-intro{
|
||||
min-height:54px;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 13px;
|
||||
border:1px solid #263f56;border-radius:11px;background:#0c1b2a;
|
||||
}
|
||||
.hockey-lines-intro>div{min-width:0;display:grid;gap:3px}.hockey-lines-intro strong{font-size:15px}.hockey-lines-intro span{color:#7f96ad;font-size:8px}.hockey-lines-intro small{color:#56e3c1;font-size:8px;font-weight:850;white-space:nowrap}
|
||||
.hockey-lines-columns{min-height:0;display:grid;grid-template-columns:1fr 1fr;gap:12px;overflow:hidden}
|
||||
.hockey-lines-team{min-width:0;min-height:0;display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid #243a50;border-radius:12px;background:#0b1725;overflow-y:auto}
|
||||
.hockey-lines-team.side-home{box-shadow:inset 3px 0 0 #4d9cff}.hockey-lines-team.side-away{box-shadow:inset -3px 0 0 #ff5f79}
|
||||
.hockey-lines-team-header{display:flex;align-items:center;justify-content:space-between;gap:10px;position:sticky;top:-10px;z-index:3;padding:7px 4px 8px;background:#0b1725}
|
||||
.hockey-lines-team-header>div{min-width:0;display:grid;gap:2px}.hockey-lines-team-header span{color:#70879f;font-size:7px;font-weight:950;letter-spacing:.09em}.hockey-lines-team-header strong{overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap}.hockey-lines-team-header em{padding:4px 8px;border:1px solid #2b475f;border-radius:999px;color:#80a0ba;background:#102235;font-size:7px;font-style:normal;font-weight:900}
|
||||
.hockey-lines-actions{display:flex;gap:6px}.hockey-lines-actions button{min-height:28px;padding:0 10px;border:1px solid #31516a;border-radius:7px;color:#cfe3f3;background:#10263a;font-size:8px;font-weight:900;cursor:pointer}.hockey-lines-actions button:hover{border-color:#54dcbf;color:#fff}.hockey-lines-actions button:disabled{opacity:.45;cursor:default}
|
||||
.hockey-line-card{display:grid;gap:6px;padding:7px;border:1px solid #22394f;border-radius:10px;background:#0e1d2c}.hockey-line-card.is-unassigned{border-style:dashed;background:#0a1622}
|
||||
.hockey-line-card>header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 2px}.hockey-line-card>header strong{font-size:9px}.hockey-line-card>header span{display:grid;place-items:center;min-width:22px;height:18px;padding:0 5px;border-radius:999px;color:#7e97af;background:#14283b;font-size:7px;font-weight:950}
|
||||
.hockey-line-dropzone{min-height:38px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;padding:4px;border:1px solid transparent;border-radius:8px;transition:border-color .12s,background .12s}
|
||||
.hockey-line-dropzone>span{grid-column:1/-1;align-self:center;color:#4f6880;font-size:8px;text-align:center}.hockey-line-dropzone.is-over{border-color:#54dcbf;background:rgba(84,220,191,.06)}
|
||||
.hockey-line-player{min-width:0;display:grid;grid-template-columns:12px 31px minmax(0,1fr);grid-template-rows:auto auto;column-gap:5px;align-items:center;padding:5px 6px;border:1px solid #29445c;border-radius:8px;background:#102235;cursor:grab;transition:transform .1s,border-color .1s,opacity .1s}.hockey-line-player:hover{border-color:#47708f;transform:translateY(-1px)}.hockey-line-player.is-dragging{opacity:.35}.hockey-line-player.is-drop-before{border-color:#54e5c4;box-shadow:inset 3px 0 0 #54e5c4}.hockey-line-drag{grid-row:1/3;color:#58738c;font-size:9px;letter-spacing:-2px}.hockey-line-player b{grid-row:1/3;display:grid;place-items:center;min-height:27px;border-radius:6px;color:#dcecff;background:#0a1724;font-size:8px}.hockey-line-player strong{min-width:0;overflow:hidden;font-size:9px;text-overflow:ellipsis;white-space:nowrap}.hockey-line-player small{min-width:0;overflow:hidden;color:#6f879e;font-size:7px;text-overflow:ellipsis;white-space:nowrap}
|
||||
.hockey-lines-empty{position:absolute;inset:0;display:grid;place-content:center;gap:6px;color:#7890a8;text-align:center}.hockey-lines-empty strong{color:#d9e8f6;font-size:17px}.hockey-lines-empty span{font-size:9px}
|
||||
|
||||
Reference in New Issue
Block a user