/* =============================================================================
   styles.css — the turntable's own sheet.

   Tokens only. Every colour here is a var() that assets/css/site.css defines
   and assets/css/dark.css redefines, so this one file serves both editions and
   there is nothing to keep in step. A literal colour in this file is a bug in
   the dark edition that the paper edition cannot show you.

   Two house rules are load-bearing here and both were paid for elsewhere:

     * --accent is an INK, never a large fill. Anything that has to BE the
       accent colour takes --accent-fill with --on-accent on top of it.
     * Nothing may make the document wider than the viewport. Every grid track
       below is minmax(0, 1fr) rather than 1fr, because a 1fr track grows to
       min-content and one unwrappable row would then set the width of the
       whole document and carry every fixed element off the side of the phone
       with it.
   ========================================================================== */

.lb-deck { display: grid; gap: 1.15rem; margin-top: 1.6rem; }

/* ------------------------------------------------------------- the tracks */
.lb-tracks {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: .55rem;
}
/* THE CARD IS THE BOX; THE BUTTON IS ITS HEAD.
   The border used to be on .lb-track — the <button> — so everything else
   belonging to a record (share, mixer, transport, EQ) hung underneath it as
   loose rows on the page ground. Four stacked strips under a bordered
   rectangle read as four separate things that happen to be near each other,
   and on a phone the reader cannot tell which rows belong to which record.

   A CONTROL STILL CANNOT LIVE INSIDE A <button>, which is why the head is not
   simply made bigger: nested interactive elements are invalid and the inner
   ones stop being reachable. So the BORDER MOVES OUT to .lb-card, the button
   keeps doing exactly what it did, and every row is inside the same box. */
.lb-track {
    display: grid; gap: .1rem; min-width: 0;
    font: inherit; text-align: left; cursor: pointer;
    padding: .8rem .9rem .55rem;
    border: 0; border-radius: 0;
    background: transparent; color: var(--ink);
    transition: background .2s var(--ease);
}
.lb-track:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.lb-track b { font-size: .95rem; font-weight: 600; letter-spacing: -.015em; }
.lb-track__b { font-size: .72rem; color: var(--ink-55); letter-spacing: .1em; text-transform: uppercase; }
.lb-track__d {
    font-size: .78rem; color: var(--ink-55);
    font-variant-numeric: tabular-nums; margin-top: .15rem;
}
.lb-track[aria-pressed="true"] b { text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------- the load bar */
.lb-bar {
    --p: 0%;
    position: relative; margin: 0; padding: .55rem .7rem;
    border: 1px solid var(--line); border-radius: 9px;
    background: var(--tint); overflow: hidden;
    font-size: .78rem; color: var(--ink-55);
}
.lb-bar[hidden] { display: none; }
.lb-bar i {
    position: absolute; inset: 0 auto 0 0; width: var(--p);
    background: var(--accent-fill); opacity: .22;
    transition: width .15s linear;
}
@media (prefers-reduced-motion: reduce) { .lb-bar i { transition: none; } }
.lb-bar span { position: relative; }

.lb-note { margin: 0; font-size: .82rem; color: var(--taken); }
.lb-note:empty { display: none; }

/* ------------------------------------------------------------- the stage */
.lb-stage {
    display: grid;
    /* minmax(0, 1fr) on the right-hand track: the waveform is a canvas with no
       intrinsic width and the times line is a row that would rather not wrap. */
    grid-template-columns: 190px minmax(0, 1fr);
    gap: 1.1rem; align-items: center;
}
.lb-stage__r { display: grid; gap: .55rem; min-width: 0; }

.lb-platter {
    display: block; width: 190px; height: 190px;
    /* the browser must not claim the gesture: without this a drag on the disc
       scrolls the page on every touch device there is */
    touch-action: none;
    cursor: grab; border-radius: 50%;
    background: var(--paper);
    border: 1px solid var(--line);
    -webkit-user-select: none; user-select: none;
}
.lb-platter.is-held { cursor: grabbing; }
.lb-platter:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.lb-now { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; }
.lb-now b { font-size: 1.05rem; font-weight: 600; letter-spacing: -.02em; }
.lb-now span { font-size: .76rem; color: var(--ink-55); }

.lb-wave {
    display: block; width: 100%; height: 104px;
    touch-action: none; cursor: text;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--paper);
}

.lb-times {
    margin: 0; display: flex; flex-wrap: wrap; gap: .35rem .9rem;
    align-items: baseline;
    font-size: .8rem; color: var(--ink-55);
    font-variant-numeric: tabular-nums;
}
.lb-times__t { color: var(--ink); font-weight: 600; }
.lb-times__m { margin-right: auto; }
.lb-times b { color: var(--ink); font-weight: 600; }

@media (max-width: 44rem) {
    .lb-stage { grid-template-columns: minmax(0, 1fr); justify-items: center; }
    .lb-stage__r { width: 100%; }
    .lb-platter { width: min(230px, 62vw); height: min(230px, 62vw); }
    .lb-times__m { margin-right: 0; flex-basis: 100%; order: 3; }
}

/* ---------------------------------------------------------- the transport */
.run .btn--go { flex: 0 0 auto; min-width: 8rem; }
.lb-brakeb[aria-pressed="true"] {
    background: var(--accent-fill); border-color: var(--accent); color: var(--on-accent);
}
.lb-brakeb { touch-action: none; -webkit-user-select: none; user-select: none; }
.lb-rateout {
    font-size: .78rem; color: var(--ink-55);
    font-variant-numeric: tabular-nums; letter-spacing: .04em;
}
.lb-rateout b { color: var(--ink); font-weight: 600; }
.run__kbd { margin-left: auto; }
@media (max-width: 46rem) {
    .run__kbd { margin-left: 0; flex-basis: 100%; }
}

/* -------------------------------------------------------------- the dials
   16px is the floor on any control this site ships: below it iOS Safari zooms
   the page on focus and carries the fixed header off the screen with it. A
   range input has no text, but the reset beside it is a button with words in
   it and it sits in the same row. */
.lb-zero {
    font: inherit; font-size: .76rem; cursor: pointer;
    padding: .1rem .45rem; margin-left: .3rem;
    border: 1px solid var(--line); border-radius: 6px;
    background: transparent; color: var(--ink-55);
    transition: border-color .2s var(--ease), color .2s var(--ease);
}
.lb-zero:hover { border-color: var(--ink); color: var(--ink); }
.lb-zero:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.dial input[type="range"] { min-height: 24px; touch-action: pan-y; }

/* AND ON A FINGER THEY ARE 44px. The note above raised the tap-target question
   for .lb-zero and then answered a different one: 16px is the floor for TEXT,
   because below it iOS Safari zooms on focus, but a target is measured in the
   area a fingertip has to land in. The rules above make .lb-zero .76rem type
   in .1rem of padding, which is 25px tall, and pin the ranges at 24px — every
   control on the deck at little over half the 44px minimum. Measured at
   360x800 with pointer: coarse after this block, they are 94x44, 100x44 and
   320x44, with the page still 360 wide and nothing overflowing it.

   Gated on the pointer and not on the width, because "narrow" is a window
   somebody dragged and "coarse" is a hand. The height is bought with padding
   rather than font-size, so the type stays exactly as quiet as it was, and the
   range keeps its thin track — the input box grows around it, which is what
   makes the slider easy to grab without making it look like a scrollbar. */
@media (hover: none) and (pointer: coarse) {
    .lb-zero {
        min-height: 44px;
        padding: .1rem .7rem;
        display: inline-flex; align-items: center;
    }
    .dial input[type="range"] { min-height: 44px; }
}

/* The two honest lines under the console. The engine line is the one the brief
   demands: if this browser gave us the fallback, the page says so in words
   rather than presenting a dead platter. */
.lb-engine { font-variant-numeric: tabular-nums; }
.lb-engine[data-worklet="0"] { color: var(--unsure); }
.lb-engine[data-worklet="1"] { color: var(--free); }

/* ------------------------------------------------------- the share row
   A track card is a <button>, and a button cannot contain another one — so the
   card is a wrapper and the share controls sit beneath it rather than inside.
   Quiet by design: the card is the thing you press to play, and these two are
   for afterwards. */
.lb-card {
    display: flex; flex-direction: column; min-width: 0;
    border: 1px solid var(--line); border-radius: 12px;
    background: var(--paper); overflow: hidden;
    transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.lb-card:hover { border-color: var(--ink); }
/* The chosen record, marked on the BOX rather than the button — :has() is how
   a wrapper follows the state of the control inside it, and this estate
   already leans on it (see the popped clock board in clockwork). */
.lb-card:has(.lb-track[aria-pressed="true"]) {
    border-color: var(--ink);
    box-shadow: inset 0 0 0 1px var(--ink);
}
.lb-card:has(.lb-track[aria-pressed="true"]) .lb-track { background: var(--tint); }
.lb-card .lb-track { width: 100%; }

/* Every row inside the card shares the head's gutter, so the controls line up
   under the title rather than floating at the box's edge. */
.lb-card .lb-share,
.lb-card .lb-track__ctl,
.lb-card .lb-ops { padding-inline: .7rem; }
.lb-card .lb-ops { padding-bottom: .6rem; }

/* --------------------------------------------------------- your own record */
/* The row that reaches the loader. It sits between the shelf and the progress
   bar because that is the order it happens in: choose a record, watch it
   arrive, then play it. */
.lb-load { margin-top: .6rem; }
.lb-load__r {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
.lb-load__b {
    font: inherit; font-size: .78rem; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase;
    padding: .52rem .95rem; border-radius: 999px;
    border: 1px solid var(--line); background: transparent; color: var(--ink-77);
    cursor: pointer;
    transition: border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease);
}
.lb-load__b:hover { border-color: var(--ink); color: var(--ink); }
.lb-load__b:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lb-load__or { font-size: .78rem; color: var(--ink-55); }
.lb-load__u {
    flex: 1 1 15rem; min-width: 0;
    font: inherit;
    /* 16px on a touch screen or iOS Safari zooms the page on focus and carries
       the deck off to one side. */
    font-size: 16px;
    padding: .5rem .8rem; border-radius: 999px;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink);
}
.lb-load__u:focus { outline: none; border-color: var(--ink); }
.lb-load__n {
    margin: .4rem 0 0; font-size: .74rem; line-height: 1.45; color: var(--ink-55);
}
.lb-load__n b { color: var(--ink); font-weight: 600; }

/* The deck lights up while a file is over it. */
.lb-deck.is-drop { outline: 2px dashed var(--accent); outline-offset: 6px; }

@media (max-width: 560px) {
    .lb-load__or { display: none; }
    .lb-load__u { flex: 1 1 100%; }
}

/* A refusal has to read as one. --accent is the only warm colour this page
   has and it is defined in both editions, so this needs no dark cut. */
.lb-load__n.is-warn { color: var(--ink); }
.lb-load__n.is-warn b { color: var(--accent); }

/* ------------------------------------------------------------ EQ and scope */
.lb-instr {
    position: relative;
    display: grid; gap: .75rem; margin-top: .75rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    align-items: start;
}
/* minmax(0, …) on both, or one unwrappable row inside either column sets the
   track width and the whole deck grows sideways with it. */
@media (max-width: 780px) {
    .lb-instr { grid-template-columns: minmax(0, 1fr); }
}

.lb-eq {
    display: grid; gap: .4rem;
    padding: .65rem .75rem; border: 1px solid var(--line); border-radius: 12px;
    background: var(--tint);
}
.lb-eq__b { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 3.9rem; align-items: center; gap: .45rem; }
.lb-eq__l { font-size: .68rem; font-weight: 700; letter-spacing: .12em; color: var(--ink-55); }
.lb-eq__s { width: 100%; }
.lb-eq__v {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .74rem; color: var(--ink-77); text-align: right;
}
.lb-eq__flat {
    justify-self: start; margin-top: .1rem;
    font: inherit; font-size: .68rem; font-weight: 700; letter-spacing: .1em;
    padding: .34rem .8rem; border-radius: 999px;
    border: 1px solid var(--line); background: transparent; color: var(--ink-55);
    cursor: pointer;
}
.lb-eq__flat:hover { border-color: var(--ink); color: var(--ink); }

.lb-scope__wrap {
    padding: .55rem .6rem .6rem;
    border: 1px solid var(--line); border-radius: 12px; background: var(--tint);
}
/* THE WINDOW. It was a 268px disc floating in a panel three times that wide,
   which wasted the space and made the trace too small to read anything off.
   It fills its column now and keeps the framed-instrument feel through a deep
   corner radius rather than a circle — the clip and the rim are still drawn
   in the canvas, so they cannot drift from the trace at any device pixel
   ratio, and a transient that overruns is still cut by the frame instead of
   squaring off against a corner. */
.lb-port {
    position: relative;
    width: 100%; max-width: none; margin: 0;
    aspect-ratio: 16 / 9;
}
.lb-scope {
    display: block; width: 100%; height: 100%;
    border-radius: 16px;
    background: var(--paper);
}
.lb-scope__r {
    display: flex; align-items: center; justify-content: space-between;
    gap: .6rem; margin-top: .42rem; flex-wrap: wrap;
}
.lb-scope__n {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .72rem; color: var(--ink-55);
}

/* ---------------------------------------------------- EQ settings and meter */
.lb-eq__pre { display: flex; flex-wrap: wrap; gap: .24rem; margin-top: .15rem; }
.lb-eq__p {
    font: inherit; font-size: .68rem; font-weight: 700; letter-spacing: .04em;
    padding: .24rem .55rem; border-radius: 999px;
    border: 1px solid var(--line); background: transparent; color: var(--ink-55);
    cursor: pointer;
}
.lb-eq__p:hover { border-color: var(--ink); color: var(--ink); }
.lb-eq__p.is-on { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.lb-meter { display: grid; gap: .22rem; margin-top: .4rem; }
.lb-meter__row { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 2.9rem; gap: .45rem; align-items: center; }
.lb-meter__l { font-size: .62rem; font-weight: 700; letter-spacing: .12em; color: var(--ink-55); }
.lb-meter__t {
    height: 9px; border-radius: 999px; overflow: hidden;
    background: color-mix(in srgb, var(--ink) 12%, transparent);
}
.lb-meter__t i { display: block; height: 100%; width: 0; background: var(--ink); transition: width .06s linear; }
/* Gain reduction reads the other way round — it is the accent because it is
   the thing you are meant to notice. */
.lb-meter__t--gr i { background: var(--accent); }
.lb-meter__v {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .7rem; color: var(--ink-77); text-align: right;
}
.lb-meter.is-limiting .lb-meter__l { color: var(--accent); }
.lb-meter__f {
    display: flex; gap: .75rem; flex-wrap: wrap;
    margin: .45rem 0 0; padding-top: .45rem;
    border-top: 1px solid var(--line);
    font-size: .64rem; font-weight: 700; letter-spacing: .1em; color: var(--ink-55);
}
.lb-meter__f b {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 700; letter-spacing: 0; color: var(--ink); margin-left: .35rem;
}
/* ------------------------------------------------------------- the slot rack
   One row per slot, and every row on the same five tracks — the key, the title
   it is holding, the file button, the link box and Load. Naming the title
   track minmax(0, 1fr) rather than 1fr is what keeps that true: a 1fr track
   grows to its content's min-content width, so one long song title would set
   the column width for all nine rows and push Load off the end. */
.lb-slots { display: grid; gap: .28rem; }
.lb-slot {
    display: grid; align-items: center; gap: .38rem;
    grid-template-columns: 1.5rem minmax(0, 1fr) auto minmax(0, 1.1fr) auto;
}
.lb-slot[hidden] { display: none; }
.lb-slot__t {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: .76rem; color: var(--ink-55);
}
.lb-slot.is-loaded .lb-slot__t { color: var(--ink); font-weight: 600; }
.lb-slot .lb-load__b { font-size: .64rem; padding: .32rem .62rem; }
.lb-slot .lb-load__u { padding: .3rem .62rem; }

.lb-load__k {
    flex: 0 0 auto; width: 1.5rem; height: 1.5rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; border: 1px solid var(--line);
    font-size: .68rem; font-weight: 700; color: var(--ink-55);
}
.lb-slot.is-live .lb-load__k {
    background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.lb-load__more {
    margin-top: .4rem; font: inherit; font-size: .7rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    padding: .4rem .85rem; border-radius: 999px;
    border: 1px dashed var(--line); background: transparent; color: var(--ink-55);
    cursor: pointer;
}
.lb-load__more:hover { border-style: solid; border-color: var(--ink); color: var(--ink); }

/* Below this the five tracks cannot all be read, so the row folds into two
   lines rather than each one becoming too narrow to use. */
@media (max-width: 720px) {
    .lb-slot {
        grid-template-columns: 1.5rem minmax(0, 1fr) auto;
        grid-template-areas: "key title file" "url url load";
        row-gap: .35rem;
    }
    .lb-slot .lb-load__k { grid-area: key; }
    .lb-slot__t { grid-area: title; }
    .lb-slot .lb-load__b:first-of-type { grid-area: file; }
    .lb-slot .lb-load__u { grid-area: url; }
    .lb-slot .lb-load__b:last-of-type { grid-area: load; }
}
/* --------------------------------------------------------- the card controls
   Every record on the shelf carries the same small rack: a live three-band
   reading while it is the one playing, its own trim, a mute, and its name as
   something you can take away.

   The EQ bars are only drawn on the card that is PLAYING. Drawing them on all
   of them would mean twelve canvases reading one analyser and showing the same
   three numbers, which says nothing about any particular record — the point of
   putting them on the card is that they say "this is the one you are hearing". */
.lb-track__ctl {
    display: flex; align-items: center; gap: .3rem; flex-wrap: nowrap;
    margin-top: 0; padding-top: .4rem; padding-bottom: .1rem;
    border-top: 1px solid var(--line-soft, var(--line));
}
/* The trim shares one line with COPY, MUTE and the bars inside a card that is
   only a third of the shelf wide, so it takes whatever is left rather than a
   fixed width — at 4.2rem the row wrapped onto three lines and the control
   rack was taller than the record it belonged to. */
.lb-trim { flex: 1 1 3rem; min-width: 2.6rem; max-width: 6rem; }
/* THE THUMBNAIL EQ. Five bars, and they are meant to be looked at: tall
   enough to read across a room, rounded, and with a floor of two pixels so a
   silent card still shows an instrument rather than an empty gap where one
   ought to be. Only the card that is PLAYING is lit — the rest sit grey at
   the floor, which is what makes the lit one findable at a glance.

   The transition is short and linear. Anything longer smears three bands into
   one moving blur, and an easing curve makes the bars lag the music they are
   supposed to be showing. */
.lb-bars {
    display: flex; align-items: flex-end; gap: 3px;
    height: 22px; margin-left: auto;
}
.lb-bars i {
    display: block; width: 4px; height: 2px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--ink) 26%, transparent);
    transition: height .07s linear, background .2s var(--ease);
}
.lb-card.is-playing .lb-bars i {
    background: var(--accent);
    box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 45%, transparent);
}
.lb-track__len { font-variant-numeric: tabular-nums; }
/* ------------------------------------------------------- folding the rack */
/* The instruments are the biggest thing on the page and not everybody wants
   them open while they are listening. Folded, the panel keeps only its own
   button, so the way back is where the way out was. */
.lb-instr__min {
    position: absolute; top: -2.1rem; right: 0;
    font: inherit; font-size: .66rem; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase;
    padding: .3rem .7rem; border-radius: 999px;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink-55);
    cursor: pointer; z-index: 2;
}
.lb-instr__min:hover { border-color: var(--ink); color: var(--ink); }
.lb-instr.is-folded { grid-template-columns: minmax(0, 1fr); min-height: 1.2rem; }
.lb-instr.is-folded > *:not(.lb-instr__min) { display: none; }
/* --------------------------------------------------------- click to load */
/* A card looks like a label and behaves like a button, and nothing on it said
   so — people read the title, the artist and the length and then looked for
   the control. This is the control, named. Small and in the accent so it reads
   as an instruction rather than as another piece of the record's metadata,
   and it steps aside once that card is the one playing. */
.lb-track__go {
    display: block; margin-top: .3rem;
    font-size: .62rem; font-weight: 700; letter-spacing: .11em;
    text-transform: uppercase; color: var(--accent);
}
.lb-card.is-playing .lb-track__go,
.lb-track[aria-pressed="true"] .lb-track__go { visibility: hidden; }
.lb-track:hover .lb-track__go { text-decoration: underline; }

/* The formats, named once above the rack rather than only in the failure
   message — which is the worst place to first learn what a field accepts. */
.lb-formats {
    margin: 0 0 .7rem; font-size: .8rem; color: var(--ink-55, #6b7280);
    line-height: 1.5;
}
.lb-formats b { color: var(--ink, #1E262B); font-weight: 600; letter-spacing: .01em; }
/* The placeholder now carries a worked example and is longer than the old one;
   it must not be clipped to nothing on a narrow rack. */
.lb-load__u { text-overflow: ellipsis; }
@media (max-width: 620px) {
    .lb-load__u::placeholder { font-size: .82em; }
}

/* ==================================================== THE ROW ON EVERY CARD
   Transport and a tiny EQ, built by deck.js so a generated or opened track is
   dressed the same as the three that shipped. Kept deliberately small: the
   card is a chooser, and these are conveniences on it, not the deck. */
.lb-ops {
    display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
    margin-top: .25rem;
}
.lb-ops__eq { display: flex; gap: .3rem; margin-left: auto; }
.lb-ops__band { display: flex; align-items: center; gap: .18rem; }
.lb-ops__band span {
    font-size: .54rem; font-weight: 700; letter-spacing: .08em;
    color: var(--ink-55, #6b7280);
}
/* A 54px slider is a real control on a mouse and a fiddly one on a thumb; on
   a touch screen it gets the height back even though the width cannot grow. */
.lb-ops__band input[type="range"] { width: 54px; height: 18px; }
@media (pointer: coarse) {

}

/* ==================================================== THE ROW ON EVERY CARD
   Transport, COPY/MUTE, the two share buttons and the library's REFRESH were
   four button specifications inside one card: .lb-share__b at 10px/700 in a
   7px box 30px tall, .lb-track__ctl button at .62rem/800/.06em in a 999px
   lozenge ~21px tall, .lb-ops__b at .72rem in a 7px box 24.4px tall, and the
   panel's own rung at 2.04rem. Four heights, three radii, three type weights.
   That is the chunkiness in the screenshot, and shrinking any one of them
   does not touch it. Written once here.

   THE STROKE IS HALF THE INK, AND IT IS MIXED WITH `transparent`.
   --line is rgba(30,38,43,.12) on the paper, which composites to #E4E5E6 and
   measures 1.26:1 against white — not a boundary so much as a rumour, and
   under the 3:1 WCAG 1.4.11 asks of a control's edge. The old buttons bought
   their presence back with bulk instead: 7px corners around .34rem of padding.
   Faint AND fat is the worst pair to be. The stroke here is the midpoint of
   the page's two inks — 3.12:1 on paper, 5.33:1 on the moon edition — a real
   boundary in both, from one declaration, at one pixel. The card keeps the
   house hairline; the switches inside it do not, the way a Braun case is soft
   and its keys are crisp.

   Mixed with `transparent`, NEVER with var(--paper): a .band--deep section
   repoints --ink to white and leaves --paper at #ffffff, so a two-token mix
   would resolve white-on-white there. An alpha composites over whatever ground
   is actually behind it. color-mix is used unguarded because this sheet
   already does, at lines 356, 474 and 479. */
:root {
    --lb-edge:      color-mix(in srgb, var(--ink, #1E262B) 50%, transparent);
    --lb-edge-soft: color-mix(in srgb, var(--ink, #1E262B) 26%, transparent);
    --lb-wash:      color-mix(in srgb, var(--ink, #1E262B)  7%, transparent);
    --lb-press:     color-mix(in srgb, var(--ink, #1E262B) 14%, transparent);

    /* THE CARD RUNG, AND WHY IT IS NOT THE PANEL RUNG. The make panel stands
       every control at --lb-ctl-h: 2.04rem because sixteen mood pills set that
       height and everything else was brought to them. A card's buttons are a
       convenience on a chooser, not an instrument, so they stand one step
       below: near enough to rhyme, far enough that a card never reads as a
       second control panel. Two rungs, and no third. */
    --lb-ctl-h-s: 1.75rem;   /* 28px at the 16px root */
}

/* ONE BUTTON, WRITTEN ONCE.
   The weight comes DOWN from 700/800 to 600 and the tracking goes UP to .12em,
   because what makes a 10px capital legible is the space between the letters,
   not the mass inside them: at 800 the counters of a 10px O fill in and the
   label stops being a word and becomes a grey block. (800 was never rendering
   anyway — the subsetted DM Sans declares `font-weight: 200 700`, so every 800
   in this file has been clamped to 700 in silence since it was written.)

   THE 16px TOUCH FLOOR DOES NOT APPLY HERE, and it is worth saying so nobody
   "fixes" it later. iOS Safari zooms when a CARET lands in a field below 16px:
   it is a rule about typing, which is why .lb-load__u carries it. A <button>
   never takes a caret. The rule that DOES apply to a button is the 44px
   target, and that is handled on the pointer further down. */
.lb-track__ctl button,
.lb-share__b,
.lb-ops__b {
    display: inline-flex; align-items: center; justify-content: center;
    box-sizing: border-box; position: relative;
    flex: 0 0 auto;                       /* see THE WIDTH OF A BUTTON below */
    height: var(--lb-ctl-h-s); min-height: 0;
    padding: 0 .55rem;
    font: inherit; font-size: .625rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; line-height: 1;
    white-space: nowrap;
    border: 1px solid var(--lb-edge);
    /* 4/28 is a ratio of .143 — a corner with the sharpness taken off it. The
       old 7px on a 24.4px box was .29 and the old 999px lozenge was .50, and a
       lozenge is the shape that says "one of a set of choices". These are
       ACTIONS. The sixteen mood pills keep their 999px for exactly that
       reason: shape stays the part of this design still saying what a control
       does. */
    border-radius: 4px;
    /* transparent, not var(--paper): these rows sit on a card that sits on the
       panel's --tint ground, and a hard white fill punched a paper-coloured
       hole in the tint. */
    background: transparent;
    color: var(--ink-55, rgba(30, 38, 43, .64));
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color .14s var(--ease), border-color .14s var(--ease),
                background-color .14s var(--ease);
}

/* THE WIDTH OF A BUTTON IS ITS LABEL PLUS ITS PADDING. NOTHING ELSE.
   .lb-share__b carried `flex: 1 1 auto` in its base rule and .lb-lib__head is
   a flex row, so REFRESH grew into every leftover pixel of the library header
   at ANY width — 189px at a 409px viewport, unbounded on a desk. The comment
   at line 650 tells this story and calls it fixed, but what got scoped there
   was the phone OVERRIDE; the grow in the base rule was left alone, so the fix
   was only ever live below 620px. Grow is a property of the ROW, so it is
   declared on the row. Measured after: REFRESH is 70.89 x 28. */
.lb-share { display: flex; gap: .4rem; margin-top: 0; padding-bottom: .5rem; }
.lb-share .lb-share__b { flex: 1 1 auto; }
/* Baseline-aligning an inline-flex button against a heading is the browser's
   guess at where its content sits; centre is the thing meant. */
.lb-lib__head { align-items: center; }

/* ---------------------------------------------------- THE TRANSPORT GROUP
   BACK / PLAY / FORWARD ARE ONE CONTROL, SO THEY ARE DRAWN AS ONE.
   Three separate boxes put twelve hairline edges on a card for three keys that
   are never apart, never reordered, and never used for anything but moving
   through the same track. Joined: four outer edges and two dividers — six
   strokes for identical function. "As little design as possible" is a number
   here, and that is the number.

   COPY, MUTE and the share pair stay SEPARATE, which is not inconsistency. A
   segmented control means "these are alternatives, pick one"; those four are
   unrelated errands that happen to sit near each other, and joining them would
   be the shape lying about the function.

   Inner radius is 3px against the group's 4px: a corner concentric with the
   one outside it is that radius minus the stroke between them, and 4 - 1 = 3.
   REQUIRES the deck.js patch — without .lb-ops__tp in the DOM none of the
   rules below match anything and the three keys keep their own boxes.
   Measured: the group is 110 x 28 on a mouse (3 x 36 segments plus the two
   outer border pixels — the dividers are inside the segments, which are
   border-box), 134 x 28 on a finger. */
.lb-ops__tp {
    display: inline-flex; align-items: stretch;
    height: var(--lb-ctl-h-s);
    border: 1px solid var(--lb-edge); border-radius: 4px;
    background: transparent;
}
.lb-ops__tp .lb-ops__b {
    height: auto; min-width: 2.25rem; padding: 0;
    border: 0; border-radius: 0;
    /* The keys carry a drawn glyph rather than a word, so they take the full
       ink: a triangle is a graphical object that has to be understood, and
       --ink measures 15.36:1 on paper and 18.96:1 on the moon edition against
       --ink-55's 4.72:1. The words around them stay quiet because a word can
       afford to be. */
    color: var(--ink, #1E262B);
}
.lb-ops__tp .lb-ops__b + .lb-ops__b { border-left: 1px solid var(--lb-edge-soft); }
.lb-ops__tp .lb-ops__b:first-child { border-radius: 3px 0 0 3px; }
.lb-ops__tp .lb-ops__b:last-child  { border-radius: 0 3px 3px 0; }

/* THE GLYPHS ARE DRAWN, NOT TYPED, and the reason is not taste. U+25C0, U+25B6
   and U+2759 arrive at whatever size, weight and baseline the platform's
   fallback font decided, and on several platforms U+25B6 is picked up by the
   colour emoji face and lands as an orange-blue picture in a greyscale row. A
   design whose whole argument is alignment cannot hand three of its four
   glyphs to a font it does not ship. Drawn, they are 10px in every browser and
   they inherit currentColor, so they follow the live fill, the hover ink and,
   in forced colours, ButtonText. And a fixed key width is what stops the row
   twitching: the play triangle and the pause bars are different widths, so the
   middle key used to resize on every press and reflow the group under the
   finger already on it. */
.lb-ops__g { display: block; height: 10px; width: auto; fill: currentColor; }

/* THE ONE FILL ON THE ROW, AND IT MEANS ONE THING: THIS IS THE RECORD ON THE
   DECK. It was var(--ink) — a black block on a card that already marks the
   live record with an ink border, an inset ink ring and an underlined title,
   which is the fourth time the page says the same word in the same colour.
   It takes --accent-fill with --on-accent on top, never --accent: that is this
   sheet's own header rule for anything that has to BE the accent rather than
   be drawn in it, and .lb-brakeb already does it.

   BE HONEST ABOUT WHAT THE FILL MEASURES. --accent-fill is #FB923C, which is
   2.26:1 against the paper card — under the 3:1 of WCAG 1.4.11. It is
   legitimate here ONLY because the state is not carried by colour: paint()
   swaps the glyph from a triangle to a pause bar, and the label changes with
   it. So the dividers STAY — blanking the neighbours would leave a 2.26:1
   fill with no edge at all — and the fill is reinforcement, not the signal.
   On the moon edition the same fill is 6.77:1 and the point is moot. The glyph
   on the fill measures 7.81:1 paper, 6.76:1 dark. */
.lb-ops[data-live="1"] .lb-ops__play {
    background: var(--accent-fill, #FB923C);
    color: var(--on-accent, #2A1206);
}

/* MUTED IS THE SAME MOVE, AND IT WAS FAILING A MEASUREMENT. The shipped rule
   put #2A1206 on --accent #C2410C — 3.41:1, under the 4.5:1 floor for a 10px
   label, and against the house rule that --accent is an ink and never a fill.
   On --accent-fill the same label measures 7.81:1 paper, 6.76:1 dark. MUTED
   also changes its word (deck.js:1826), so a reader who cannot see the fill
   still reads the state. */
.lb-track__ctl button.is-on {
    background: var(--accent-fill, #FB923C);
    border-color: var(--accent-fill, #FB923C);
    color: var(--on-accent, #2A1206);
}

/* ------------------------------------------------------------- THE STATES
   A hairline design that only resolves on hover does not exist for a phone, so
   the RESTING state is the one that had to measure: a 3.12:1 stroke and a
   4.72:1 label with the pointer nowhere near it. Hover then has one job — say
   WHICH ONE — and says it three ways: stroke to full ink, label to full ink,
   and a 7% wash underneath. There is no accent in it. The old
   `.lb-ops__b:hover` painted the accent on every key, so hovering the
   transport looked exactly like a key going live; a colour that means two
   things means neither.

   :hover is scoped to (hover: hover) because a touch browser keeps the last
   tapped element in :hover, which leaves a phone with one permanently lit
   button and no way to unlight it. */
@media (hover: hover) {
    .lb-track__ctl button:not(:disabled):hover,
    .lb-share__b:not(:disabled):hover,
    .lb-ops__b:not(:disabled):hover {
        color: var(--ink, #1E262B);
        border-color: var(--ink, #1E262B);
        background: var(--lb-wash);
    }
    /* Inside the group a segment has no border of its own to raise, so the
       wash and the ink do the work and the frame stays put — one object, one
       key of it under a finger. */
    .lb-ops__tp .lb-ops__b:not(:disabled):hover { border-color: transparent; }
    .lb-ops__tp .lb-ops__b:not(:disabled):hover + .lb-ops__b { border-left-color: var(--lb-edge-soft); }
}
.lb-track__ctl button:not(:disabled):active,
.lb-share__b:not(:disabled):active,
.lb-ops__b:not(:disabled):active {
    background: var(--lb-press);
    /* No lift. .btn translates -1px on hover because it is a 40px call to
       action with room to move; a 28px key that jumps is a key that misses the
       finger already on it. Pressed is a ground going darker, which is what a
       physical key does. */
    transform: none;
}
/* The ring is the site's ring: 2px of accent at 2px of offset, the same one
   .lb-track, .lb-platter, .lb-zero, .lb-load__b and .lb-die already draw. A
   focused key inside the group is raised so its ring draws over its neighbour
   instead of being cut in half by it. */
.lb-track__ctl button:focus-visible,
.lb-share__b:focus-visible,
.lb-ops__b:focus-visible {
    outline: 2px solid var(--accent, #C2410C); outline-offset: 2px;
}
.lb-ops__tp .lb-ops__b:focus-visible { outline-offset: 1px; z-index: 1; }

/* Disabled is the one state allowed below the contrast floor — WCAG exempts
   inactive controls, and a disabled control that still measures like a live
   one is lying about whether it can be pressed. .45 is the house figure, taken
   from .btn[disabled]. */
.lb-track__ctl button:disabled,
.lb-share__b:disabled,
.lb-ops__b:disabled,
.lb-track__ctl button[aria-disabled="true"],
.lb-share__b[aria-disabled="true"],
.lb-ops__b[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
    .lb-track__ctl button,
    .lb-share__b,
    .lb-ops__b { transition: none; }
}

/* -------------------------------------------------------- ON A FINGERTIP
   28px TALL AND 44px TO HIT. The house pattern for this is .lb-zero, which
   buys its 44px with padding — right for one button standing alone, wrong
   here: six buttons per card across two rows, each grown to 44, is 88px of
   controls under a 60px record. So the drawn box stays 28px and an invisible
   ::after extends the TARGET to 44 — 28 + 8 + 8 — VERTICALLY ONLY. Vertically
   only is what makes it safe: the extension never reaches sideways into the
   neighbour it is 6.4px away from, and each row reserves its own block padding
   so an extension stops exactly at its row's edge instead of covering the row
   above. .lb-ops is appended AFTER .lb-track__ctl, so without that padding its
   extensions would paint over MUTE and eat the taps meant for it. If a fourth
   row is ever added to a card it must be named here too.
   Gated on the pointer, never on the width: "narrow" is a window somebody
   dragged and "coarse" is a hand. */
@media (pointer: coarse) {
    .lb-track__ctl, .lb-ops, .lb-share { padding-block: .5rem; row-gap: .5rem; }
    .lb-track__ctl button::after,
    .lb-share__b::after,
    .lb-ops__b::after { content: ""; position: absolute; inset: -8px 0; }
    /* The word buttons are already past 44 across — COPY, the shortest label
       on the row, measures 51.5px — but a transport key is a glyph in a box,
       so the box takes the width instead. 2.75rem is 44px.
       AND THE SEGMENTS ARE 26px, NOT 28. They are `height: auto` inside the
       group, so the group's own 1px border is OUTSIDE them and a -8px
       extension gives 26 + 8 + 8 = 42 — two pixels under the floor, measured,
       not assumed. Nine pixels each way is 44, and .lb-ops takes the extra
       pixel of block padding so the extension still stops at its own row's
       edge rather than reaching up into MUTE. */
    .lb-ops { padding-block: .5625rem; }
    .lb-ops__tp .lb-ops__b { min-width: 2.75rem; }
    .lb-ops__tp .lb-ops__b::after { inset: -9px 0; }
    /* 16px or iOS Safari zooms the page on focus and carries the fixed header
       off the side of the phone. The seed is a text field and has been at
       .84rem = 13.44px since it was written; .lb-load__u already carries the
       fix and a comment saying why. Gated on the pointer, like the rest. */
    .lb-make__seed { font-size: 16px; }
}

/* --------------------------------------------- WHEN THE READER OVERRIDES US
   A design carried by one-pixel strokes fails hardest here, so it says what it
   wants rather than leaving it to the compositor. Neither of these questions
   was answered anywhere on this property before — not here, not in site.css,
   not in dark.css. */
@media (prefers-contrast: more) {
    :root {
        --lb-edge: var(--ink, #1E262B);
        --lb-edge-soft: var(--ink, #1E262B);
    }
    .lb-track__ctl button,
    .lb-share__b,
    .lb-ops__b { color: var(--ink, #1E262B); }
}
@media (forced-colors: active) {
    .lb-track__ctl button,
    .lb-share__b,
    .lb-ops__b,
    .lb-ops__tp {
        border: 1px solid ButtonBorder;
        background: ButtonFace; color: ButtonText;
    }
    .lb-ops__tp .lb-ops__b { border: 0; }
    .lb-ops__tp .lb-ops__b + .lb-ops__b { border-left: 1px solid ButtonBorder; }
    .lb-ops[data-live="1"] .lb-ops__play,
    .lb-track__ctl button.is-on { background: Highlight; color: HighlightText; }
    .lb-track__ctl button:focus-visible,
    .lb-share__b:focus-visible,
    .lb-ops__b:focus-visible { outline-color: Highlight; }
}

/* ========================================================== THE SLIDERS
   Ten range inputs on this page — a trim and three EQ bands on every card, and
   pitch, speed, level and three more bands on the deck — and until now not one
   of them was drawn. Every one arrived as the browser's default: a fat thumb
   on a pale groove, on a page that measures its own hairlines. The furthest
   the estate had gone was `accent-color: var(--ink)` at site.css:743, which is
   a colour, not a design; nothing more can be said about a native slider until
   it is taken apart with appearance: none.

   Taken apart, it is drawn the way everything else here is: a 2px rail, a
   small square-shouldered thumb, and the accent spent ONCE, on the filled part
   of the rail — the only thing on the control that is a value.

   THE FILL IS NOT GUESSED. js/ranges.js writes --lb-p (0..1) on each input
   from that input's own min/max/value, and the geometry below turns it into
   the exact pixel the thumb centre stands on. Where the control is BIPOLAR —
   pitch, and all six EQ bands, whose min is the negative of their max — the
   fill grows from the CENTRE outward, because a bar anchored at the left edge
   under a band that is cutting 6 dB states the opposite of what is true. */
input[type="range"] {
    /* The geometry lives in one place because the arithmetic below is DERIVED
       from it. Typed out twice, the thumb stops being centred the first time
       somebody changes a size and edits one of the two copies. */
    --lb-trk: 2px;     /* the rail                    */
    --lb-tw:  10px;    /* the thumb, ALONG the travel */
    --lb-th:  14px;    /* the thumb, ACROSS the rail  */
    --lb-p:   0;       /* where the value is,   0..1 — written by ranges.js */
    --lb-o:   0;       /* where the fill starts, 0..1 — 0 left, .5 centre   */

    --lb-rail: var(--line, rgba(30, 38, 43, .12));
    --lb-fill: var(--accent, #C2410C);
    --lb-tick: transparent;   /* only a bipolar rail gets a centre pip */

    /* THE THUMB TRAVELS INSET BY HALF ITS OWN WIDTH: its centre runs from
       tw/2 to (100% - tw/2), never 0 to 100%. A fill painted at a plain
       `--lb-p * 100%` therefore runs ahead of the thumb at one end and lags it
       at the other by tw/2 — five pixels, which on a 54px per-card slider is a
       fifth of the travel and reads as a control that cannot agree with
       itself. Both stops are computed in the thumb's own space:
              x = tw/2 + p x (100% - tw)                                    */
    --lb-x1: calc(var(--lb-tw) / 2 + min(var(--lb-p), var(--lb-o)) * (100% - var(--lb-tw)));
    --lb-x2: calc(var(--lb-tw) / 2 + max(var(--lb-p), var(--lb-o)) * (100% - var(--lb-tw)));

    -webkit-appearance: none; appearance: none;
    /* 18px = the 14px thumb plus its 2px shoulder above and below, exactly. At
       16px Chrome clips the shoulder against the input box; more reserves
       height the control does not use. */
    height: 18px;
    margin: 0; padding: 0; border: 0;
    background: transparent;
    vertical-align: middle;
    cursor: pointer;
    /* pan-y, so dragging the RAIL moves the value and dragging the page still
       scrolls it. Without this a horizontal drag on a phone does both. */
    touch-action: pan-y;
    -webkit-tap-highlight-color: transparent;
}
/* site.css:742 gives every range `margin: .35rem 0 0`, which is right under a
   stacked dial label and wrong inside a flex row: in .lb-ops__band it pushed
   the slider 5.6px below the LO/MID/HI label it belongs to. The base rule
   zeroes it for everybody; the deck's dials, which do want the air, ask for it
   back. (Note that site.css's own rule is 0,1,1 — the same specificity as the
   base rule above — so this sheet wins only because index.html loads it second
   at line 54. That is already true of every other range declaration here.) */
.dial input[type="range"] { margin-top: .35rem; }

/* ranges.js marks the sliders whose min is the negative of their max. The
   attribute only turns a colour on: the centre pip that says where zero is. */
input[type="range"][data-lb-bi="1"] { --lb-tick: var(--ink-55, rgba(30, 38, 43, .64)); }

/* THE TWO ENGINES CANNOT SHARE A RULE. A selector list containing a pseudo the
   engine does not know is INVALID AND THE WHOLE RULE IS DROPPED, so grouping
   ::-webkit-slider-runnable-track with ::-moz-range-track loses the track in
   both browsers rather than half of it in one. They are written twice on
   purpose; the values come from the same custom properties, so there is still
   only one place to change a number. Counted, rather than asserted: of the 77
   blocks in this restyle Blink parses 67 and drops exactly the 10 that are
   ::-moz- only, and none of the survivors lost a declaration. */
input[type="range"]::-webkit-slider-runnable-track {
    height: var(--lb-trk);
    border: 0; border-radius: 0;   /* a rail is a ruled line, not a pill */
    background-color: var(--lb-rail);
    background-image:
        /* the fill, painted between the origin and the value */
        linear-gradient(to right,
            transparent var(--lb-x1), var(--lb-fill) var(--lb-x1),
            var(--lb-fill) var(--lb-x2), transparent var(--lb-x2)),
        /* and, underneath it, the 1px centre pip — hidden by the thumb while
           the value IS zero, which is the one moment it has nothing to say */
        linear-gradient(to right,
            transparent calc(50% - .5px), var(--lb-tick) calc(50% - .5px),
            var(--lb-tick) calc(50% + .5px), transparent calc(50% + .5px));
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    box-sizing: border-box;   /* so the forced-colors border cannot resize it */
    width: var(--lb-tw); height: var(--lb-th);
    border: 0; border-radius: 1px;
    background: var(--ink, #1E262B);
    /* THE SHOULDER IS STRUCTURAL. Ink on accent measures 2.97:1 in paper and
       2.80:1 in dark — both under the 3:1 a control needs against what is next
       to it — so where the thumb sits on top of its own fill the two would
       smear into one shape. 2px of page ground between them means neither has
       to carry contrast against the other. */
    box-shadow: 0 0 0 2px var(--paper, #ffffff);
    /* CHROME TOP-ALIGNS THE THUMB TO THE TRACK, so against a 2px rail it hangs
       6px low unless it is pulled up by half the difference:
              margin-top = (track - thumb) / 2 = (2 - 14) / 2 = -6px
       At pointer: coarse the thumb is 18px, so the same expression gives -8px,
       and under prefers-contrast: more the rail is 3px, giving -5.5px. That is
       why it is a calc and not a number: three sizes, one line, none of them
       able to drift. WebKit needs it too — at margin-top: 0 the thumb hangs
       below the rail there exactly as it does in Blink. */
    margin-top: calc((var(--lb-trk) - var(--lb-th)) / 2);
    transition: background-color .16s var(--ease), box-shadow .16s var(--ease);
}
/* Firefox centres its own thumb and needs no margin — and must not be given
   one, or it lands 6px high. */
input[type="range"]::-moz-range-track {
    height: var(--lb-trk);
    border: 0; border-radius: 0;
    background-color: var(--lb-rail);
    background-image:
        linear-gradient(to right,
            transparent var(--lb-x1), var(--lb-fill) var(--lb-x1),
            var(--lb-fill) var(--lb-x2), transparent var(--lb-x2)),
        linear-gradient(to right,
            transparent calc(50% - .5px), var(--lb-tick) calc(50% - .5px),
            var(--lb-tick) calc(50% + .5px), transparent calc(50% + .5px));
}
input[type="range"]::-moz-range-thumb {
    box-sizing: border-box;
    width: var(--lb-tw); height: var(--lb-th);
    border: 0; border-radius: 1px;
    background: var(--ink, #1E262B);
    box-shadow: 0 0 0 2px var(--paper, #ffffff);
    transition: background-color .16s var(--ease), box-shadow .16s var(--ease);
}
/* Firefox is the one engine that fills the rail itself, and it is worth
   having: it is the only fill on the page that survives with JavaScript off.
   But it can only ever fill FROM THE LEFT, so on the seven bipolar controls it
   would draw a half-full bar under a band that is doing nothing. There it is
   turned off and the gradient above — which knows where zero is — does the
   work in every engine alike. */
input[type="range"]::-moz-range-progress {
    height: var(--lb-trk);
    border: 0; border-radius: 0;
    background: var(--lb-fill);
}
input[type="range"][data-lb-bi="1"]::-moz-range-progress { background: transparent; }
input[type="range"]::-moz-focus-outer { border: 0; }

/* THE STATES. There is no hover: a colour flicker on a 10px object is not
   information, and the cursor has already said the thing is movable. :active
   is the one moment worth marking — the shoulder takes the accent, so the
   control lights where the hand is touching it and nothing else moves. */
input[type="range"]:active::-webkit-slider-thumb { box-shadow: 0 0 0 2px var(--accent, #C2410C); }
input[type="range"]:active::-moz-range-thumb     { box-shadow: 0 0 0 2px var(--accent, #C2410C); }

/* The house ring at a smaller offset than site.css:749's 4px. The ring sits
   2px + 2px = 4px outside the box; the gap from a slider to the next band's
   label is .34rem = 5.44px, so it clears by 1.44px. At the inherited 4px
   offset it stood 6px proud and struck the label, and a focus ring that
   damages the thing beside it reads as a bug rather than as focus. */
input[type="range"]:focus { outline: none; }
input[type="range"]:focus-visible { outline: 2px solid var(--accent, #C2410C); outline-offset: 2px; }

/* Disabled still has to SHOW THE VALUE — that is information, and hiding it is
   not what disabled means. What goes is the invitation: the fill drops to grey
   and the thumb goes hollow, an outline of an object rather than an object.
   Not done with opacity, which would take the rail down with it. */
input[type="range"]:disabled { --lb-fill: var(--ink-55, rgba(30, 38, 43, .64)); cursor: default; }
input[type="range"]:disabled::-webkit-slider-thumb {
    background: var(--paper, #ffffff);
    box-shadow: inset 0 0 0 1px var(--ink-55, rgba(30, 38, 43, .64)), 0 0 0 2px var(--paper, #ffffff);
}
input[type="range"]:disabled::-moz-range-thumb {
    background: var(--paper, #ffffff);
    box-shadow: inset 0 0 0 1px var(--ink-55, rgba(30, 38, 43, .64)), 0 0 0 2px var(--paper, #ffffff);
}

/* AND ON A FINGER THE BOX IS 44px. The thumb stays small on purpose: on both
   engines a press anywhere on the rail seeks the value to that point and
   starts the drag, so the INPUT is the target and the thumb is only where the
   value is drawn. The height is bought around a rail that does not grow — the
   same move the .dial block at line 174 already makes — so the control gets
   easier to hit without getting louder. min-height, not height, and
   deliberately: .lb-ops__band already sets height: 26px at coarse from a
   higher-specificity selector, and min-height clamps it whatever wins.
   Measured at coarse: EQ band 85.8 x 44, its rail 62 x 44, trim 96 x 44. */
@media (hover: none) and (pointer: coarse) {
    input[type="range"] { --lb-tw: 12px; --lb-th: 18px; min-height: 44px; }
}

/* Colour may move; the fill may not. A transition on the fill would make the
   rail arrive after the value it is reporting, which on an EQ band being swept
   is a control that lies for a sixth of a second. */
@media (prefers-reduced-motion: reduce) {
    input[type="range"]::-webkit-slider-thumb { transition: none; }
    input[type="range"]::-moz-range-thumb     { transition: none; }
}

/* A HAIRLINE DESIGN FAILS HARDEST HERE, so the rail is the thing that gives.
   --line is 1.26:1 against paper and 1.58:1 against the dark ground — enough
   to place the control, not enough for someone who has asked for more. The
   rail goes to --ink-55 (4.72:1 paper, 6.80:1 dark), the pip to full ink, and
   the rail gains a pixel; the thumb needs nothing, being 15.36:1 already. The
   thumb re-centres itself — (3 - 14) / 2 = -5.5px — with no second number to
   keep in step. */
@media (prefers-contrast: more) {
    input[type="range"] {
        --lb-trk: 3px;
        --lb-rail: var(--ink-55, rgba(30, 38, 43, .64));
    }
    input[type="range"][data-lb-bi="1"] { --lb-tick: var(--ink, #1E262B); }
    input[type="range"]:focus-visible { outline-width: 3px; }
}

/* FORCED COLORS. Here the tokens are gone: the ground is Canvas, ink is
   CanvasText, and an author's orange either survives inside a gradient — a
   colour the reader explicitly asked not to see — or is thrown away and the
   fill disappears. Neither is acceptable, so the control is restated in system
   colours and opted out of the forcing, which is the only way to keep the fill
   and the shoulder while still honouring the reader's palette.
   forced-color-adjust inherits, so setting it on the input covers the shadow
   parts drawn inside it. */
@media (forced-colors: active) {
    input[type="range"] {
        forced-color-adjust: none;
        --lb-rail: CanvasText;
        --lb-fill: Highlight;
    }
    input[type="range"][data-lb-bi="1"] { --lb-tick: CanvasText; }
    /* STILL ONE ENGINE PER RULE, and this is the block where that is easiest
       to forget. Grouped as `::-webkit-slider-thumb, ::-moz-range-thumb` these
       four rules PARSE TO NOTHING in Blink — confirmed by counting
       cssRules: the two grouped rules were the only ones missing — and the
       thumb loses its forced-colors treatment in the one mode that cannot
       afford to lose it. Written apart, they survive.
       box-shadow is not painted in forced colors, so the shoulder that keeps
       the thumb off its own fill is redrawn as a border — and the thumb is
       border-box, so it does not change size doing it. */
    input[type="range"]::-webkit-slider-thumb {
        background: ButtonText; box-shadow: none; border: 2px solid Canvas;
    }
    input[type="range"]::-moz-range-thumb {
        background: ButtonText; box-shadow: none; border: 2px solid Canvas;
    }
    input[type="range"]:disabled { --lb-fill: GrayText; }
    input[type="range"]:disabled::-webkit-slider-thumb { background: GrayText; }
    input[type="range"]:disabled::-moz-range-thumb     { background: GrayText; }
    input[type="range"]:focus-visible { outline-color: Highlight; }
}

/* ----------------------------------------------- the row the sliders sit in
   Two rhythm fixes that belong with this block because the sliders are what
   made them visible. The three EQ bands were three different widths — not
   because the sliders differ but because LO, MID and HI are 12.31, 18.03 and
   10.09px of type, and each band gave its own label whatever it asked for. A
   fixed 1.15rem (18.4px) column holds the widest of the three and makes all
   three bands identical. The gaps go up by a hair to give the focus ring its
   4px. */
.lb-ops__band { gap: .34rem; }
.lb-ops__band span { flex: 0 0 1.15rem; }
.lb-ops__eq { gap: .4rem; }

/* ========================================================= THE GENERATOR */
.lb-make {
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 12px;
    padding: .9rem 1rem 1rem; margin-bottom: 1.1rem;
    background: var(--tint, #FAFAFA);
}
.lb-make__head {
    display: flex; align-items: center; gap: .8rem 1rem; flex-wrap: wrap;
    margin-bottom: .7rem;
}
.lb-make__t { margin: 0; font-size: .82rem; line-height: 1.45; max-width: 46ch; }
.lb-make__t b { display: block; font-size: 1rem; margin-bottom: .1rem; }
.lb-make__t span { color: var(--ink-55, #6b7280); font-size: .78rem; }
.lb-make__t span b { display: inline; font-size: inherit; color: var(--ink, #1E262B); }
.lb-make__head .btn { margin-left: auto; }
/* THE ROWS LINE UP OR THEY LOOK ASSEMBLED.
   These were flex rows with a 4.2rem label and everything after it taking its
   natural width, so the three pill rails started at the same x and ended at
   three different ones, and the seed row — an input, two buttons and a
   sentence — ended somewhere else again. A grid with ONE label column and one
   content column is what makes four rows read as one panel. */
/* THE LABEL COLUMN IS AS WIDE AS THE LONGEST LABEL AND NOT A MILLIMETRE MORE.
   It was 4.9rem — 78px — while the longest of the four keys, TEXTURE, measures
   50.1px at this size and weight. Twenty-eight wasted pixels on every row, and
   they came out of the controls: the five texture pills were left 38px each,
   which is less than the 54px "Clean" needs, so the labels wrapped inside a
   fixed-height pill and were clipped mid-word. 3.4rem clears TEXTURE with four
   pixels to spare and hands the rest back. */
.lb-make__row {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    align-items: center; gap: .35rem .7rem; margin-top: .4rem;
}
.lb-make__k {
    font-size: .6rem; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-55, #6b7280);
}
.lb-make__seg .seg__b { font-size: .76rem; padding: .34rem .66rem; }
/* The seed row's own three controls, sized so the row ends where the pill
   rails above it end rather than trailing off. */
.lb-make__ctl {
    display: flex; align-items: center; gap: .4rem; min-width: 0;
}
.lb-make__seed {
    font: inherit; font-size: .84rem; flex: 1 1 8rem; min-width: 0;
    padding: .34rem .5rem;
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 7px;
    background: var(--paper, #fff); color: var(--ink, #1E262B);
    font-variant-numeric: tabular-nums;
}

/* THE DIE. Square, so it reads as an object rather than another pill in a row
   of pills, and it turns a quarter when pressed — which is the whole of the
   animation a die needs. */
.lb-die {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.05rem; height: 2.05rem; padding: 0; cursor: pointer;
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 8px;
    background: var(--paper, #fff); color: var(--ink-55, #6b7280);
    transition: transform .28s var(--ease), color .16s var(--ease),
                border-color .16s var(--ease);
}
.lb-die:hover { color: var(--accent, #C2410C); border-color: var(--accent, #C2410C); }
.lb-die:focus-visible { outline: 2px solid var(--accent, #C2410C); outline-offset: 2px; }
.lb-die.is-rolling { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .lb-die { transition: none; } }
.lb-make__out {
    margin: .8rem 0 0; padding: .6rem .75rem; font-size: .84rem;
    border: 1px dashed var(--line, rgba(30,38,43,.14)); border-radius: 8px;
}
.lb-make__out[data-bad="1"] { border-color: var(--taken, #B91C1C); color: var(--taken, #B91C1C); }
.lb-make__dl { font-weight: 600; }
.lb-make__seedout {
    font-size: .74rem; color: var(--ink-55, #6b7280);
    font-variant-numeric: tabular-nums; margin-left: .4rem;
}

/* ============================================================ ON A PHONE
   The rack was laid out for a desk. On a narrow screen the card rows wrapped
   into a ragged stack — a share row, a mixer row and now a transport row
   under every card, each breaking at a different width — so below 620 the
   controls go to a tighter rhythm and the label column stops reserving space
   it does not need. */
@media (max-width: 620px) {
    .lb-make { padding: .75rem .8rem .85rem; }
    .lb-make__head { gap: .5rem; }
    .lb-make__head .btn { margin-left: 0; width: 100%; }
    .lb-make__k { flex-basis: 100%; margin-bottom: -.15rem; }
    .lb-make__seg { width: 100%; }
    /* AND A PILL IS NEVER NARROWER THAN ITS OWN LABEL.
       This said `flex: 1 1 0; min-width: 0`, which is the pair that lets a flex
       item shrink below its content — six mood pills were held on one line at
       35px each when "Black Glass" needs 71 and "Undertow" 62, so the labels
       broke onto a second line inside a pill one line tall and were clipped
       mid-word: "Clea", "Blac". The shared .seg is ALREADY `flex-wrap: wrap`;
       this override was the only thing preventing it.

       So: basis auto and the default min-width, which is min-content — a pill
       takes the width of its word, grows to share whatever is left over, and a
       row that cannot fit wraps instead of lying. Measured at 375px: texture
       and length still come out as one even row each, and mood takes the two
       lines it has always needed. */
    .lb-make__seg .seg__b {
        flex: 1 1 auto;
        padding-left: .3rem; padding-right: .3rem;
        white-space: nowrap;
    }
    .lb-make__seed { width: 100%; }

    .lb-ops { gap: .25rem; }
    .lb-ops__eq { margin-left: 0; width: 100%; justify-content: space-between; }
    .lb-ops__band { flex: 1 1 0; }
    .lb-ops__band input[type="range"] { width: 100%; min-width: 0; }

    /* The share row's three buttons fit across a phone if they are allowed to
       share the width rather than each taking their natural size.

       AND THE RULE IS SCOPED TO THAT ROW, which it was not. Written as a bare
       .lb-share__b it matched every button carrying the class ANYWHERE, and
       three of them are not in a share row at all: the library's Refresh sits
       alone in .lb-lib__head, so flex:1 1 0 handed it the whole remaining
       width — measured at 189px in a 409px viewport, a button the width of the
       page whose label is one short word. The seed row already carried
       `.lb-make__row--seed .lb-share__b { flex: 0 0 auto }`, which is the same
       bug spot-fixed once at the other end rather than at its source. */
    .lb-share { display: flex; gap: .25rem; }

    .lb-share .lb-share__b { flex: 1 1 0; min-width: 0; }

    .lb-tb { min-width: 3rem; }
    .run { gap: .35rem; }
    .run__kbd { flex-basis: 100%; }
}

/* ============================================================= THE LIBRARY
   Below the controls, and shown straight away: what the server keeps is a
   recipe, so there is nothing to wait for.

   ONE HEIGHT FOR THE LIBRARY'S OWN CONTROLS, borrowed from the panel it sits
   inside. .lb-make declares --lb-ctl-h and holds its pills, its seed box, its
   die and its NEW button to it; Refresh, the search and the sort are four more
   controls in the same instrument. The local alias exists so a touch screen can
   raise all four together without touching the sixteen mood pills above them. */
.lb-lib {
    --lb-lib-h: var(--lb-ctl-h, 2.04rem);
    margin-top: .9rem; padding-top: .8rem;
    border-top: 1px solid var(--line, rgba(30,38,43,.14));
}

/* FOUR THINGS IN ONE ROW; ON A PHONE, TWO ROWS OF TWO. align-items is centre
   rather than baseline — baseline was right when the head held a paragraph and
   a button, and is unreliable the moment an input and a select are in the row. */
.lb-lib__head {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: .4rem .55rem; margin-bottom: .5rem;
}
.lb-lib__t { margin: 0; font-size: .88rem; flex: 0 1 auto; min-width: 0; }
.lb-lib__t b { font-size: .95rem; }
.lb-lib__t span { color: var(--ink-55, #6b7280); font-size: .76rem; margin-left: .4rem; }

/* NORMAL SIZE, AND THE BUG THAT MADE IT ABNORMAL.
   .lb-share__b is `flex: 1 1 auto` at the base of this sheet, which is right
   for the SHARE ROW it was written for — three buttons dividing a card's width.
   A button standing ALONE in a flex row inherits the same instruction and eats
   the row: MEASURED IN THIS BUILD AT vw 1280, Refresh was 878.8px wide in a
   1119px head. The margin-left:auto that used to be this rule's whole body
   could never have pinned it right, because a grown item leaves no free space
   for an auto margin to take. The phone half of this was already fixed once, by
   rescoping the 620px rule to `.lb-share .lb-share__b`; this is the other half,
   in the same words as the seed row's spot-fix further up the sheet.
   And 10px/700/uppercase/.12em is a legend, not a control — the panel's own
   control height and a readable size are what "normal" has to mean here. */
.lb-lib__head .lb-share__b {
    flex: 0 0 auto; margin-left: auto;
    font-size: .74rem; font-weight: 600; letter-spacing: 0; text-transform: none;
    height: var(--lb-lib-h); min-height: 0; box-sizing: border-box;
    padding: 0 .8rem; line-height: calc(var(--lb-lib-h) - 2px);
}

/* The search and the sort answer the same question, so they are ONE object and
   they break to their own line together. Order in the markup is load-bearing:
   with the group last, a 100% basis breaks it cleanly to row two and leaves the
   title and Refresh together on row one. Put it in the middle and Refresh is
   orphaned onto a third row. Measured: a flat 94.4px head from a 230px panel
   all the way up, with no third row at any width. */
.lb-lib__f {
    display: flex; align-items: center; gap: .35rem;
    flex: 0 1 21rem; min-width: 0;
}
.lb-lib__f[hidden] { display: none; }   /* display:flex beats the UA's [hidden] */

.lb-lib__q {
    flex: 1 1 6rem; min-width: 0;
    font: inherit; font-size: .8rem;
    height: var(--lb-lib-h); box-sizing: border-box; padding: 0 .55rem;
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 7px;
    background: var(--paper, #fff); color: var(--ink, #1E262B);
    -webkit-appearance: none; appearance: none;
}
.lb-lib__q::placeholder { color: var(--ink-55, #6b7280); opacity: 1; }
.lb-lib__q:focus { outline: none; border-color: var(--ink, #1E262B); }
.lb-lib__q:focus-visible { outline: 2px solid var(--accent, #C2410C); outline-offset: 1px; }

/* THE ARROW IS THE BROWSER'S, ON PURPOSE. appearance:none plus a data: URI
   chevron is the usual move and it is a literal-colour bug waiting to happen —
   currentColor inside a data: URI resolves against the SVG's own root, not this
   page's, so it inks black and the dark edition gets a black arrow on a black
   field. Left native, the UA draws it in the text colour, and the dark edition
   has already set color-scheme, so the popup comes up dark too. */
.lb-lib__sort {
    flex: 0 1 auto; min-width: 0; max-width: 9.5rem;
    font: inherit; font-size: .8rem;
    height: var(--lb-lib-h); box-sizing: border-box; padding: 0 .35rem;
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 7px;
    background: var(--paper, #fff); color: var(--ink, #1E262B);
    cursor: pointer;
}
.lb-lib__sort:hover { border-color: var(--ink, #1E262B); }
.lb-lib__sort:focus-visible { outline: 2px solid var(--accent, #C2410C); outline-offset: 2px; }

/* The line under the head is the only documentation there is: it says what the
   box understood, so the reader learns the vocabulary by using it. */
.lb-lib__read {
    margin: 0 0 .5rem; font-size: .74rem; line-height: 1.4;
    color: var(--ink-55, #6b7280);
}
.lb-lib__read:empty { display: none; }

/* SIXTEEN PIXELS, MATCHED ON THE POINTER AND NOT ON A WIDTH. iOS Safari zooms
   the page when an input or a select under 16px takes focus, and this page has
   a fixed header that the zoom then carries off the visual viewport. A phone
   held sideways is 932px wide and still does it, so "narrow" is the wrong test:
   narrow is a window somebody dragged, coarse is a hand. The controls take the
   44px they need to sit in at the same time, so the row stays one height.
   Measured at a 368px viewport: 71.2 x 44 Refresh, 186 x 44 search, 129 x 44
   sort, head 94.4px, document still 368 wide. */
@media (pointer: coarse) {
    .lb-lib { --lb-lib-h: 2.75rem; }
    .lb-lib__q, .lb-lib__sort { font-size: 16px; }
}

/* ---------------------------------------------------------------- the list */
.lb-lib__grid {
    display: grid; gap: .4rem; align-content: start;
    grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr));
    max-height: 21rem;
    max-height: min(21rem, 60dvh);
    overflow-y: auto;
    /* The page does not start moving when this list runs out. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
/* THE EMPTY MESSAGE IS A GRID ITEM and was living in one 190px track, wrapping
   "Nothing published yet…" into four ragged lines. A sentence spans the list it
   is standing in for. The error branch uses the same class. */
.lb-lib__empty { grid-column: 1 / -1; }

.lb-lib__i {
    display: block; text-align: left; cursor: pointer; min-width: 0;
    font: inherit; padding: .5rem .6rem;
    border: 1px solid var(--line, rgba(30,38,43,.14)); border-radius: 9px;
    background: var(--paper, #fff); color: var(--ink, #1E262B);
}
.lb-lib__i:hover { border-color: var(--accent, #C2410C); }
/* THE LIST HAD NO FOCUS STYLE AT ALL — up to a thousand tab-reachable buttons
   in a scroller with :hover as their only feedback. Inset, so the scroller's
   own edge cannot clip the ring. */
.lb-lib__i:focus-visible { outline: 2px solid var(--accent, #C2410C); outline-offset: -2px; }
/* made.php allows sixty characters and does not require a space among them; an
   unbreakable sixty-character word overflows its cell and, in a grid, takes the
   whole document's width with it. */
.lb-lib__i b { display: block; font-size: .88rem; line-height: 1.25; overflow-wrap: anywhere; }
.lb-lib__i span { display: block; font-size: .72rem; color: var(--ink-55, #6b7280); overflow-wrap: anywhere; }
.lb-lib__i i {
    display: block; font-size: .66rem; font-style: normal; overflow-wrap: anywhere;
    color: var(--ink-55, #6b7280); font-variant-numeric: tabular-nums; opacity: .8;
}
.lb-lib__i[data-loading] { border-color: var(--accent, #C2410C); opacity: .6; }
.lb-lib__i[data-loading] b::after { content: " \2014 building\2026"; font-weight: 400; }

/* SHOW MORE sits OUTSIDE the scroller, so revealing rows does not move the
   button that revealed them and focus stays put. It is centred on a desk and
   full width on a phone, and the difference is the same distinction the Refresh
   fix rests on: Refresh is a control standing in a row of other things, so it
   takes its natural width; this is the END OF THE LIST, so where the screen is
   narrow it should be as wide as the list it continues. */
.lb-lib__foot { display: flex; justify-content: center; margin: .45rem 0 0; }
.lb-lib__foot[hidden] { display: none; }
.lb-lib__more {
    flex: 0 0 auto; font: inherit; font-size: .78rem; font-weight: 600;
    height: var(--lb-lib-h); box-sizing: border-box; padding: 0 1.4rem;
    border-radius: 999px; cursor: pointer;
    border: 1px solid var(--line, rgba(30,38,43,.14));
    background: transparent; color: var(--ink, #1E262B);
}
.lb-lib__more:hover, .lb-lib__more:focus-visible {
    border-color: var(--accent, #C2410C); color: var(--accent, #C2410C);
}
.lb-lib__more[hidden] { display: none; }

.lb-lib__empty, .lb-lib__note {
    margin: .4rem 0 0; font-size: .76rem; color: var(--ink-55, #6b7280);
}
.lb-lib__empty b { color: var(--ink, #1E262B); }
.lb-make__sz { font-size: .74rem; color: var(--ink-55, #6b7280); }

/* ============================================================ ON A PHONE
   THIS REPLACES the old `.lb-lib__grid { grid-template-columns: 1fr 1fr;
   max-height: 17rem; }` inside the existing 620px block. If the old 17rem rule
   is left behind it wins on source order and the phone keeps its keyhole —
   which is the single most likely way to ship this and see no change.

   AUTO-FILL RATHER THAN A HARD 1fr 1fr. Measured: a 230px panel gives ONE
   column of 230 and a 273px panel two of 133, where the hard pair would force
   two 110px columns that no generated name fits into. */
@media (max-width: 620px) {
    .lb-lib__f { flex: 1 1 100%; }
    /* The title stacks so the head cannot go to three rows: inline, "The
       library 1000 of 1000 kept" plus Refresh plus the gap overflows a panel
       under about 282px, and flex WRAPS rather than shrinks when the line can
       break instead — min-width:0 on the title does nothing about that. */
    .lb-lib__t b { display: block; line-height: 1.2; }
    .lb-lib__t span { display: block; margin-left: 0; line-height: 1.2; }

    .lb-lib__grid {
        grid-template-columns: repeat(auto-fill, minmax(min(8rem, 100%), 1fr));
        max-height: 24rem;
        max-height: min(24rem, 58dvh);
    }
    .lb-lib__more { flex: 1 1 auto; }
    .lb-lib__i { padding: .45rem .5rem; }
    /* THE NAME GETS TWO LINES BEFORE IT IS CUT. The generator's names run to 31
       characters — "Lantern of the Quiet Half" — against about fourteen that
       fit on one line at 133px, so a single line truncated roughly every second
       card. The whole name is in the title attribute for a long press. This
       block must sit AFTER the .lb-lib__i rules above: -webkit-line-clamp needs
       display:-webkit-box, which overrides the display:block up there. */
    .lb-lib__i b {
        display: -webkit-box; -webkit-line-clamp: 2;
        -webkit-box-orient: vertical; overflow: hidden;
    }
    .lb-lib__i span { font-size: .68rem; }
    .lb-lib__i i { font-size: .62rem; }
}

.lb-make__sz { font-size: .74rem; color: var(--ink-55, #6b7280); }
@media (max-width: 620px) {
}
/* The mood's own sentence, under its pills rather than overwriting the seed
   line — choosing a mood used to delete the only explanation of what a seed is. */
/* The two quiet lines — the mood's sentence and the seed's — sit in the
   content column, hard under the row they belong to. They were a third of a
   line adrift, which is the white space the panel did not need. */
.lb-make__hint {
    margin: .15rem 0 .1rem 5.6rem; font-size: .74rem;
    color: var(--ink-55, #6b7280); line-height: 1.35;
}
@media (max-width: 620px) { .lb-make__hint { margin-left: 0; } }

/* ONE HEIGHT FOR EVERY CONTROL IN THE PANEL.
   Measured before this: the mood pills stood 32.6px, the die 32.8, the seed
   input 34.6 and the NEW button 30 — four heights in four rows that are meant
   to read as one instrument. The pill is the reference because there are
   sixteen of them; everything else is brought to it. */
.lb-make { --lb-ctl-h: 2.04rem; }
.lb-make__seg .seg__b,
.lb-make__ctl .lb-share__b,
.lb-make__seed,
.lb-die {
    height: var(--lb-ctl-h);
    box-sizing: border-box;
}
.lb-make__seg .seg__b,
.lb-make__ctl .lb-share__b { padding-top: 0; padding-bottom: 0; line-height: calc(var(--lb-ctl-h) - 2px); }
.lb-make__seed { padding-top: 0; padding-bottom: 0; }
.lb-die { width: var(--lb-ctl-h); }
