this works now, ironed out shit and made stuff work

This commit is contained in:
2025-08-17 11:47:56 +02:00
parent 57a7b0e68f
commit 5dc45b9a9b
8 changed files with 1664 additions and 1663 deletions

View File

@@ -1,326 +1,326 @@
:root {
--bg: #f6f8fb;
--card: #fff;
--text: #0f172a;
--muted: #6b7280;
--accent: #2563eb;
--border: #e5e7eb;
--hover: #f3f4f6;
--shadow: 0 4px 12px rgba(16, 24, 40, 0.06);
--radius: 8px;
--mono: "JetBrains Mono", monospace;
}
/* Dark mode variables */
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #3b82f6;
--border: #334155;
--hover: #334155;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
font-family: Inter, sans-serif;
background: var(--bg);
color: var(--text);
padding: 16px;
display: flex;
justify-content: center;
align-items: center;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
.wrap {
width: 100%;
max-width: 1100px;
}
header {
margin-bottom: 14px;
}
.header-content {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
header h1 {
text-align: center;
font-size: 1.6rem;
color: var(--text);
}
header p {
color: var(--muted);
font-size: 0.9rem;
}
.dark-mode-toggle {
position: absolute;
right: 0;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 6px 10px;
cursor: pointer;
color: var(--text);
font-size: 1.2rem;
transition: all 0.3s ease;
}
.dark-mode-toggle:hover {
background: var(--hover);
transform: scale(1.05);
}
html.dark .dark-mode-icon::before {
content: "☀️";
}
html:not(.dark) .dark-mode-icon::before {
content: "🌙";
}
.dark-mode-icon {
display: inline-block;
}
.dark-mode-icon::before {
font-size: 1em;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.content.single-column {
grid-template-columns: 1fr;
}
.card {
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 12px;
}
/* Search/filter controls */
.search-controls {
margin-bottom: 12px;
display: flex;
gap: 8px;
}
.search-input {
flex: 1;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: 4px;
font-size: 0.9rem;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
.search-input:focus {
outline: none;
border-color: var(--accent);
}
.filter-select {
padding: 6px 8px;
border: 1px solid var(--border);
border-radius: 4px;
font-size: 0.9rem;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
.filter-select:focus {
outline: none;
border-color: var(--accent);
}
/* Problems list */
.problems-list .problem-item {
padding: 8px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
transition: background-color 0.3s ease;
}
.problem-item:hover {
background: var(--hover);
}
.problem-item:last-child {
border-bottom: none;
}
.problem-item a {
text-decoration: none;
color: var(--accent);
font-weight: 600;
transition: color 0.3s ease;
}
.problem-item a:hover {
text-decoration: underline;
}
/* Difficulty badge */
.difficulty {
display: inline-flex;
align-items: center;
padding: 0.25em 0.6em;
border-radius: 10px;
font-size: 0.85em;
font-weight: bold;
text-transform: uppercase;
color: white;
white-space: nowrap;
}
.difficulty[data-difficulty="easy"] {
background-color: #4caf50; /* Green */
}
.difficulty[data-difficulty="medium"] {
background-color: #ffc107; /* Amber */
color: #333;
}
.difficulty[data-difficulty="hard"] {
background-color: #f44336; /* Red */
}
/* Leaderboard */
.leaderboard-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
}
.leaderboard-controls {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.leaderboard-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
}
.leaderboard-table th,
.leaderboard-table td {
padding: 6px 8px;
border-bottom: 1px solid var(--border);
text-align: left;
}
.leaderboard-table th {
background: var(--hover);
font-weight: 600;
color: var(--muted);
}
.leaderboard-table tr:hover {
background: var(--hover);
}
/* Sort indicators */
.sortable {
cursor: pointer;
position: relative;
padding-right: 16px;
}
.sortable::after {
content: "↕";
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
font-size: 0.8em;
opacity: 0.5;
}
.sort-asc::after {
content: "↑";
opacity: 1;
}
.sort-desc::after {
content: "↓";
opacity: 1;
}
/* Toggle button */
.btn {
border: none;
background: transparent;
cursor: pointer;
color: var(--accent);
font-size: 0.85rem;
padding: 4px 6px;
border-radius: 4px;
}
.btn:hover {
background: rgba(37, 99, 235, 0.08);
}
.btn.active {
background: rgba(37, 99, 235, 0.15);
}
@media (max-width: 800px) {
.content {
grid-template-columns: 1fr;
}
.leaderboard-controls {
flex-direction: column;
}
}
/* Leaderboard horizontal collapse */
#leaderboardSection {
transition:
max-width 0.35s ease,
opacity 0.25s ease;
overflow: hidden;
max-width: 100%;
}
#leaderboardSection.hidden {
max-width: 0;
opacity: 0;
pointer-events: none;
}
#leaderboardSection.visible {
max-width: 100%; /* take full available space in grid column */
opacity: 1;
}
#rankingExplanation {
transition: all 0.35s ease;
}
/* Pagination Controls */
.pagination-controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.pagination-btn {
background: var(--card);
border: 1px solid var(--border);
border-radius: 4px;
padding: 6px 12px;
cursor: pointer;
color: var(--text);
font-size: 0.9rem;
transition: all 0.3s ease;
}
.pagination-btn:hover:not(:disabled) {
background: var(--hover);
border-color: var(--accent);
}
.pagination-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination-info {
color: var(--muted);
font-size: 0.9rem;
}
/* Hide pagination when not needed */
.pagination-controls.hidden {
display: none;
}
:root {
--bg: #f6f8fb;
--card: #fff;
--text: #0f172a;
--muted: #6b7280;
--accent: #2563eb;
--border: #e5e7eb;
--hover: #f3f4f6;
--shadow: 0 4px 12px rgba(16, 24, 40, 0.06);
--radius: 8px;
--mono: "JetBrains Mono", monospace;
}
/* Dark mode variables */
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #3b82f6;
--border: #334155;
--hover: #334155;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
font-family: Inter, sans-serif;
background: var(--bg);
color: var(--text);
padding: 16px;
display: flex;
justify-content: center;
align-items: center;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
.wrap {
width: 100%;
max-width: 1100px;
}
header {
margin-bottom: 14px;
}
.header-content {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
header h1 {
text-align: center;
font-size: 1.6rem;
color: var(--text);
}
header p {
color: var(--muted);
font-size: 0.9rem;
}
.dark-mode-toggle {
position: absolute;
right: 0;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 6px 10px;
cursor: pointer;
color: var(--text);
font-size: 1.2rem;
transition: all 0.3s ease;
}
.dark-mode-toggle:hover {
background: var(--hover);
transform: scale(1.05);
}
html.dark .dark-mode-icon::before {
content: "☀";
}
html:not(.dark) .dark-mode-icon::before {
content: "";
}
.dark-mode-icon {
display: inline-block;
}
.dark-mode-icon::before {
font-size: 1em;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.content.single-column {
grid-template-columns: 1fr;
}
.card {
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 12px;
}
/* Search/filter controls */
.search-controls {
margin-bottom: 12px;
display: flex;
gap: 8px;
}
.search-input {
flex: 1;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: 4px;
font-size: 0.9rem;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
.search-input:focus {
outline: none;
border-color: var(--accent);
}
.filter-select {
padding: 6px 8px;
border: 1px solid var(--border);
border-radius: 4px;
font-size: 0.9rem;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
.filter-select:focus {
outline: none;
border-color: var(--accent);
}
/* Problems list */
.problems-list .problem-item {
padding: 8px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
transition: background-color 0.3s ease;
}
.problem-item:hover {
background: var(--hover);
}
.problem-item:last-child {
border-bottom: none;
}
.problem-item a {
text-decoration: none;
color: var(--accent);
font-weight: 600;
transition: color 0.3s ease;
}
.problem-item a:hover {
text-decoration: underline;
}
/* Difficulty badge */
.difficulty {
display: inline-flex;
align-items: center;
padding: 0.25em 0.6em;
border-radius: 10px;
font-size: 0.85em;
font-weight: bold;
text-transform: uppercase;
color: white;
white-space: nowrap;
}
.difficulty[data-difficulty="easy"] {
background-color: #4caf50; /* Green */
}
.difficulty[data-difficulty="medium"] {
background-color: #ffc107; /* Amber */
color: #333;
}
.difficulty[data-difficulty="hard"] {
background-color: #f44336; /* Red */
}
/* Leaderboard */
.leaderboard-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
}
.leaderboard-controls {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.leaderboard-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
}
.leaderboard-table th,
.leaderboard-table td {
padding: 6px 8px;
border-bottom: 1px solid var(--border);
text-align: left;
}
.leaderboard-table th {
background: var(--hover);
font-weight: 600;
color: var(--muted);
}
.leaderboard-table tr:hover {
background: var(--hover);
}
/* Sort indicators */
.sortable {
cursor: pointer;
position: relative;
padding-right: 16px;
}
.sortable::after {
content: "↕";
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
font-size: 0.8em;
opacity: 0.5;
}
.sort-asc::after {
content: "↑";
opacity: 1;
}
.sort-desc::after {
content: "↓";
opacity: 1;
}
/* Toggle button */
.btn {
border: none;
background: transparent;
cursor: pointer;
color: var(--accent);
font-size: 0.85rem;
padding: 4px 6px;
border-radius: 4px;
}
.btn:hover {
background: rgba(37, 99, 235, 0.08);
}
.btn.active {
background: rgba(37, 99, 235, 0.15);
}
@media (max-width: 800px) {
.content {
grid-template-columns: 1fr;
}
.leaderboard-controls {
flex-direction: column;
}
}
/* Leaderboard horizontal collapse */
#leaderboardSection {
transition:
max-width 0.35s ease,
opacity 0.25s ease;
overflow: hidden;
max-width: 100%;
}
#leaderboardSection.hidden {
max-width: 0;
opacity: 0;
pointer-events: none;
}
#leaderboardSection.visible {
max-width: 100%; /* take full available space in grid column */
opacity: 1;
}
#rankingExplanation {
transition: all 0.35s ease;
}
/* Pagination Controls */
.pagination-controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.pagination-btn {
background: var(--card);
border: 1px solid var(--border);
border-radius: 4px;
padding: 6px 12px;
cursor: pointer;
color: var(--text);
font-size: 0.9rem;
transition: all 0.3s ease;
}
.pagination-btn:hover:not(:disabled) {
background: var(--hover);
border-color: var(--accent);
}
.pagination-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination-info {
color: var(--muted);
font-size: 0.9rem;
}
/* Hide pagination when not needed */
.pagination-controls.hidden {
display: none;
}

View File

@@ -1,296 +1,296 @@
:root {
--bg: #f9f9f9;
--card: #fff;
--text: #333;
--muted: #666;
--accent: #007bff;
--accent-hover: #0069d9;
--border: #eaeaea;
--hover: #f8f9fa;
--code-bg: #f6f8fa;
--editor-border: #ddd;
}
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #3b82f6;
--accent-hover: #2563eb;
--border: #334155;
--hover: #334155;
--code-bg: #1e293b;
--editor-border: #475569;
}
body {
font-family: "Inter", sans-serif;
margin: 0;
padding: 0;
background-color: var(--bg);
color: var(--text);
min-height: 100vh; /* allow content to grow */
overflow-y: auto; /* allow vertical scroll */
box-sizing: border-box;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
.main-container {
display: flex;
flex-wrap: wrap; /* wrap on small screens */
min-height: 100vh;
width: 100vw;
}
.problem-panel {
flex: 1 1 400px; /* grow/shrink with base 400px */
min-width: 300px;
background: var(--card);
overflow-y: auto;
padding: 20px;
border-right: 1px solid var(--border);
max-height: 100vh;
transition: background-color 0.3s ease;
}
.editor-container {
flex: 1 1 400px;
min-width: 300px;
display: flex;
flex-direction: column;
background: var(--card);
max-height: 100vh;
overflow: hidden; /* internal scroll handling */
transition: background-color 0.3s ease;
}
.editor-header {
padding: 15px 20px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.editor-wrapper {
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
padding: 0 20px;
overflow-y: auto;
}
.problem-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.back-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
cursor: pointer;
font-size: 16px;
color: var(--muted);
margin-right: 15px;
padding: 6px 10px;
transition: all 0.3s ease;
}
.back-btn:hover {
color: var(--text);
background: var(--hover);
}
.dark-mode-toggle {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
padding: 6px 10px;
cursor: pointer;
color: var(--text);
font-size: 1.2rem;
transition: all 0.3s ease;
}
.dark-mode-toggle:hover {
background: var(--hover);
transform: scale(1.05);
}
html.dark .dark-mode-icon::before {
content: "☀";
}
html:not(.dark) .dark-mode-icon::before {
content: "🌙";
}
.dark-mode-icon {
display: inline-block;
}
.dark-mode-icon::before {
font-size: 1em;
}
h1 {
font-size: 22px;
font-weight: 600;
margin: 0;
color: var(--text);
flex: 1;
}
.problem-desc {
line-height: 1.6;
font-size: 15px;
overflow-wrap: break-word;
}
.problem-desc pre {
background: var(--code-bg);
padding: 12px;
border-radius: 4px;
overflow-x: auto;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
border: 1px solid var(--border);
}
.problem-desc code {
background: var(--code-bg);
padding: 2px 4px;
border-radius: 3px;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
}
.editor-actions {
padding: 15px 0;
display: flex;
justify-content: flex-end;
flex-shrink: 0;
}
.editor-actions button {
background-color: var(--accent);
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
font-size: 14px;
transition: background-color 0.3s ease;
}
.editor-actions button:hover {
background-color: var(--accent-hover);
}
#editor {
flex: 1 1 auto;
min-height: 300px;
border: 1px solid var(--editor-border);
border-radius: 4px;
overflow: auto;
max-height: 60vh;
}
.result-panel {
margin-top: 20px;
padding: 15px;
background: var(--hover);
border-radius: 4px;
margin-bottom: 20px;
min-height: 120px;
overflow-y: auto;
max-height: 30vh;
border: 1px solid var(--border);
transition: background-color 0.3s ease;
}
.result-panel h3 {
margin-top: 0;
font-size: 16px;
margin-bottom: 10px;
}
.result-panel pre {
background: var(--code-bg);
padding: 12px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
margin: 5px 0;
border: 1px solid var(--border);
}
.placeholder {
color: var(--muted);
font-style: italic;
text-align: center;
padding: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-size: 14px;
color: var(--muted);
}
input[type="text"] {
width: 100%;
padding: 8px;
border: 1px solid var(--border);
border-radius: 4px;
margin-bottom: 15px;
font-family: "Inter", sans-serif;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
input[type="text"]:focus {
outline: none;
border-color: var(--accent);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.main-container {
flex-direction: column;
height: auto;
overflow-y: visible;
}
.problem-panel,
.editor-container {
flex: none;
width: 100%;
min-width: auto;
max-height: none;
border-right: none;
border-bottom: 1px solid var(--border);
}
#editor {
min-height: 400px;
max-height: none;
}
.result-panel {
max-height: none;
}
}
:root {
--bg: #f9f9f9;
--card: #fff;
--text: #333;
--muted: #666;
--accent: #007bff;
--accent-hover: #0069d9;
--border: #eaeaea;
--hover: #f8f9fa;
--code-bg: #f6f8fa;
--editor-border: #ddd;
}
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #3b82f6;
--accent-hover: #2563eb;
--border: #334155;
--hover: #334155;
--code-bg: #1e293b;
--editor-border: #475569;
}
body {
font-family: "Inter", sans-serif;
margin: 0;
padding: 0;
background-color: var(--bg);
color: var(--text);
min-height: 100vh; /* allow content to grow */
overflow-y: auto; /* allow vertical scroll */
box-sizing: border-box;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
.main-container {
display: flex;
flex-wrap: wrap; /* wrap on small screens */
min-height: 100vh;
width: 100vw;
}
.problem-panel {
flex: 1 1 400px; /* grow/shrink with base 400px */
min-width: 300px;
background: var(--card);
overflow-y: auto;
padding: 20px;
border-right: 1px solid var(--border);
max-height: 100vh;
transition: background-color 0.3s ease;
}
.editor-container {
flex: 1 1 400px;
min-width: 300px;
display: flex;
flex-direction: column;
background: var(--card);
max-height: 100vh;
overflow: hidden; /* internal scroll handling */
transition: background-color 0.3s ease;
}
.editor-header {
padding: 15px 20px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.editor-wrapper {
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
padding: 0 20px;
overflow-y: auto;
}
.problem-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.back-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
cursor: pointer;
font-size: 16px;
color: var(--muted);
margin-right: 15px;
padding: 6px 10px;
transition: all 0.3s ease;
}
.back-btn:hover {
color: var(--text);
background: var(--hover);
}
.dark-mode-toggle {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
padding: 6px 10px;
cursor: pointer;
color: var(--text);
font-size: 1.2rem;
transition: all 0.3s ease;
}
.dark-mode-toggle:hover {
background: var(--hover);
transform: scale(1.05);
}
html.dark .dark-mode-icon::before {
content: "☀";
}
html:not(.dark) .dark-mode-icon::before {
content: "";
}
.dark-mode-icon {
display: inline-block;
}
.dark-mode-icon::before {
font-size: 1em;
}
h1 {
font-size: 22px;
font-weight: 600;
margin: 0;
color: var(--text);
flex: 1;
}
.problem-desc {
line-height: 1.6;
font-size: 15px;
overflow-wrap: break-word;
}
.problem-desc pre {
background: var(--code-bg);
padding: 12px;
border-radius: 4px;
overflow-x: auto;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
border: 1px solid var(--border);
}
.problem-desc code {
background: var(--code-bg);
padding: 2px 4px;
border-radius: 3px;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
}
.editor-actions {
padding: 15px 0;
display: flex;
justify-content: flex-end;
flex-shrink: 0;
}
.editor-actions button {
background-color: var(--accent);
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
font-size: 14px;
transition: background-color 0.3s ease;
}
.editor-actions button:hover {
background-color: var(--accent-hover);
}
#editor {
flex: 1 1 auto;
min-height: 300px;
border: 1px solid var(--editor-border);
border-radius: 4px;
overflow: auto;
max-height: 60vh;
}
.result-panel {
margin-top: 20px;
padding: 15px;
background: var(--hover);
border-radius: 4px;
margin-bottom: 20px;
min-height: 120px;
overflow-y: auto;
max-height: 30vh;
border: 1px solid var(--border);
transition: background-color 0.3s ease;
}
.result-panel h3 {
margin-top: 0;
font-size: 16px;
margin-bottom: 10px;
}
.result-panel pre {
background: var(--code-bg);
padding: 12px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
font-family: "JetBrains Mono", monospace;
font-size: 14px;
margin: 5px 0;
border: 1px solid var(--border);
}
.placeholder {
color: var(--muted);
font-style: italic;
text-align: center;
padding: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-size: 14px;
color: var(--muted);
}
input[type="text"] {
width: 100%;
padding: 8px;
border: 1px solid var(--border);
border-radius: 4px;
margin-bottom: 15px;
font-family: "Inter", sans-serif;
background: var(--card);
color: var(--text);
transition: border-color 0.3s ease;
}
input[type="text"]:focus {
outline: none;
border-color: var(--accent);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.main-container {
flex-direction: column;
height: auto;
overflow-y: visible;
}
.problem-panel,
.editor-container {
flex: none;
width: 100%;
min-width: auto;
max-height: none;
border-right: none;
border-bottom: 1px solid var(--border);
}
#editor {
min-height: 400px;
max-height: none;
}
.result-panel {
max-height: none;
}
}

View File

@@ -1,402 +1,403 @@
document.addEventListener("DOMContentLoaded", () => {
// Dark mode functionality
const darkModeToggle = document.getElementById("darkModeToggle");
const html = document.documentElement;
// Load saved dark mode preference
const savedDarkMode = localStorage.getItem("darkMode");
if (
savedDarkMode === "true" ||
(savedDarkMode === null &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
html.classList.add("dark");
}
darkModeToggle?.addEventListener("click", () => {
html.classList.toggle("dark");
localStorage.setItem("darkMode", html.classList.contains("dark"));
});
// Problem search and pagination
const problemSearch = document.getElementById("problemSearch");
const problemsContainer = document.getElementById("problemsContainer");
const problemsPagination = document.getElementById("problemsPagination");
const problemsPrevBtn = document.getElementById("problemsPrevBtn");
const problemsNextBtn = document.getElementById("problemsNextBtn");
const problemsPaginationInfo = document.getElementById(
"problemsPaginationInfo",
);
let allProblemItems = [];
let filteredProblemItems = [];
let currentPage = 1;
const itemsPerPage = 10;
// Initialize problem items
function initializeProblemItems() {
allProblemItems = Array.from(
problemsContainer?.querySelectorAll(".problem-item") || [],
);
filteredProblemItems = [...allProblemItems];
updatePagination();
}
function updatePagination() {
const totalPages = Math.ceil(filteredProblemItems.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
// Hide all items first
allProblemItems.forEach((item) => {
item.style.display = "none";
});
// Show current page items
filteredProblemItems.slice(startIndex, endIndex).forEach((item) => {
item.style.display = "";
});
// Update pagination controls
if (problemsPrevBtn) problemsPrevBtn.disabled = currentPage <= 1;
if (problemsNextBtn) problemsNextBtn.disabled = currentPage >= totalPages;
if (problemsPaginationInfo) {
problemsPaginationInfo.textContent =
totalPages > 0
? `Page ${currentPage} of ${totalPages}`
: "No problems found";
}
// Hide pagination if not needed
if (problemsPagination) {
problemsPagination.classList.toggle("hidden", totalPages <= 1);
}
}
function filterProblems() {
const term = problemSearch?.value.toLowerCase().trim() || "";
filteredProblemItems = allProblemItems.filter((item) => {
const name = item.dataset.name?.toLowerCase() || "";
const desc = item.dataset.desc?.toLowerCase() || "";
return !term || name.includes(term) || desc.includes(term);
});
currentPage = 1;
updatePagination();
}
// Event listeners for pagination
problemsPrevBtn?.addEventListener("click", () => {
if (currentPage > 1) {
currentPage--;
updatePagination();
}
});
problemsNextBtn?.addEventListener("click", () => {
const totalPages = Math.ceil(filteredProblemItems.length / itemsPerPage);
if (currentPage < totalPages) {
currentPage++;
updatePagination();
}
});
problemSearch?.addEventListener("input", filterProblems);
// Initialize problems pagination
if (problemsContainer) {
initializeProblemItems();
}
// Leaderboard functionality
const problemFilter = document.getElementById("problemFilter");
const runtimeFilter = document.getElementById("runtimeFilter");
const leaderboardBody = document.getElementById("leaderboardBody");
const sortableHeaders = document.querySelectorAll(".sortable");
let currentSort = { column: "rank", direction: "asc" };
let allRows = [];
// Initialize rows array
function initializeRows() {
allRows = Array.from(leaderboardBody.querySelectorAll("tr")).map((row) => {
return {
element: row,
user: row.dataset.user || "",
problem: row.dataset.problem || "",
runtime: parseFloat(row.dataset.runtime) || 0,
memory: parseFloat(row.dataset.memory) || 0,
timestamp: new Date(row.dataset.timestamp || Date.now()).getTime(),
language: row.dataset.language || "",
originalIndex: Array.from(leaderboardBody.children).indexOf(row),
};
});
}
function updateRankClasses() {
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
visibleRows.forEach((rowData, index) => {
const rank = index + 1;
const row = rowData.element;
// Update rank cell
const rankCell = row.cells[0];
if (rankCell) rankCell.textContent = rank;
// Update rank classes
row.className = row.className.replace(/\brank-\d+\b/g, "");
if (rank === 1) row.classList.add("rank-1");
else if (rank <= 3) row.classList.add("rank-top3");
});
}
function calculateOverallRanking() {
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
if (visibleRows.length === 0) return;
// Group submissions by problem to find the best performance for each
const problemBests = {};
visibleRows.forEach((rowData) => {
const problem = rowData.problem;
if (!problemBests[problem]) {
problemBests[problem] = {
bestRuntime: Infinity,
bestMemory: Infinity,
};
}
problemBests[problem].bestRuntime = Math.min(
problemBests[problem].bestRuntime,
rowData.runtime,
);
problemBests[problem].bestMemory = Math.min(
problemBests[problem].bestMemory,
rowData.memory,
);
});
// Calculate normalized scores for each submission
visibleRows.forEach((rowData) => {
const problemBest = problemBests[rowData.problem];
// Prevent division by zero
const runtimeScore =
problemBest.bestRuntime > 0
? rowData.runtime / problemBest.bestRuntime
: 1;
const memoryScore =
problemBest.bestMemory > 0
? rowData.memory / problemBest.bestMemory
: 1;
// Weighted overall score (70% runtime, 30% memory)
rowData.overallScore = runtimeScore * 0.7 + memoryScore * 0.3;
});
// Sort by overall score (lower is better), then by timestamp (earlier is better for ties)
visibleRows.sort((a, b) => {
const scoreDiff = a.overallScore - b.overallScore;
if (Math.abs(scoreDiff) > 0.000001) return scoreDiff; // Use small epsilon for float comparison
// If scores are essentially equal, prefer earlier submission
return a.timestamp - b.timestamp;
});
// Reorder DOM elements and update ranks
visibleRows.forEach((rowData, index) => {
leaderboardBody.appendChild(rowData.element);
});
updateRankClasses();
}
function filterLeaderboard() {
const problemTerm = (problemFilter?.value || "").toLowerCase().trim();
const runtimeType = runtimeFilter?.value || "all";
// Reset all rows to visible first
allRows.forEach((rowData) => {
rowData.element.style.display = "";
});
// Apply problem filter
if (problemTerm) {
allRows.forEach((rowData) => {
const problemMatch = rowData.problem
.toLowerCase()
.includes(problemTerm);
if (!problemMatch) {
rowData.element.style.display = "none";
}
});
}
// Apply runtime filter (best/worst per user per problem)
if (runtimeType === "best" || runtimeType === "worst") {
const userProblemGroups = {};
// Group by user + problem combination
allRows.forEach((rowData) => {
if (rowData.element.style.display === "none") return;
const key = `${rowData.user}::${rowData.problem}`;
if (!userProblemGroups[key]) {
userProblemGroups[key] = [];
}
userProblemGroups[key].push(rowData);
});
// Hide all except best/worst for each user-problem combination
Object.values(userProblemGroups).forEach((group) => {
if (group.length <= 1) return;
// Sort by runtime
group.sort((a, b) => a.runtime - b.runtime);
const keepIndex = runtimeType === "best" ? 0 : group.length - 1;
group.forEach((rowData, index) => {
if (index !== keepIndex) {
rowData.element.style.display = "none";
}
});
});
}
calculateOverallRanking();
}
function getCellValue(rowData, column) {
switch (column) {
case "rank":
return parseInt(rowData.element.cells[0]?.textContent) || 0;
case "user":
return rowData.user.toLowerCase();
case "problem":
return rowData.problem.toLowerCase();
case "runtime":
return rowData.runtime;
case "memory":
return rowData.memory;
case "timestamp":
return rowData.timestamp;
case "language":
return rowData.language.toLowerCase();
default:
return "";
}
}
function sortLeaderboard(column, direction) {
if (column === "rank") {
calculateOverallRanking();
return;
}
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
visibleRows.sort((a, b) => {
const valueA = getCellValue(a, column);
const valueB = getCellValue(b, column);
let comparison = 0;
if (typeof valueA === "number" && typeof valueB === "number") {
comparison = valueA - valueB;
} else {
comparison = valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
}
return direction === "asc" ? comparison : -comparison;
});
// Reorder DOM elements
visibleRows.forEach((rowData) => {
leaderboardBody.appendChild(rowData.element);
});
updateRankClasses();
}
// Event listeners for sorting
sortableHeaders.forEach((header) => {
header.addEventListener("click", () => {
const column = header.dataset.sort;
if (!column) return;
// Remove sorting classes from all headers
sortableHeaders.forEach((h) =>
h.classList.remove("sort-asc", "sort-desc"),
);
// Toggle sort direction
if (currentSort.column === column) {
currentSort.direction =
currentSort.direction === "asc" ? "desc" : "asc";
} else {
currentSort.column = column;
currentSort.direction = "asc";
}
// Add sorting class to current header
header.classList.add(`sort-${currentSort.direction}`);
sortLeaderboard(column, currentSort.direction);
});
});
// Filter event listeners
problemFilter?.addEventListener("input", filterLeaderboard);
runtimeFilter?.addEventListener("change", filterLeaderboard);
// Rank info popout
const rankInfoBtn = document.getElementById("rankInfoBtn");
const rankingExplanation = document.getElementById("rankingExplanation");
rankInfoBtn?.addEventListener("click", (e) => {
e.preventDefault();
rankingExplanation?.classList.toggle("active");
rankInfoBtn?.classList.toggle("active");
});
// Close ranking explanation when clicking outside
document.addEventListener("click", (e) => {
if (
rankingExplanation?.classList.contains("active") &&
!rankingExplanation.contains(e.target) &&
!rankInfoBtn?.contains(e.target)
) {
rankingExplanation.classList.remove("active");
rankInfoBtn?.classList.remove("active");
}
});
// Initialize everything
if (leaderboardBody && leaderboardBody.children.length > 0) {
initializeRows();
calculateOverallRanking();
// Set initial sort indicator
const defaultHeader = document.querySelector('[data-sort="rank"]');
if (defaultHeader) {
defaultHeader.classList.add("sort-asc");
}
}
// Apply dark mode to dynamically created elements
function applyDarkModeToElements() {
const isDark = html.classList.contains("dark");
// Any additional dark mode styling for dynamically created elements can go here
}
// Watch for dark mode changes
new MutationObserver(applyDarkModeToElements).observe(html, {
attributes: true,
attributeFilter: ["class"],
});
});
document.addEventListener("DOMContentLoaded", () => {
// Dark mode functionality
const darkModeToggle = document.getElementById("darkModeToggle");
const html = document.documentElement;
// Load saved dark mode preference
const savedDarkMode = localStorage.getItem("darkMode");
if (
savedDarkMode === "true" ||
(savedDarkMode === null &&
// detect if the user already has a dark mode enabled in the system settings ( works for all systems )
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
html.classList.add("dark");
}
darkModeToggle?.addEventListener("click", () => {
html.classList.toggle("dark");
localStorage.setItem("darkMode", html.classList.contains("dark"));
});
// Problem search and pagination
const problemSearch = document.getElementById("problemSearch");
const problemsContainer = document.getElementById("problemsContainer");
const problemsPagination = document.getElementById("problemsPagination");
const problemsPrevBtn = document.getElementById("problemsPrevBtn");
const problemsNextBtn = document.getElementById("problemsNextBtn");
const problemsPaginationInfo = document.getElementById(
"problemsPaginationInfo",
);
let allProblemItems = [];
let filteredProblemItems = [];
let currentPage = 1;
const itemsPerPage = 5;
// Initialize problem items
function initializeProblemItems() {
allProblemItems = Array.from(
problemsContainer?.querySelectorAll(".problem-item") || [],
);
filteredProblemItems = [...allProblemItems];
updatePagination();
}
function updatePagination() {
const totalPages = Math.ceil(filteredProblemItems.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
// Hide all items first
allProblemItems.forEach((item) => {
item.style.display = "none";
});
// Show current page items
filteredProblemItems.slice(startIndex, endIndex).forEach((item) => {
item.style.display = "";
});
// Update pagination controls
if (problemsPrevBtn) problemsPrevBtn.disabled = currentPage <= 1;
if (problemsNextBtn) problemsNextBtn.disabled = currentPage >= totalPages;
if (problemsPaginationInfo) {
problemsPaginationInfo.textContent =
totalPages > 0
? `Page ${currentPage} of ${totalPages}`
: "No problems found";
}
// Hide pagination if not needed
if (problemsPagination) {
problemsPagination.classList.toggle("hidden", totalPages <= 1);
}
}
function filterProblems() {
const term = problemSearch?.value.toLowerCase().trim() || "";
filteredProblemItems = allProblemItems.filter((item) => {
const name = item.dataset.name?.toLowerCase() || "";
const desc = item.dataset.desc?.toLowerCase() || "";
return !term || name.includes(term) || desc.includes(term);
});
currentPage = 1;
updatePagination();
}
// Event listeners for pagination
problemsPrevBtn?.addEventListener("click", () => {
if (currentPage > 1) {
currentPage--;
updatePagination();
}
});
problemsNextBtn?.addEventListener("click", () => {
const totalPages = Math.ceil(filteredProblemItems.length / itemsPerPage);
if (currentPage < totalPages) {
currentPage++;
updatePagination();
}
});
problemSearch?.addEventListener("input", filterProblems);
// Initialize problems pagination
if (problemsContainer) {
initializeProblemItems();
}
// Leaderboard functionality
const problemFilter = document.getElementById("problemFilter");
const runtimeFilter = document.getElementById("runtimeFilter");
const leaderboardBody = document.getElementById("leaderboardBody");
const sortableHeaders = document.querySelectorAll(".sortable");
let currentSort = { column: "rank", direction: "asc" };
let allRows = [];
// Initialize rows array
function initializeRows() {
allRows = Array.from(leaderboardBody.querySelectorAll("tr")).map((row) => {
return {
element: row,
user: row.dataset.user || "",
problem: row.dataset.problem || "",
runtime: parseFloat(row.dataset.runtime) || 0,
memory: parseFloat(row.dataset.memory) || 0,
timestamp: new Date(row.dataset.timestamp || Date.now()).getTime(),
language: row.dataset.language || "",
originalIndex: Array.from(leaderboardBody.children).indexOf(row),
};
});
}
function updateRankClasses() {
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
visibleRows.forEach((rowData, index) => {
const rank = index + 1;
const row = rowData.element;
// Update rank cell
const rankCell = row.cells[0];
if (rankCell) rankCell.textContent = rank;
// Update rank classes
row.className = row.className.replace(/\brank-\d+\b/g, "");
if (rank === 1) row.classList.add("rank-1");
else if (rank <= 3) row.classList.add("rank-top3");
});
}
function calculateOverallRanking() {
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
if (visibleRows.length === 0) return;
// Group submissions by problem to find the best performance for each
const problemBests = {};
visibleRows.forEach((rowData) => {
const problem = rowData.problem;
if (!problemBests[problem]) {
problemBests[problem] = {
bestRuntime: Infinity,
bestMemory: Infinity,
};
}
problemBests[problem].bestRuntime = Math.min(
problemBests[problem].bestRuntime,
rowData.runtime,
);
problemBests[problem].bestMemory = Math.min(
problemBests[problem].bestMemory,
rowData.memory,
);
});
// Calculate normalized scores for each submission
visibleRows.forEach((rowData) => {
const problemBest = problemBests[rowData.problem];
// Prevent division by zero
const runtimeScore =
problemBest.bestRuntime > 0
? rowData.runtime / problemBest.bestRuntime
: 1;
const memoryScore =
problemBest.bestMemory > 0
? rowData.memory / problemBest.bestMemory
: 1;
// Weighted overall score (70% runtime, 30% memory)
rowData.overallScore = runtimeScore * 0.7 + memoryScore * 0.3;
});
// Sort by overall score (lower is better), then by timestamp (earlier is better for ties)
visibleRows.sort((a, b) => {
const scoreDiff = a.overallScore - b.overallScore;
if (Math.abs(scoreDiff) > 0.000001) return scoreDiff; // Use small epsilon for float comparison
// If scores are essentially equal, prefer earlier submission
return a.timestamp - b.timestamp;
});
// Reorder DOM elements and update ranks
visibleRows.forEach((rowData, index) => {
leaderboardBody.appendChild(rowData.element);
});
updateRankClasses();
}
function filterLeaderboard() {
const problemTerm = (problemFilter?.value || "").toLowerCase().trim();
const runtimeType = runtimeFilter?.value || "all";
// Reset all rows to visible first
allRows.forEach((rowData) => {
rowData.element.style.display = "";
});
// Apply problem filter
if (problemTerm) {
allRows.forEach((rowData) => {
const problemMatch = rowData.problem
.toLowerCase()
.includes(problemTerm);
if (!problemMatch) {
rowData.element.style.display = "none";
}
});
}
// Apply runtime filter (best/worst per user per problem)
if (runtimeType === "best" || runtimeType === "worst") {
const userProblemGroups = {};
// Group by user + problem combination
allRows.forEach((rowData) => {
if (rowData.element.style.display === "none") return;
const key = `${rowData.user}::${rowData.problem}`;
if (!userProblemGroups[key]) {
userProblemGroups[key] = [];
}
userProblemGroups[key].push(rowData);
});
// Hide all except best/worst for each user-problem combination
Object.values(userProblemGroups).forEach((group) => {
if (group.length <= 1) return;
// Sort by runtime
group.sort((a, b) => a.runtime - b.runtime);
const keepIndex = runtimeType === "best" ? 0 : group.length - 1;
group.forEach((rowData, index) => {
if (index !== keepIndex) {
rowData.element.style.display = "none";
}
});
});
}
calculateOverallRanking();
}
function getCellValue(rowData, column) {
switch (column) {
case "rank":
return parseInt(rowData.element.cells[0]?.textContent) || 0;
case "user":
return rowData.user.toLowerCase();
case "problem":
return rowData.problem.toLowerCase();
case "runtime":
return rowData.runtime;
case "memory":
return rowData.memory;
case "timestamp":
return rowData.timestamp;
case "language":
return rowData.language.toLowerCase();
default:
return "";
}
}
function sortLeaderboard(column, direction) {
if (column === "rank") {
calculateOverallRanking();
return;
}
const visibleRows = allRows.filter(
(row) => row.element.style.display !== "none",
);
visibleRows.sort((a, b) => {
const valueA = getCellValue(a, column);
const valueB = getCellValue(b, column);
let comparison = 0;
if (typeof valueA === "number" && typeof valueB === "number") {
comparison = valueA - valueB;
} else {
comparison = valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
}
return direction === "asc" ? comparison : -comparison;
});
// Reorder DOM elements
visibleRows.forEach((rowData) => {
leaderboardBody.appendChild(rowData.element);
});
updateRankClasses();
}
// Event listeners for sorting
sortableHeaders.forEach((header) => {
header.addEventListener("click", () => {
const column = header.dataset.sort;
if (!column) return;
// Remove sorting classes from all headers
sortableHeaders.forEach((h) =>
h.classList.remove("sort-asc", "sort-desc"),
);
// Toggle sort direction
if (currentSort.column === column) {
currentSort.direction =
currentSort.direction === "asc" ? "desc" : "asc";
} else {
currentSort.column = column;
currentSort.direction = "asc";
}
// Add sorting class to current header
header.classList.add(`sort-${currentSort.direction}`);
sortLeaderboard(column, currentSort.direction);
});
});
// Filter event listeners
problemFilter?.addEventListener("input", filterLeaderboard);
runtimeFilter?.addEventListener("change", filterLeaderboard);
// Rank info popout
const rankInfoBtn = document.getElementById("rankInfoBtn");
const rankingExplanation = document.getElementById("rankingExplanation");
rankInfoBtn?.addEventListener("click", (e) => {
e.preventDefault();
rankingExplanation?.classList.toggle("active");
rankInfoBtn?.classList.toggle("active");
});
// Close ranking explanation when clicking outside
document.addEventListener("click", (e) => {
if (
rankingExplanation?.classList.contains("active") &&
!rankingExplanation.contains(e.target) &&
!rankInfoBtn?.contains(e.target)
) {
rankingExplanation.classList.remove("active");
rankInfoBtn?.classList.remove("active");
}
});
// Initialize everything
if (leaderboardBody && leaderboardBody.children.length > 0) {
initializeRows();
calculateOverallRanking();
// Set initial sort indicator
const defaultHeader = document.querySelector('[data-sort="rank"]');
if (defaultHeader) {
defaultHeader.classList.add("sort-asc");
}
}
// Apply dark mode to dynamically created elements
function applyDarkModeToElements() {
const isDark = html.classList.contains("dark");
// Any additional dark mode styling for dynamically created elements can go here
}
// Watch for dark mode changes
new MutationObserver(applyDarkModeToElements).observe(html, {
attributes: true,
attributeFilter: ["class"],
});
});

View File

@@ -1,317 +1,317 @@
:root {
--bg: #f8f9fa;
--card: #fff;
--text: #333;
--heading: #2c3e50;
--heading-secondary: #34495e;
--accent: #3498db;
--accent-hover: #2980b9;
--success: #27ae60;
--success-hover: #229954;
--error: #e74c3c;
--muted: #6c757d;
--muted-hover: #5a6268;
--border: #ddd;
--code-bg: #f4f4f4;
--success-bg: #d4edda;
--success-text: #155724;
--error-bg: #f8d7da;
--error-text: #721c24;
--hover-bg: #e3f2fd;
--shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--heading: #3b82f6;
--heading-secondary: #94a3b8;
--accent: #3b82f6;
--accent-hover: #2563eb;
--success: #22c55e;
--success-hover: #16a34a;
--error: #ef4444;
--muted: #64748b;
--muted-hover: #475569;
--border: #334155;
--code-bg: #1e293b;
--success-bg: #065f46;
--success-text: #d1fae5;
--error-bg: #7f1d1d;
--error-text: #fecaca;
--hover-bg: #1e40af;
--shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
/* Reset and base styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
line-height: 1.6;
color: var(--text);
background-color: var(--bg);
padding: 20px;
max-width: 1200px;
margin: 0 auto;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
/* Main heading */
h1 {
color: var(--heading);
margin-bottom: -10px;
padding-bottom: 3px;
border-bottom: 3px solid var(--accent);
font-size: 2.2em;
}
h2 {
color: var(--heading-secondary);
margin: 30px 0 20px 0;
font-size: 1.5em;
}
h3 {
color: var(--heading-secondary);
margin: 25px 0 15px 0;
font-size: 1.3em;
}
/* Links and buttons */
a {
color: var(--accent);
text-decoration: none;
padding: 8px 16px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
a:hover {
background-color: var(--hover-bg);
text-decoration: none;
}
/* Primary action link (Submit New Problem) */
a[href="/problem/new"] {
background-color: var(--accent);
color: white;
font-weight: 600;
margin-bottom: 30px;
display: inline-block;
padding: 12px 24px;
border-radius: 8px;
}
a[href="/problem/new"]:hover {
background-color: var(--accent-hover);
}
/* Problem list */
ul {
list-style: none;
background: var(--card);
border-radius: 8px;
box-shadow: var(--shadow);
padding: 25px;
margin: 20px 0;
transition: background-color 0.3s ease;
}
li {
padding: 15px 0;
border-bottom: 1px solid var(--border);
}
li:last-child {
border-bottom: none;
}
li a {
display: block;
padding: 12px 20px;
margin: -12px -20px;
border-radius: 6px;
font-size: 1.1em;
}
li a:hover {
background-color: var(--hover-bg);
transform: translateX(5px);
transition: all 0.2s ease;
}
/* Problem page specific styles */
.problem-header {
display: flex;
align-items: center;
margin-bottom: 30px;
gap: 20px;
}
.back-btn {
background-color: var(--muted);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background-color 0.3s ease;
}
.back-btn:hover {
background-color: var(--muted-hover);
}
.problem-desc {
background: var(--card);
padding: 30px;
border-radius: 8px;
box-shadow: var(--shadow);
margin-bottom: 30px;
font-size: 1.1em;
line-height: 1.7;
transition: background-color 0.3s ease;
}
/* Editor section */
.editor-section {
background: var(--card);
padding: 30px;
border-radius: 8px;
box-shadow: var(--shadow);
margin-bottom: 30px;
transition: background-color 0.3s ease;
}
#editor {
border: 2px solid var(--border);
border-radius: 8px;
margin: 20px 0;
height: 400px;
overflow: hidden;
}
.editor-actions {
margin-top: 20px;
text-align: right;
}
form button[type="submit"] {
background-color: var(--success);
color: white;
border: none;
padding: 12px 30px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: background-color 0.3s ease;
}
form button[type="submit"]:hover {
background-color: var(--success-hover);
}
/* Results section */
b {
color: var(--heading);
display: inline-block;
margin: 10px 0 5px 0;
}
pre {
background-color: var(--code-bg);
padding: 20px;
border-radius: 6px;
border-left: 4px solid var(--accent);
margin: 10px 0 20px 0;
overflow-x: auto;
font-family: "JetBrains Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.4;
border: 1px solid var(--border);
transition: background-color 0.3s ease;
}
pre[style*="color:red"] {
border-left-color: var(--error);
background-color: var(--error-bg);
}
/* Status messages */
p[style*="color:green"] {
background-color: var(--success-bg);
color: var(--success-text);
padding: 15px 20px;
border-radius: 6px;
border-left: 4px solid var(--success);
margin: 20px 0;
font-weight: 600;
}
p[style*="color:red"] {
background-color: var(--error-bg);
color: var(--error-text);
padding: 15px 20px;
border-radius: 6px;
border-left: 4px solid var(--error);
margin: 20px 0;
font-weight: 600;
}
/* Back to Problems link */
a[href="/"] {
display: inline-block;
margin-top: 30px;
background-color: var(--muted);
color: white;
padding: 10px 20px;
border-radius: 6px;
font-weight: 500;
}
a[href="/"]:hover {
background-color: var(--muted-hover);
}
/* Responsive design */
@media (max-width: 768px) {
body {
padding: 15px;
}
.problem-header {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
h1 {
font-size: 1.8em;
}
.problem-desc,
.editor-section,
ul {
padding: 20px;
}
#editor {
height: 300px;
}
.editor-actions {
text-align: center;
}
}
:root {
--bg: #f8f9fa;
--card: #fff;
--text: #333;
--heading: #2c3e50;
--heading-secondary: #34495e;
--accent: #3498db;
--accent-hover: #2980b9;
--success: #27ae60;
--success-hover: #229954;
--error: #e74c3c;
--muted: #6c757d;
--muted-hover: #5a6268;
--border: #ddd;
--code-bg: #f4f4f4;
--success-bg: #d4edda;
--success-text: #155724;
--error-bg: #f8d7da;
--error-text: #721c24;
--hover-bg: #e3f2fd;
--shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
html.dark {
--bg: #0f172a;
--card: #1e293b;
--text: #f1f5f9;
--heading: #3b82f6;
--heading-secondary: #94a3b8;
--accent: #3b82f6;
--accent-hover: #2563eb;
--success: #22c55e;
--success-hover: #16a34a;
--error: #ef4444;
--muted: #64748b;
--muted-hover: #475569;
--border: #334155;
--code-bg: #1e293b;
--success-bg: #065f46;
--success-text: #d1fae5;
--error-bg: #7f1d1d;
--error-text: #fecaca;
--hover-bg: #1e40af;
--shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
/* Reset and base styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
line-height: 1.6;
color: var(--text);
background-color: var(--bg);
padding: 20px;
max-width: 1200px;
margin: 0 auto;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
/* Main heading */
h1 {
color: var(--heading);
margin-bottom: -10px;
padding-bottom: 3px;
border-bottom: 3px solid var(--accent);
font-size: 2.2em;
}
h2 {
color: var(--heading-secondary);
margin: 30px 0 20px 0;
font-size: 1.5em;
}
h3 {
color: var(--heading-secondary);
margin: 25px 0 15px 0;
font-size: 1.3em;
}
/* Links and buttons */
a {
color: var(--accent);
text-decoration: none;
padding: 8px 16px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
a:hover {
background-color: var(--hover-bg);
text-decoration: none;
}
/* Primary action link (Submit New Problem) */
a[href="/problem/new"] {
background-color: var(--accent);
color: white;
font-weight: 600;
margin-bottom: 30px;
display: inline-block;
padding: 12px 24px;
border-radius: 8px;
}
a[href="/problem/new"]:hover {
background-color: var(--accent-hover);
}
/* Problem list */
ul {
list-style: none;
background: var(--card);
border-radius: 8px;
box-shadow: var(--shadow);
padding: 25px;
margin: 20px 0;
transition: background-color 0.3s ease;
}
li {
padding: 15px 0;
border-bottom: 1px solid var(--border);
}
li:last-child {
border-bottom: none;
}
li a {
display: block;
padding: 12px 20px;
margin: -12px -20px;
border-radius: 6px;
font-size: 1.1em;
}
li a:hover {
background-color: var(--hover-bg);
transform: translateX(5px);
transition: all 0.2s ease;
}
/* Problem page specific styles */
.problem-header {
display: flex;
align-items: center;
margin-bottom: 30px;
gap: 20px;
}
.back-btn {
background-color: var(--muted);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background-color 0.3s ease;
}
.back-btn:hover {
background-color: var(--muted-hover);
}
.problem-desc {
background: var(--card);
padding: 30px;
border-radius: 8px;
box-shadow: var(--shadow);
margin-bottom: 30px;
font-size: 1.1em;
line-height: 1.7;
transition: background-color 0.3s ease;
}
/* Editor section */
.editor-section {
background: var(--card);
padding: 30px;
border-radius: 8px;
box-shadow: var(--shadow);
margin-bottom: 30px;
transition: background-color 0.3s ease;
}
#editor {
border: 2px solid var(--border);
border-radius: 8px;
margin: 20px 0;
height: 400px;
overflow: hidden;
}
.editor-actions {
margin-top: 20px;
text-align: right;
}
form button[type="submit"] {
background-color: var(--success);
color: white;
border: none;
padding: 12px 30px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: background-color 0.3s ease;
}
form button[type="submit"]:hover {
background-color: var(--success-hover);
}
/* Results section */
b {
color: var(--heading);
display: inline-block;
margin: 10px 0 5px 0;
}
pre {
background-color: var(--code-bg);
padding: 20px;
border-radius: 6px;
border-left: 4px solid var(--accent);
margin: 10px 0 20px 0;
overflow-x: auto;
font-family: "JetBrains Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.4;
border: 1px solid var(--border);
transition: background-color 0.3s ease;
}
pre[style*="color:red"] {
border-left-color: var(--error);
background-color: var(--error-bg);
}
/* Status messages */
p[style*="color:green"] {
background-color: var(--success-bg);
color: var(--success-text);
padding: 15px 20px;
border-radius: 6px;
border-left: 4px solid var(--success);
margin: 20px 0;
font-weight: 600;
}
p[style*="color:red"] {
background-color: var(--error-bg);
color: var(--error-text);
padding: 15px 20px;
border-radius: 6px;
border-left: 4px solid var(--error);
margin: 20px 0;
font-weight: 600;
}
/* Back to Problems link */
a[href="/"] {
display: inline-block;
margin-top: 30px;
background-color: var(--muted);
color: white;
padding: 10px 20px;
border-radius: 6px;
font-weight: 500;
}
a[href="/"]:hover {
background-color: var(--muted-hover);
}
/* Responsive design */
@media (max-width: 768px) {
body {
padding: 15px;
}
.problem-header {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
h1 {
font-size: 1.8em;
}
.problem-desc,
.editor-section,
ul {
padding: 20px;
}
#editor {
height: 300px;
}
.editor-actions {
text-align: center;
}
}