/* ===== Background music =====
 *
 * A SEPARATE FILE, ON PURPOSE. Everything else on this site is in styles.css and
 * envelope.css, and the obvious thing would have been to add thirty lines to
 * each. Two reasons not to:
 *
 *   - Those two files were being edited by someone else while this feature was
 *     written. A new file cannot produce a merge conflict in the middle of a
 *     grid definition, and a rule that lands in the wrong half of a conflict is
 *     the kind of bug nobody sees until a phone renders it.
 *   - This is one feature with two ends — a row on the write page and a pill on
 *     the recipient's page — and they have to agree. Keeping them together means
 *     the pair is legible as a pair, the same argument js/music.js makes for the
 *     mapping living beside the player.
 *
 * Loaded AFTER styles.css on both pages, so anything here that shares a
 * specificity with a rule there wins deliberately rather than by accident.
 * Nothing here restyles an existing class; the write-page markup reuses .extra,
 * .attached, .btn-mini and friends unchanged, and only what is genuinely new is
 * below.
 *
 * Variables (--ink, --accent, --line, --accent-wash, --r-sm) come from
 * styles.css's :root and are used rather than re-declared: a second copy of the
 * palette is a second palette.
 */

/* ---------- The write page: the music tile ----------
 *
 * It had a block of its own while it was free, wearing .extras for the frame and
 * .music-block as a hook that set no properties at all. Now that it is part of the
 * ₹99 card it is the first tile INSIDE .extras-grid (see create.html), so it wears
 * .extra like the photo and voice tiles and inherits everything: the frame, the
 * padding, the 1fr middle row that lines all three notes up along the bottom. The
 * .music-block rule and its comment went with the block — nothing was rehomed
 * here, because there was nothing in it.
 */

/* Same slot mechanics as .photo-control — two mutually exclusive states in one
   grid cell, hidden ones contributing no gap. */
.music-control { display: grid; gap: 10px; justify-items: start; }

/* Matches the .extra .photo-control / .voice-control pair in styles.css: the
   tile's middle row is 1fr so that all the tiles' notes line up at the bottom,
   and without this the control stretches down through that space. */
.extra .music-control { align-self: start; }

/* The attached state, borrowing .attached's frame from styles.css and adding
   only what a track needs: a native player the sender can audition with, sized
   the way .voice-done audio is, for the same reason (three browsers draw three
   different heights, and these tiles sit in an equal-height row).

   Native <audio controls> and not the card's own custom bubble, deliberately.
   The sender's job here is to LISTEN and decide, which wants a scrub bar and a
   volume control they already know; the recipient's job is to receive a letter,
   which wants one big button that cannot be mistaken for browser furniture. The
   same split is argued at length around #voiceDone in create.html. */
.attached-music audio {
    display: block;
    width: 100%;
    min-width: 0;
    height: 36px;
}

.attached-music .attached-acts { margin-top: 1px; }

/* The track's name. It is the one piece of text here the sender reads rather
   than acts on, so it gets the tile's normal ink and not the faint note grey. */
.music-name {
    font-size: .78rem;
    line-height: 1.35;
    color: var(--ink);
    min-width: 0;
    overflow-wrap: break-word;
}

/* ---------- The write page: the autoplay checkbox ----------
 *
 * One row, below both attachment tiles, shown whenever there is any audio on the
 * card — the background music OR the sender's own voice note. One checkbox for
 * both, because from the recipient's side there is only one question ("does sound
 * start by itself?") and two checkboxes would invite the sender to answer it
 * twice, differently. The two sounds are either/or, so in practice this is one
 * question about one sound.
 *
 * A real <input type="checkbox">, unstyled apart from the accent colour: the
 * native control brings keyboard support, a label association, a focus ring and
 * an announcement that a hand-rolled div toggle would have to re-earn. accent-color
 * is ignored by browsers that do not know it, which costs a tick in the wrong
 * shade and nothing else.
 */
.auto-row {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: #fff;
}

.auto-row input[type="checkbox"] {
    flex: none;
    width: 17px;
    height: 17px;
    /* Aligns the box with the cap-height of the first line of the label rather
       than the line box, which sits it a couple of pixels low. */
    margin: 1px 0 0;
    accent-color: var(--accent);
}

.auto-label { display: grid; gap: 2px; min-width: 0; cursor: pointer; }
.auto-label b { font-size: .84rem; font-weight: 600; color: var(--ink); }
.auto-label i {
    font-style: normal;
    font-size: .74rem;
    line-height: 1.45;
    color: var(--ink-soft);
}

/* ---------- The recipient's page: the stop control ----------
 *
 * Fixed to the top of the viewport, because the letter it belongs to is still
 * inside the envelope for the first two seconds of playback and a control on the
 * card would be unreachable for exactly as long as it takes to want it. This is
 * also SC 1.4.2 (audio that plays for more than three seconds must have a way to
 * stop it), which is a requirement rather than a nicety.
 *
 * Right, not left: on a phone the left of that strip is where a browser puts its
 * own back affordance and a WhatsApp in-app browser puts its close button.
 *
 * env(safe-area-inset-top) keeps it out of the notch. The fallback is a plain
 * 12px for anything that does not know env(), which is every desktop browser and
 * costs nothing there.
 *
 * z-index sits above the envelope stack (which tops out in the low tens in
 * envelope.css) and below nothing else — the card page has no dialogs.
 */
.music-ctl {
    position: fixed;
    top: calc(12px + env(safe-area-inset-top, 0px));
    right: 12px;
    z-index: 60;

    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 11px 7px 9px;

    font-family: var(--font-body);
    font-size: .74rem;
    font-weight: 500;
    letter-spacing: .01em;
    color: var(--ink);

    /* Reads on a photo, a dark envelope or bare paper. A translucent white with
       a blur is the one treatment that stays legible over all three without
       painting a hard box over the top corner of the card. */
    background: rgba(255, 255, 255, .82);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid rgba(0, 0, 0, .07);
    border-radius: 100px;
    box-shadow: 0 2px 10px rgba(44, 36, 32, .12);
    cursor: pointer;

    /* Fades in with the tap rather than appearing hard, which at the top of the
       screen during the flap animation reads as something breaking. Only the
       opacity animates; a control that slides is a control you have to wait
       for. */
    animation: music-ctl-in .45s ease both;
}

/* The one hidden state. `.hidden` is styles.css's own utility and is already
   display:none, but this element is display:inline-flex and specificity between
   two single classes goes to source order — so it is restated here, after the
   block above, rather than relying on which file loaded last. */
.music-ctl.hidden { display: none; }

@keyframes music-ctl-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* The speaker. Drawn in CSS rather than as an inline SVG so that the mute state
   is a class change on one element instead of two icons swapped in JS — and so
   that card.html does not carry two paths' worth of markup for a 13px glyph.

   The cone is a triangle clipped out of a square; the two arcs are borders on a
   circle with three of its four quarters transparent. */
.music-ico {
    flex: none;
    position: relative;
    width: 14px;
    height: 14px;
    color: var(--accent);
}

.music-ico::before {
    content: "";
    position: absolute;
    left: 0;
    top: 3px;
    width: 6px;
    height: 8px;
    background: currentColor;
    /* box + cone: the speaker body with a wedge opening to the right. */
    clip-path: polygon(0 25%, 50% 25%, 100% 0, 100% 100%, 50% 75%, 0 75%);
}

.music-ico::after {
    content: "";
    position: absolute;
    left: 6px;
    top: 1px;
    width: 11px;
    height: 11px;
    border: 1.5px solid currentColor;
    border-radius: 50%;
    /* Only the right-hand quarter arcs are drawn: the rest of the ring would
       cross the cone. */
    border-color: transparent currentColor transparent transparent;
    /* Two sound waves out of one ring by squashing it: closer to a speaker glyph
       than a full circle and cheaper than a second element. */
    transform: scale(.85, .7);
    opacity: .9;
}

/* Muted: the waves go, and the label carries the meaning. A strike-through bar
   would be more literal and needs a third pseudo-element the button does not
   have — the text next to it already says "Music off", which is unambiguous in a
   way a 14px glyph cannot be. */
.music-ctl:not(.playing) .music-ico { color: var(--ink-faint); }
.music-ctl:not(.playing) .music-ico::after { opacity: 0; }

.music-ctl:not(.playing) { color: var(--ink-soft); }

/* Focus visible, and visible against a translucent pill on any background. */
.music-ctl:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Reduced motion silences the fade, not the music. prefers-reduced-motion is
   about vestibular safety; treating it as a preference about SOUND would be
   inventing a signal the user did not send, and would quietly break the feature
   for everyone whose OS defaults it on. (Headless Chrome does, which is its own
   trap for anyone testing this.) */
@media (prefers-reduced-motion: reduce) {
    .music-ctl { animation: none; }
}
