    /* The way in wears music's colours: its border, words and microphone are windows onto the same
       pale warm field the demo paints music with (10°→55° and back, one cycle per 240 px of screen along a 45° slant
       (a 240 px square tile, the stripes 240/√2 px apart, so a 240 px shift is one seamless cycle) —
       narrower than music's 1400 so the whole band shows across the button and reads as a flow —
       moving 50 px a second, a little under music's 70), in music's hues at full saturation, lit near white (as loud music is) yet still coloured.
       The button's own markup is owner-gated text; only its look is set here. */
    :root { --try-s: 100%; --try-l: 88%; }   /* lit near white: the page is always dark, whatever the system theme */
    #try, #try svg, #live-stats .glow, .live-cap .glow, .live-cap .ic { --try-field: repeating-linear-gradient(135deg, hsl(10 var(--try-s) var(--try-l)) 0.000px, hsl(21 var(--try-s) var(--try-l)) 21.213px, hsl(32 var(--try-s) var(--try-l)) 42.426px, hsl(44 var(--try-s) var(--try-l)) 63.640px, hsl(55 var(--try-s) var(--try-l)) 84.853px, hsl(44 var(--try-s) var(--try-l)) 106.066px, hsl(32 var(--try-s) var(--try-l)) 127.279px, hsl(21 var(--try-s) var(--try-l)) 148.492px, hsl(10 var(--try-s) var(--try-l)) 169.706px); }
    /* #try:hover too: the page's own hover rule sets the background shorthand, which would wipe these */
    #try, #try:hover { color: transparent; border-color: transparent;
           background-image: var(--try-field), linear-gradient(var(--try-fill), var(--try-fill)), linear-gradient(Canvas, Canvas), var(--try-field);
           -webkit-background-clip: text, padding-box, padding-box, border-box; background-clip: text, padding-box, padding-box, border-box;
           background-origin: border-box; background-repeat: repeat, no-repeat, no-repeat, repeat; background-size: 240px 240px, auto, auto, 240px 240px;
           background-position: var(--try-x, 0px) var(--try-y, 0px), 0 0, 0 0, var(--try-x, 0px) var(--try-y, 0px); }
    /* The field is fixed to the screen and slides 50 px a second, but not with background-attachment: fixed: that made
       browsers repaint the button on every scroll frame and its words trailed the page while scrolling. live-demo.js
       places it instead (--try-x/--try-y, the screen's corner and the slide, measured from the button's own box). */
    #try { --try-fill: rgba(127,127,127,.12); } @media (hover: hover) { #try:hover { --try-fill: rgba(127,127,127,.24); } }
    #try { filter: drop-shadow(0 0 2.5px #ffc98255); }   /* the lit things' one halo, as on the flying bird and the lit footer bird */
    /* the microphone: its strokes are transparent like the words, so the field shows through its shape */
    #try svg { background: var(--try-field) var(--try-x, 0px) var(--try-y, 0px) / 240px 240px;
               -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='16' viewBox='0 0 12 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round'%3E%3Crect x='3.5' y='1' width='5' height='9' rx='2.5'/%3E%3Cpath d='M1 7.5a5 5 0 0 0 10 0M6 12.5V15'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
                       mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='16' viewBox='0 0 12 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round'%3E%3Crect x='3.5' y='1' width='5' height='9' rx='2.5'/%3E%3Cpath d='M1 7.5a5 5 0 0 0 10 0M6 12.5V15'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
    /* Firefox paints background-clip:text only when it is the element's single background layer: with the fill and
       the ring layers listed too it fills the whole button with the field. There the words keep the field as one
       layer, the ring is an overlay masked to the 1 px border, and the faint fill is left out (it would sit over the
       words). Chrome and Safari keep the rules above. */
    @supports (-moz-appearance: none) {
      #try, #try:hover { background: var(--try-field) var(--try-x, 0px) var(--try-y, 0px) / 240px 240px border-box; -webkit-background-clip: text; background-clip: text; }
      #try::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; pointer-events: none;
                     background: var(--try-field) var(--try-x, 0px) var(--try-y, 0px) / 240px 240px;
                     mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
    }
    #live { position: fixed; inset: 0; z-index: 20; display: flex; flex-direction: column; align-items: center;
            background: Canvas; color: CanvasText;
            font: 15px/1.45 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; opacity: 0; transition: opacity .4s; }
    /* One narrow column, the width of the page's own text; below that width the margins simply run
       out and the timeline goes edge to edge. border-box or the padding lands OUTSIDE the 100% and
       a 375 px phone gets 407 px children with the ✕ hanging off the right edge (measured). */
    #live > * { width: 100%; max-width: 46rem; box-sizing: border-box; }
    #live[hidden] { display: none; }
    #live.on { opacity: 1; }
    #live-bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; column-gap: 12px; padding: 12px 12px; }
    /* a line arriving fades in, quickly; lines rebuilt (a view switch, a relabel) just appear */
    @keyframes lv-in { from { opacity: 0; } } .lv-new { animation: lv-in .2s ease-out; }
    @media (prefers-reduced-motion: reduce) { .lv-new { animation: none; } }
    .lv-off { opacity: 0 !important; pointer-events: none; } #live-view, #live-stats { transition: opacity .2s; } #live-stats.lv-slow { transition-duration: 1s; }
    #live-view { margin-left: 0; } #live-close { margin-right: -8px; }   /* the toggle's own edge sits on the content edge */
    #live-view { justify-self: start; display: flex; align-items: center; gap: 2px; font-family: var(--mono); font-size: 14px; }
    #live-view button { font: inherit; color: inherit; background: none; border: none; border-radius: 3px; padding: 3px 7px; opacity: .45; cursor: pointer; line-height: 1; }
    /* one toggle: tap anywhere on it to switch; the current view's half is lit */
    #live-toggle { display: flex; align-items: center; padding: 2px !important; opacity: 1 !important; border-radius: 5px !important;
                   background: rgba(127,127,127,.10) !important; }
    #live-toggle span { display: flex; align-items: center; height: 20px; padding: 0 7px; border-radius: 3px; opacity: .45; transition: opacity .2s, background .2s; }
    #live-toggle span.on { opacity: 1; background: rgba(127,127,127,.22); }
    #live-toggle svg { display: block; } #live-toggle span[data-v=json] { font-size: 15px; font-weight: 600; letter-spacing: 1.5px; }
    #live-dl { margin-left: 6px; align-self: center; line-height: 0; } #live-dl svg { display: block; } @media (hover: hover) { #live-dl:hover { opacity: 1; } }
    #live-timer { display: flex; align-items: baseline; gap: 10px; justify-self: center; }
    #live-dot { align-self: center; width: 10px; height: 10px; border-radius: 50%; background: currentColor; opacity: .25; }
    #live-dot.on { background: #ff3b30; animation: live-pulse 1.4s ease-in-out infinite; }
    @keyframes live-pulse { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
    @media (prefers-reduced-motion: reduce) { #live-dot.on { animation: none; opacity: .9; } #live { transition: none; } }
    #live-clock { font-family: var(--mono); font-size: 18px; }
    /* what the stream has billed so far */
    #live-timer .w { font-family: var(--mono); font-size: 14px; opacity: .4; margin: 0 -4px; } #live-timer .sl { font-size: 18px; margin: 0; }
    /* notes: what the page itself has to say, as lines among the captions and messages — faint, or
       standing out when something went wrong; never in the downloads */
    .live-cap.note, .live-msg.note { font-family: var(--mono); font-size: 13px; opacity: .6; }
    .live-cap.note .t { opacity: .7; }
    .live-cap.note.err, .live-msg.note.err { opacity: 1; color: #ff6b6b; }
    #live-close { justify-self: end; align-self: center; font: inherit; font-size: 19px; line-height: 1; padding: 2px 8px; background: none; border: none; color: inherit; opacity: .55; cursor: pointer; }
    @media (hover: hover) { #live-close:hover { opacity: 1; } }
    #live-caps { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 2px;
                 padding: 12px 12px 26px; overflow-y: auto; overscroll-behavior: contain;
                 mask-image: linear-gradient(to bottom, transparent 0, black 1.4em, black calc(100% - 1.4em), transparent 100%); scrollbar-width: none; }
    #live-caps::-webkit-scrollbar { display: none; }
    /* The talk rises from the timeline and fills upward; auto margin, not justify-content, or the
       scrollback above becomes unreachable. Nothing fades: alpha on a word means confidence, only. */
    /* Nothing fades: confidence is the only thing the alpha of a word means. */
    .live-cap { display: grid; grid-template-columns: 42px 1fr; gap: 10px; align-items: baseline;
                font-size: 20px; line-height: 1.4; padding: 2px 6px; margin: 0 -6px; border-radius: 3px; }
    .live-cap .t { font-family: var(--mono); font-size: 11px; opacity: .4; text-align: left; }
    .live-cap.ev .evx { font-style: italic; }   /* an event's row in the words' own size and strength (a confident word's), set apart by its italic */
    .live-cap.ev .em { font-size: .8em; }    /* and its emoji a size below that */
    .live-cap.ev .em { font-style: normal; }   /* the row's italic would slant the emoji too (a browser skews a glyph it has no italic of): upright */
    /* Music, vocals and bird rows wear the page's one glow, as their lines over the waveform do: the field and halo of
       Try it live, slid from script (--glow-x) on the button's clock, brighter where the audio is louder, as on their lines. Words show it through their letters, the icon
       (flat, in place of an emoji) through its shape, as the button's microphone does. */
    .live-cap .glow, .live-cap .ic { --try-l: var(--gl, 88%); }   /* lit as the row's own line is (live-demo.js rowLight, --gl on the row) */
    .live-cap .glow { color: transparent; background: var(--try-field) var(--glow-x, 0px) 0 / 240px 240px fixed;
                      -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 0 2.5px #ffc98255); }
    .live-cap .ic { display: inline-block; width: 1.05em; height: 1.05em; vertical-align: middle; position: relative; top: -.1em;
                    background: var(--try-field) var(--glow-x, 0px) 0 / 240px 240px fixed;
                    -webkit-mask: var(--ic) center / contain no-repeat; mask: var(--ic) center / contain no-repeat; }
    .ic-music { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18V5l12-2v13'/%3E%3Ccircle cx='6' cy='18' r='3' fill='black'/%3E%3Ccircle cx='18' cy='16' r='3' fill='black'/%3E%3C/svg%3E"); }
    .ic-vocals { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='g'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M12.6 4.4l7 7' stroke='black' stroke-width='1.3'/%3E%3C/mask%3E%3Ccircle cx='15.5' cy='8.5' r='5.5' mask='url(%23g)'/%3E%3Cpath d='M11 13 4.5 19.5' stroke='black' stroke-width='3.6' stroke-linecap='round'/%3E%3C/svg%3E"); }
    .ic-bird { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-19.24 -23.54 51.3 51.3' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M0 0 L-12.03 -36.64' stroke-width='3.68' stroke-opacity='.55'/%3E%3Cpath d='M0 0 L-25.24 -25.84' stroke-width='3.68'/%3E%3Cpath d='M0 0 C9.7 2.77 6.89 13.2 -3.59 13.27' stroke-width='4'/%3E%3Cpath d='M-3.59 13.27 L-11.05 21.65 L-7.59 9.36' stroke-width='4'/%3E%3Cpath d='M0 0 C-3.14 -12.25 6.18 -16.08 12.52 -5.93' stroke-width='4'/%3E%3Cpath d='M12.52 -5.93 L27.77 -9.31' stroke-width='4'/%3E%3C/svg%3E"); width: 1.25em; height: 1.25em; }   /* the mark's box has room around the bird */
    .live-who { font-family: var(--mono); font-size: 13px; margin: 6px 0 4px 52px; padding-top: 10px; position: relative; }
    .live-who::before { content: ''; position: absolute; top: 0; left: -52px; right: -6px; border-top: 1px solid rgba(127,127,127,.18); }   /* as far above the name's letters as they are above the caption's (the caption's line height adds ~6 px) */
    /* a music row keeps the caption grid (so its time sits in the time column), its words in mono */
    /* Music, wherever it is drawn, is a window onto ONE pale rainbow fixed to the screen that flows
       slowly sideways (fixed attachment: every window shows the part of the field behind it; the
       canvas computes the same field). Brightness = how loud the music is right now. */
    #live { --rb-x: 0px; --ml: 80%; }
    .mu { color: transparent; -webkit-background-clip: text; background-clip: text; background-attachment: fixed;
          background-image: linear-gradient(90deg, hsl(10 80% var(--ml)), hsl(21 80% var(--ml)), hsl(32 80% var(--ml)), hsl(44 80% var(--ml)), hsl(55 80% var(--ml)), hsl(44 80% var(--ml)), hsl(32 80% var(--ml)), hsl(21 80% var(--ml)), hsl(10 80% var(--ml)));
          background-size: 1400px 100%; background-position: var(--rb-x) 0; }
    .sid.mu { color: transparent; background-image: linear-gradient(90deg, hsl(10 80% var(--ml)), hsl(21 80% var(--ml)), hsl(32 80% var(--ml)), hsl(44 80% var(--ml)), hsl(55 80% var(--ml)), hsl(44 80% var(--ml)), hsl(32 80% var(--ml)), hsl(21 80% var(--ml)), hsl(10 80% var(--ml))), linear-gradient(rgba(127,127,127,.24), rgba(127,127,127,.24));
              -webkit-background-clip: text, padding-box; background-clip: text, padding-box; background-attachment: fixed, scroll;
              background-size: 1400px 100%, auto; background-position: var(--rb-x) 0, 0 0; background-repeat: repeat, no-repeat; }
    /* A caption and the stretch of audio it came from light up together, whichever one you point at. */
    .live-cap.hot { background: rgba(127,127,127,.04); } .live-cap:hover { background: rgba(127,127,127,.16); }
    .live-hint { opacity: .55; font-size: 17px; text-align: center; margin: auto 0; line-height: 1.5; }
    .live-hint.live-quiet { margin: 18px 0 6px; }   /* under the captions, not centred in the field */
    .live-hint small { font-size: 14px; }
    .live-hint a { color: inherit; }
    #live-timeline { position: relative; padding-top: 14px; user-select: none; }
    #live-timeline canvas { display: block; width: 100%; }
    #live-axis { height: 28px; } #live-wave { height: calc(130px + var(--lanes, 0) * 5px); }   /* 5 = LANE; --lanes (the lanes beyond the two main lines) is set on #live-timeline */
    @media (max-width: 600px) { #live-wave { height: calc(84px + var(--lanes, 0) * 5px); } .live-cap { font-size: 18px; }
                                
    }
    #live-playhead { position: absolute; top: 0; bottom: 0; width: 1px; background: currentColor; opacity: .7; pointer-events: none; }
    #live-timeline { padding-bottom: 8px; }
    /* the running counters: under the timeline, left-aligned, refreshed once a second */
    #live-stats { font-family: var(--mono); font-size: 11px; line-height: 1.7; padding: 12px 12px 5px;
                  display: grid; grid-template-columns: repeat(3, auto); justify-content: center; column-gap: 12px; }
    #live-stats span { white-space: nowrap; opacity: .85; } #live-stats .dim { opacity: .5; }
    #live-stats .n { text-align: right; } #live-stats .traffic { grid-column: 1 / -1; text-align: center; }   /* numbers right-aligned in their column, so digits line up */
    /* the music row wears the page's one glow, as bright as the caption rows': the field and halo of Try it live and the birds, slid
       from script (--glow-x) on page time, the button's clock, so it shows the colour they show at the same screen spot */
    #live-stats .glow { --try-l: var(--gl-stats, 88%); }   /* lit as the music rows are (live-demo.js --gl-stats) */
    #live-stats .glow { color: transparent; background: var(--try-field) var(--glow-x, 0px) 0 / 240px 240px fixed;
                        -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 0 2.5px #ffc98255); }
    @media (max-width: 600px) { #live-timeline { width: calc(100% - 20px); } #live-stats { padding: 12px 10px 4px; } }
    /* unfolded, the first line of the stats starts where the current-time line ends: its text's top on that level (measured: 16.5 px
       below it before = the 12 px padding + 4.5 px of line box above the letters); the ruler ends 8 px above that level, clear of it */
    #live-timeline:not(.mini) + #live-stats { padding-top: 0; margin-top: -4.5px; }
    /* microphone sensitivity: upright, in the gutter right of the current-time line */
    #live-gain { position: absolute; right: 0; top: 4px; bottom: 10px; width: 48px; display: flex; flex-direction: column;
                 align-items: center; gap: 4px; font-family: var(--mono); font-size: 10px; opacity: .55; }
    #live-gain input { writing-mode: vertical-lr; direction: rtl; flex: 1; min-height: 0; width: 22px; margin: 0; }
    /* both sliders drawn like the page's other lines: a hairline and a small square */
    #live-gain input { -webkit-appearance: none; appearance: none; cursor: pointer; }
    #live-gain input::-webkit-slider-runnable-track { width: 2px; background: none; }
    /* its hairline is the input's own background: bright below the knob, dimmer above */
    #live-gain input { background: center / 2px 100% no-repeat; }
    #live-gain input::-webkit-slider-thumb {
      -webkit-appearance: none; width: 14px; height: 14px; border-radius: 0; background: currentColor; border: none; }
    #live-gain input::-webkit-slider-thumb { margin-left: -6px; }
    #live-gain input::-moz-range-track { background: currentColor; border: none; }
    #live-gain input::-moz-range-track { width: 2px; background: none; }
    #live-gain input::-moz-range-thumb { width: 14px; height: 14px; border-radius: 0; background: currentColor; border: none; }
    @media (hover: hover) { #live-gain:hover { opacity: 1; } }
    /* the switch that folds the waveform away (more room for the captions): at the top of the gutter, the slider below it */
    #live-mini { position: absolute; right: 0; top: 2px; width: 48px; height: 18px; padding: 0;
                  display: flex; align-items: center; justify-content: center; background: none; border: none; color: inherit;
                  opacity: .55; cursor: pointer; }   /* as the controls around it: the slider, its labels, the ✕ */
    #live-mini svg { display: block; } #live-gain { top: 30px; }
    /* a short rule under the switch, between it and the slider's "mic", so the two read as two controls */
    #live-timeline:not(.mini) #live-mini::after { content: ''; position: absolute; left: 12px; right: 12px; bottom: -5px;
                                                 border-top: 1px solid currentColor; opacity: 1; }
    @media (hover: hover) { #live-mini:hover { opacity: 1; } }
    /* folded: a strip of the audio level with the switch (and the current-time line across it); the captions (flex: 1) take the rest */
    #live-timeline.mini { padding-top: 2px; padding-bottom: 2px; } #live-timeline.mini #live-wave { height: 18px; }
    #live-timeline.mini #live-axis, #live-timeline.mini #live-gain { display: none; }
    #live-gain.held { opacity: 1; }   /* bright while held or dragged, not after the finger lifts */
    /* unfolded, the gutter's controls span the current-time line exactly: the arrow's stroke starts at its top
       (the path's top is 3.5 of the icon's 12 px, less half the 1.75 stroke) and the dB figure's baseline sits on its bottom */
    #live-timeline:not(.mini) #live-mini { top: 0; align-items: flex-start; }
    #live-timeline:not(.mini) #live-mini svg { margin-top: -2.625px; }
    #live-timeline:not(.mini) #live-gain { top: 17.375px; bottom: 0; }
    #live-timeline:not(.mini) #live-gain input { margin-top: -2.7px; }   /* "mic" 2 px higher, and the slider reaches up until its two gaps (to "mic", to the dB figure) are both 4.9 px */   /* "mic" stays 5 px under the rule, as it always was: the slider takes the room */
    /* what sits below the arrow moves up with it, so the slider is as long as it can be
       and the slider is the longer for it; the switch keeps its 18 px hit area, only its rule moves */
    #live-timeline:not(.mini) #live-mini::after { bottom: 3.625px; }   /* the rule 3 px closer to the arrow: stroke -> rule 7.6 px (was 10.6) */
    #live-timeline:not(.mini) #live-gain .v { line-height: 10px; margin-bottom: var(--gain-v-drop, 0px); }
    /* Portrait only. A phone on its side keeps the bar — never trap the visitor without the ✕ —
       and trades the captions and the timeline for one line. Bounded by pointer:coarse so a short
       desktop window is left alone. */
    #live-json { flex: 1; min-height: 0; margin: 0; padding: 12px 12px 26px; overflow-y: auto; overscroll-behavior: contain;
                 display: flex; flex-direction: column; gap: 0; font: 12px/1.5 var(--mono);
                 scrollbar-width: none; mask-image: linear-gradient(to bottom, transparent 0, black 1.4em, black calc(100% - 1.4em), transparent 100%); }
    .sid { padding: 0 4px; border-radius: 3px; background: rgba(127,127,127,.24); font-weight: 600; }
    .live-msg { display: grid; grid-template-columns: 42px 1fr; gap: 10px; align-items: baseline; }
    .live-msg .t { font-size: 11px; opacity: .4; text-align: left; }
    .live-msg summary { list-style: none; cursor: pointer; opacity: .85; }
    .live-msg summary::-webkit-details-marker { display: none; }
    .live-msg summary::after { content: ' ▸'; opacity: .45; }
    .live-msg details[open] summary::after { content: ' ▾'; }
    .live-msg summary:hover { opacity: 1; }
    .live-msg pre { margin: 4px 0 2px; padding: 0 0 0 1.2em; background: none; border-radius: 0; font: inherit; opacity: .7;
                    white-space: pre-wrap; word-break: break-all; }
    .live-msg > div { opacity: .85; }
    .live-msg { padding: 6.5px 6px; margin: 0 -6px; }   /* padding, not gap: neighbours' highlights touch, no flicker between them */
    .live-msg.faint summary { opacity: .6; } .live-msg.fainter summary { opacity: .42; }             /* stats set back when closed; opened it reads like the rest */
    .live-msg.hot { background: rgba(127,127,127,.04); } .live-msg:hover { background: rgba(127,127,127,.16); }
    #live-json::-webkit-scrollbar { display: none; }
    #live-json { background: none; border-radius: 0; }       /* not the page's code-block look */
    #live-caps[hidden], #live-json[hidden] { display: none; }
    #live-rotate { display: none; }
    @media (orientation: landscape) and (max-height: 30rem) and (pointer: coarse) {
      #live-caps, #live-json, #live-timeline { display: none; }
      #live-rotate { display: block; margin: auto; padding: 0 1.25rem; text-align: center;
                     opacity: .6; font-size: 17px; line-height: 1.5; }
    }
