/* SHITBEARD r05 finish, shared across the same pages/components. Artwork and instruments stay intact. */
:root{--theme-panel-shadow:3px 3px 0 var(--theme-ink);--theme-key-shadow:1px 1px 0 var(--theme-ink);--theme-dialog-shadow:5px 5px 0 var(--theme-ink);--theme-surface-radius:0px;--theme-panel-rule:1px solid var(--theme-ink);--theme-list-rule:1px dotted var(--theme-ink);--theme-dots:radial-gradient(var(--theme-ink) .6px,transparent .6px);--theme-dot-size:4px 4px;--theme-thumb-width:9px;--theme-thumb-height:15px;--theme-inverse-ink:#fff;--theme-inverse-face:#000;--theme-paper:#fff;--theme-ink:#000;--theme-muted:#444;--theme-font-ui:Geneva,Tahoma,Arial,sans-serif;--theme-font-mono:ui-monospace,monospace;--theme-header-max:1180px;--theme-header-pad-x:40px;--theme-header-pad-x-phone:16px;--theme-header-pad-y:12px;--theme-header-gap:24px;--theme-header-gap-phone:8px;--theme-brand-mark:44px;--theme-brand-size:28px;--theme-brand-size-phone:24px;--theme-brand-gap:10px;--theme-brand-width:220px;--theme-brand-tracking:-.04em;--theme-nav-size:16px;--theme-nav-inset:8px;--theme-nav-gap:4px;--theme-nav-icon:28px;--theme-nav-bar:60px;--theme-target:44px;--theme-state-ok:#17632d;--theme-state-bad:#9b1c1c}
:root[data-theme="shitbeard"]{--theme-panel-shadow:3px 3px 0 var(--theme-ink);--theme-key-shadow:1px 1px 0 var(--theme-ink);--theme-dialog-shadow:5px 5px 0 var(--theme-ink);--theme-surface-radius:0px;--theme-panel-rule:1px solid var(--theme-ink);--theme-list-rule:1px dotted var(--theme-ink);--theme-dots:radial-gradient(var(--theme-ink) .6px,transparent .6px);--theme-dot-size:4px 4px;--theme-thumb-width:9px;--theme-thumb-height:15px;--theme-inverse-ink:#fff;--theme-inverse-face:#000;--theme-paper:#fff;--theme-ink:#000;--theme-muted:#444;--theme-font-ui:Geneva,Tahoma,Arial,sans-serif;--theme-font-mono:ui-monospace,monospace;--theme-header-max:1180px;--theme-header-pad-x:40px;--theme-header-pad-x-phone:16px;--theme-header-pad-y:12px;--theme-header-gap:24px;--theme-header-gap-phone:8px;--theme-brand-mark:44px;--theme-brand-size:28px;--theme-brand-size-phone:24px;--theme-brand-gap:10px;--theme-brand-width:220px;--theme-brand-tracking:-.04em;--theme-nav-size:16px;--theme-nav-inset:8px;--theme-nav-gap:4px;--theme-nav-icon:28px;--theme-nav-bar:60px;--theme-target:44px;--theme-state-ok:#17632d;--theme-state-bad:#9b1c1c}
html[data-theme="shitbeard"]{color-scheme:light;background:var(--theme-paper)!important;font-family:var(--theme-font-ui)}
/* The scheme the finish paints is light on every host, whatever the OS asks for: declared on the root, the body and every native control, so UA-painted faces (fields, selects, ranges, buttons, scrollbars, popups) never go dark under a dark OS scheme while the ink stays ink (#314). */
html[data-theme="shitbeard"],html[data-theme="shitbeard"] body,html[data-theme="shitbeard"] :is(input,select,textarea,button,dialog,details,summary){color-scheme:light}
html[data-theme="shitbeard"] body{background:var(--theme-paper)!important;color:var(--theme-ink)!important;font-family:var(--theme-font-ui)}
html[data-theme="shitbeard"] :is(h1,h2,h3,.brand){font-family:var(--theme-font-ui);font-weight:700}
html[data-theme="shitbeard"] :is(.small,.status-line,.ui-status,.badge,.indicator,.time,.health,.action-feedback){font-family:var(--theme-font-mono)}
/* The canonical page header (task 203, icons since #291): one brand, one row of icon-only nav links, one trailing slot, on
   every page. Markup comes from ui/partials/site-brand.html, nav-listen.html, nav-operator.html and nav-account.html; geometry
   from the theme-header/brand/nav tokens. Each link is an inline glyph with its name in aria-label/title; no visible nav text.
   Geometry is not theme-scoped, so the frame holds before the bootstrap runs; the paint below is SHITBEARD's. */
body>header.site-header{box-sizing:border-box;display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-start;gap:var(--theme-header-gap);width:auto;max-width:none;min-height:0;margin:0;padding:var(--theme-header-pad-y) max(var(--theme-header-pad-x),calc((100% - var(--theme-header-max))/2 + var(--theme-header-pad-x)));border-radius:0;box-shadow:none;position:relative;text-align:left}
body>header.site-header .brand{order:0;flex:none;display:inline-flex;align-items:center;gap:var(--theme-brand-gap);min-width:var(--theme-brand-width);max-width:none;min-height:var(--theme-target);margin:0;padding:0;font:700 var(--theme-brand-size)/1 var(--theme-font-ui);font-style:normal;letter-spacing:var(--theme-brand-tracking);text-decoration:none;text-transform:none;white-space:nowrap}
body>header.site-header .brand-portrait{flex:none;width:var(--theme-brand-mark);height:var(--theme-brand-mark);margin:0;object-fit:contain;border-radius:50%;box-shadow:none}
body>header.site-header .brand>span{display:block;min-width:0;margin:0;padding:0;color:inherit;font:inherit;letter-spacing:inherit}
body>header.site-header .site-nav{order:1;flex:0 1 auto;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;gap:0 var(--theme-nav-gap);min-width:0;margin:0;padding:0}
body>header.site-header :is(.site-nav,.site-end)>a:not(.control-gear){display:inline-flex;align-items:center;justify-content:center;min-width:var(--theme-target);min-height:var(--theme-target);padding:0 var(--theme-nav-inset);margin:0;font:400 var(--theme-nav-size)/1.2 var(--theme-font-ui);letter-spacing:0;text-decoration:none;white-space:nowrap;border:0;border-bottom:2px solid transparent;border-radius:0;background:none}
body>header.site-header :is(.site-nav,.site-end)>a:not(.control-gear)>svg{display:block;flex:none;width:var(--theme-nav-icon);height:var(--theme-nav-icon)}
body>header.site-header :is(.site-nav,.site-end)>a:not(.control-gear):hover{border-bottom-color:currentColor}
body>header.site-header .site-end{order:2;flex:none;display:flex;align-items:center;justify-content:flex-end;gap:var(--theme-nav-gap);width:auto;max-width:none;min-height:var(--theme-target);margin:0 0 0 auto;padding:0}
body>header.site-header .site-end>:is(button,a.control-gear){height:var(--theme-target);min-height:var(--theme-target);margin:0}
html[data-theme="shitbeard"] body>header.site-header{background:var(--theme-paper)!important;border:0;border-bottom:2px solid var(--theme-ink)}
html[data-theme="shitbeard"] body>header.site-header :is(.brand,.site-nav>a,.site-end>a:not(.control-gear)){color:var(--theme-ink)}
html[data-theme="shitbeard"] body>header.site-header .brand-portrait{border:var(--theme-panel-rule)}
/* The current page is marked by its rule, not by weight, so no label moves from page to page. */
html[data-theme="shitbeard"] body>header.site-header .site-nav>a[aria-current="page"]{border-bottom-color:var(--theme-ink)}
html[data-theme="shitbeard"] :is(.panel,.result-card,.room-join,.room-chat,.room-cue-details,.room-audio-toolbar,.dead-show-details,.dead-library,.users-table){background:var(--theme-paper)!important;color:var(--theme-ink)!important;border:var(--theme-panel-rule)!important;border-radius:var(--theme-surface-radius)!important;box-shadow:var(--theme-panel-shadow)!important}
html[data-theme="shitbeard"] :is(.tracks li,.users-table td,.result-row,.detail-side){border-bottom:var(--theme-list-rule)}
html[data-theme="shitbeard"] :is(dialog,.ui-dialog){background:var(--theme-paper)!important;color:var(--theme-ink)!important;border:2px solid var(--theme-ink)!important;border-radius:var(--theme-surface-radius)!important;box-shadow:var(--theme-dialog-shadow)!important}
/* Keep sticky dialog headers on the same S7 surface as their body. */
html[data-theme="shitbeard"] body.ui-controls .ui-dialog{--ui-dialog-surface:var(--theme-paper)}
html[data-theme="shitbeard"] dialog::backdrop{background:var(--theme-paper)!important;background-image:var(--theme-dots)!important;background-size:var(--theme-dot-size);opacity:.7!important}
html[data-theme="shitbeard"] body.ui-controls :is(button,a.primary,a.secondary,.ui-button,.ui-bezel-option,.ui-filter-chip,.control-gear,.tape-load-link){background:var(--theme-paper)!important;color:var(--theme-ink)!important;border:1px solid var(--theme-ink)!important;border-radius:var(--theme-surface-radius)!important;box-shadow:var(--theme-key-shadow)!important;text-shadow:none!important;min-height:44px;touch-action:manipulation}
html[data-theme="shitbeard"] body.ui-controls :is(button.primary,.ui-button--primary,.ui-button--auth,.ui-deck-key--primary){background:var(--theme-inverse-face)!important;color:var(--theme-inverse-ink)!important}
/* Random Records (#291, Sean: its keys were too dark): paper-faced keys; the inverse face is the hover/active state only. */
html[data-theme="shitbeard"] body.ui-controls.random-page:not(.rdead-page) button.primary:not([data-feedback]):not([data-state]){background:var(--theme-paper)!important;color:var(--theme-ink)!important}
html[data-theme="shitbeard"] body.ui-controls :is(button,a.primary,a.secondary,.ui-button,.ui-bezel-option,.ui-filter-chip,.control-gear):is(:hover,:active):not(:disabled):not([aria-disabled="true"]){background:var(--theme-inverse-face)!important;color:var(--theme-inverse-ink)!important}
html[data-theme="shitbeard"] body.ui-controls :is(button,[role="tab"],.ui-bezel-option,.ui-filter-chip):is([aria-pressed="true"],[aria-selected="true"],:has(input:checked)){border:2px solid var(--theme-ink)!important;background:var(--theme-paper)!important;color:var(--theme-ink)!important;box-shadow:none!important;font-weight:700}
html[data-theme="shitbeard"] body.ui-controls :is(button,input,select,textarea,.ui-button,.ui-bezel-option):is(:disabled,[aria-disabled="true"]){opacity:1!important;background:var(--theme-paper)!important;color:var(--theme-muted)!important;border-style:dotted!important;box-shadow:none!important;cursor:default!important}
/* A checked box that is disabled still shows its tick (0.14.172): the disabled face above resets the whole background,
   which erased the mark, so a locked "Include in livestream" read as unchecked while its take was on the livestream. */
html[data-theme="shitbeard"] body.ui-controls input[type=checkbox]:checked:is(:disabled,[aria-disabled="true"]){background-image:var(--ui-check-mark)!important;background-repeat:no-repeat!important;background-position:center!important}
html[data-theme="shitbeard"] body.ui-controls :is(button,[role="tab"],.ui-button)[aria-busy="true"]{border-style:dashed!important;cursor:progress!important}
html[data-theme="shitbeard"] body.ui-controls :is(input:not([type=checkbox]):not([type=radio]):not([type=range]),select,textarea){background:var(--theme-paper)!important;color:var(--theme-ink)!important;border:1px solid var(--theme-ink)!important;border-radius:var(--theme-surface-radius)!important;box-shadow:none!important;min-height:44px}
html[data-theme="shitbeard"] :is(a,button,input,select,textarea,summary,[tabindex]):focus-visible{outline:2px solid var(--theme-ink);outline-offset:3px}
html[data-theme="shitbeard"] body.ui-controls :is(.ui-bezel,.ui-quality-track,.ui-quality-thumb,.ui-chip,.ui-progress,.deck-key){border-radius:var(--theme-surface-radius)!important;box-shadow:none!important}
html[data-theme="shitbeard"] :is(.message.error,.error,[data-state="error"],[data-feedback="error"]){color:var(--error,var(--ui-error))!important;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px}
html[data-theme="shitbeard"] body.ui-controls :is(button,a.primary,.ui-button):is([data-feedback="error"],[data-state="error"]){background:var(--theme-paper)!important;color:var(--error,var(--ui-error))!important;border-color:var(--error,var(--ui-error))!important}
html[data-theme="shitbeard"] :is([data-state="pending"],[data-feedback="pending"]){font-weight:700;border-style:dashed!important}
html[data-theme="shitbeard"] input[type=range]{accent-color:var(--theme-ink)}
html[data-theme="shitbeard"] input[type=range]::-webkit-slider-thumb{border-radius:0!important;background:var(--theme-paper)!important;border:1px solid var(--theme-ink)!important;box-shadow:none!important;width:var(--theme-thumb-width);height:var(--theme-thumb-height)}
html[data-theme="shitbeard"] input[type=range]::-moz-range-thumb{border-radius:0!important;background:var(--theme-paper)!important;border:1px solid var(--theme-ink)!important;box-shadow:none!important;width:var(--theme-thumb-width);height:var(--theme-thumb-height)}
/* A dotted desktop margin, matching r05. Do not obscure album art, maps, meters or the room canvas. */
@media(min-width:900px){html[data-theme="shitbeard"] body:not(.listening-room){background-image:var(--theme-dots)!important;background-size:var(--theme-dot-size)}html[data-theme="shitbeard"] main{background:var(--theme-paper)!important}}

/* SHITBEARD is the only style (task 184). Narrow headers (task 203): brand and the trailing slot share the first row; the nav labels
   take the full second row, their text aligned with the brand edge. */
@media(max-width:760px){body>header.site-header{flex-wrap:wrap;gap:var(--theme-header-gap-phone);padding:var(--theme-header-pad-y) var(--theme-header-pad-x-phone)}body>header.site-header .brand{min-width:0;font-size:var(--theme-brand-size-phone)}body>header.site-header .site-end>:is(button,a.control-gear){width:auto;min-width:var(--theme-target)}
/* Phones (#291): the one nav row is pinned to the bottom of the screen as an icon bar; the header keeps brand and trailing slot only. The page
   reserves the bar's height so nothing ends under it. */
body>header.site-header .site-nav{position:fixed;left:0;right:0;bottom:0;z-index:40;order:3;flex:none;flex-wrap:nowrap;justify-content:space-around;gap:0;width:auto;margin:0;padding:0 0 env(safe-area-inset-bottom,0px);min-height:var(--theme-nav-bar);background:var(--theme-paper);border-top:2px solid var(--theme-ink)}
body>header.site-header .site-nav>a:not(.control-gear){flex:1 1 0;min-width:var(--theme-target);min-height:calc(var(--theme-nav-bar) - 2px);padding:0}
body:has(>header.site-header .site-nav:not(.site-nav-desk)){padding-bottom:calc(var(--theme-nav-bar) + env(safe-area-inset-bottom,0px))}
/* The shared site nav (site-nav.js) completes the header nav with every destination the signed-in person may open; those added
   links, and a nav a page did not have, are desk-only, so the phone bottom bar keeps exactly the page's own links. */
body>header.site-header :is(.site-nav.site-nav-desk,.site-nav>a.site-nav-desk){display:none!important}}
/* The phone's Admin icon (0.14.172, site-nav.js) opens the /admin hub; a desk already lists every operator destination. */

html[data-theme="shitbeard"] body.ui-controls :is(.tag-options label,.check-option,.side-image-option label):has(input:checked){color:var(--theme-ink)!important;background:var(--theme-paper)!important;border:2px solid var(--theme-ink)!important}

/* #314 polish: every control surface shares one column, one page head, one type scale and one spacing scale. Geometry is not
   theme-scoped (the frame holds before the bootstrap runs); the paint above stays SHITBEARD's. Listener players (/, /dead,
   /random, /rdead) keep their own stages and stay title-less (#209); the listening room keeps its deck. */
/* The column: main takes the header's column (--theme-header-max wide, --theme-header-pad-x inset), so page content, panels and
   keys share the brand and nav edges on every operator and library host. Auth panels stay narrow and centred. */
body.ui-controls:is(.control-theme,.record-page,.tape-library-page,.tape-editor-page,.levels-page,.records-page,.rooms-page,.chain-page,.auth-page,.landing-page)>main{box-sizing:border-box;width:auto;max-width:var(--theme-header-max);margin:0 auto;padding:24px var(--theme-header-pad-x) 48px}
/* The page head: title and lede at the left, the status/action slot (.heading-end) at the right edge; on a phone the slot
   takes its own full row and stays right-aligned. */
html[data-theme] body.ui-controls .heading{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:8px 24px;margin:0 0 24px;padding:0}
html[data-theme] body.ui-controls .heading>div:first-child{flex:1 1 320px;min-width:0}
html[data-theme] body.ui-controls .heading h1{margin:0;font:700 32px/1.1 var(--theme-font-ui);letter-spacing:-.02em;overflow-wrap:anywhere}
html[data-theme] body.ui-controls .heading>div>p{margin:6px 0 0;font:400 13px/1.6 var(--theme-font-mono);color:var(--theme-muted);max-width:70ch}
html[data-theme] body.ui-controls .heading-end{flex:0 1 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px;margin-left:auto;min-height:44px;text-align:right;font:400 13px/1.5 var(--theme-font-mono);color:var(--theme-muted)}
html[data-theme] body.ui-controls main:is(.catalog-main,.records-main)>.heading{margin:0}
/* #326: the title sits at the same height on every page (the head aligns to its top edge, so a 44px end slot never pushes
   it down); one distance from the page head to the first block on every page (24px, 16px on a phone): the block under the head
   adds no margin of its own (Records' panel added 32px, Users' grid 28px, the chain filters 32px), and the grid mains
   (Records, Catalog) space their rows by the same 24/16. The catalog way-back link sits in the head's right-aligned end slot. */
html[data-theme] body.ui-controls main>.heading+*,html[data-theme] body.ui-controls main>.heading+[hidden]+*{margin-top:0}
html[data-theme] body.ui-controls main:is(.catalog-main,.records-main){row-gap:24px}
html[data-theme] body.ui-controls .heading-end>p{margin:0}
/* Panels and their section heads: one padding, one h2, the end slot right-aligned. */
html[data-theme] body.ui-controls .panel{padding:24px}
html[data-theme] body.ui-controls .panel>h2,html[data-theme] body.ui-controls :is(.section-head,.section-title) h2{margin:0 0 16px;font:700 18px/1.25 var(--theme-font-ui);letter-spacing:0;text-transform:none}
html[data-theme] body.ui-controls :is(.section-head,.section-title){display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px;margin:0 0 16px}
html[data-theme] body.ui-controls :is(.section-head,.section-title) h2{margin:0}
html[data-theme] body.ui-controls :is(.section-head,.section-title)>:last-child:not(:first-child){margin-left:auto;text-align:right}
/* Keys: one recipe (theme font, 16px/600, 10x16, 44px target); compact list keys 14px; bezel options and tabs 14px/600. Glyphs
   inside keys follow currentColor, so an inverted (hover/active) key never shows a dark glyph on its dark face. */
html[data-theme] body.ui-controls :is(button,a.primary,a.secondary,.ui-button,a.tape-load-link):not(.control-gear,.visual-exit,.ui-bezel-option,.ui-dialog-close,.tape-artwork-disclosure,.dead-map-pin,.deck-key,.transport-icon,.meter-range-option,.meter-range-auto,.meter-output-option,.listener-settings-gear,.landing-tile){font:600 16px/1.25 var(--theme-font-ui);letter-spacing:0;padding:10px 16px;min-height:44px}
html[data-theme] body.ui-controls :is(.control-list,.users-table,.recordings-sort,.filters,.dead-sort,.tag-chip,.tape-tag-chip,.catalog-takes,.rooms-list,.dead-shows,.library-pagination,.catalog-pager,.recordings-pager) button:not(.control-gear){font-size:14px;padding:6px 12px}
html[data-theme] body.ui-controls .ui-bezel-option{font:600 14px/1.2 var(--theme-font-ui);letter-spacing:0;padding:8px 14px 12px}
html[data-theme] body.ui-controls :is(button,a.primary,a.secondary,.ui-button,.control-gear) svg:not([fill="none"]){fill:currentColor}
/* Fields and their labels: 14px fields on a 44px line, 12px/600 muted labels with one 6px gap to the field. Checkbox and radio
   rows are reading text, not labels, and keep the ink. */
html[data-theme] body.ui-controls :is(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):not([type=hidden]),select,textarea){font:400 14px/1.3 var(--theme-font-ui);padding:10px 12px;min-height:44px}
html[data-theme] body.ui-controls label:not(.check-option,.record-check,.landing-tile):not(:has(input[type=checkbox],input[type=radio])){font:600 12px/1.4 var(--theme-font-ui);letter-spacing:0;color:var(--theme-muted)}
html[data-theme] body.ui-controls legend{font:600 12px/1.4 var(--theme-font-ui);color:var(--theme-muted)}
html[data-theme] body.ui-controls label>:is(input:not([type=checkbox]):not([type=radio]),select,textarea){margin-top:6px}
/* Keyboard focus on an inverse (primary) key keeps the inverse face: the shared deck source paints every focused key with the
   paper hover face, which left a primary key's white ink on paper (white on white) under keyboard focus (#314 live audit). */
html[data-theme="shitbeard"] body.ui-controls :is(button.primary,.ui-button--primary,.ui-button--auth,.ui-deck-key--primary):focus-visible:not(:disabled):not([aria-disabled="true"]):not(.control-gear){background:var(--theme-inverse-face)!important;color:var(--theme-inverse-ink)!important}
/* The map attribution (Leaflet, OpenStreetMap links) sits on the dark map canvas: paper face and ink links, so the two
   focusable links are never ink on the dark tiles (#314 scripts-on audit, Dead map and Tapes map). */
html[data-theme="shitbeard"] .leaflet-container .leaflet-control-attribution{background:var(--theme-paper)!important;color:var(--theme-ink)!important;border:1px solid var(--theme-ink);border-radius:0;font-family:var(--theme-font-mono)}
html[data-theme="shitbeard"] .leaflet-container .leaflet-control-attribution a{color:var(--theme-ink)!important}
/* A panel that is filled by its script (the Listening rooms panel on Controls) paints no frame while it is empty. */
body.ui-controls .panel:empty{display:none}
/* The Dead deck hosted on Controls keeps its 0.14.137 phone geometry: the host dock sits 6px inside the new 16px column,
   so its three deck keys stay 80.66px wide at 390 (the shared column alone made them 84.66px; ui-widgets-browser gate).
   Geometry, so not theme-scoped: the gates mount the hosts without the bootstrap. */
@media(max-width:760px){body.control-theme .dead-page.dead-host{margin-left:6px;margin-right:6px}}
/* Pager rows (Records, Catalog, Tapes) end at the right edge like every other action slot, with the page count beside the keys. */
html[data-theme] body.ui-controls :is(.catalog-pager,.library-pagination,.recording-actions:has(>#recordings-prev)){display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px 12px;margin:16px 0 0}
/* Inner tiles and sub-surfaces (facts, health, channels, result cards, filter boxes, catalogue rows) take the one surface radius. */
html[data-theme="shitbeard"] body.ui-controls :is(.record-facts>div,.health>div,.channel,.input-facts>div,.users-result,.users-link code,.catalog-item,.catalog-takes li,.tag-filter,.tag-options label,.detail-side,.physical-side-card,.image-card,.listening-selected,.empty,.result-card,.dead-show,.dead-notes,.dead-master,.ui-chip,.tag-chip,.tape-tag-chip,.record-badge,.level-meter,.vu-panel,.audio-visual,.milkdrop-canvas,.action-feedback,.timing-controls,.ui-dialog,.ui-progress,.dead-map-canvas){border-radius:var(--theme-surface-radius)!important}
/* The header's trailing slot: Sign out (one partial on every operator host: glyph and name, glyph only on a phone) and Account. */
body>header.site-header .site-end{gap:8px}
body>header.site-header .site-end>.control-signout{display:inline-flex;align-items:center;justify-content:center;width:auto;min-width:var(--theme-target);padding:0 14px 0 12px;gap:8px;font:600 14px/1 var(--theme-font-ui);letter-spacing:0;white-space:nowrap;cursor:pointer}
body>header.site-header .site-end>.control-signout span{white-space:nowrap}
body>header.site-header .site-end>.control-signout svg{width:20px;height:20px;fill:none}
@media(max-width:760px){html[data-theme] body.ui-controls .heading{margin-bottom:16px}html[data-theme] body.ui-controls main:is(.catalog-main,.records-main){row-gap:16px}html[data-theme] body.ui-controls .heading h1{font-size:26px}html[data-theme] body.ui-controls .heading-end{flex:1 0 100%;justify-content:flex-end;min-height:0}html[data-theme] body.ui-controls .panel{padding:16px}body.ui-controls:is(.control-theme,.record-page,.tape-library-page,.tape-editor-page,.levels-page,.records-page,.rooms-page,.chain-page,.auth-page,.landing-page)>main{padding:16px var(--theme-header-pad-x-phone) 40px}body>header.site-header .site-end>.control-signout{width:var(--theme-target);padding:0}body>header.site-header .site-end>.control-signout span{display:none}}

/* #326 (correction of #314, which failed Sean's acceptance). ONE layout rule for every surface:
   - The header never names the page: one site-brand partial (portrait + "Vinylon"), no label, everywhere. Anything a script
     adds to the header (the listener settings gear) joins the trailing slot at the right edge.
   - A page that has a title states it once, as the visible h1 of the shared page head (.heading: title left, status/actions
     right) at the top of main, on the header column: Records, Tapes, Rooms, Record, Tape, Catalog, Controls, Users, the
     editors, Levels, Signal chain and the auth pages. Listening stages (the room player, Dead, Random Records, Random Dead)
     and the landing have no page head by the same rule (#209: controls only; the nav's current-page rule names them).
   - An empty list says so in one treatment (.empty). */
body>header.site-header>.listener-settings{order:2}
html[data-theme] body.ui-controls.auth-page>main>.auth-panel{box-sizing:border-box;width:100%;max-width:480px;margin:0}
html[data-theme] body.ui-controls .empty{display:block;box-sizing:border-box;margin:0;padding:20px 24px;border:1px dashed var(--theme-ink);border-radius:var(--theme-surface-radius);background:var(--theme-paper);color:var(--theme-muted);font:400 13px/1.6 var(--theme-font-mono)}
html[data-theme] body.ui-controls .empty[hidden]{display:none}
/* The audio-quality choice takes the selected-control recipe every other bezel/tab uses (paper face, 2px ink rule, ink label
   at 700). Its SHITBEARD token painted the thumb #000 under an #000 selected label (a black block with no text on Random
   Records and Dead, #326); the token is paper now (theme.json), the rule and weight come from here. Busy = dotted rule at full
   opacity, like every disabled control. Its title is a field label like every other (12px/600 muted, sentence case). */
html[data-theme="shitbeard"] body.ui-controls .ui-quality-thumb{border:2px solid var(--theme-ink)!important}
html[data-theme] body.ui-controls .quality-choice-title{font:600 12px/1.4 var(--theme-font-ui);letter-spacing:0;text-transform:none;color:var(--theme-muted)}
html[data-theme="shitbeard"] body.ui-controls .ui-quality-track:is([data-position="start"],[data-quality="lossless"]) .ui-quality-option:is([data-position="start"],[data-for="lossless"]),html[data-theme="shitbeard"] body.ui-controls .ui-quality-track:is([data-position="end"],[data-quality="compressed"]) .ui-quality-option:is([data-position="end"],[data-for="compressed"]){color:var(--theme-ink);font-weight:700}
html[data-theme="shitbeard"] body.ui-controls .ui-quality-track[aria-disabled="true"]{opacity:1;border-style:dotted}
/* A bezel option's radio is its invisible full-face hit target (ui-controls.css). The disabled recipe above sets opacity:1 on
   every disabled input, which surfaced a grey radio over the label of a disabled bezel option (Tape's NR "Off", 2.72:1 rendered,
   #326 audit); the hit target stays invisible in every state. */
html[data-theme="shitbeard"] body.ui-controls .ui-bezel-option>input[type=radio]{opacity:0!important}
/* #326 header trailing slot: every item is a bare 44px icon like the nav and Account (the header is icon-only since #291):
   Sign out and the listener settings gear lose their key face, border and shadow and show their glyph at the nav icon size,
   the name stays in aria-label/title; hover/focus mark them with the nav's 2px rule, never an inverse face. */
body>header.site-header :is(.site-end>.control-signout,.listener-settings-gear){display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:var(--theme-target);min-width:var(--theme-target);height:var(--theme-target);min-height:var(--theme-target);padding:0;gap:0}
body>header.site-header .site-end>.control-signout span{display:none}
body>header.site-header :is(.site-end>.control-signout,.listener-settings-gear) svg{width:var(--theme-nav-icon);height:var(--theme-nav-icon)}
html[data-theme="shitbeard"] body.ui-controls>header.site-header :is(.control-signout,.listener-settings-gear),html[data-theme="shitbeard"] body.ui-controls>header.site-header :is(.control-signout,.listener-settings-gear):is(:hover,:active,:focus-visible):not(:disabled):not([aria-disabled="true"]){background:transparent!important;color:var(--theme-ink)!important;border:0!important;border-bottom:2px solid transparent!important;border-radius:var(--radius-control,0px)!important;box-shadow:none!important}
html[data-theme="shitbeard"] body.ui-controls>header.site-header :is(.control-signout,.listener-settings-gear):is(:hover,:active,[aria-expanded="true"]):not(:disabled):not([aria-disabled="true"]){border-bottom-color:currentColor!important}
/* #326 listening stages (Dead, Random Records, Random Dead) start at the same height as every page head (24px under the
   header, 16px on a phone) on the same column as every page (1180px, 40px inset; 16px on a phone). The room player keeps its
   own stage (#209). */
body.ui-controls:is(.dead-page,.random-page)>main{box-sizing:border-box;max-width:var(--theme-header-max);margin:0 auto;padding-top:24px;padding-left:var(--theme-header-pad-x);padding-right:var(--theme-header-pad-x)}
@media(max-width:760px){body.ui-controls:is(.dead-page,.random-page)>main{padding-top:16px;padding-left:var(--theme-header-pad-x-phone);padding-right:var(--theme-header-pad-x-phone)}}
/* #326 (Sean: "align all top controls right side of page"): on a desk the brand alone stays left and every top control forms ONE
   trailing group at the right edge of the header column: the nav icons, then Sign out / Account, then the settings gear, one
   --theme-nav-gap apart. Pages without a nav keep the trailing slot at the right edge. Phones keep the bottom nav bar unchanged. */
@media(min-width:761px){body>header.site-header{column-gap:var(--theme-nav-gap)}body>header.site-header .brand{margin-right:var(--theme-header-gap)}body>header.site-header .site-nav{margin-left:auto}body>header.site-header .site-nav~.site-end{margin-left:0}}
/* #326 one label case: eyebrows, the audio-quality title and fieldset legends read like every field label (sentence case,
   12px/600, muted), so "AUDIO QUALITY" no longer sits in capitals above "Streaming URL". Header glyphs share one stroke weight. */
html[data-theme] body.ui-controls :is(.eyebrow,.quality-choice-title,legend){text-transform:none;letter-spacing:0;font-family:var(--theme-font-ui);font-weight:600;font-size:12px;line-height:1.4}
html[data-theme] body.ui-controls main :is(.eyebrow,legend){color:var(--theme-muted)}
body>header.site-header .listener-settings-gear svg{fill:none;stroke:currentColor;stroke-width:1.2}
/* The Dead deck keeps its pinned 0.14.137 phone geometry (96px keys, ui-widgets-browser gate) now that the Dead stage takes the
   16px phone column instead of its old 20px inset: the deck sits 4px inside the panel's content box, as #314 did for Controls. */
@media(max-width:760px){body.dead-page>main .dead-transport{width:auto;margin-left:4px;margin-right:4px}}

/* Recording, live timing and seekable playback share ONE bar face. The range keeps its
   native keyboard/touch behavior; its 44px hit area surrounds the same 14px visible rail. */
html[data-theme] body.ui-controls{--playback-bar-height:14px;--playback-bar-radius:var(--theme-surface-radius,7px);--playback-bar-edge:var(--ui-line);--playback-bar-paper:var(--paper);--playback-bar-fill:var(--ui-progress-fill)}
html[data-theme] body.ui-controls .ui-progress{box-sizing:border-box;height:var(--playback-bar-height);border:1px solid var(--playback-bar-edge)!important;border-radius:var(--playback-bar-radius)!important;background:var(--playback-bar-paper)!important;box-shadow:none!important}
html[data-theme] body.ui-controls .ui-progress-fill{background:var(--playback-bar-fill)!important;border-radius:0!important;box-shadow:none!important}
html[data-theme] body.ui-controls .playback-progress{position:relative;display:grid;align-items:center;height:44px;min-width:0;width:100%;margin:0}
html[data-theme] body.ui-controls .playback-progress[hidden]{display:none!important}
html[data-theme] body.ui-controls .playback-progress>.ui-progress{display:block;width:100%;min-width:0;pointer-events:none}
html[data-theme] body.ui-controls .playback-progress .ui-progress-fill{display:block;min-width:0}
html[data-theme] body.ui-controls .playback-progress>input[type=range]{appearance:none;-webkit-appearance:none;position:absolute;inset:0;box-sizing:border-box;width:100%;min-width:0;height:44px;min-height:44px;margin:0;padding:0;border:0!important;opacity:0;background:transparent!important;box-shadow:none!important;cursor:pointer;touch-action:pan-y}
html[data-theme] body.ui-controls .playback-progress:focus-within{outline:2px solid var(--ink);outline-offset:2px}
html[data-theme] body.ui-controls .playback-progress[data-disabled=true]{opacity:.5}
html[data-theme] body.ui-controls .playback-progress>input:disabled{cursor:default}
.embedded-player{margin:12px 0;min-width:0}.embedded-player .playback-time{margin:0;font-variant-numeric:tabular-nums}.embedded-player [role=status]:empty{display:none}.embedded-player .playback-transport{max-width:480px}
@media(prefers-reduced-motion:reduce){html[data-theme] body.ui-controls .ui-progress-fill{transition:none}}

html[data-theme] body.ui-controls audio.embedded-player-audio{display:none!important}
