все остальные апдейты на Кубок России
This commit is contained in:
314
static/script.js
314
static/script.js
@@ -1069,6 +1069,8 @@ function setEditMode(enabled) {
|
||||
el.disabled = !editModeEnabled;
|
||||
}
|
||||
});
|
||||
|
||||
setTourScheduleGlobalEditMode(editModeEnabled);
|
||||
renderRefereesEditor();
|
||||
|
||||
if (editModeEnabled && isGameTabActive()) {
|
||||
@@ -1099,6 +1101,8 @@ function updateEditModeUI() {
|
||||
el.disabled = !editModeEnabled;
|
||||
}
|
||||
});
|
||||
|
||||
setTourScheduleGlobalEditMode(editModeEnabled);
|
||||
}
|
||||
|
||||
function stepExtraTime(step) {
|
||||
@@ -4064,6 +4068,113 @@ function buildChannelValue(matchId) {
|
||||
return "";
|
||||
}
|
||||
|
||||
function resetTourScheduleRowEditValues(matchId) {
|
||||
document.querySelectorAll(`.tour-score-input[data-match-id="${matchId}"]`).forEach((input) => {
|
||||
input.value = input.dataset.initialValue || "";
|
||||
});
|
||||
|
||||
const statusSelect = document.querySelector(`.tour-status-select[data-match-id="${matchId}"]`);
|
||||
if (statusSelect) {
|
||||
statusSelect.value = statusSelect.dataset.initialStatus || "scheduled";
|
||||
}
|
||||
}
|
||||
|
||||
function setTourScheduleRowEditMode(matchId, enabled, resetValues = false) {
|
||||
const display = document.querySelector(`[data-schedule-display="${matchId}"]`);
|
||||
const edit = document.querySelector(`[data-schedule-edit="${matchId}"]`);
|
||||
const saveActions = document.querySelector(`[data-schedule-save-actions="${matchId}"]`);
|
||||
|
||||
if (resetValues) {
|
||||
resetTourScheduleRowEditValues(matchId);
|
||||
}
|
||||
|
||||
if (display) display.hidden = enabled;
|
||||
if (edit) edit.hidden = !enabled;
|
||||
if (saveActions) saveActions.hidden = !enabled;
|
||||
|
||||
document
|
||||
.querySelectorAll(`.tour-score-input[data-match-id="${matchId}"], .tour-status-select[data-match-id="${matchId}"]`)
|
||||
.forEach((el) => {
|
||||
el.disabled = !enabled;
|
||||
});
|
||||
}
|
||||
|
||||
function setTourScheduleGlobalEditMode(enabled) {
|
||||
document.querySelectorAll("[data-schedule-row]").forEach((row) => {
|
||||
const matchId = row.dataset.scheduleRow;
|
||||
if (!matchId) return;
|
||||
setTourScheduleRowEditMode(matchId, enabled, !enabled);
|
||||
});
|
||||
}
|
||||
|
||||
function enableTourScheduleEdit(matchId) {
|
||||
setTourScheduleRowEditMode(matchId, true);
|
||||
}
|
||||
|
||||
function cancelTourScheduleEdit(matchId) {
|
||||
resetTourScheduleRowEditValues(matchId);
|
||||
setTourScheduleRowEditMode(matchId, editModeEnabled);
|
||||
}
|
||||
|
||||
function readTourScoreValue(matchId, side) {
|
||||
const input = document.querySelector(`.tour-score-input[data-match-id="${matchId}"][data-score-side="${side}"]`);
|
||||
if (!input) return null;
|
||||
|
||||
const value = String(input.value || "").trim();
|
||||
if (value === "") return null;
|
||||
|
||||
const parsed = Number.parseInt(value, 10);
|
||||
if (!Number.isFinite(parsed) || parsed < 0) {
|
||||
throw new Error("invalid_score");
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
async function saveTourScheduleMatch(matchExternalId) {
|
||||
let homeScore;
|
||||
let awayScore;
|
||||
|
||||
try {
|
||||
homeScore = readTourScoreValue(matchExternalId, "home");
|
||||
awayScore = readTourScoreValue(matchExternalId, "away");
|
||||
} catch (err) {
|
||||
alert("Счёт должен быть целым числом 0 или больше");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((homeScore === null) !== (awayScore === null)) {
|
||||
alert("Заполни оба значения счёта или очисти оба поля");
|
||||
return;
|
||||
}
|
||||
|
||||
const status = document.querySelector(`.tour-status-select[data-match-id="${matchExternalId}"]`)?.value || "scheduled";
|
||||
|
||||
const res = await fetch(`/admin/session/${MATCH_DATA.sessionToken}/schedule/match`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
match_external_id: String(matchExternalId),
|
||||
home_score: homeScore,
|
||||
away_score: awayScore,
|
||||
status
|
||||
})
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
let message = "Не удалось сохранить счёт / статус";
|
||||
try {
|
||||
const data = await res.json();
|
||||
message = data.message || data.error || message;
|
||||
} catch (_) {}
|
||||
alert(message);
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function openClearMatchModal() {
|
||||
const modal = document.getElementById("clearMatchModal");
|
||||
if (modal) modal.classList.add("show");
|
||||
@@ -4078,3 +4189,206 @@ function confirmClearMatch() {
|
||||
closeClearMatchModal();
|
||||
clearMatchEvents();
|
||||
}
|
||||
|
||||
// -------------------- Пенальти Кубка России --------------------
|
||||
let penaltyState = null;
|
||||
let penaltyRequestInFlight = false;
|
||||
|
||||
function penaltyResultMark(result) {
|
||||
if (result === "scored") return "●";
|
||||
if (result === "missed") return "×";
|
||||
return "";
|
||||
}
|
||||
|
||||
function penaltyResultTitle(result) {
|
||||
if (result === "scored") return "Забил";
|
||||
if (result === "missed") return "Не забил";
|
||||
return "Не выбран";
|
||||
}
|
||||
|
||||
function normalizePenaltyRounds(state) {
|
||||
const maxRounds = Math.max(5, Number(state?.max_rounds || 5));
|
||||
const inputRounds = Array.isArray(state?.rounds) ? state.rounds : [];
|
||||
const byNumber = new Map(inputRounds.map(row => [Number(row.number), row]));
|
||||
const rounds = [];
|
||||
|
||||
for (let number = 1; number <= maxRounds; number += 1) {
|
||||
const row = byNumber.get(number) || { number, home: "", away: "" };
|
||||
rounds.push({
|
||||
number,
|
||||
home: row.home || "",
|
||||
away: row.away || ""
|
||||
});
|
||||
}
|
||||
|
||||
return rounds;
|
||||
}
|
||||
|
||||
function renderPenaltyShootout(state) {
|
||||
penaltyState = state || penaltyState || { max_rounds: 5, rounds: [], totals: { home: 0, away: 0 } };
|
||||
penaltyState.rounds = normalizePenaltyRounds(penaltyState);
|
||||
|
||||
const homeScore = document.getElementById("penaltyHomeScore");
|
||||
const awayScore = document.getElementById("penaltyAwayScore");
|
||||
const homeNext = document.getElementById("penaltyHomeNext");
|
||||
const awayNext = document.getElementById("penaltyAwayNext");
|
||||
const body = document.getElementById("penaltyRoundsBody");
|
||||
|
||||
if (homeScore) homeScore.textContent = penaltyState?.totals?.home ?? 0;
|
||||
if (awayScore) awayScore.textContent = penaltyState?.totals?.away ?? 0;
|
||||
if (homeNext) homeNext.textContent = `Следующий удар: ${getNextPenaltyShotNumber("home")}`;
|
||||
if (awayNext) awayNext.textContent = `Следующий удар: ${getNextPenaltyShotNumber("away")}`;
|
||||
|
||||
if (!body) return;
|
||||
|
||||
body.innerHTML = penaltyState.rounds.map(row => {
|
||||
return `
|
||||
<tr>
|
||||
<td class="penalty-round-number">${row.number}</td>
|
||||
<td>${renderPenaltyCell("home", row.number, row.home)}</td>
|
||||
<td>${renderPenaltyCell("away", row.number, row.away)}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function renderPenaltyCell(side, shotNumber, result) {
|
||||
const safeSide = side === "away" ? "away" : "home";
|
||||
const currentClass = result ? ` ${result}` : " empty";
|
||||
const scoredActive = result === "scored" ? " active" : "";
|
||||
const missedActive = result === "missed" ? " active" : "";
|
||||
const clearDisabled = result ? "" : " disabled";
|
||||
const mark = penaltyResultMark(result) || "—";
|
||||
return `
|
||||
<div class="penalty-cell${currentClass}">
|
||||
<div class="penalty-mark" title="${escapeHtml(penaltyResultTitle(result))}">${escapeHtml(mark)}</div>
|
||||
<div class="penalty-cell-actions">
|
||||
<button type="button" class="penalty-mini-btn scored${scoredActive}" onclick="setPenaltyShot('${safeSide}', ${shotNumber}, 'scored')">Забил</button>
|
||||
<button type="button" class="penalty-mini-btn missed${missedActive}" onclick="setPenaltyShot('${safeSide}', ${shotNumber}, 'missed')">Не забил</button>
|
||||
<button type="button" class="penalty-mini-btn clear" onclick="setPenaltyShot('${safeSide}', ${shotNumber}, 'clear')"${clearDisabled}>Очистить</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
async function loadPenaltyShootout() {
|
||||
if (!SESSION_TOKEN || !MATCH_DATA.isRussianCup) return;
|
||||
const body = document.getElementById("penaltyRoundsBody");
|
||||
if (!body) return;
|
||||
|
||||
try {
|
||||
const res = await fetch(`/admin/session/${SESSION_TOKEN}/penalties`, { cache: "no-store" });
|
||||
if (!res.ok) throw new Error("penalty_load_failed");
|
||||
const data = await res.json();
|
||||
renderPenaltyShootout(data);
|
||||
} catch (err) {
|
||||
console.error("Не удалось загрузить пенальти", err);
|
||||
body.innerHTML = `<tr><td colspan="3" class="empty-box">Не удалось загрузить серию пенальти.</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function setPenaltyShot(side, shotNumber, result) {
|
||||
if (!SESSION_TOKEN || penaltyRequestInFlight) return;
|
||||
penaltyRequestInFlight = true;
|
||||
|
||||
try {
|
||||
const res = await fetch(`/admin/session/${SESSION_TOKEN}/penalties/shot`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ side, shot_number: shotNumber, result })
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error("penalty_save_failed");
|
||||
const data = await res.json();
|
||||
renderPenaltyShootout(data);
|
||||
} catch (err) {
|
||||
console.error("Не удалось сохранить пенальти", err);
|
||||
alert("Не удалось сохранить пенальти");
|
||||
} finally {
|
||||
penaltyRequestInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
function getNextPenaltyShotNumber(side) {
|
||||
const safeSide = side === "away" ? "away" : "home";
|
||||
const rounds = normalizePenaltyRounds(penaltyState || { max_rounds: 5, rounds: [] });
|
||||
const emptyRow = rounds.find(row => !row[safeSide]);
|
||||
if (emptyRow) return emptyRow.number;
|
||||
return rounds.length + 1;
|
||||
}
|
||||
|
||||
async function setNextPenaltyShot(side, result) {
|
||||
const nextNumber = getNextPenaltyShotNumber(side);
|
||||
const currentMax = Math.max(5, Number(penaltyState?.max_rounds || 5));
|
||||
|
||||
if (nextNumber > currentMax) {
|
||||
await addPenaltyRound(false);
|
||||
}
|
||||
|
||||
await setPenaltyShot(side, nextNumber, result);
|
||||
}
|
||||
|
||||
async function addPenaltyRound(showAlert = true) {
|
||||
if (!SESSION_TOKEN || penaltyRequestInFlight) return;
|
||||
penaltyRequestInFlight = true;
|
||||
|
||||
try {
|
||||
const res = await fetch(`/admin/session/${SESSION_TOKEN}/penalties/round`, { method: "POST" });
|
||||
if (!res.ok) throw new Error("penalty_round_failed");
|
||||
const data = await res.json();
|
||||
renderPenaltyShootout(data);
|
||||
} catch (err) {
|
||||
console.error("Не удалось добавить серию пенальти", err);
|
||||
if (showAlert) alert("Не удалось добавить серию пенальти");
|
||||
} finally {
|
||||
penaltyRequestInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteLastPenaltyRound() {
|
||||
if (!SESSION_TOKEN || penaltyRequestInFlight) return;
|
||||
const currentMax = Math.max(5, Number(penaltyState?.max_rounds || 5));
|
||||
if (currentMax <= 5) {
|
||||
alert("Первые 5 серий нельзя удалить. Можно только очистить данные.");
|
||||
return;
|
||||
}
|
||||
if (!confirm(`Удалить последнюю серию №${currentMax}? Данные ударов этой серии тоже будут удалены.`)) return;
|
||||
|
||||
penaltyRequestInFlight = true;
|
||||
try {
|
||||
const res = await fetch(`/admin/session/${SESSION_TOKEN}/penalties/round`, { method: "DELETE" });
|
||||
if (!res.ok) throw new Error("penalty_delete_round_failed");
|
||||
const data = await res.json();
|
||||
renderPenaltyShootout(data);
|
||||
} catch (err) {
|
||||
console.error("Не удалось удалить последнюю серию пенальти", err);
|
||||
alert("Не удалось удалить последнюю серию пенальти");
|
||||
} finally {
|
||||
penaltyRequestInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function clearPenaltyShootout() {
|
||||
if (!SESSION_TOKEN || penaltyRequestInFlight) return;
|
||||
if (!confirm("Очистить всю серию пенальти для этого матча?")) return;
|
||||
|
||||
penaltyRequestInFlight = true;
|
||||
try {
|
||||
const res = await fetch(`/admin/session/${SESSION_TOKEN}/penalties`, { method: "DELETE" });
|
||||
if (!res.ok) throw new Error("penalty_clear_failed");
|
||||
const data = await res.json();
|
||||
renderPenaltyShootout(data);
|
||||
} catch (err) {
|
||||
console.error("Не удалось очистить пенальти", err);
|
||||
alert("Не удалось очистить пенальти");
|
||||
} finally {
|
||||
penaltyRequestInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
if (document.getElementById("penaltyPanel")) {
|
||||
loadPenaltyShootout();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -856,7 +856,8 @@ table {
|
||||
}
|
||||
|
||||
.tour-meta-col {
|
||||
width: 1%;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -2515,3 +2516,332 @@ body:not(.edit-mode-on) .referee-search {
|
||||
min-width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Пенальти Кубка России */
|
||||
.penalty-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.penalty-header,
|
||||
.penalty-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.penalty-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.penalty-subtitle,
|
||||
.penalty-help,
|
||||
.penalty-next-label {
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
font-size: 13px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.penalty-scoreboard {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.penalty-team-card {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 18px;
|
||||
padding: 18px;
|
||||
background: rgba(255, 255, 255, 0.045);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.penalty-team-card.home {
|
||||
border-color: rgba(79, 140, 255, 0.28);
|
||||
}
|
||||
|
||||
.penalty-team-card.away {
|
||||
border-color: rgba(255, 120, 120, 0.25);
|
||||
}
|
||||
|
||||
.penalty-team-name {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
.penalty-team-score {
|
||||
margin-top: 8px;
|
||||
color: #fff;
|
||||
font-size: 54px;
|
||||
line-height: 1;
|
||||
font-weight: 900;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
|
||||
.penalty-fast-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.penalty-fast-btn,
|
||||
.penalty-mini-btn {
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
transition: transform 0.12s ease, opacity 0.12s ease, box-shadow 0.12s ease;
|
||||
}
|
||||
|
||||
.penalty-fast-btn:hover,
|
||||
.penalty-mini-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.penalty-fast-btn {
|
||||
min-height: 54px;
|
||||
border-radius: 14px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.penalty-fast-btn.scored,
|
||||
.penalty-mini-btn.scored {
|
||||
background: linear-gradient(135deg, #0e9f6e, #12b981);
|
||||
box-shadow: 0 10px 28px rgba(18, 185, 129, 0.16);
|
||||
}
|
||||
|
||||
.penalty-fast-btn.missed,
|
||||
.penalty-mini-btn.missed {
|
||||
background: linear-gradient(135deg, #b91c1c, #ef4444);
|
||||
box-shadow: 0 10px 28px rgba(239, 68, 68, 0.16);
|
||||
}
|
||||
|
||||
.penalty-table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.penalty-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 8px;
|
||||
}
|
||||
|
||||
.penalty-table th {
|
||||
color: rgba(255, 255, 255, 0.58);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
padding: 0 10px 6px;
|
||||
}
|
||||
|
||||
.penalty-table td {
|
||||
padding: 0 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.penalty-round-number {
|
||||
width: 70px;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.penalty-cell {
|
||||
display: grid;
|
||||
grid-template-columns: 52px 1fr;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 58px;
|
||||
padding: 8px;
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, 0.045);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.penalty-cell.scored {
|
||||
border-color: rgba(18, 185, 129, 0.38);
|
||||
background: rgba(18, 185, 129, 0.08);
|
||||
}
|
||||
|
||||
.penalty-cell.missed {
|
||||
border-color: rgba(239, 68, 68, 0.35);
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
}
|
||||
|
||||
.penalty-mark {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.22);
|
||||
color: #fff;
|
||||
font-size: 30px;
|
||||
line-height: 1;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.penalty-cell.scored .penalty-mark {
|
||||
color: #34d399;
|
||||
}
|
||||
|
||||
.penalty-cell.missed .penalty-mark {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
.penalty-cell-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr minmax(74px, 0.8fr);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.penalty-mini-btn {
|
||||
min-height: 38px;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.penalty-mini-btn.active {
|
||||
outline: 2px solid rgba(255, 255, 255, 0.75);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.penalty-mini-btn.clear {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.penalty-mini-btn.clear:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.35;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.penalty-scoreboard {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.penalty-header,
|
||||
.penalty-footer,
|
||||
.penalty-header-actions {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Расписание тура: компактная ручная правка счёта и статуса */
|
||||
.tour-actions-col,
|
||||
.tour-actions-cell {
|
||||
width: 156px;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tour-meta-cell {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.tour-score-edit {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.tour-edit-line {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tour-score-inputs {
|
||||
display: inline-grid;
|
||||
grid-template-columns: 52px auto 52px;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.tour-score-input {
|
||||
width: 52px;
|
||||
height: 32px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
font-weight: 800;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.tour-score-input:disabled,
|
||||
.tour-status-select:disabled {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.tour-score-separator {
|
||||
font-weight: 900;
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.tour-status-select {
|
||||
height: 32px;
|
||||
width: 128px;
|
||||
max-width: 128px;
|
||||
padding: 4px 28px 4px 10px;
|
||||
flex: 0 0 128px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.tour-status-select option {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.tour-edit-btn {
|
||||
min-width: 38px;
|
||||
min-height: 32px;
|
||||
padding: 6px 9px;
|
||||
}
|
||||
|
||||
.tour-save-actions {
|
||||
display: inline-flex;
|
||||
justify-content: flex-end;
|
||||
gap: 5px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.tour-save-btn,
|
||||
.tour-cancel-btn {
|
||||
min-height: 32px;
|
||||
padding: 6px 9px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Расписание тура: редактирование включается общим карандашом в шапке */
|
||||
.tour-edit-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.edit-mode-on .tour-edit-only {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user