/*
 * @arraypress/waveform-sounds — default styles.
 *
 * Colour-agnostic, like the rest of the family: every default is derived
 * from `currentColor`, and the "on" states (the selected chip, the playing
 * row's button) are INVERTED — text colour as the fill, the page surface
 * as the ink. White on a dark page, black on a light one, no setup.
 *
 * `--ws-surface` is the page background behind the list. The runtime
 * detects it (and re-reads it when the theme flips) unless you set it;
 * set it yourself for server-rendered pages so the first paint is right.
 * Opt into a brand colour with `--ws-accent` + `--ws-on-accent`.
 *
 * The row canvases read `--ws-wave-color` and `--ws-progress-color` (a
 * canvas can't use CSS, so the runtime resolves them, and re-reads them
 * when the page theme flips).
 */
/* THE ONE RULE for the inverted states: an element whose background is
 * `var(--ws-accent)` never sets its own `color` — its CHILDREN take the
 * ink. `--ws-accent` defaults to `currentColor`, which resolves where it's
 * used (even registered with @property: Chrome keeps the keyword), so a
 * button with `color: ink; background: currentColor` paints ink on ink. */
.waveform-sounds {
    --ws-accent: currentColor;
    /* The ink on an inverted fill: the page surface (set by you, or
     * measured by the runtime), else the INVERSE of the text colour — right
     * with no script at all (light text → near-black ink, and vice versa). */
    --ws-on-accent: var(--ws-surface, rgb(from currentColor calc(255 - r) calc(255 - g) calc(255 - b)));
    --ws-muted: color-mix(in srgb, currentColor 62%, transparent);
    --ws-border: color-mix(in srgb, currentColor 12%, transparent);
    --ws-hover: color-mix(in srgb, currentColor 5%, transparent);
    --ws-current: color-mix(in srgb, var(--ws-accent) 7%, transparent);
    --ws-field: color-mix(in srgb, currentColor 5%, transparent);
    --ws-wave-color: color-mix(in srgb, currentColor 30%, transparent);
    --ws-progress-color: var(--ws-accent);
    --ws-radius: 10px;
    --ws-control-radius: 999px;
    --ws-row-height: 3.25rem;
    --ws-wave-height: 28px;
    --ws-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    container-type: inline-size;
    color: inherit;
    font: inherit;
}
.waveform-sounds *, .waveform-sounds *::before, .waveform-sounds *::after { box-sizing: border-box; }
.waveform-sounds [hidden] { display: none !important; }

.ws-sr {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.ws-icon { width: 1em; height: 1em; fill: currentColor; flex: none; }

/* ── Toolbar ─────────────────────────────────────────────────────────── */
.ws-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.ws-search {
    flex: 1 1 16rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    height: 2.75rem;
    padding: 0 1rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
    background: var(--ws-field);
    color: inherit;
    cursor: text;
}
.ws-search:focus-within { border-color: var(--ws-accent); }
.ws-search-input {
    flex: 1;
    min-width: 0;
    height: 100%;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    outline: none;
}
.ws-search .ws-icon { color: var(--ws-muted); }
.ws-search-input::placeholder { color: var(--ws-muted); }
.ws-search-input::-webkit-search-cancel-button,
.ws-menu-search::-webkit-search-cancel-button {
    -webkit-appearance: none;
    width: 0.9em;
    height: 0.9em;
    background: currentColor;
    opacity: 0.55;
    cursor: pointer;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.4 5 5 6.4 10.6 12 5 17.6 6.4 19l5.6-5.6 5.6 5.6 1.4-1.4-5.6-5.6L19 6.4 17.6 5 12 10.6z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.ws-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
/* ── Dropdowns (type / key / sort) ──────────────────────────────────── */
.ws-menu { position: relative; }
.ws-menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 2.75rem;
    max-width: 16rem;
    padding: 0 0.85rem 0 1rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
    background: var(--ws-field);
    color: inherit;
    font: inherit;
    font-size: 0.9em;
    cursor: pointer;
}
.ws-menu-btn:hover { background: var(--ws-hover); }
.ws-menu-btn[aria-expanded='true'] { border-color: var(--ws-accent); }
.ws-menu-prefix { color: var(--ws-muted); }
.ws-menu-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-menu-chevron { font-size: 1.1em; color: var(--ws-muted); transition: transform 0.15s; }
.ws-menu-btn[aria-expanded='true'] .ws-menu-chevron { transform: rotate(180deg); }
.ws-menu-pop {
    position: absolute;
    top: calc(100% + 0.4rem);
    left: 0;
    z-index: 20;
    width: max-content;
    min-width: max(100%, 14rem);
    max-width: min(22rem, 90vw);
    padding: 0.35rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-radius);
    background: var(--ws-popover-bg, var(--ws-surface, Canvas));
    box-shadow: 0 18px 40px -16px rgba(0, 0, 0, 0.45);
}
.ws-menu--end .ws-menu-pop { left: auto; right: 0; }
.ws-menu-search {
    display: block;
    width: 100%;
    height: 2.4rem;
    margin-bottom: 0.3rem;
    padding: 0 0.75rem;
    border: 1px solid var(--ws-border);
    border-radius: calc(var(--ws-radius) * 0.7);
    background: var(--ws-field);
    color: inherit;
    font: inherit;
    font-size: 0.9em;
    outline: none;
}
.ws-menu-search:focus { border-color: var(--ws-accent); }
.ws-menu-list { list-style: none; margin: 0; padding: 0; max-height: 18rem; overflow-y: auto; outline: none; }
.ws-menu-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border-radius: calc(var(--ws-radius) * 0.6);
    font-size: 0.9em;
    cursor: pointer;
}
.ws-menu-option:hover, .ws-menu-option.is-active { background: var(--ws-hover); }
.ws-menu-option.is-active { outline: 1px solid var(--ws-border); }
.ws-menu-check { visibility: hidden; flex: none; }
.ws-menu-option[aria-selected='true'] { font-weight: 600; }
.ws-menu-option[aria-selected='true'] .ws-menu-check { visibility: visible; }
.ws-menu-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-menu-count { font-family: var(--ws-mono); font-size: 0.85em; color: var(--ws-muted); }
.ws-menu-none { margin: 0; padding: 0.6rem; color: var(--ws-muted); font-size: 0.9em; }

/* ── The BPM menu: a panel with a two-handle range ───────────────────── */
.ws-bpm-pop { width: 17rem; padding: 0.85rem 1rem 0.7rem; }
.ws-bpm-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.6rem; }
.ws-bpm-readout { font-weight: 600; font-variant-numeric: tabular-nums; }
.ws-bpm-clear {
    padding: 0;
    border: 0;
    background: none;
    color: var(--ws-muted);
    font: inherit;
    font-size: 0.85em;
    cursor: pointer;
}
.ws-bpm-clear:hover { color: inherit; text-decoration: underline; }

/* Two native range inputs stacked on one track. The track and the filled
 * span are drawn by the wrapper (--ws-lo / --ws-hi are the handles' 0..1
 * positions, set by the runtime); the inputs contribute only their thumbs.
 * A thumb's centre runs from half a thumb in from each end, hence the
 * calc() on the fill. */
.ws-range {
    --ws-thumb: 18px;
    --ws-lo: 0;
    --ws-hi: 1;
    position: relative;
    height: 1.75rem;
}
.ws-range::before,
.ws-range::after {
    content: '';
    position: absolute;
    top: 50%;
    height: 4px;
    border-radius: 2px;
    transform: translateY(-50%);
}
.ws-range::before { left: 0; right: 0; background: var(--ws-border); }
.ws-range::after {
    left: calc(var(--ws-thumb) / 2 + var(--ws-lo) * (100% - var(--ws-thumb)));
    right: calc(var(--ws-thumb) / 2 + (1 - var(--ws-hi)) * (100% - var(--ws-thumb)));
    background: var(--ws-accent);
    opacity: 0.35;
}
.ws-range.is-active::after { opacity: 1; }
.ws-range-input {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    margin: 0;
    background: none;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}
/* When the handles meet, the lower one goes on top (it's the one that can
 * still move: left). */
.ws-range.is-min-top [data-ws-bpm-min] { z-index: 2; }
.ws-range-input::-webkit-slider-runnable-track { height: 100%; background: none; }
.ws-range-input::-moz-range-track { background: none; }
.ws-range-input::-webkit-slider-thumb {
    width: var(--ws-thumb);
    height: var(--ws-thumb);
    margin-top: calc((1.75rem - var(--ws-thumb)) / 2);
    border: 2px solid var(--ws-surface, Canvas);
    border-radius: 50%;
    background: var(--ws-accent);
    box-shadow: 0 0 0 1px var(--ws-border);
    cursor: grab;
    pointer-events: auto;
    -webkit-appearance: none;
    appearance: none;
}
.ws-range-input::-moz-range-thumb {
    width: var(--ws-thumb);
    height: var(--ws-thumb);
    box-sizing: border-box;
    border: 2px solid var(--ws-surface, Canvas);
    border-radius: 50%;
    background: var(--ws-accent);
    box-shadow: 0 0 0 1px var(--ws-border);
    cursor: grab;
    pointer-events: auto;
}
.ws-range-input:active::-webkit-slider-thumb { cursor: grabbing; }
.ws-range-input:focus-visible { outline: none; }
.ws-range-input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--ws-accent); }
.ws-range-input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--ws-accent); }
.ws-range-ends {
    display: flex;
    justify-content: space-between;
    margin-top: 0.15rem;
    color: var(--ws-muted);
    font-family: var(--ws-mono);
    font-size: 0.75em;
    font-variant-numeric: tabular-nums;
}
.ws-loop {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 2.75rem;
    padding: 0 1rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
    background: none;
    color: inherit;
    font: inherit;
    font-size: 0.9em;
    cursor: pointer;
}
.ws-loop[aria-pressed='true'] { border-color: var(--ws-accent); background: var(--ws-accent); }
.ws-loop[aria-pressed='true'] > * { color: var(--ws-on-accent); }

/* Loops or one-shots: a segmented control, one button pressed. */
.ws-seg {
    display: inline-flex;
    height: 2.75rem;
    padding: 0.25rem;
    gap: 0.15rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
}
.ws-seg-btn {
    padding: 0 0.85rem;
    border: 0;
    border-radius: var(--ws-control-radius);
    background: none;
    color: inherit;
    font: inherit;
    font-size: 0.88em;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s;
}
.ws-seg-btn:hover { background: var(--ws-hover); }
/* On the accent the CHILD takes the inverted ink: the button itself never
 * sets a colour (see the pause icon note at the top). */
.ws-seg-btn[aria-pressed='true'] { background: var(--ws-accent); }
.ws-seg-btn[aria-pressed='true'] > * { color: var(--ws-on-accent); }

.ws-meta { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
.ws-types { display: flex; flex-wrap: wrap; gap: 0.4rem; flex: 1 1 auto; min-width: 0; }
.ws-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 2.25rem;
    padding: 0 0.9rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
    background: none;
    color: inherit;
    font: inherit;
    font-size: 0.88em;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.ws-chip:hover { background: var(--ws-hover); }
.ws-chip[aria-pressed='true'] { border-color: var(--ws-accent); background: var(--ws-accent); }
.ws-chip[aria-pressed='true'] > * { color: var(--ws-on-accent); }
.ws-chip-count { font-family: var(--ws-mono); font-size: 0.85em; opacity: 0.7; }
/* Full ink on the accent: a dimmed count on a saturated fill fails contrast
 * (70% measured 4.04:1 on #ff4f24). */
.ws-chip[aria-pressed='true'] .ws-chip-count { opacity: 1; }
.ws-count { margin: 0 0 0 auto; color: var(--ws-muted); font-size: 0.88em; font-variant-numeric: tabular-nums; }

/* ── Rows ────────────────────────────────────────────────────────────── */
.ws-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--ws-border);
}
.ws-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-height: var(--ws-row-height);
    padding: 0.4rem 0.75rem 0.4rem 0.4rem;
    border-bottom: 1px solid var(--ws-border);
    cursor: pointer;
    transition: background 0.12s;
}
.ws-row:hover { background: var(--ws-hover); }
.ws-row.is-current { background: var(--ws-current); }
.ws-row.is-error .ws-title { text-decoration: line-through; opacity: 0.6; }

.ws-play {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 0;
    border-radius: 999px;
    background: var(--ws-field);
    color: inherit;
    font-size: 0.95rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.ws-row:hover .ws-play { background: color-mix(in srgb, currentColor 12%, transparent); }
.ws-row.is-current .ws-play { background: var(--ws-accent); }
.ws-row.is-current .ws-play > * { color: var(--ws-on-accent); }
.ws-play .ws-icon-pause { display: none; }
.ws-row.is-playing .ws-play .ws-icon-play { display: none; }
.ws-row.is-playing .ws-play .ws-icon-pause { display: block; }
.ws-play:focus-visible,
.ws-chip:focus-visible,
.ws-menu-btn:focus-visible,
.ws-loop:focus-visible,
.ws-seg-btn:focus-visible,
.ws-more:focus-visible,
.ws-clear:focus-visible,
.ws-wave:focus-visible,
.ws-download:focus-visible { outline: 2px solid var(--ws-accent); outline-offset: 2px; }

.ws-cell { min-width: 0; font-size: 0.9em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-title { flex: 1.4 1 9rem; display: flex; align-items: center; gap: 0.4rem; font-weight: 500; }
.ws-title-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* A loop's mark: quiet, beside the name. */
.ws-loop-mark { flex: none; display: inline-flex; color: var(--ws-muted); }
.ws-loop-mark .ws-icon { width: 0.95em; height: 0.95em; }
.ws-type { flex: 1 1 6rem; color: var(--ws-muted); }
.ws-bpm, .ws-key, .ws-duration { flex: none; font-family: var(--ws-mono); font-size: 0.82em; color: var(--ws-muted); font-variant-numeric: tabular-nums; }
.ws-bpm { width: 3.25ch; text-align: right; }
.ws-key { width: 3.5ch; }
.ws-duration { width: 4.5ch; text-align: right; }
.ws-wave {
    flex: 2 1 8rem;
    position: relative;
    height: var(--ws-wave-height);
    min-width: 6rem;
    cursor: pointer;
    /* Let a finger that lands on a waveform still scroll the page: touch
     * seeks on a TAP (the runtime handles it on click), not on press. */
    touch-action: pan-y;
    border-radius: 4px;
}
.ws-canvas { display: block; width: 100%; height: 100%; }
.ws-download {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 999px;
    color: var(--ws-muted);
    font-size: 1.05rem;
    text-decoration: none;
    transition: color 0.15s, background 0.15s;
}
.ws-download:hover { color: inherit; background: var(--ws-hover); }

/* The meta cells are columns of the row on wide lists... */
.ws-cells { display: contents; }

/* ...and on narrow ones (a phone, a sidebar) the row is three lines beside
 * the play button: the full title, then "Bass · 128 · Fm · 0:08", then the
 * waveform. A title is never squeezed by the columns. */
@container (max-width: 560px) {
    .ws-row {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas: "play title dl" "play cells cells" "play wave wave";
        column-gap: 0.85rem;
        row-gap: 0.2rem;
        padding: 0.7rem 0.5rem;
    }
    .ws-play { grid-area: play; align-self: center; }
    .ws-title { grid-area: title; white-space: normal; overflow-wrap: anywhere; }
    .ws-title-text { overflow: visible; }
    .ws-cells { grid-area: cells; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; min-width: 0; }
    .ws-cells > .ws-cell { flex: none; width: auto; text-align: left; font-size: 0.78em; }
    .ws-cells > .ws-cell:empty { display: none; }
    /* A dot only after an earlier cell with something in it: a sound with no
       key must not read "· 0:08". */
    .ws-cells > .ws-cell:not(:empty) ~ .ws-cell:not(:empty)::before { content: '·'; margin-right: 0.5rem; opacity: 0.6; }
    .ws-wave { grid-area: wave; margin-top: 0.35rem; min-width: 0; }
    .ws-download { grid-area: dl; align-self: start; }
}

/* ── Footer bits ─────────────────────────────────────────────────────── */
.ws-empty { margin: 1.5rem 0; color: var(--ws-muted); }
.ws-clear, .ws-more {
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-control-radius);
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.ws-clear { margin-left: 0.5rem; padding: 0.35rem 0.85rem; font-size: 0.88em; }
.ws-more { display: block; margin: 1.25rem auto 0; padding: 0.7rem 1.4rem; font-size: 0.92em; }
.ws-more:hover, .ws-clear:hover { background: var(--ws-hover); }

/* The strip layout: the engine is a full player docked under the list.
 * It stays in place by default; set --ws-strip-position: sticky to keep it
 * at the bottom of the viewport while a long list scrolls past. */
.ws-engine--strip {
    position: var(--ws-strip-position, static);
    bottom: 0;
    margin-top: 1rem;
    padding: 0.75rem;
    border: 1px solid var(--ws-border);
    border-radius: var(--ws-radius);
    /* The page surface (measured, or given), not the system Canvas colour,
       which is white on a dark page that doesn't declare color-scheme. */
    background: var(--ws-strip-bg, var(--ws-surface, Canvas));
    z-index: 1;
}

/* Touch: 44px targets, and 16px inputs (iOS zooms into anything smaller). */
@media (pointer: coarse) {
    .ws-play, .ws-download { width: 2.75rem; height: 2.75rem; }
    .ws-chip { height: 2.5rem; }
    .ws-search-input, .ws-menu-search { font-size: 16px; }
    .ws-range { --ws-thumb: 24px; height: 2.25rem; }
    .ws-range-input::-webkit-slider-thumb { margin-top: calc((2.25rem - var(--ws-thumb)) / 2); }
    .ws-menu-option { padding: 0.75rem 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
    .ws-row, .ws-chip, .ws-play { transition: none; }
}
