Restyle the app interface

This commit is contained in:
Andras Schmelczer 2026-05-24 10:58:36 +01:00
parent 839747304e
commit a73914d0ef
20 changed files with 1662 additions and 472 deletions

View file

@ -1,275 +1,8 @@
@use 'style/mixins' as *;
@use 'style/common';
html > body {
width: 100%;
height: 100%;
display: flex;
position: relative;
> .canvas-container {
height: 100%;
width: 100%;
display: flex;
> canvas {
height: 100%;
width: 100%;
touch-action: none;
cursor:
url('../assets/icons/brush.svg') 0 24,
auto;
}
> .errors-container {
position: absolute;
top: 0;
left: 0;
margin: var(--normal-margin);
pre {
font-size: 20px;
color: red;
}
}
.counters {
@include blurred-background(white);
position: absolute;
border-radius: var(--border-radius);
padding: var(--small-margin);
@include on-large-screen {
top: var(--normal-margin);
right: var(--normal-margin);
}
@include on-small-screen {
bottom: var(--normal-margin);
right: var(--normal-margin);
}
}
}
> aside {
@include blurred-background(#fff);
box-shadow: var(--shadow);
display: flex;
position: absolute;
overflow: hidden;
@include on-large-screen {
top: 50%;
left: 0;
transform: translateY(-50%);
max-height: 350px;
}
@include on-small-screen {
top: 0;
left: 50%;
transform: translateX(-50%);
flex-direction: column;
}
transition: opacity var(--transition-time-long);
border-radius: var(--border-radius);
margin: var(--small-margin);
> nav.buttons {
@include center-children;
justify-content: space-evenly;
@include on-large-screen {
flex-direction: column;
}
> button {
position: relative;
border: none;
background-color: transparent;
cursor: pointer;
@include square(var(--icon-size));
margin: var(--small-margin);
&::before,
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
&::before {
background-color: var(--accent-color);
@include on-large-screen {
width: 0;
border-radius: 0 var(--border-radius) var(--border-radius) 0;
transition:
background-color var(--transition-time),
width var(--transition-time);
left: calc(-1 * var(--small-margin));
height: 140%;
top: 50%;
transform: translateY(-50%);
}
@include on-small-screen {
height: 0;
border-radius: 0 0 var(--border-radius) var(--border-radius);
transition:
background-color var(--transition-time),
height var(--transition-time);
top: calc(-1 * var(--small-margin));
width: 140%;
left: 50%;
transform: translateX(-50%);
}
}
&::after {
background-color: var(--accent-color);
transition:
transform var(--transition-time),
background-color var(--transition-time);
mask-repeat: no-repeat;
@include square(var(--icon-size));
}
&.active {
&::before {
@include on-large-screen {
width: calc(100% + 2 * var(--small-margin));
}
@include on-small-screen {
height: calc(100% + 2 * var(--small-margin));
}
}
&::after {
background-color: white;
}
}
&:hover::after {
transform: scale(1.15);
}
&.info::after {
mask-image: url('../assets/icons/info.svg');
}
&.maximize-full-screen::after {
mask-image: url('../assets/icons/maximize.svg');
}
&.minimize-full-screen::after {
mask-image: url('../assets/icons/minimize.svg');
}
&.settings::after {
mask-image: url('../assets/icons/settings.svg');
}
&.restart::after {
mask-image: url('../assets/icons/restart.svg');
}
}
}
> main.pages {
overflow-x: hidden;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--main-color) transparent;
&::-webkit-scrollbar-track,
&::-webkit-scrollbar {
background-color: transparent;
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: var(--main-color);
border-radius: var(--border-radius);
}
&,
> * {
transition:
width var(--transition-time-long),
height var(--transition-time-long);
@include on-large-screen {
width: max(500px, 10vw);
}
@include on-small-screen {
height: max(500px, 70vh);
}
}
&.hidden {
@include on-large-screen {
width: 0;
}
@include on-small-screen {
height: 0;
}
}
> section {
padding: var(--normal-margin);
display: flex;
flex-direction: column;
.slider {
$track-height: 12px;
margin-bottom: var(--small-margin);
user-select: none;
p {
display: flex;
justify-content: space-between;
}
input[type='range'] {
width: 100%;
height: $track-height;
appearance: none;
background: transparent;
outline: none;
border-radius: 1000px;
&::-webkit-slider-runnable-track {
appearance: none;
cursor: pointer;
border-radius: 1000px;
@include square(15px);
background: var(--accent-color);
}
&::-webkit-slider-thumb {
appearance: none;
cursor: pointer;
border-radius: 1000px;
$size: 24px;
@include square($size);
background: white;
box-shadow: 0 0 5px 1px var(--accent-color);
transform: translateY(-5px);
transition: transform var(--transition-time);
&:hover {
transform: translateY(-5px) scale(1.1);
}
}
}
}
}
}
}
}
@use 'style/app-shell';
@use 'style/garden-prompt';
@use 'style/control-dock';
@use 'style/toolbar';
@use 'style/config-pane';
@use 'style/panels';
@use 'style/loading';

133
src/style/_app-shell.scss Normal file
View file

@ -0,0 +1,133 @@
html > body.is-loading .perf-stats-overlay {
display: none;
}
$grain-noise-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='257' height='257' viewBox='0 0 257 257'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' seed='17' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='257' height='257' filter='url(%23n)'/%3E%3C/svg%3E");
$grain-noise-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='389' height='389' viewBox='0 0 389 389'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.53' numOctaves='5' seed='41' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='389' height='389' filter='url(%23n)'/%3E%3C/svg%3E");
html > body {
width: 100%;
height: 100vh;
height: 100dvh;
overflow: hidden;
display: flex;
position: relative;
background: var(--garden-background, #10151f);
> .canvas-container {
height: 100%;
width: 100%;
display: flex;
position: relative;
overflow: hidden;
> canvas {
position: relative;
z-index: 0;
height: 100%;
width: 100%;
touch-action: none;
}
> .garden-grain {
--garden-grain-strength: 0;
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
contain: strict;
&::before,
&::after {
content: '';
position: absolute;
inset: 0;
}
&::before {
opacity: clamp(0, calc(var(--garden-grain-strength) * 4.25), 0.24);
background-image: $grain-noise-a;
background-size: 257px 257px;
filter: contrast(145%) brightness(0.82);
mix-blend-mode: multiply;
}
&::after {
opacity: clamp(0, calc(var(--garden-grain-strength) * 2.5), 0.12);
background-image: $grain-noise-b;
background-position: 73px 41px;
background-size: 389px 389px;
filter: contrast(135%) brightness(1);
mix-blend-mode: screen;
transform: rotate(0.01deg);
}
&[hidden] {
display: none;
}
}
> .eraser-preview {
position: absolute;
top: 0;
left: 0;
z-index: 3;
width: var(--eraser-preview-size, 96px);
height: var(--eraser-preview-size, 96px);
border: 2px solid rgb(255 234 228 / 88%);
border-radius: 50%;
background: rgb(255 140 117 / 13%);
box-shadow:
0 0 0 1px rgb(255 88 70 / 34%),
0 0 26px rgb(255 118 92 / 24%);
opacity: 0;
pointer-events: none;
transform: translate(-50%, -50%);
transition:
opacity var(--transition-time),
width var(--transition-time),
height var(--transition-time);
mix-blend-mode: screen;
&.visible {
opacity: 1;
}
}
> .perf-stats-overlay {
position: absolute;
top: max(8px, env(safe-area-inset-top));
left: max(8px, env(safe-area-inset-left));
z-index: 6;
padding: 6px 8px;
border: 1px solid rgb(255 255 255 / 18%);
border-radius: 6px;
background: rgb(0 0 0 / 62%);
color: rgb(255 255 255 / 92%);
font:
600 12px/1.35 ui-monospace,
SFMono-Regular,
Menlo,
Consolas,
monospace;
white-space: pre;
pointer-events: none;
user-select: none;
box-shadow: 0 8px 24px rgb(0 0 0 / 28%);
}
> .errors-container {
position: absolute;
top: 0;
left: 0;
margin: var(--normal-margin);
z-index: 5;
pre {
font-size: 20px;
color: red;
}
}
}
}

309
src/style/_config-pane.scss Normal file
View file

@ -0,0 +1,309 @@
@use 'mixins' as *;
.config-pane-container {
--config-pane-available-height: calc(
100vh - 24px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)
);
position: fixed;
top: max(12px, env(safe-area-inset-top, 0px));
right: max(12px, env(safe-area-inset-right, 0px));
display: grid;
grid-template-rows: auto minmax(0, 1fr);
gap: 4px;
z-index: 20;
width: min(
420px,
calc(100vw - 24px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px))
);
max-height: var(--config-pane-available-height);
pointer-events: none;
@supports (height: 100dvh) {
--config-pane-available-height: calc(
100dvh - 24px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)
);
}
}
.config-pane-container--open {
pointer-events: auto;
}
.config-pane {
--tp-blade-value-width: min(260px, 64%);
width: 100%;
max-height: calc(var(--config-pane-available-height) - 36px);
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
pointer-events: auto;
scrollbar-width: thin;
touch-action: pan-y;
-webkit-overflow-scrolling: touch;
// Tweakpane v4 internal classes re-verify on upgrade.
// No public theming hook exists for label padding or the slider/number
// flex ratio; if a fourth override appears here, switch to a custom plugin.
.tp-lblv_l {
padding-right: 10px;
}
.tp-sldtxtv_s {
flex: 1 1 auto;
min-width: 0;
}
.tp-sldtxtv_t {
flex: 0 0 54px;
}
}
.config-pane-close {
position: relative;
justify-self: end;
display: grid;
width: 28px;
height: 28px;
place-items: center;
border: 0;
border-radius: 4px;
background: transparent;
color: rgb(235 238 245 / 82%);
cursor: pointer;
font: inherit;
font-size: 0;
pointer-events: auto;
transition:
background-color var(--transition-time),
color var(--transition-time);
&::before,
&::after {
content: '';
position: absolute;
width: 14px;
height: 2px;
border-radius: 999px;
background: currentColor;
}
&::before {
transform: rotate(45deg);
}
&::after {
transform: rotate(-45deg);
}
&:hover {
background: rgb(255 255 255 / 10%);
color: white;
}
&:focus-visible {
outline: 2px solid white;
outline-offset: -2px;
}
&[hidden] {
display: none;
}
}
@mixin mobile-config-pane() {
.config-pane-container {
--config-pane-available-height: min(
64vh,
calc(
100vh - 112px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)
)
);
top: max(8px, env(safe-area-inset-top, 0px));
right: auto;
left: 50%;
width: min(80vw, 420px);
transform: translateX(-50%);
@supports (height: 100dvh) {
--config-pane-available-height: min(
64dvh,
calc(
100dvh -
112px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)
)
);
}
}
.config-pane {
--tp-blade-value-width: min(210px, 62%);
--tp-container-unit-size: 18px;
padding-bottom: 10px;
font-size: 11px;
// Tweakpane v4 internal class re-verify on upgrade.
.tp-sldtxtv_t {
flex-basis: 48px;
}
}
.config-pane-close {
width: 32px;
height: 32px;
}
}
@include on-mobile-input {
@include mobile-config-pane;
}
.color-reaction-matrix-blade {
padding: 6px 8px 8px;
}
.color-reaction-matrix {
display: grid;
grid-template-columns: 28px repeat(3, minmax(0, 1fr));
gap: 4px;
align-items: stretch;
}
.color-reaction-matrix__corner,
.color-reaction-matrix__header {
display: flex;
min-width: 0;
min-height: 28px;
align-items: center;
justify-content: center;
color: rgb(255 255 255 / 76%);
font-size: 11px;
line-height: 1;
}
.color-reaction-matrix__header {
gap: 0;
}
.color-reaction-matrix__corner {
justify-content: flex-start;
padding-left: 2px;
color: rgb(255 255 255 / 62%);
}
.color-reaction-matrix__swatch {
flex: 0 0 auto;
width: 12px;
height: 12px;
border: 1px solid rgb(255 255 255 / 55%);
border-radius: 999px;
box-shadow: 0 0 0 1px rgb(0 0 0 / 18%);
}
.color-reaction-matrix__cell {
min-width: 0;
display: grid;
}
.color-reaction-matrix__button {
position: relative;
display: grid;
width: 100%;
min-width: 0;
height: 28px;
place-items: center;
border: 1px solid rgb(255 255 255 / 16%);
border-radius: 4px;
padding: 0 4px;
background: rgb(255 255 255 / 8%);
color: white;
font: inherit;
cursor: pointer;
transition:
background-color var(--transition-time),
border-color var(--transition-time),
color var(--transition-time),
transform var(--transition-time);
}
.color-reaction-matrix__button:hover {
transform: translateY(-1px);
}
.color-reaction-matrix__button:focus-visible {
outline: 2px solid rgb(255 255 255 / 72%);
outline-offset: 1px;
}
.color-reaction-matrix__button[data-reaction='follow'] {
border-color: rgb(115 235 160 / 44%);
background: rgb(53 165 96 / 20%);
color: rgb(157 255 195 / 94%);
}
.color-reaction-matrix__button[data-reaction='ignore'] {
border-color: rgb(255 255 255 / 18%);
background: rgb(255 255 255 / 7%);
color: rgb(235 238 245 / 72%);
}
.color-reaction-matrix__button[data-reaction='avoid'] {
border-color: rgb(255 145 120 / 46%);
background: rgb(215 74 54 / 19%);
color: rgb(255 171 148 / 94%);
}
.color-reaction-matrix__icon {
position: relative;
display: block;
width: 16px;
height: 16px;
}
.color-reaction-matrix__icon::before,
.color-reaction-matrix__icon::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
border-radius: 999px;
background: currentColor;
transform: translate(-50%, -50%);
}
.color-reaction-matrix__button[data-reaction='follow']
> .color-reaction-matrix__icon::before,
.color-reaction-matrix__button[data-reaction='avoid']
> .color-reaction-matrix__icon::before {
width: 14px;
height: 2px;
}
.color-reaction-matrix__button[data-reaction='follow']
> .color-reaction-matrix__icon::after {
width: 2px;
height: 14px;
}
.color-reaction-matrix__button[data-reaction='avoid']
> .color-reaction-matrix__icon::after {
display: none;
}
.color-reaction-matrix__button[data-reaction='ignore'] > .color-reaction-matrix__icon {
width: 12px;
height: 12px;
border: 2px solid currentColor;
border-radius: 999px;
opacity: 0.82;
}
.color-reaction-matrix__button[data-reaction='ignore']
> .color-reaction-matrix__icon::before,
.color-reaction-matrix__button[data-reaction='ignore']
> .color-reaction-matrix__icon::after {
display: none;
}

View file

@ -0,0 +1,39 @@
html > body > aside.control-dock {
--dock-hidden-translate-y: calc(100% + env(safe-area-inset-bottom, 0px) + 16px);
position: absolute;
left: 0;
right: 0;
bottom: env(safe-area-inset-bottom, 0px);
z-index: 4;
width: min(calc(100vw - 1rem), 980px);
margin: 0 auto;
transform: translateY(0);
visibility: visible;
pointer-events: none;
transition:
opacity var(--transition-time-long),
transform var(--transition-time-long),
visibility 0s;
> .toolbar-row,
> .info-page {
pointer-events: auto;
}
&.menu-hidden {
opacity: 0;
visibility: hidden;
transform: translateY(var(--dock-hidden-translate-y));
pointer-events: none;
transition:
opacity var(--transition-time-long),
transform var(--transition-time-long),
visibility 0s var(--transition-time-long);
> .toolbar-row,
> .info-page {
pointer-events: none;
}
}
}

View file

@ -0,0 +1,126 @@
@use 'mixins' as *;
html > body > .canvas-container > .garden-prompt {
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
pointer-events: none;
z-index: 2;
&:empty {
display: none;
}
&.draw-hint {
display: flex;
align-items: center;
top: calc(1.25rem + env(safe-area-inset-top));
gap: 16px;
width: max-content;
min-height: 78px;
max-width: min(88vw, 460px);
padding: 12px 18px 12px 14px;
border: 1px solid rgb(255 255 255 / 16%);
border-radius: 8px;
background: rgb(10 12 16 / 50%);
box-shadow:
0 14px 42px rgb(0 0 0 / 28%),
inset 0 0 0 1px rgb(255 255 255 / 5%);
backdrop-filter: blur(12px);
color: rgb(255 255 255 / 94%);
font-size: 20px;
font-weight: 400;
line-height: 1.2;
text-shadow: 0 1px 12px rgb(0 0 0 / 58%);
}
.draw-hint-mark {
width: 128px;
height: 72px;
flex: 0 0 128px;
overflow: visible;
}
.draw-hint-shadow,
.draw-hint-stroke {
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
.draw-hint-shadow {
stroke: rgb(0 0 0 / 42%);
stroke-width: 10px;
}
.draw-hint-stroke {
stroke: color-mix(in srgb, var(--accent-color) 74%, white);
stroke-width: 5px;
stroke-dasharray: 154;
animation: draw-hint-stroke 2.4s ease-in-out infinite;
filter: drop-shadow(
0 0 12px color-mix(in srgb, var(--accent-color) 60%, transparent)
);
}
.draw-hint-start {
fill: rgb(255 255 255 / 64%);
}
.draw-hint-end {
fill: white;
stroke: color-mix(in srgb, var(--accent-color) 72%, transparent);
stroke-width: 5px;
transform-origin: 116px 42px;
animation: draw-hint-tap 2.4s ease-in-out infinite;
}
@include on-small-screen {
&.draw-hint {
top: calc(0.75rem + env(safe-area-inset-top));
gap: 10px;
min-height: 58px;
max-width: min(92vw, 340px);
padding: 9px 12px 9px 10px;
font-size: 16px;
}
.draw-hint-mark {
width: 96px;
height: 54px;
flex-basis: 96px;
}
}
}
@keyframes draw-hint-stroke {
0%,
18% {
stroke-dashoffset: 154;
}
58%,
100% {
stroke-dashoffset: 0;
}
}
@keyframes draw-hint-tap {
0%,
16% {
opacity: 0;
transform: scale(0.72);
}
36%,
74% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0.76;
transform: scale(0.88);
}
}

183
src/style/_loading.scss Normal file
View file

@ -0,0 +1,183 @@
.loading-indicator {
--loading-gap: 22px;
position: absolute;
top: 50%;
left: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 3;
width: min(86vw, 380px);
transform: translate(-50%, -50%);
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-time-long);
contain: layout;
> .splash {
display: flex;
flex-direction: column;
gap: 16px;
align-items: center;
pointer-events: auto;
opacity: 1;
visibility: visible;
transition:
opacity var(--transition-time),
visibility 0s linear 0s;
&[data-visible='false'] {
opacity: 0;
visibility: hidden;
pointer-events: none;
transition:
opacity var(--transition-time),
visibility 0s linear var(--transition-time);
}
> .splash-title {
margin: 0;
color: rgb(255 255 255 / 96%);
font-size: clamp(28px, 6vw, 42px);
font-weight: 700;
line-height: 1.1;
text-align: center;
letter-spacing: 0.01em;
text-shadow:
0 2px 18px rgb(0 0 0 / 60%),
0 0 32px rgb(255 255 255 / 10%);
}
> .splash-description {
margin: 0;
max-width: 28ch;
color: rgb(255 255 255 / 80%);
font-size: 15px;
font-weight: 400;
line-height: 1.45;
text-align: center;
text-shadow: 0 1px 12px rgb(0 0 0 / 60%);
}
> .start-button {
margin-top: 8px;
padding: 14px 40px;
border: 1px solid rgb(255 255 255 / 38%);
border-radius: 999px;
background: rgb(255 255 255 / 8%);
color: rgb(255 255 255 / 96%);
font-size: 16px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
cursor: pointer;
backdrop-filter: blur(6px);
box-shadow:
0 0 24px rgb(255 255 255 / 14%),
0 1px 6px rgb(0 0 0 / 28%);
transition:
opacity var(--transition-time),
transform var(--transition-time),
background var(--transition-time);
&[disabled] {
opacity: 0.5;
cursor: progress;
}
&:not([disabled]):hover,
&:not([disabled]):focus-visible {
background: rgb(255 255 255 / 16%);
transform: scale(1.04);
outline: none;
}
&:not([disabled]):active {
transform: scale(0.98);
}
}
}
> .loading-bar {
position: absolute;
top: calc(100% + var(--loading-gap));
left: 0;
right: 0;
display: flex;
flex-direction: column;
gap: 18px;
align-items: center;
width: 100%;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition:
opacity var(--transition-time),
visibility 0s linear var(--transition-time);
&[data-visible='true'] {
opacity: 1;
visibility: visible;
transition:
opacity var(--transition-time),
visibility 0s linear 0s;
}
> .loading-status {
color: rgb(255 255 255 / 88%);
font-size: 16px;
font-weight: 400;
line-height: 1.25;
text-align: center;
text-shadow: 0 1px 12px rgb(0 0 0 / 60%);
letter-spacing: 0.01em;
min-height: 1.25em;
}
> .loading-progress {
--loading-progress: 0%;
position: relative;
width: 100%;
height: 3px;
overflow: hidden;
border-radius: 999px;
background: rgb(255 255 255 / 14%);
box-shadow: 0 1px 6px rgb(0 0 0 / 28%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: var(--loading-progress);
border-radius: inherit;
background: linear-gradient(
90deg,
rgb(255 255 255 / 72%),
rgb(255 255 255 / 96%)
);
box-shadow: 0 0 12px rgb(255 255 255 / 38%);
transition: width var(--transition-time-long) ease-out;
}
}
}
}
html > body.is-loading {
.loading-indicator {
opacity: 1;
}
.eraser-preview {
visibility: hidden;
}
aside.control-dock {
opacity: 0;
visibility: hidden;
}
}

96
src/style/_panels.scss Normal file
View file

@ -0,0 +1,96 @@
@use 'mixins' as *;
html > body > aside.control-dock > .info-page {
width: min(calc(100vw - 1rem), 560px);
max-height: min(58vh, 520px);
max-height: min(58dvh, 520px);
margin: 0 auto 10px;
overflow-x: hidden;
overflow-y: auto;
border: 1px solid rgb(255 255 255 / 78%);
border-radius: 8px;
background:
linear-gradient(180deg, rgb(255 255 255 / 97%), rgb(243 247 239 / 96%)),
rgb(255 255 255);
color: rgb(24 30 27);
box-shadow:
0 20px 54px rgb(0 0 0 / 38%),
0 2px 12px rgb(0 0 0 / 22%);
backdrop-filter: blur(12px);
scrollbar-width: thin;
scrollbar-color: var(--main-color) transparent;
transition:
max-height var(--transition-time-long),
opacity var(--transition-time-long),
transform var(--transition-time-long),
margin-bottom var(--transition-time-long);
&::-webkit-scrollbar-track,
&::-webkit-scrollbar {
background-color: transparent;
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: var(--main-color);
border-radius: 8px;
}
&:focus-visible {
outline: 2px solid white;
outline-offset: 3px;
}
> section {
display: flex;
flex-direction: column;
gap: 0.85rem;
padding: var(--normal-margin);
h1 {
margin-bottom: 0;
color: rgb(16 24 20);
font-size: 2rem;
line-height: 1.1;
}
p {
max-width: 54ch;
margin-bottom: 0;
color: rgb(42 48 45);
font-size: 1.1rem;
line-height: 1.65;
hyphens: auto;
}
a {
color: rgb(0 84 120);
font-weight: 400;
&:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
}
}
}
&.hidden {
max-height: 0;
margin-bottom: 0;
border-color: transparent;
opacity: 0;
pointer-events: none;
box-shadow: none;
transform: translateY(8px);
visibility: hidden;
}
@include on-small-screen {
max-height: min(54vh, 500px);
max-height: min(54dvh, 500px);
> section {
padding: var(--small-margin);
}
}
}

4
src/style/_toolbar.scss Normal file
View file

@ -0,0 +1,4 @@
@use 'toolbar/layout';
@use 'toolbar/buttons';
@use 'toolbar/garden-controls';
@use 'toolbar/responsive';

View file

@ -1,6 +1,5 @@
@use 'vars';
@use 'fonts';
@use 'mixins' as *;
*,
*::before,
@ -9,41 +8,34 @@
padding: 0;
box-sizing: border-box;
@media (prefers-reduced-motion) {
@media (prefers-reduced-motion: reduce) {
transition: none !important;
animation: none !important;
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Comfortaa', sans-serif;
margin-bottom: var(--small-margin);
}
p {
font-family: 'Open Sans', sans-serif;
}
html {
height: 100%;
touch-action: manipulation;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
.large-button {
border: none;
background-color: var(--accent-color);
cursor: pointer;
border-radius: var(--border-radius);
padding: calc(var(--small-margin) / 2) var(--small-margin);
margin: var(--small-margin) auto;
align-self: flex-end;
@include main-font();
color: white;
body {
font-family: 'Open Sans', sans-serif;
touch-action: manipulation;
}
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
margin: -1px !important;
padding: 0 !important;
overflow: hidden !important;
clip: rect(0 0 0 0) !important;
clip-path: inset(50%) !important;
white-space: nowrap !important;
border: 0 !important;
}

View file

@ -1,25 +1,8 @@
/* comfortaa-regular - latin */
@font-face {
font-family: 'Comfortaa';
font-style: normal;
font-weight: 400;
font-display: swap;
src:
local(''),
url('../../assets/fonts/comfortaa-v40-latin-regular.woff2') format('woff2'),
/* Chrome 26+, Opera 23+, Firefox 39+ */
url('../../assets/fonts/comfortaa-v40-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-regular - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src:
local(''),
url('../../assets/fonts/open-sans-v34-latin-regular.woff2') format('woff2'),
/* Chrome 26+, Opera 23+, Firefox 39+ */
url('../../assets/fonts/open-sans-v34-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
src: url('../../assets/fonts/open-sans-v34-latin-regular.woff2') format('woff2');
}

View file

@ -1,6 +1,3 @@
@use 'sass:math';
@use 'sass:color';
$breakpoint-width: 600px !default;
@mixin on-small-screen() {
@ -9,131 +6,8 @@ $breakpoint-width: 600px !default;
}
}
@mixin on-large-screen() {
@media (min-width: $breakpoint-width) {
@mixin on-mobile-input() {
@media (max-width: ($breakpoint-width - 1px)), (hover: none) and (pointer: coarse) {
@content;
}
}
@mixin title-fragment-link() {
position: relative;
&:before {
content: '#';
position: absolute;
left: -0.5ch;
top: 50%;
opacity: 0;
transform: translateX(-100%) translateY(-50%);
transition: opacity var(--transition-time);
}
&:hover:before {
opacity: 0.5;
}
}
@mixin center-children() {
display: flex;
align-items: center;
justify-content: center;
}
@mixin absolute-center() {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
@mixin blurred-background($color: transparent) {
background-color: color.adjust($color, $alpha: -0.66);
backdrop-filter: blur(var(--blur-radius));
}
@mixin square($size) {
width: $size;
height: $size;
}
@mixin title-font() {
font:
400 3rem 'Comfortaa',
sans-serif;
color: var(--normal-text-color);
line-height: 1;
@include on-small-screen {
font-size: 3rem;
line-height: 1.1;
}
}
@mixin sub-title-font() {
font:
400 1.75rem 'Comfortaa',
sans-serif;
color: var(--normal-text-color);
hyphens: auto;
}
@mixin main-font() {
font:
400 1.1rem 'Open Sans',
sans-serif;
color: var(--normal-text-color);
line-height: 1.8;
hyphens: auto;
}
@mixin special-text-font() {
font:
400 1rem 'Open Sans',
sans-serif;
color: var(--special-text-color);
hyphens: auto;
font-style: italic;
}
@mixin link {
$border-shift: 10px;
$line-width: 2px;
@include special-text-font();
cursor: pointer;
position: relative;
display: inline-block;
overflow: hidden;
padding: 0 3px $line-width 0;
&:before,
&:after {
content: '';
display: block;
position: absolute;
bottom: 0;
}
&:before {
width: calc(100% + #{$border-shift});
border-bottom: $line-width dashed var(--accent-color);
transition: transform var(--transition-time);
}
&:after {
width: 100%;
height: $line-width;
background: linear-gradient(
90deg,
var(--card-color) 0,
transparent 4px,
transparent calc(100% - 4px),
var(--card-color) 100%
);
}
&:hover:before {
transform: translateX(-$border-shift);
}
}

View file

@ -0,0 +1,161 @@
@use 'shared' as *;
.buttons {
grid-area: buttons;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
justify-self: center;
gap: 4px;
width: fit-content;
max-width: 100%;
min-width: 0;
> button,
> .audio-control > button {
position: relative;
width: 44px;
height: 44px;
flex: 1 1 44px;
max-width: 54px;
min-width: 0;
@include toolbar-control-surface(transparent, rgb(255 255 255 / 9%));
&::after {
content: '';
position: absolute;
inset: 0;
z-index: 1;
width: 20px;
height: 20px;
margin: auto;
background-color: rgb(245 250 244 / 76%);
mask-position: center;
mask-repeat: no-repeat;
mask-size: contain;
transition:
background-color var(--transition-time),
transform var(--transition-time);
}
&:hover::after {
transform: scale(1.08);
}
&.active {
border-color: color-mix(in srgb, var(--accent-color) 55%, white 15%);
background: color-mix(in srgb, var(--accent-color) 30%, transparent);
}
&.active::after {
background-color: white;
}
@each $class, $icon in $toolbar-icons {
&.#{$class}::after {
mask-image: url('../../../assets/icons/#{$icon}.svg');
}
}
&.full-screen-toggle.active::after {
mask-image: url('../../../assets/icons/minimize.svg');
}
&.sound.muted::before {
content: '';
position: absolute;
inset: 0;
z-index: 2;
width: 2px;
height: 28px;
margin: auto;
border-radius: 999px;
background: white;
transform: rotate(-45deg);
transform-origin: center;
}
&.sound.muted::after {
background-color: rgb(255 255 255 / 46%);
}
}
> .audio-control {
display: flex;
align-items: center;
width: 132px;
height: 44px;
flex: 2 1 132px;
max-width: 150px;
min-width: 0;
padding-right: 10px;
@include toolbar-control-surface(rgb(255 255 255 / 4%), rgb(255 255 255 / 7%));
> button {
flex: 0 0 42px;
min-width: 42px;
border-color: transparent;
&:focus-visible {
outline-offset: -4px;
}
}
> .volume-control {
--range-progress: var(--volume-progress, 42%);
--range-track-height: 4px;
--range-fill: color-mix(in srgb, var(--accent-color) 62%, white 8%);
--range-empty: rgb(255 255 255 / 18%);
--range-track-shadow:
inset 0 1px 1px rgb(0 0 0 / 24%), 0 1px 0 rgb(255 255 255 / 8%);
--range-thumb-width: 12px;
--range-thumb-height: 12px;
--range-thumb-border: 2px solid rgb(13 18 24);
--range-thumb-radius: 50%;
--range-thumb-background: rgb(245 250 244);
--range-thumb-shadow: 0 0 0 1px rgb(255 255 255 / 46%), 0 3px 8px rgb(0 0 0 / 28%);
--range-thumb-hover-shadow:
0 0 0 1px rgb(255 255 255 / 56%),
0 0 0 5px color-mix(in srgb, var(--accent-color) 25%, transparent),
0 4px 10px rgb(0 0 0 / 34%);
--range-thumb-hover-transform: scale(1.08);
--range-focus-outline-offset: -4px;
position: relative;
display: grid;
align-items: center;
height: 44px;
flex: 1 1 auto;
min-width: 0;
padding-left: 3px;
cursor: ew-resize;
opacity: 0.96;
transition: opacity var(--transition-time);
&.muted {
opacity: 0.56;
}
}
> .volume-control input[type='range'] {
@include toolbar-range-input();
}
}
> .export-status {
flex: 0 1 140px;
min-height: 20px;
max-width: 140px;
overflow: hidden;
color: rgb(255 255 255 / 82%);
font-size: 13px;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
&:empty {
display: none;
}
}
}

View file

@ -0,0 +1,148 @@
@use 'shared' as *;
.garden-controls {
grid-area: swatches;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
min-width: 0;
padding: 0 4px;
> .swatches {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
min-height: 58px;
padding: 6px 10px;
> .color-swatch {
position: relative;
width: 44px;
height: 44px;
border: 2px solid rgb(255 255 255 / 54%);
border-radius: 50%;
box-shadow:
inset 0 0 0 1px rgb(0 0 0 / 16%),
0 3px 10px rgb(0 0 0 / 22%);
&:hover {
transform: translateY(-2px);
}
&.active {
outline: 2px solid rgb(255 255 255 / 96%);
outline-offset: 3px;
box-shadow:
inset 0 0 0 1px rgb(0 0 0 / 14%),
0 0 0 7px color-mix(in srgb, var(--accent-color) 52%, transparent),
0 7px 18px rgb(0 0 0 / 26%);
}
}
> .eraser-size-control,
> .mirror-segment-control {
--control-thumb-hover-transform: scale(1.03);
--control-thumb-radius: 50%;
--control-thumb-transform: none;
--range-progress: var(--control-progress);
--range-track-height: 7px;
--range-fill: rgb(var(--control-rgb) / 72%);
--range-empty: rgb(255 255 255 / 24%);
--range-track-shadow: inset 0 1px 2px rgb(0 0 0 / 24%);
--range-thumb-width: var(--control-thumb-width);
--range-thumb-height: var(--control-thumb-height);
--range-thumb-border: 2px solid rgb(255 255 255 / 92%);
--range-thumb-radius: var(--control-thumb-radius);
--range-thumb-background: var(--control-thumb-background);
--range-thumb-shadow:
inset 0 1px 2px rgb(255 255 255 / 22%), 0 4px 12px rgb(0 0 0 / 30%);
--range-thumb-hover-shadow:
inset 0 1px 2px rgb(255 255 255 / 22%), 0 0 0 4px rgb(var(--control-rgb) / 22%),
0 5px 14px rgb(0 0 0 / 34%);
--range-thumb-hover-transform: var(--control-thumb-hover-transform);
--range-thumb-transform: var(--control-thumb-transform);
--range-thumb-transition:
box-shadow var(--transition-time), height var(--transition-time),
margin-top var(--transition-time), transform var(--transition-time),
width var(--transition-time);
position: relative;
display: grid;
align-items: center;
width: 184px;
height: 46px;
flex: 0 0 184px;
padding: 0 12px;
overflow: hidden;
border: 1px solid rgb(255 255 255 / 14%);
border-radius: 8px;
background: linear-gradient(180deg, rgb(255 255 255 / 9%), rgb(255 255 255 / 4%));
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / 6%),
0 3px 10px rgb(0 0 0 / 18%);
cursor: ew-resize;
transition:
border-color var(--transition-time),
background-color var(--transition-time),
box-shadow var(--transition-time),
transform var(--transition-time);
&:hover {
border-color: rgb(255 255 255 / 24%);
transform: translateY(-2px);
}
&.active {
border-color: rgb(var(--control-rgb) / 72%);
background-color: rgb(var(--control-rgb) / 11%);
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / 10%),
0 0 0 5px rgb(var(--control-rgb) / 28%),
0 6px 15px rgb(0 0 0 / 22%);
}
input[type='range'] {
@include toolbar-range-input();
}
}
> .eraser-size-control {
--control-progress: var(--eraser-progress, 33%);
--control-rgb: 255 140 117;
--control-thumb-background:
linear-gradient(
110deg,
transparent 0 12%,
rgb(255 255 255 / 44%) 13% 20%,
transparent 21% 100%
),
linear-gradient(
90deg,
#ff8fa3 0 52%,
rgb(54 46 51 / 78%) 53% 56%,
#f5eee5 57% 100%
);
--control-thumb-height: calc(21px * var(--eraser-control-scale, 1));
--control-thumb-hover-transform: rotate(-10deg) scale(1.03);
--control-thumb-radius: calc(6px * var(--eraser-control-scale, 1));
--control-thumb-transform: rotate(-10deg);
--control-thumb-width: calc(34px * var(--eraser-control-scale, 1));
}
> .mirror-segment-control {
--control-progress: var(--mirror-progress, 0%);
--control-rgb: 148 233 203;
--control-thumb-background:
radial-gradient(circle, white 0 3px, rgb(9 20 18 / 78%) 3.5px 8px),
repeating-conic-gradient(
from -90deg,
rgb(218 255 241) 0 8deg,
rgb(8 22 19 / 94%) 8deg var(--mirror-angle, 360deg)
);
--control-thumb-height: 44px;
--control-thumb-width: 44px;
}
}
}

View file

@ -0,0 +1,173 @@
@use 'shared' as *;
.toolbar-row {
--toolbar-background-opacity: 0%;
--toolbar-background-strength: 0;
--toolbar-divider-space: clamp(6px, 1.8vw, 14px);
--toolbar-top-max-width: 594px;
--vibe-button-hit-size: 64px;
display: grid;
grid-template-areas:
'previous controls next'
'previous divider next'
'previous buttons next';
grid-template-columns:
var(--vibe-button-hit-size)
minmax(0, var(--toolbar-top-max-width))
var(--vibe-button-hit-size);
align-items: stretch;
justify-content: center;
width: fit-content;
max-width: 100%;
margin: 0 auto;
padding-inline: clamp(8px, 1.4vw, 14px);
column-gap: 0;
row-gap: 0;
border-radius: 12px;
color: rgb(245 250 244 / 92%);
background-color: rgb(5 8 13 / var(--toolbar-background-opacity));
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / calc(var(--toolbar-background-strength) * 16%)),
inset 0 1px 0 rgb(255 255 255 / calc(var(--toolbar-background-strength) * 7%)),
0 14px 34px rgb(0 0 0 / calc(var(--toolbar-background-strength) * 28%));
backdrop-filter: blur(calc(var(--toolbar-background-strength) * 18px))
brightness(calc(1 - var(--toolbar-background-strength) * 0.38))
saturate(calc(1 - var(--toolbar-background-strength) * 0.18));
font-size: 13px;
font-weight: 400;
line-height: 1;
transition:
backdrop-filter var(--transition-time-long),
background-color var(--transition-time-long),
box-shadow var(--transition-time-long);
&::after {
content: '';
grid-area: divider;
align-self: center;
justify-self: center;
width: min(100%, var(--toolbar-top-max-width));
height: 1px;
margin-block: var(--toolbar-divider-space);
background: rgb(255 255 255 / 12%);
}
button {
min-width: 44px;
min-height: 44px;
border: 0;
font: inherit;
cursor: pointer;
@include toolbar-button-transition();
&:disabled {
cursor: progress;
opacity: 0.58;
}
&:focus-visible {
outline: 2px solid white;
outline-offset: 2px;
}
}
> .toolbar-shell {
grid-area: controls;
display: grid;
grid-template-areas: 'swatches';
grid-template-columns: minmax(0, 1fr);
align-items: center;
justify-content: center;
justify-self: center;
width: min(100%, var(--toolbar-top-max-width));
min-width: 0;
padding: 8px 9px;
}
> .vibe-button {
--vibe-button-surface-inset-block: 10px;
--vibe-button-surface-inset-inline: 8px;
--vibe-chevron-size: 22px;
--vibe-chevron-stroke: 4px;
position: relative;
isolation: isolate;
display: grid;
place-items: center;
width: var(--vibe-button-hit-size);
height: auto;
min-height: 72px;
flex: 0 0 auto;
padding: 0;
border-radius: 0;
background: transparent;
color: rgb(255 255 255 / 88%);
font-size: 0;
line-height: 1;
&::after {
content: '';
position: absolute;
z-index: 0;
inset: var(--vibe-button-surface-inset-block)
var(--vibe-button-surface-inset-inline);
border-radius: 8px;
background: rgb(255 255 255 / calc(9% + var(--toolbar-background-strength) * 10%));
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / 18%),
0 8px 18px rgb(0 0 0 / calc(var(--toolbar-background-strength) * 22%));
transition:
background var(--transition-time),
box-shadow var(--transition-time),
opacity var(--transition-time);
}
&::before {
content: '';
position: absolute;
z-index: 1;
top: 50%;
left: 50%;
width: var(--vibe-chevron-size);
height: var(--vibe-chevron-size);
border-color: currentColor;
border-style: solid;
border-width: 0 0 var(--vibe-chevron-stroke) var(--vibe-chevron-stroke);
filter: drop-shadow(0 1px 3px rgb(0 0 0 / 70%));
transform: translate(-35%, -50%) rotate(45deg);
}
&.next-vibe::before {
border-width: var(--vibe-chevron-stroke) var(--vibe-chevron-stroke) 0 0;
transform: translate(-65%, -50%) rotate(45deg);
}
&:hover {
color: white;
}
&:hover::after {
background: color-mix(in srgb, var(--accent-color) 34%, rgb(255 255 255 / 18%));
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / 28%),
0 10px 22px rgb(0 0 0 / calc(var(--toolbar-background-strength) * 30%));
}
&.previous-vibe:hover {
transform: translateX(-2px);
}
&.next-vibe:hover {
transform: translateX(2px);
}
}
> .previous-vibe {
grid-area: previous;
}
> .next-vibe {
grid-area: next;
}
}

View file

@ -0,0 +1,157 @@
@use '../mixins' as *;
.toolbar-row {
@include on-small-screen {
--toolbar-divider-space: 4px;
--toolbar-top-max-width: 329px;
--vibe-button-hit-size: 44px;
grid-template-areas:
'previous controls next'
'. divider .'
'buttons buttons buttons';
width: 100%;
padding-inline: 4px;
column-gap: 0;
row-gap: 0;
> .vibe-button {
--vibe-button-surface-inset-block: 5px;
--vibe-button-surface-inset-inline: 3px;
--vibe-chevron-size: 17px;
--vibe-chevron-stroke: 3px;
width: var(--vibe-button-hit-size);
min-height: 44px;
}
> .toolbar-shell {
padding: 4px;
}
> nav.buttons {
justify-self: stretch;
justify-content: space-between;
gap: clamp(1px, 0.55vw, 2px);
width: auto;
max-width: none;
margin-inline: -4px;
> button {
width: auto;
height: 38px;
flex: 1 1 clamp(28px, 8vw, 38px);
max-width: 38px;
min-height: 38px;
&::after {
width: 17px;
height: 17px;
}
}
> .audio-control {
width: auto;
height: 38px;
flex: 2 1 clamp(58px, 18vw, 118px);
max-width: 118px;
padding-right: clamp(4px, 1.8vw, 9px);
> button {
width: auto;
flex: 1 1 clamp(28px, 8vw, 38px);
min-width: 0;
}
> .volume-control {
height: 38px;
}
}
> .export-status {
flex-basis: 0;
max-width: 0;
text-align: center;
}
}
> .toolbar-shell > .garden-controls {
padding: 2px 4px;
> .swatches {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
justify-items: center;
justify-content: stretch;
width: 100%;
min-width: 0;
min-height: 48px;
flex: 1 1 100%;
padding: 3px 5px;
column-gap: 6px;
row-gap: 6px;
> .color-swatch {
width: 38px;
height: 38px;
min-width: 38px;
min-height: 38px;
grid-column: span 2;
}
> .eraser-size-control,
> .mirror-segment-control {
justify-self: stretch;
width: 100%;
min-width: 0;
height: 38px;
padding: 0 7px;
}
> .eraser-size-control {
grid-column: 1 / span 3;
}
> .mirror-segment-control {
--control-thumb-height: 34px;
--control-thumb-width: 34px;
grid-column: 4 / span 3;
}
}
}
}
}
@media (prefers-reduced-motion: reduce) {
.toolbar-row {
> .vibe-button.previous-vibe:hover,
> .vibe-button.next-vibe:hover,
> .toolbar-shell > .garden-controls > .swatches > .color-swatch:hover,
> .toolbar-shell > .garden-controls > .swatches > .eraser-size-control:hover,
> .toolbar-shell > .garden-controls > .swatches > .mirror-segment-control:hover {
transform: none;
}
> nav.buttons > button:hover::after,
> nav.buttons > .audio-control > button:hover::after {
transform: none;
}
> nav.buttons > .audio-control > .volume-control input[type='range'] {
&::-webkit-slider-thumb:hover {
transform: none;
}
}
> .toolbar-shell > .garden-controls > .swatches {
> .eraser-size-control input[type='range'],
> .mirror-segment-control input[type='range'] {
&::-webkit-slider-thumb:hover {
transform: var(--range-thumb-transform, none);
}
}
}
}
}

View file

@ -0,0 +1,104 @@
$toolbar-icons: (
info: 'info',
full-screen-toggle: 'maximize',
settings: 'settings',
sound: 'sound',
export-4k: 'download',
restart: 'restart',
);
@mixin toolbar-button-transition() {
transition:
background-color var(--transition-time),
border-color var(--transition-time),
color var(--transition-time),
box-shadow var(--transition-time),
opacity var(--transition-time),
transform var(--transition-time);
}
@mixin toolbar-control-surface($background, $hover-background) {
border: 1px solid transparent;
border-radius: 8px;
background: $background;
transition:
border-color var(--transition-time),
background-color var(--transition-time),
box-shadow var(--transition-time),
opacity var(--transition-time);
&:hover {
border-color: rgb(255 255 255 / 10%);
background: $hover-background;
}
}
@mixin toolbar-range-track() {
height: var(--range-track-height);
border: var(--range-track-border, 0);
border-radius: 999px;
background: linear-gradient(
90deg,
var(--range-fill) 0 var(--range-progress),
var(--range-empty) var(--range-progress) 100%
);
box-shadow: var(--range-track-shadow);
cursor: ew-resize;
}
@mixin toolbar-range-thumb() {
width: var(--range-thumb-width);
height: var(--range-thumb-height);
border: var(--range-thumb-border);
border-radius: var(--range-thumb-radius);
background: var(--range-thumb-background);
box-shadow: var(--range-thumb-shadow);
cursor: ew-resize;
transform: var(--range-thumb-transform, none);
}
@mixin toolbar-range-input() {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
appearance: none;
background: transparent;
cursor: ew-resize;
outline: none;
touch-action: pan-y;
&:focus-visible {
border-radius: 8px;
outline: 2px solid white;
outline-offset: var(--range-focus-outline-offset, 2px);
}
&::-webkit-slider-runnable-track {
@include toolbar-range-track();
}
&::-webkit-slider-thumb {
@include toolbar-range-thumb();
margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2);
appearance: none;
transition: var(
--range-thumb-transition,
box-shadow var(--transition-time),
transform var(--transition-time)
);
}
&::-webkit-slider-thumb:hover {
box-shadow: var(--range-thumb-hover-shadow, var(--range-thumb-shadow));
transform: var(--range-thumb-hover-transform, var(--range-thumb-transform, none));
}
&::-moz-range-track {
@include toolbar-range-track();
}
&::-moz-range-thumb {
@include toolbar-range-thumb();
}
}

View file

@ -1,33 +1,8 @@
@use 'mixins' as *;
:root {
--transition-time: 200ms;
--transition-time-long: 350ms;
--line-width: 4px;
--line-height: 1.125rem;
--accent-color: rgb(6.39851188659668, 70.28645324707031, 102.23043060302734);
--very-light-text-color: #ffffff;
--accent-color: rgb(255 93 162);
--main-color: #aaa;
--normal-text-color: #31343f;
--blurred-card-color: transparent;
--blur-radius: 12px;
--special-text-color: var(--accent-color);
--border-radius: 0.6rem;
--large-margin: 4.6rem;
--normal-margin: 2rem;
--small-margin: 1rem;
--shadow: 0 0 5px 2px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.2);
--icon-size: 2.5rem;
--large-icon-size: 3.75rem;
--body-width: min(80%, 60rem);
}
@include on-small-screen {
:root {
--body-width: 90%;
--large-margin: 2.8rem;
--normal-margin: 2rem;
--icon-size: 2rem;
}
}