2177 lines
45 KiB
CSS
2177 lines
45 KiB
CSS
/*
|
|
* Sudoku Tools application styles.
|
|
*
|
|
* The Toolbox shell owns the base theme tokens. Everything here derives from
|
|
* those tokens so standalone, connected, light, dark, and system appearances
|
|
* remain visually aligned.
|
|
*/
|
|
|
|
:root {
|
|
--sudoku-success: #15735a;
|
|
--sudoku-warning: #9a5b0b;
|
|
--sudoku-info: #3560a8;
|
|
--sudoku-board-radius: clamp(0.55rem, 1.2vw, 0.9rem);
|
|
}
|
|
|
|
html {
|
|
min-width: 20rem;
|
|
min-height: 100%;
|
|
background: var(--toolbox-background);
|
|
scrollbar-gutter: stable;
|
|
}
|
|
|
|
body {
|
|
min-width: 20rem;
|
|
min-height: 100vh;
|
|
margin: 0;
|
|
background: var(--toolbox-background);
|
|
color: var(--toolbox-text);
|
|
font-family: var(--toolbox-font);
|
|
text-rendering: optimizeLegibility;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
#root {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
::selection {
|
|
background: color-mix(in srgb, var(--toolbox-focus) 44%, transparent);
|
|
color: var(--toolbox-text);
|
|
}
|
|
|
|
.toolbox-shell__main {
|
|
width: min(100%, 90rem);
|
|
padding: clamp(0.75rem, 1.7vw, 1.5rem);
|
|
}
|
|
|
|
.sudoku-workbench,
|
|
.modal,
|
|
.fatal-error {
|
|
--sudoku-success: color-mix(in srgb, #06805d 78%, var(--toolbox-text));
|
|
--sudoku-warning: color-mix(in srgb, #bf730a 78%, var(--toolbox-text));
|
|
--sudoku-info: color-mix(in srgb, #3268bd 76%, var(--toolbox-text));
|
|
--sudoku-line: color-mix(
|
|
in srgb,
|
|
var(--toolbox-text) 38%,
|
|
var(--toolbox-border)
|
|
);
|
|
--sudoku-line-strong: color-mix(
|
|
in srgb,
|
|
var(--toolbox-text) 78%,
|
|
var(--toolbox-border)
|
|
);
|
|
color: var(--toolbox-text);
|
|
font-family: var(--toolbox-font);
|
|
}
|
|
|
|
/* Help is mounted next to the shell, so bridge its selected dark theme. */
|
|
body:has(.toolbox-shell[data-toolbox-theme="dark"]) .modal,
|
|
body:has(.toolbox-shell[data-toolbox-theme="dark"]) .fatal-error {
|
|
color-scheme: dark;
|
|
--toolbox-background: #0f1422;
|
|
--toolbox-surface: #171d2d;
|
|
--toolbox-surface-soft: #20283a;
|
|
--toolbox-text: #edf1fb;
|
|
--toolbox-muted: #a9b3ca;
|
|
--toolbox-border: #303a50;
|
|
--toolbox-accent: #a9b7ff;
|
|
--toolbox-accent-hover: #c3ccff;
|
|
--toolbox-accent-soft: #252f55;
|
|
--toolbox-accent-contrast: #11182a;
|
|
--toolbox-focus: #66cdbd;
|
|
--toolbox-danger: #ff8fa3;
|
|
--toolbox-shadow: 0 14px 42px rgb(0 0 0 / 24%);
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
body:has(.toolbox-shell[data-toolbox-theme="system"]) .modal,
|
|
body:has(.toolbox-shell[data-toolbox-theme="system"]) .fatal-error {
|
|
color-scheme: dark;
|
|
--toolbox-background: #0f1422;
|
|
--toolbox-surface: #171d2d;
|
|
--toolbox-surface-soft: #20283a;
|
|
--toolbox-text: #edf1fb;
|
|
--toolbox-muted: #a9b3ca;
|
|
--toolbox-border: #303a50;
|
|
--toolbox-accent: #a9b7ff;
|
|
--toolbox-accent-hover: #c3ccff;
|
|
--toolbox-accent-soft: #252f55;
|
|
--toolbox-accent-contrast: #11182a;
|
|
--toolbox-focus: #66cdbd;
|
|
--toolbox-danger: #ff8fa3;
|
|
--toolbox-shadow: 0 14px 42px rgb(0 0 0 / 24%);
|
|
}
|
|
}
|
|
|
|
/* Shared type and control language */
|
|
|
|
.sudoku-workbench :where(h1, h2, h3),
|
|
.modal :where(h2, h3),
|
|
.fatal-error :where(h1, h2) {
|
|
margin: 0;
|
|
color: var(--toolbox-text);
|
|
font-weight: 760;
|
|
letter-spacing: -0.027em;
|
|
line-height: 1.16;
|
|
}
|
|
|
|
.sudoku-workbench h1 {
|
|
font-size: clamp(1.65rem, 3.2vw, 2.65rem);
|
|
}
|
|
|
|
.sudoku-workbench h2,
|
|
.modal h2 {
|
|
font-size: clamp(1.25rem, 2.1vw, 1.65rem);
|
|
}
|
|
|
|
.sudoku-workbench h3,
|
|
.modal h3 {
|
|
font-size: 1rem;
|
|
letter-spacing: -0.015em;
|
|
}
|
|
|
|
.sudoku-workbench :where(p, ul, ol, dl),
|
|
.modal :where(p, ul, ol, dl),
|
|
.fatal-error p {
|
|
margin-block: 0;
|
|
}
|
|
|
|
.sudoku-workbench p,
|
|
.modal p,
|
|
.fatal-error p {
|
|
line-height: 1.58;
|
|
}
|
|
|
|
.stack {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.eyebrow {
|
|
margin: 0 0 0.28rem !important;
|
|
color: var(--toolbox-accent);
|
|
font-size: 0.68rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.115em;
|
|
line-height: 1.35 !important;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.muted {
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.88rem;
|
|
}
|
|
|
|
.sr-only {
|
|
position: absolute !important;
|
|
width: 1px !important;
|
|
height: 1px !important;
|
|
padding: 0 !important;
|
|
overflow: hidden !important;
|
|
clip: rect(0, 0, 0, 0) !important;
|
|
white-space: nowrap !important;
|
|
border: 0 !important;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error)
|
|
:where(button, input, select, textarea) {
|
|
font: inherit;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) button {
|
|
min-height: 2.65rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.45rem;
|
|
padding: 0.6rem 0.85rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.62rem;
|
|
background: var(--toolbox-surface);
|
|
box-shadow: 0 1px 1px rgb(20 30 60 / 4%);
|
|
color: var(--toolbox-text);
|
|
font-size: 0.82rem;
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
touch-action: manipulation;
|
|
transition:
|
|
border-color 140ms ease,
|
|
background-color 140ms ease,
|
|
color 140ms ease,
|
|
box-shadow 140ms ease,
|
|
transform 140ms ease;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) button.is-active,
|
|
:where(.sudoku-workbench, .modal) button[aria-pressed="true"],
|
|
:where(.sudoku-workbench, .modal) [role="tab"][aria-selected="true"],
|
|
:where(.sudoku-workbench, .modal) .primary-button,
|
|
.fatal-error .primary-button {
|
|
border-color: var(--toolbox-accent);
|
|
background: var(--toolbox-accent);
|
|
box-shadow: 0 0.2rem 0.7rem
|
|
color-mix(in srgb, var(--toolbox-accent) 16%, transparent);
|
|
color: var(--toolbox-accent-contrast);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) button:disabled {
|
|
box-shadow: none;
|
|
cursor: not-allowed;
|
|
opacity: 0.46;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) .text-button {
|
|
min-height: 2.1rem;
|
|
padding: 0.3rem 0.45rem;
|
|
border-color: transparent;
|
|
background: transparent;
|
|
box-shadow: none;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) .danger {
|
|
color: var(--toolbox-danger);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error)
|
|
button.danger:not(.text-button) {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 34%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 7%,
|
|
var(--toolbox-surface)
|
|
);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal)
|
|
:where(input:not([type="checkbox"]):not([type="radio"]), select, textarea) {
|
|
width: 100%;
|
|
min-width: 0;
|
|
min-height: 2.65rem;
|
|
padding: 0.58rem 0.7rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.58rem;
|
|
outline: none;
|
|
background: var(--toolbox-surface);
|
|
box-shadow: inset 0 1px 1px rgb(20 30 60 / 3%);
|
|
color: var(--toolbox-text);
|
|
line-height: 1.35;
|
|
transition:
|
|
border-color 140ms ease,
|
|
box-shadow 140ms ease,
|
|
background-color 140ms ease;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) textarea {
|
|
min-height: 5.75rem;
|
|
resize: vertical;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) select {
|
|
padding-right: 2rem;
|
|
cursor: pointer;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) input::placeholder,
|
|
:where(.sudoku-workbench, .modal) textarea::placeholder {
|
|
color: color-mix(in srgb, var(--toolbox-muted) 72%, transparent);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) input:disabled,
|
|
:where(.sudoku-workbench, .modal) select:disabled,
|
|
:where(.sudoku-workbench, .modal) textarea:disabled {
|
|
cursor: not-allowed;
|
|
opacity: 0.58;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) input[type="checkbox"],
|
|
:where(.sudoku-workbench, .modal) input[type="radio"] {
|
|
width: 1.05rem;
|
|
height: 1.05rem;
|
|
flex: none;
|
|
margin: 0;
|
|
accent-color: var(--toolbox-accent);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) label {
|
|
min-width: 0;
|
|
display: grid;
|
|
gap: 0.38rem;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.74rem;
|
|
font-weight: 720;
|
|
letter-spacing: 0.015em;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal) .check-row {
|
|
min-height: 2rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.55rem;
|
|
color: var(--toolbox-text);
|
|
font-size: 0.82rem;
|
|
font-weight: 620;
|
|
letter-spacing: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal)
|
|
:where(button, input, select, textarea, [tabindex]):focus-visible,
|
|
.fatal-error button:focus-visible {
|
|
outline: 3px solid
|
|
color-mix(in srgb, var(--toolbox-focus) 74%, var(--toolbox-accent));
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal)
|
|
:where(
|
|
input:not([type="checkbox"]):not([type="radio"]),
|
|
select,
|
|
textarea
|
|
):focus-visible {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--toolbox-focus) 70%,
|
|
var(--toolbox-accent)
|
|
);
|
|
outline: none;
|
|
box-shadow: 0 0 0 3px
|
|
color-mix(in srgb, var(--toolbox-focus) 22%, transparent);
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
:where(.sudoku-workbench, .modal, .fatal-error)
|
|
button:not(:disabled):not(.sudoku-cell):hover {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--toolbox-accent) 46%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: var(--toolbox-accent-soft);
|
|
color: var(--toolbox-accent);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error)
|
|
button.is-active:not(:disabled):hover,
|
|
:where(.sudoku-workbench, .modal)
|
|
button[aria-pressed="true"]:not(:disabled):hover,
|
|
:where(.sudoku-workbench, .modal)
|
|
[role="tab"][aria-selected="true"]:not(:disabled):hover,
|
|
:where(.sudoku-workbench, .modal) .primary-button:not(:disabled):hover,
|
|
.sudoku-workbench .hero-actions button:first-child:not(:disabled):hover,
|
|
.fatal-error .primary-button:not(:disabled):hover {
|
|
border-color: var(--toolbox-accent-hover);
|
|
background: var(--toolbox-accent-hover);
|
|
color: var(--toolbox-accent-contrast);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error)
|
|
button:not(:disabled):not(.sudoku-cell):active {
|
|
transform: translateY(1px);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) .text-button:hover {
|
|
border-color: transparent;
|
|
background: var(--toolbox-surface-soft);
|
|
}
|
|
|
|
:where(.sudoku-workbench, .modal, .fatal-error) .danger:hover {
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 10%,
|
|
var(--toolbox-surface)
|
|
) !important;
|
|
color: var(--toolbox-danger) !important;
|
|
}
|
|
}
|
|
|
|
/* Workbench shell */
|
|
|
|
.sudoku-workbench {
|
|
width: min(100%, 90rem);
|
|
display: grid;
|
|
gap: clamp(0.8rem, 1.5vw, 1.2rem);
|
|
margin-inline: auto;
|
|
}
|
|
|
|
.workbench-hero {
|
|
position: relative;
|
|
isolation: isolate;
|
|
min-width: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 1rem 2rem;
|
|
overflow: hidden;
|
|
padding: clamp(1rem, 2.3vw, 1.75rem);
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: calc(var(--toolbox-radius) + 0.25rem);
|
|
background:
|
|
radial-gradient(
|
|
circle at 82% 12%,
|
|
color-mix(in srgb, var(--toolbox-focus) 18%, transparent),
|
|
transparent 30%
|
|
),
|
|
linear-gradient(
|
|
135deg,
|
|
color-mix(
|
|
in srgb,
|
|
var(--toolbox-accent-soft) 72%,
|
|
var(--toolbox-surface)
|
|
),
|
|
var(--toolbox-surface) 62%
|
|
);
|
|
box-shadow: var(--toolbox-shadow);
|
|
}
|
|
|
|
.workbench-hero::after {
|
|
position: absolute;
|
|
z-index: -1;
|
|
right: clamp(-2.5rem, -1vw, -0.75rem);
|
|
bottom: clamp(-4.8rem, -5vw, -2.75rem);
|
|
width: clamp(10rem, 20vw, 17rem);
|
|
aspect-ratio: 1;
|
|
border: 2px solid color-mix(in srgb, var(--toolbox-accent) 11%, transparent);
|
|
background-image:
|
|
linear-gradient(
|
|
to right,
|
|
transparent 32.8%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 33%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 33.7%,
|
|
transparent 34%,
|
|
transparent 66.1%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 66.3%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 67%,
|
|
transparent 67.2%
|
|
),
|
|
linear-gradient(
|
|
to bottom,
|
|
transparent 32.8%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 33%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 33.7%,
|
|
transparent 34%,
|
|
transparent 66.1%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 66.3%,
|
|
color-mix(in srgb, var(--toolbox-accent) 10%, transparent) 67%,
|
|
transparent 67.2%
|
|
);
|
|
border-radius: 1.5rem;
|
|
content: "";
|
|
opacity: 0.9;
|
|
transform: rotate(10deg);
|
|
}
|
|
|
|
.hero-copy {
|
|
min-width: 0;
|
|
max-width: 51rem;
|
|
}
|
|
|
|
.hero-copy > p:not(.eyebrow) {
|
|
max-width: 64ch;
|
|
margin-top: 0.55rem;
|
|
color: var(--toolbox-muted);
|
|
font-size: clamp(0.86rem, 1.2vw, 0.96rem);
|
|
}
|
|
|
|
.hero-actions,
|
|
.action-row,
|
|
.toolbar-group,
|
|
.export-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 0.55rem;
|
|
}
|
|
|
|
.hero-actions {
|
|
position: relative;
|
|
z-index: 1;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.hero-actions button:first-child {
|
|
border-color: var(--toolbox-accent);
|
|
background: var(--toolbox-accent);
|
|
color: var(--toolbox-accent-contrast);
|
|
}
|
|
|
|
.workspace-tabs,
|
|
.subtabs,
|
|
.mode-switcher {
|
|
display: grid;
|
|
gap: 0.3rem;
|
|
padding: 0.32rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.78rem;
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-surface-soft) 78%,
|
|
var(--toolbox-surface)
|
|
);
|
|
}
|
|
|
|
.workspace-tabs {
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
}
|
|
|
|
.workspace-tabs button,
|
|
.subtabs button,
|
|
.mode-switcher button {
|
|
min-height: 2.45rem;
|
|
border-color: transparent;
|
|
background: transparent;
|
|
box-shadow: none;
|
|
color: var(--toolbox-muted);
|
|
}
|
|
|
|
.workspace-tabs button.is-active,
|
|
.workspace-tabs button[aria-selected="true"],
|
|
.subtabs button.is-active,
|
|
.mode-switcher button.is-active {
|
|
border-color: var(--toolbox-border);
|
|
background: var(--toolbox-surface);
|
|
box-shadow: 0 0.15rem 0.55rem rgb(20 30 60 / 8%);
|
|
color: var(--toolbox-accent);
|
|
}
|
|
|
|
.workbench-status {
|
|
min-height: 2.25rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.6rem 1rem;
|
|
padding: 0.35rem 0.2rem;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.78rem;
|
|
}
|
|
|
|
.timer-display {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.4rem;
|
|
padding: 0.3rem 0.55rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 999px;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-text);
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.78rem;
|
|
font-variant-numeric: tabular-nums;
|
|
font-weight: 720;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.workbench-grid {
|
|
min-width: 0;
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1.65fr) minmax(19.5rem, 0.82fr);
|
|
align-items: start;
|
|
gap: clamp(0.85rem, 1.6vw, 1.35rem);
|
|
}
|
|
|
|
.workbench-grid--helpers {
|
|
grid-template-columns: minmax(24rem, 0.92fr) minmax(31rem, 1.08fr);
|
|
}
|
|
|
|
.board-column,
|
|
.side-panel,
|
|
.play-panel,
|
|
.setter-panel,
|
|
.solve-workspace,
|
|
.helpers-workspace {
|
|
min-width: 0;
|
|
}
|
|
|
|
.board-column {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.board-toolbar {
|
|
min-height: 2.8rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.55rem 1rem;
|
|
}
|
|
|
|
.board-toolbar > span {
|
|
color: var(--toolbox-muted);
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.75rem;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.select-wrap {
|
|
min-width: min(100%, 11rem);
|
|
}
|
|
|
|
.select-wrap select {
|
|
min-height: 2.45rem !important;
|
|
}
|
|
|
|
.board-surface,
|
|
.side-panel {
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: calc(var(--toolbox-radius) + 0.2rem);
|
|
background: var(--toolbox-surface);
|
|
box-shadow: var(--toolbox-shadow);
|
|
}
|
|
|
|
.board-surface {
|
|
position: relative;
|
|
display: grid;
|
|
justify-items: center;
|
|
padding: clamp(0.5rem, 1.7vw, 1.15rem);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.board-surface.is-paused .sudoku-board-frame {
|
|
opacity: 0.72;
|
|
filter: saturate(0.6);
|
|
}
|
|
|
|
.side-panel {
|
|
padding: clamp(0.85rem, 1.7vw, 1.2rem);
|
|
}
|
|
|
|
.paused-cover {
|
|
position: absolute;
|
|
z-index: 12;
|
|
inset: 0;
|
|
display: grid;
|
|
align-content: center;
|
|
justify-items: center;
|
|
gap: 0.65rem;
|
|
padding: 1.5rem;
|
|
border-radius: inherit;
|
|
background: color-mix(in srgb, var(--toolbox-surface) 78%, transparent);
|
|
color: var(--toolbox-text);
|
|
text-align: center;
|
|
backdrop-filter: blur(12px);
|
|
}
|
|
|
|
.paused-cover::before {
|
|
width: 3.5rem;
|
|
height: 3.5rem;
|
|
display: grid;
|
|
place-items: center;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 50%;
|
|
background: var(--toolbox-surface);
|
|
box-shadow: var(--toolbox-shadow);
|
|
color: var(--toolbox-accent);
|
|
content: "Ⅱ";
|
|
font-size: 1.25rem;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.board-meta {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 0.55rem 1rem;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.78rem;
|
|
}
|
|
|
|
.board-meta .rule-card {
|
|
flex: 1 1 100%;
|
|
}
|
|
|
|
.rule-card,
|
|
.panel-section,
|
|
.helper-card,
|
|
.analysis-summary,
|
|
.logical-results {
|
|
min-width: 0;
|
|
padding: clamp(0.8rem, 1.45vw, 1rem);
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.78rem;
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-surface-soft) 43%,
|
|
var(--toolbox-surface)
|
|
);
|
|
}
|
|
|
|
.rule-card {
|
|
display: grid;
|
|
gap: 0.45rem;
|
|
}
|
|
|
|
.rule-card p:not(.eyebrow) {
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.84rem;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.constraint-chips {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.35rem;
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.constraint-chips :where(li, span) {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 0.25rem 0.5rem;
|
|
border: 1px solid
|
|
color-mix(in srgb, var(--toolbox-accent) 24%, var(--toolbox-border));
|
|
border-radius: 999px;
|
|
background: var(--toolbox-accent-soft);
|
|
color: var(--toolbox-accent);
|
|
font-size: 0.7rem;
|
|
font-weight: 720;
|
|
}
|
|
|
|
.option-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.75rem;
|
|
padding-block: 0.35rem;
|
|
color: var(--toolbox-text) !important;
|
|
font-size: 0.8rem !important;
|
|
font-weight: 610 !important;
|
|
letter-spacing: 0 !important;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.option-row + .option-row {
|
|
border-top: 1px solid
|
|
color-mix(in srgb, var(--toolbox-border) 68%, transparent);
|
|
}
|
|
|
|
.section-heading {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 0.65rem 1rem;
|
|
}
|
|
|
|
.field-grid,
|
|
.inline-fields,
|
|
.helper-controls {
|
|
display: grid;
|
|
gap: 0.7rem;
|
|
}
|
|
|
|
.field-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.inline-fields {
|
|
grid-template-columns: minmax(6rem, 0.7fr) minmax(7.5rem, 1fr);
|
|
align-items: end;
|
|
}
|
|
|
|
.compact-field {
|
|
width: min(100%, 9rem);
|
|
}
|
|
|
|
.button-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 0.45rem;
|
|
}
|
|
|
|
.panel-section {
|
|
display: grid;
|
|
gap: 0.72rem;
|
|
}
|
|
|
|
.panel-section.action-row {
|
|
display: flex;
|
|
}
|
|
|
|
.feedback-callout,
|
|
.status-line,
|
|
.error-callout,
|
|
.callout {
|
|
margin: 0;
|
|
padding: 0.68rem 0.78rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.62rem;
|
|
background: var(--toolbox-surface-soft);
|
|
color: var(--toolbox-text);
|
|
font-size: 0.8rem;
|
|
line-height: 1.48 !important;
|
|
}
|
|
|
|
.feedback-success {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--sudoku-success) 34%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--sudoku-success) 9%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: var(--sudoku-success);
|
|
}
|
|
|
|
.feedback-error,
|
|
.error-callout {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 38%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 9%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: var(--toolbox-danger);
|
|
}
|
|
|
|
.feedback-info,
|
|
.status-line {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--sudoku-info) 30%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(in srgb, var(--sudoku-info) 8%, var(--toolbox-surface));
|
|
color: var(--sudoku-info);
|
|
}
|
|
|
|
.callout {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--sudoku-warning) 30%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--sudoku-warning) 8%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: color-mix(in srgb, var(--sudoku-warning) 84%, var(--toolbox-text));
|
|
}
|
|
|
|
/* Sudoku board */
|
|
|
|
.sudoku-board-frame {
|
|
--board-pad: clamp(0.28rem, 0.75vw, 0.48rem);
|
|
--board-edge: clamp(2px, 0.35vw, 3px);
|
|
position: relative;
|
|
isolation: isolate;
|
|
width: min(100%, 43rem);
|
|
padding: var(--board-pad);
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: var(--sudoku-board-radius);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-surface-soft) 74%,
|
|
var(--toolbox-surface)
|
|
);
|
|
box-shadow:
|
|
0 0.6rem 1.8rem rgb(20 30 60 / 9%),
|
|
inset 0 1px 0 color-mix(in srgb, white 38%, transparent);
|
|
container-type: inline-size;
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
}
|
|
|
|
.sudoku-board {
|
|
position: relative;
|
|
width: 100%;
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--sudoku-size), minmax(0, 1fr));
|
|
grid-template-rows: repeat(var(--sudoku-size), minmax(0, 1fr));
|
|
aspect-ratio: 1;
|
|
overflow: hidden;
|
|
border: var(--board-edge) solid var(--sudoku-line-strong);
|
|
border-radius: clamp(0.22rem, 0.55vw, 0.42rem);
|
|
background: var(--sudoku-line);
|
|
box-shadow: 0 1px 0 color-mix(in srgb, white 22%, transparent);
|
|
touch-action: none;
|
|
}
|
|
|
|
.sudoku-cell {
|
|
--cell-fill: var(--toolbox-surface);
|
|
position: relative;
|
|
min-width: 0 !important;
|
|
min-height: 0 !important;
|
|
overflow: hidden;
|
|
padding: 0 !important;
|
|
border: 0.5px solid var(--sudoku-line) !important;
|
|
border-radius: 0 !important;
|
|
outline-offset: -3px !important;
|
|
background: var(--cell-fill) !important;
|
|
box-shadow: none !important;
|
|
color: var(--toolbox-accent) !important;
|
|
font-variant-numeric: tabular-nums;
|
|
cursor: pointer;
|
|
transition:
|
|
background-color 100ms ease,
|
|
color 100ms ease;
|
|
}
|
|
|
|
.sudoku-cell.is-given {
|
|
color: var(--toolbox-text) !important;
|
|
cursor: default;
|
|
}
|
|
|
|
.sudoku-cell[class*="has-color-"] {
|
|
--cell-fill: color-mix(
|
|
in srgb,
|
|
var(--sudoku-mark-color) 24%,
|
|
var(--toolbox-surface)
|
|
);
|
|
}
|
|
|
|
.sudoku-cell.is-selected {
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-accent) 20%,
|
|
var(--cell-fill)
|
|
) !important;
|
|
}
|
|
|
|
.sudoku-cell.is-selected::after {
|
|
position: absolute;
|
|
z-index: 5;
|
|
inset: max(1px, 5%);
|
|
border: max(1.5px, 0.25cqi) solid
|
|
color-mix(in srgb, var(--toolbox-accent) 82%, transparent);
|
|
border-radius: max(1px, 0.25cqi);
|
|
content: "";
|
|
pointer-events: none;
|
|
}
|
|
|
|
.sudoku-cell.has-conflict {
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 18%,
|
|
var(--cell-fill)
|
|
) !important;
|
|
color: var(--toolbox-danger) !important;
|
|
}
|
|
|
|
.sudoku-cell.has-conflict::before {
|
|
position: absolute;
|
|
z-index: 4;
|
|
inset: 10%;
|
|
border-radius: 50%;
|
|
background: color-mix(in srgb, var(--toolbox-danger) 10%, transparent);
|
|
content: "";
|
|
pointer-events: none;
|
|
}
|
|
|
|
.sudoku-cell:focus-visible {
|
|
outline: none !important;
|
|
}
|
|
|
|
.sudoku-cell:focus-visible::after {
|
|
position: absolute;
|
|
z-index: 6;
|
|
inset: max(1px, 4%);
|
|
border: max(2px, 0.3cqi) solid var(--toolbox-focus);
|
|
border-radius: max(1px, 0.25cqi);
|
|
content: "";
|
|
pointer-events: none;
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
.sudoku-cell:not(.is-selected):not(.has-conflict):hover {
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-accent) 8%,
|
|
var(--cell-fill)
|
|
) !important;
|
|
}
|
|
}
|
|
|
|
.cell-value,
|
|
.corner-marks,
|
|
.center-marks {
|
|
position: relative;
|
|
z-index: 4;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cell-value {
|
|
display: block;
|
|
font-size: clamp(0.74rem, 4.2cqi, 2rem);
|
|
font-weight: 650;
|
|
line-height: 1;
|
|
}
|
|
|
|
.is-given .cell-value {
|
|
font-weight: 820;
|
|
}
|
|
|
|
.corner-marks {
|
|
position: absolute;
|
|
inset: 7%;
|
|
display: flex;
|
|
align-content: flex-start;
|
|
align-items: flex-start;
|
|
flex-wrap: wrap;
|
|
justify-content: flex-start;
|
|
gap: 0 0.14em;
|
|
overflow: hidden;
|
|
color: color-mix(in srgb, var(--toolbox-text) 77%, var(--toolbox-muted));
|
|
font-size: clamp(0.34rem, 1.38cqi, 0.64rem);
|
|
font-weight: 720;
|
|
line-height: 1.05;
|
|
text-align: left;
|
|
}
|
|
|
|
.center-marks {
|
|
max-width: 88%;
|
|
display: block;
|
|
overflow: hidden;
|
|
color: color-mix(in srgb, var(--toolbox-text) 72%, var(--toolbox-muted));
|
|
font-size: clamp(0.38rem, 1.48cqi, 0.68rem);
|
|
font-weight: 650;
|
|
letter-spacing: 0.035em;
|
|
line-height: 1.08;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.constraint-layer {
|
|
position: absolute;
|
|
z-index: 3;
|
|
top: var(--board-pad);
|
|
left: var(--board-pad);
|
|
width: calc(100% - var(--board-pad) - var(--board-pad));
|
|
height: calc(100% - var(--board-pad) - var(--board-pad));
|
|
overflow: visible;
|
|
pointer-events: none;
|
|
shape-rendering: geometricPrecision;
|
|
}
|
|
|
|
.constraint-layer :where(path, polyline, line, circle) {
|
|
vector-effect: non-scaling-stroke;
|
|
}
|
|
|
|
.region-boundaries path {
|
|
fill: none;
|
|
stroke: var(--sudoku-line-strong);
|
|
stroke-linecap: square;
|
|
stroke-linejoin: miter;
|
|
stroke-width: clamp(1.8px, 0.28cqi, 3px);
|
|
}
|
|
|
|
.constraint-diagonal {
|
|
stroke: color-mix(in srgb, var(--toolbox-accent) 68%, var(--toolbox-text));
|
|
stroke-linecap: round;
|
|
stroke-width: clamp(2px, 0.34cqi, 3.5px);
|
|
opacity: 0.66;
|
|
}
|
|
|
|
.constraint-cage path {
|
|
fill: none;
|
|
stroke: color-mix(in srgb, var(--toolbox-text) 76%, var(--toolbox-muted));
|
|
stroke-dasharray: 3 2.5;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: clamp(1px, 0.17cqi, 1.7px);
|
|
}
|
|
|
|
.constraint-cage text {
|
|
fill: var(--toolbox-text);
|
|
font-family: var(--toolbox-font);
|
|
font-size: 0.22px;
|
|
font-weight: 760;
|
|
paint-order: stroke;
|
|
stroke: var(--toolbox-surface);
|
|
stroke-width: 0.035px;
|
|
}
|
|
|
|
.constraint-thermo polyline {
|
|
fill: none;
|
|
stroke: color-mix(in srgb, var(--toolbox-muted) 48%, var(--toolbox-surface));
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: clamp(8px, 2.05cqi, 17px);
|
|
}
|
|
|
|
.constraint-thermo circle {
|
|
fill: color-mix(in srgb, var(--toolbox-muted) 42%, var(--toolbox-surface));
|
|
stroke: color-mix(in srgb, var(--toolbox-muted) 67%, var(--toolbox-surface));
|
|
stroke-width: clamp(1px, 0.15cqi, 1.5px);
|
|
}
|
|
|
|
.constraint-arrow polyline {
|
|
fill: none;
|
|
stroke: color-mix(in srgb, var(--toolbox-text) 62%, var(--toolbox-muted));
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: clamp(2px, 0.34cqi, 3px);
|
|
}
|
|
|
|
.constraint-arrow circle:first-child {
|
|
fill: color-mix(in srgb, var(--toolbox-surface) 78%, transparent);
|
|
stroke: color-mix(in srgb, var(--toolbox-text) 62%, var(--toolbox-muted));
|
|
stroke-width: clamp(1.5px, 0.27cqi, 2.5px);
|
|
}
|
|
|
|
.constraint-arrow circle:last-child {
|
|
fill: color-mix(in srgb, var(--toolbox-text) 66%, var(--toolbox-muted));
|
|
stroke: none;
|
|
}
|
|
|
|
.constraint-renban polyline,
|
|
.constraint-palindrome polyline {
|
|
fill: none;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: clamp(8px, 2.1cqi, 18px);
|
|
}
|
|
|
|
.constraint-renban polyline {
|
|
stroke: color-mix(in srgb, #d973b4 44%, transparent);
|
|
}
|
|
|
|
.constraint-palindrome polyline {
|
|
stroke: color-mix(in srgb, #8f9aae 48%, transparent);
|
|
}
|
|
|
|
.constraint-palindrome circle {
|
|
fill: color-mix(in srgb, var(--toolbox-surface) 82%, transparent);
|
|
stroke: color-mix(in srgb, #657087 65%, var(--toolbox-muted));
|
|
stroke-width: clamp(1px, 0.15cqi, 1.5px);
|
|
}
|
|
|
|
.constraint-kropki {
|
|
stroke: color-mix(in srgb, var(--toolbox-text) 80%, var(--toolbox-muted));
|
|
stroke-width: clamp(1.2px, 0.2cqi, 2px);
|
|
}
|
|
|
|
.constraint-kropki--white {
|
|
fill: var(--toolbox-surface);
|
|
}
|
|
|
|
.constraint-kropki--black {
|
|
fill: color-mix(in srgb, var(--toolbox-text) 88%, black);
|
|
}
|
|
|
|
.constraint-label {
|
|
dominant-baseline: central;
|
|
fill: var(--toolbox-text);
|
|
font-family: var(--toolbox-font);
|
|
font-size: 0.28px;
|
|
font-weight: 850;
|
|
paint-order: stroke;
|
|
stroke: var(--toolbox-surface);
|
|
stroke-linejoin: round;
|
|
stroke-width: 0.07px;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.constraint-label--inequality {
|
|
font-size: 0.38px;
|
|
}
|
|
|
|
/* Number and colour entry */
|
|
|
|
.number-pad {
|
|
display: grid;
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.mode-switcher {
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
}
|
|
|
|
.mode-switcher button {
|
|
padding-inline: 0.35rem;
|
|
font-size: 0.72rem;
|
|
}
|
|
|
|
.digit-pad {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(2.75rem, 1fr));
|
|
gap: 0.42rem;
|
|
}
|
|
|
|
.digit-pad--wide {
|
|
grid-template-columns: repeat(auto-fit, minmax(2.5rem, 1fr));
|
|
}
|
|
|
|
.digit-pad button {
|
|
min-width: 0;
|
|
min-height: 2.9rem;
|
|
padding-inline: 0.35rem;
|
|
font-size: 1rem;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.digit-pad .erase-key {
|
|
padding-inline: 0.65rem;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.76rem;
|
|
}
|
|
|
|
.color-choice > span:first-child {
|
|
width: 1.35rem;
|
|
height: 1.35rem;
|
|
display: block;
|
|
border: 2px solid color-mix(in srgb, var(--sudoku-mark-color) 75%, white);
|
|
border-radius: 50%;
|
|
background: var(--sudoku-mark-color);
|
|
box-shadow:
|
|
0 0 0 1px color-mix(in srgb, var(--sudoku-mark-color) 72%, black),
|
|
inset 0 0.18rem 0.28rem rgb(255 255 255 / 22%);
|
|
}
|
|
|
|
.color-1,
|
|
.has-color-1 {
|
|
--sudoku-mark-color: #e56f65;
|
|
}
|
|
|
|
.color-2,
|
|
.has-color-2 {
|
|
--sudoku-mark-color: #eca73f;
|
|
}
|
|
|
|
.color-3,
|
|
.has-color-3 {
|
|
--sudoku-mark-color: #e0c84f;
|
|
}
|
|
|
|
.color-4,
|
|
.has-color-4 {
|
|
--sudoku-mark-color: #62b77a;
|
|
}
|
|
|
|
.color-5,
|
|
.has-color-5 {
|
|
--sudoku-mark-color: #4bb8b4;
|
|
}
|
|
|
|
.color-6,
|
|
.has-color-6 {
|
|
--sudoku-mark-color: #5d93dd;
|
|
}
|
|
|
|
.color-7,
|
|
.has-color-7 {
|
|
--sudoku-mark-color: #9a7cda;
|
|
}
|
|
|
|
.color-8,
|
|
.has-color-8 {
|
|
--sudoku-mark-color: #ce78b0;
|
|
}
|
|
|
|
/* Setter, solver, and helper result surfaces */
|
|
|
|
.constraint-list,
|
|
.library-list,
|
|
.cell-possibilities {
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.constraint-list {
|
|
display: grid;
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.constraint-list li {
|
|
min-width: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.55rem;
|
|
padding: 0.38rem 0.45rem 0.38rem 0.65rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.58rem;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-text);
|
|
font-size: 0.78rem;
|
|
}
|
|
|
|
.constraint-list li > span {
|
|
min-width: 0;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.subtabs {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
}
|
|
|
|
.helper-controls {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
align-items: end;
|
|
}
|
|
|
|
.helper-controls .check-row {
|
|
align-self: center;
|
|
}
|
|
|
|
.helper-result {
|
|
display: grid;
|
|
gap: 0.8rem;
|
|
margin-top: 0.9rem;
|
|
}
|
|
|
|
.metric-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
|
|
gap: 0.45rem;
|
|
}
|
|
|
|
.metric-row > span {
|
|
min-width: 0;
|
|
padding: 0.55rem 0.65rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.58rem;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.75rem;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
.metric-row strong {
|
|
color: var(--toolbox-text);
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.cell-possibilities {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
|
|
gap: 0.35rem;
|
|
counter-reset: none;
|
|
}
|
|
|
|
.cell-possibilities li {
|
|
padding: 0.42rem 0.55rem;
|
|
border-radius: 0.48rem;
|
|
background: var(--toolbox-surface-soft);
|
|
color: var(--toolbox-text);
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.72rem;
|
|
}
|
|
|
|
.combination-cloud,
|
|
.pair-table {
|
|
max-height: 17rem;
|
|
display: flex;
|
|
align-content: flex-start;
|
|
flex-wrap: wrap;
|
|
gap: 0.35rem;
|
|
overflow: auto;
|
|
padding: 0.65rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.62rem;
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-background) 52%,
|
|
var(--toolbox-surface)
|
|
);
|
|
scrollbar-color: var(--toolbox-border) transparent;
|
|
}
|
|
|
|
.combination-cloud code,
|
|
.pair-table code {
|
|
padding: 0.28rem 0.44rem;
|
|
border: 1px solid
|
|
color-mix(in srgb, var(--toolbox-accent) 18%, var(--toolbox-border));
|
|
border-radius: 0.42rem;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-accent);
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.72rem;
|
|
font-weight: 720;
|
|
}
|
|
|
|
.residual-equation {
|
|
color: var(--toolbox-muted);
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: clamp(1.15rem, 3vw, 1.65rem);
|
|
letter-spacing: -0.035em;
|
|
text-align: center;
|
|
}
|
|
|
|
.residual-equation strong {
|
|
color: var(--toolbox-accent);
|
|
}
|
|
|
|
.analysis-summary,
|
|
.logical-results {
|
|
display: grid;
|
|
gap: 0.8rem;
|
|
}
|
|
|
|
.status-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
align-self: flex-start;
|
|
padding: 0.28rem 0.55rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 999px;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.67rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.status-solved {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--sudoku-success) 35%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--sudoku-success) 9%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: var(--sudoku-success);
|
|
}
|
|
|
|
.status-invalid {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 38%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-danger) 9%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: var(--toolbox-danger);
|
|
}
|
|
|
|
.status-stuck,
|
|
.status-limit,
|
|
.status-step-limit {
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--sudoku-warning) 36%,
|
|
var(--toolbox-border)
|
|
);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--sudoku-warning) 8%,
|
|
var(--toolbox-surface)
|
|
);
|
|
color: var(--sudoku-warning);
|
|
}
|
|
|
|
.solve-steps {
|
|
max-height: 32rem;
|
|
display: grid;
|
|
gap: 0.42rem;
|
|
overflow: auto;
|
|
padding: 0.15rem;
|
|
scrollbar-color: var(--toolbox-border) transparent;
|
|
}
|
|
|
|
.solve-step {
|
|
width: 100%;
|
|
min-height: 0 !important;
|
|
display: grid !important;
|
|
grid-template-columns: 2rem minmax(0, 1fr);
|
|
align-items: start !important;
|
|
gap: 0.65rem !important;
|
|
padding: 0.68rem !important;
|
|
text-align: left !important;
|
|
}
|
|
|
|
.solve-step > span:last-child {
|
|
min-width: 0;
|
|
display: grid;
|
|
gap: 0.18rem;
|
|
}
|
|
|
|
.solve-step small,
|
|
.step-effects {
|
|
display: block;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.72rem;
|
|
font-weight: 500;
|
|
line-height: 1.45;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.step-number {
|
|
width: 2rem;
|
|
height: 2rem;
|
|
display: grid;
|
|
place-items: center;
|
|
border-radius: 50%;
|
|
background: var(--toolbox-surface-soft);
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.72rem;
|
|
font-variant-numeric: tabular-nums;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.solve-step.is-active .step-number {
|
|
background: var(--toolbox-accent-contrast);
|
|
color: var(--toolbox-accent);
|
|
}
|
|
|
|
.solve-step.is-active :where(strong, small, .step-effects) {
|
|
color: var(--toolbox-accent-contrast);
|
|
}
|
|
|
|
.shortcut-note {
|
|
padding-top: 0.65rem;
|
|
border-top: 1px solid var(--toolbox-border);
|
|
font-size: 0.72rem;
|
|
}
|
|
|
|
/* Dialogs and local library */
|
|
|
|
.modal {
|
|
width: min(calc(100% - 2rem), 40rem);
|
|
max-width: none;
|
|
max-height: min(calc(100dvh - 2rem), 52rem);
|
|
margin: auto;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.95rem;
|
|
outline: none;
|
|
background: var(--toolbox-surface);
|
|
box-shadow: 0 1.3rem 4.5rem rgb(5 10 25 / 28%);
|
|
color: var(--toolbox-text);
|
|
}
|
|
|
|
.modal--wide {
|
|
width: min(calc(100% - 2rem), 68rem);
|
|
}
|
|
|
|
.modal::backdrop {
|
|
background: rgb(8 13 28 / 58%);
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.modal[open] {
|
|
animation: modal-enter 150ms ease-out both;
|
|
}
|
|
|
|
@keyframes modal-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(0.45rem) scale(0.985);
|
|
}
|
|
|
|
to {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
.modal__surface {
|
|
max-height: inherit;
|
|
display: grid;
|
|
grid-template-rows: auto minmax(0, 1fr);
|
|
}
|
|
|
|
.modal__header {
|
|
min-height: 4rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
padding: 0.85rem 1rem 0.85rem 1.2rem;
|
|
border-bottom: 1px solid var(--toolbox-border);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-surface) 90%,
|
|
var(--toolbox-background)
|
|
);
|
|
}
|
|
|
|
.modal__header .icon-button {
|
|
width: 2.45rem;
|
|
min-width: 2.45rem;
|
|
height: 2.45rem;
|
|
min-height: 2.45rem;
|
|
padding: 0;
|
|
border-radius: 50%;
|
|
font-size: 1.35rem;
|
|
font-weight: 450;
|
|
}
|
|
|
|
.modal__body {
|
|
min-height: 0;
|
|
overflow: auto;
|
|
overscroll-behavior: contain;
|
|
padding: clamp(0.9rem, 2.2vw, 1.3rem);
|
|
scrollbar-color: var(--toolbox-border) transparent;
|
|
}
|
|
|
|
.import-export-grid,
|
|
.help-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.import-export-grid > section,
|
|
.help-grid > section {
|
|
min-width: 0;
|
|
padding: 0.9rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.75rem;
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--toolbox-surface-soft) 46%,
|
|
var(--toolbox-surface)
|
|
);
|
|
}
|
|
|
|
.import-export-grid textarea {
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
|
|
font-size: 0.76rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.export-actions {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.export-actions button {
|
|
flex: 1 1 11rem;
|
|
}
|
|
|
|
.library-toolbar {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 0.8rem 1.25rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.library-list {
|
|
display: grid;
|
|
gap: 0.45rem;
|
|
}
|
|
|
|
.library-list li {
|
|
min-width: 0;
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.38rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.68rem;
|
|
background: var(--toolbox-surface);
|
|
}
|
|
|
|
.library-open {
|
|
min-width: 0;
|
|
display: grid !important;
|
|
justify-items: start !important;
|
|
gap: 0.18rem !important;
|
|
border-color: transparent !important;
|
|
background: transparent !important;
|
|
box-shadow: none !important;
|
|
text-align: left !important;
|
|
}
|
|
|
|
.library-open strong {
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
color: var(--toolbox-text);
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.library-open span {
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.7rem;
|
|
font-weight: 520;
|
|
}
|
|
|
|
.empty-state {
|
|
display: grid;
|
|
justify-items: center;
|
|
gap: 0.4rem;
|
|
padding: clamp(2rem, 8vw, 4.5rem) 1rem;
|
|
border: 1px dashed var(--toolbox-border);
|
|
border-radius: 0.8rem;
|
|
background: var(--toolbox-surface-soft);
|
|
color: var(--toolbox-muted);
|
|
text-align: center;
|
|
}
|
|
|
|
.empty-state::before {
|
|
width: 3rem;
|
|
height: 3rem;
|
|
display: grid;
|
|
place-items: center;
|
|
margin-bottom: 0.25rem;
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 0.8rem;
|
|
background: var(--toolbox-surface);
|
|
color: var(--toolbox-accent);
|
|
content: "▦";
|
|
font-size: 1.35rem;
|
|
}
|
|
|
|
.danger-zone {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 1rem;
|
|
padding-top: 1rem;
|
|
border-top: 1px solid var(--toolbox-border);
|
|
}
|
|
|
|
.help-grid section {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: 0.55rem;
|
|
}
|
|
|
|
.help-grid p {
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.84rem;
|
|
}
|
|
|
|
.help-grid p strong {
|
|
color: var(--toolbox-text);
|
|
}
|
|
|
|
.shortcut-list {
|
|
display: grid;
|
|
gap: 0.28rem;
|
|
}
|
|
|
|
.shortcut-list > div {
|
|
display: grid;
|
|
grid-template-columns: minmax(7rem, 0.62fr) minmax(0, 1fr);
|
|
gap: 0.65rem;
|
|
padding-block: 0.3rem;
|
|
border-bottom: 1px solid
|
|
color-mix(in srgb, var(--toolbox-border) 66%, transparent);
|
|
font-size: 0.76rem;
|
|
}
|
|
|
|
.shortcut-list dt {
|
|
color: var(--toolbox-text);
|
|
font-weight: 720;
|
|
}
|
|
|
|
.shortcut-list dd {
|
|
margin: 0;
|
|
color: var(--toolbox-muted);
|
|
}
|
|
|
|
/* Loading and fatal recovery */
|
|
|
|
.workbench-loading {
|
|
min-height: min(34rem, calc(100dvh - 10rem));
|
|
display: grid;
|
|
grid-auto-flow: column;
|
|
justify-content: center;
|
|
place-items: center;
|
|
margin: 0;
|
|
color: var(--toolbox-muted);
|
|
font-size: 0.88rem;
|
|
}
|
|
|
|
.workbench-loading::before {
|
|
width: 1.15rem;
|
|
height: 1.15rem;
|
|
margin-right: 0.65rem;
|
|
border: 2px solid var(--toolbox-border);
|
|
border-top-color: var(--toolbox-accent);
|
|
border-radius: 50%;
|
|
content: "";
|
|
animation: loading-spin 700ms linear infinite;
|
|
}
|
|
|
|
@keyframes loading-spin {
|
|
to {
|
|
transform: rotate(1turn);
|
|
}
|
|
}
|
|
|
|
.fatal-error {
|
|
width: min(calc(100% - 2rem), 36rem);
|
|
display: grid;
|
|
gap: 1rem;
|
|
margin: clamp(2rem, 10vh, 7rem) auto;
|
|
padding: clamp(1.2rem, 4vw, 2rem);
|
|
border: 1px solid var(--toolbox-border);
|
|
border-radius: 1rem;
|
|
background: var(--toolbox-surface);
|
|
box-shadow: var(--toolbox-shadow);
|
|
}
|
|
|
|
.fatal-error p {
|
|
color: var(--toolbox-muted);
|
|
}
|
|
|
|
.fatal-error button {
|
|
justify-self: start;
|
|
}
|
|
|
|
/* Responsive composition */
|
|
|
|
@media (max-width: 67rem) {
|
|
.workbench-grid,
|
|
.workbench-grid--helpers {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
|
|
.side-panel {
|
|
width: 100%;
|
|
}
|
|
|
|
.board-toolbar,
|
|
.board-meta {
|
|
width: min(100%, 45rem);
|
|
margin-inline: auto;
|
|
}
|
|
|
|
.helper-controls {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 48rem) {
|
|
.toolbox-shell__main {
|
|
padding-inline: 0.75rem;
|
|
}
|
|
|
|
.workbench-hero {
|
|
align-items: flex-start;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.workbench-hero::after {
|
|
opacity: 0.58;
|
|
}
|
|
|
|
.hero-actions {
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.workbench-status,
|
|
.board-toolbar {
|
|
align-items: flex-start;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.board-toolbar > :where(.toolbar-group, .action-row) {
|
|
width: 100%;
|
|
}
|
|
|
|
.side-panel {
|
|
padding: 0.75rem;
|
|
}
|
|
|
|
.subtabs,
|
|
.import-export-grid,
|
|
.help-grid {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
|
|
.library-toolbar {
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 38rem) {
|
|
.workspace-tabs {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.field-grid,
|
|
.helper-controls {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
|
|
.section-heading {
|
|
align-items: stretch;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.compact-field {
|
|
width: 100%;
|
|
}
|
|
|
|
.panel-section.action-row,
|
|
.action-row,
|
|
.hero-actions {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.panel-section.action-row > button,
|
|
.action-row > button,
|
|
.hero-actions > button {
|
|
flex: 1 1 9rem;
|
|
}
|
|
|
|
.modal {
|
|
width: calc(100% - 1rem);
|
|
max-height: calc(100dvh - 1rem);
|
|
border-radius: 0.78rem;
|
|
}
|
|
|
|
.modal__header {
|
|
min-height: 3.6rem;
|
|
padding-left: 0.9rem;
|
|
}
|
|
|
|
.modal__body {
|
|
padding: 0.75rem;
|
|
}
|
|
|
|
.library-list li {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
|
|
.library-list li > .text-button {
|
|
justify-self: end;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 30rem) {
|
|
.toolbox-shell__main {
|
|
padding: 0.55rem;
|
|
}
|
|
|
|
.sudoku-workbench {
|
|
gap: 0.65rem;
|
|
}
|
|
|
|
.workbench-hero,
|
|
.side-panel {
|
|
border-radius: 0.72rem;
|
|
}
|
|
|
|
.workbench-hero {
|
|
padding: 0.9rem;
|
|
}
|
|
|
|
.workspace-tabs button {
|
|
min-height: 2.7rem;
|
|
}
|
|
|
|
.board-surface {
|
|
padding: 0.25rem;
|
|
}
|
|
|
|
.sudoku-board-frame {
|
|
--board-pad: 0.2rem;
|
|
border-radius: 0.55rem;
|
|
}
|
|
|
|
.mode-switcher {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.inline-fields {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
|
|
.button-grid {
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.button-grid button {
|
|
padding-inline: 0.4rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.shortcut-list > div {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
gap: 0.12rem;
|
|
}
|
|
}
|
|
|
|
@media (pointer: coarse) {
|
|
:where(.sudoku-workbench, .modal, .fatal-error) button:not(.sudoku-cell),
|
|
:where(.sudoku-workbench, .modal)
|
|
:where(input:not([type="checkbox"]):not([type="radio"]), select) {
|
|
min-height: 2.75rem;
|
|
}
|
|
|
|
.sudoku-cell {
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
scroll-behavior: auto !important;
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
.sudoku-cell.is-selected::after,
|
|
.sudoku-cell.has-conflict::before {
|
|
border: 2px solid Highlight;
|
|
background: transparent;
|
|
}
|
|
|
|
.sudoku-cell.has-conflict {
|
|
outline: 2px dashed Mark;
|
|
outline-offset: -4px;
|
|
}
|
|
|
|
.constraint-layer :where(path, polyline, line, circle),
|
|
.region-boundaries path {
|
|
stroke: CanvasText;
|
|
}
|
|
}
|
|
|
|
/* A print is a clean puzzle sheet, not a snapshot of the controls. */
|
|
|
|
@media print {
|
|
@page {
|
|
size: auto;
|
|
margin: 1.2cm;
|
|
}
|
|
|
|
:root,
|
|
body {
|
|
background: #fff !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.toolbox-shell {
|
|
min-height: 0;
|
|
background: #fff !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.toolbox-shell__header,
|
|
.toolbox-shell__footer,
|
|
.hero-actions,
|
|
.workspace-tabs,
|
|
.workbench-status,
|
|
.board-toolbar,
|
|
.side-panel,
|
|
.number-pad,
|
|
.paused-cover,
|
|
.feedback-callout,
|
|
.status-line,
|
|
.modal {
|
|
display: none !important;
|
|
}
|
|
|
|
.toolbox-shell__main,
|
|
.sudoku-workbench,
|
|
.workbench-grid,
|
|
.board-column {
|
|
width: 100% !important;
|
|
max-width: none !important;
|
|
display: block !important;
|
|
margin: 0 !important;
|
|
padding: 0 !important;
|
|
}
|
|
|
|
.workbench-hero {
|
|
margin-bottom: 0.6cm;
|
|
padding: 0 !important;
|
|
border: 0 !important;
|
|
background: transparent !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.workbench-hero::after {
|
|
display: none;
|
|
}
|
|
|
|
.hero-copy > p:not(.eyebrow) {
|
|
color: #333 !important;
|
|
}
|
|
|
|
.board-surface {
|
|
display: block;
|
|
padding: 0 !important;
|
|
border: 0 !important;
|
|
background: #fff !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.sudoku-board-frame {
|
|
--toolbox-surface: #fff;
|
|
--toolbox-text: #000;
|
|
--toolbox-muted: #444;
|
|
--toolbox-accent: #111;
|
|
--toolbox-danger: #000;
|
|
--sudoku-line: #888;
|
|
--sudoku-line-strong: #000;
|
|
width: min(100%, 18cm);
|
|
margin-inline: auto;
|
|
padding: 0;
|
|
border: 0;
|
|
background: #fff !important;
|
|
box-shadow: none;
|
|
break-inside: avoid;
|
|
print-color-adjust: exact;
|
|
}
|
|
|
|
.sudoku-cell,
|
|
.sudoku-cell.is-selected,
|
|
.sudoku-cell.has-conflict,
|
|
.sudoku-cell[class*="has-color-"] {
|
|
--cell-fill: #fff;
|
|
background: #fff !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.sudoku-cell::before,
|
|
.sudoku-cell::after {
|
|
display: none !important;
|
|
}
|
|
|
|
.constraint-layer {
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.board-meta,
|
|
.rule-card {
|
|
width: min(100%, 18cm);
|
|
margin: 0.5cm auto 0;
|
|
color: #222 !important;
|
|
}
|
|
|
|
.rule-card {
|
|
padding: 0;
|
|
border: 0;
|
|
background: transparent !important;
|
|
}
|
|
}
|