:root {
    --bg-color-start: white;
    --bg-color-end:   white;
    --fg:             #1a1a1a;
    --fg-shadow:      rgba(255, 255, 255, 0.55);
    --surface:        rgba(250, 250, 250, 0.16);

    --button-color:   #333333;
    --button-text:    #ffffff;
    --accent:         lightblue;

    --ripple-inner:   #FF4136;
    --ripple-outer:   #FFB700;
    --ripple-bg:      #FF4136;

    --loader-color:   #FFF;
    --shadow-width:   0px;
    --ripple-speed:   .5s;
    --ripple-y:       0;
    --ripple-x:       0;

    --panel-backdrop: blur(16px) brightness(1.5) saturate(0.6);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg-color-start: #1a0a26;
        --bg-color-end:   #0d0d1a;
        --fg:             #f0f0f0;
        --fg-shadow:      rgba(0, 0, 0, 0.55);
        --surface:        rgba(255, 255, 255, 0.08);

        --button-color:   #FFB700;
        --button-text:    #1a1a1a;
        --accent:         #4a8aaa;

        --loader-color:   #FFB700;

        --panel-backdrop: blur(16px) brightness(0.5) saturate(0.6);
    }
}

html {
    color-scheme: light dark;
    background-color: var(--bg-color-end);
}

html, body {
    margin: 0;
    font-family: system-ui, sans-serif;
}

body::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(135deg, var(--bg-color-start) 0%, var(--bg-color-end) 100%);
    clip-path: circle(0px at var(--ripple-x) var(--ripple-y));
    transition: clip-path .5s cubic-bezier(0.4, 0, 0.2, 1);
}

main {
    height: 100dvh;
    width: 100vw;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;

    /* Smooth out abrupt filter/transform changes when an effect engages.
       Half-second eases means transitions read as gentle drift rather than
       sudden cuts. */
    transition: filter .6s ease, transform .6s ease;
}

/* =============================================================================
   Video effects — visual counterparts to audio presets. Driven by
   videoEffects.js (setVideoEffect on each onEffectChange). The class names
   here mirror the keys in that module's `videoFx` registry.

   Design rules: no fast strobes, no shakes, no aggressive contrast spikes.
   Everything either holds steady or moves on slow oscillations (≥ 1.2s).
   ============================================================================= */

/* Bitcrush family — gently crushed colour with a touch of structure */
video.fx-crunch   { filter: contrast(1.2) saturate(1.25) brightness(0.93); }
video.fx-lofi     { filter: saturate(0.55) sepia(0.25) contrast(1.05) brightness(0.95); }
video.fx-meltdown {
    filter: hue-rotate(15deg) saturate(1.25) blur(1.5px);
    transform: scale(1.01);
}

/* Delays — soft blur, gentle vertical drift */
video.fx-dub      { filter: blur(3px) brightness(1.08) saturate(1.1); }
video.fx-slapback { filter: brightness(1.06) contrast(1.05); transform: scale(1.005); }
video.fx-vibrato  { animation: fx-vibrato-y 1.4s ease-in-out infinite; }
@keyframes fx-vibrato-y {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(2px); }
}

/* Filter+drive — saturation, slow blur breathing, slow hue+blur drift */
video.fx-distort  { filter: contrast(1.18) saturate(1.25) hue-rotate(6deg) brightness(1.04); }
video.fx-lpwobble { animation: fx-lpwobble-blur 2.4s ease-in-out infinite; }
@keyframes fx-lpwobble-blur {
    0%, 100% { filter: blur(3.5px) brightness(0.88); }
    50%      { filter: blur(0.3px) brightness(1.02); }
}
video.fx-banddrift { animation: fx-banddrift-hue 6s ease-in-out infinite; }
@keyframes fx-banddrift-hue {
    0%, 100% { filter: hue-rotate(-10deg) saturate(1.1) blur(0.5px); }
    50%      { filter: hue-rotate(10deg)  saturate(1.25) blur(1.5px); }
}

/* Gates — JS does the playback stutter. CSS adds a soft cue (slight tint +
   crispness) so it's visually distinct. No flicker. */
video.fx-stutter  { filter: brightness(1.06) contrast(1.08) saturate(1.05); }

/* Reverse — JS drives the time travel; CSS gives a cool desaturated tint. */
video.fx-reverse  { filter: hue-rotate(-30deg) saturate(0.7) brightness(0.95); }

/* Pitch — very subtle scale (transition smooths it) */
video.fx-pitchup   { transform: scale(1.015); }
video.fx-pitchdown { transform: scale(0.985); }

/* Reverbs — soft glow / blur */
video.fx-reverb-medium { filter: blur(1.8px) brightness(1.07) saturate(0.92); }
video.fx-reverb-small  { filter: blur(0.8px) brightness(1.04); }

/* Repeats are wired to playback stutter (tighter loop lengths than gates) —
   they share the .fx-stutter class for the visual cue. No separate rule. */

#hold {
    margin: auto;
    flex: 0 0 auto;

    width: 10em;
    height: 10em;
    border-radius: 50%;
    background: rgba(255, 65, 54, 0.45);
    /*background: rgba(255, 215, 0, 0.45);*/
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    color: var(--fg);

    display: grid;
    place-items: center;
    cursor: pointer;
    z-index: 2;

    transition: transform .15s ease-out,
                background-color .3s ease;
}

#hold:hover  { transform: scale(1.05); }
#hold:active { transform: scale(0.95); }

#hold svg {
    width: 50%;
    height: 50%;
    pointer-events: none;
    overflow: visible;
}

#hold .icon {
    fill: currentColor;
    transition: opacity .2s ease;
}

#hold .icon-mic   { opacity: 1; }
#hold .icon-play  { opacity: 0; }
#hold .icon-pause { opacity: 0; }

body.audio-started #hold .icon-mic  { opacity: 0; }
body.audio-started #hold .icon-play { opacity: 1; }

body.audio-started:has(#audio-toggle:checked) #hold .icon-play  { opacity: 0; }
body.audio-started:has(#audio-toggle:checked) #hold .icon-pause { opacity: 1; }

#hold .icon-mic   { transform-origin: 12px 12px; }
#hold .icon-pause { transform-origin: 12px 12px; }
#hold .icon-play  { transform-origin: 12px 12px; }

.loader {
    width: 48px;
    height: 48px;
    border: 5px solid var(--loader-color);
    border-bottom-color: transparent;
    border-radius: 50%;
    box-sizing: border-box;
    animation: rotation 1s linear infinite;
}

@keyframes rotation {
    to { transform: rotate(360deg); }
}

#panels {
    position: absolute;
    left: 0;
    bottom: 0;
    max-width: min(90vw, 38em);
    box-sizing: border-box;
    padding: 0.75em;
    font-family: monospace;
    font-size: 11px;
    color: var(--fg);
    z-index: 3;
}

@media screen and (min-width: 48em) {
    #panels {
        padding: 1.5em;
    }
    .panel {
        min-width: 22em;
        max-width: 22em;
        padding: 1.5em;
        margin: 0.75em 0;
        border-radius: 0.2em;
    }

    #messages.panel {
        min-width: 100%;
        max-width: 100%;
    }
}

.panel {
    background: var(--surface);
    backdrop-filter: var(--panel-backdrop);
    -webkit-backdrop-filter: var(--panel-backdrop);
    padding: 1em;
    margin: 1em;
    border-radius: 0.2em;
    box-sizing: border-box;

    overflow-x: hidden;
}

.panel summary,
.panel p,
.panel label,
.panel pre,
.panel h3,
.panel li a {
    color: var(--fg);
}

details:open summary {
    margin-block-end: 1em;
}

.panel ul {
    padding: 0;
    list-style: none;
}

.panel li {
    display: flex;
    flex-direction: column;
    gap: 0.4em;
    margin-block: 1em;
}

.panel li > label {
    font-size: 0.85em;
    letter-spacing: 0.04em;
    opacity: 0.7;
}

.privacy-note {
    margin: 0 0 1em;
    font-size: 0.9em;
    line-height: 1.5;
    opacity: 0.65;
}

.panel select {
    appearance: none;
    -webkit-appearance: none;

    width: 100%;
    box-sizing: border-box;
    padding: 0.6em 2.4em 0.6em 1em;
    font: inherit;
    color: var(--fg);
    background-color: var(--surface);
    border: 1px solid color-mix(in srgb, var(--fg) 18%, transparent);
    border-radius: 0.6em;
    cursor: pointer;

    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23888' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.9em center;
    background-size: 0.7em;

    transition: border-color .15s ease, background-color .15s ease;
}

.panel select:hover  { border-color: color-mix(in srgb, var(--fg) 35%, transparent); }
.panel select:focus  { outline: none; border-color: var(--button-color); }

.panel select option {
    background-color: var(--bg-color-end);
    color: var(--fg);
}

#messages {
    max-width: 60em;
}

#messages > div {
    min-width: 0;
}

#messages > div > span:first-child {
    flex-shrink: 0;
    max-width: 40vw;
    overflow: hidden;
    text-overflow: ellipsis;
}

#messages > div > canvas {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 240px;
    width: auto !important;
}

#messages .message {
    margin: 0;
    white-space: pre-wrap;
    word-break: break-all;
}

.panel meter {
    width: 100%;
    height: 8px;
    border-radius: 4px;
    border: none;
    background: none;
    color: var(--button-color);
}

.panel meter::-webkit-meter-bar {
    background: none;
    border-radius: 4px;
    border: none;
}
.panel meter::-webkit-meter-optimum-value      { background: var(--button-color); border-radius: 4px; }
.panel meter::-webkit-meter-suboptimum-value   { background: var(--ripple-outer); border-radius: 4px; }
.panel meter::-webkit-meter-even-less-good-value { background: var(--ripple-inner); border-radius: 4px; }
.panel meter::-moz-meter-bar {
    background: var(--button-color);
    border-radius: 4px;
}

.slider {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 4px;
    background: color-mix(in srgb, var(--fg) 20%, transparent);
    border-radius: 4px;
    outline: none;
    opacity: 0.85;
    transition: opacity .2s ease;
    cursor: pointer;
}

.slider:hover { opacity: 1; }

.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 1.1em;
    height: 1.1em;
    border-radius: 50%;
    background: var(--fg);
    border: 2px solid var(--bg-color-end);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    cursor: pointer;
}

.slider::-moz-range-thumb {
    width: 1.1em;
    height: 1.1em;
    border-radius: 50%;
    background: var(--fg);
    border: 2px solid var(--bg-color-end);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    cursor: pointer;
}
