/* Plain CSS, no build step. The palette is Steel and Copper (docs/design.md): every colour is a
   token in shared/ui/tokens.css, and nothing below uses a colour of its own.

   Design direction A, "Studio Console" (#773): the page is a rack of panels on the surface colour,
   each with a 2px copper rule along its top edge, laid out on an 8px scale (8/16/24/32/48) inside
   one 1200px frame that every page shares, with the Warm Slate direction's pill menu and the Broadcast
   Deck's status strip. Copper carries the structure: the rule on every panel, the copper left edge on the
   section you are reading, the strip's hairlines, the primary button (the light cut), the open ? help,
   and the keyboard focus ring. The live light itself is crimson. */
:root {
    --frame: 1200px;
    --gutter: 24px;
}
@media (max-width: 600px) { :root { --gutter: 16px; } }
/* The page. 17px text on every screen: phones do not zoom into a field at 16px or more. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }
body { font: 17px/1.55 var(--font-body); background: var(--bg); color: var(--text); margin: 0; min-height: 100dvh; display: flex; flex-direction: column; }
/* One frame for every page: the header's and footer's contents, and the page itself. */
.frame { max-width: calc(var(--frame) + 2 * var(--gutter)); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
/* width: in a column flexbox, the frame's auto margins would shrink the page to its content. */
main { flex: 1; width: 100%; padding-bottom: var(--s5); }
/* A page that is one thing (docs/design.md, Two page shapes): <x-layout width="column"> wraps the page in this. */
.column { width: 100%; max-width: 640px; margin-inline: auto; }
/* No header above it (the extension's sign-in window): the space the header's margin gives elsewhere. */
main.unframed { padding-top: var(--s4); }
[hidden] { display: none !important; }
/* First paint (docs/design.md): first-paint.js sets html.js before anything is drawn. Each no-script fallback is
   drawn or hidden here, never by a script after load. */
html:not(.js) .js-only { display: none !important; }
html.js .js-hide { display: none !important; }
html.js .help-text:not(.is-open) { display: none; }
html.js [data-switch] > label.check { display: none; }
html.js .copy-value.is-button:not(.is-unwired) > :not(.copy-button, [role=status]) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
html.js [data-autosave-fallback] { display: none; }
html:not(.device-not-windows) [data-device-note=not-windows], html:not(.device-phone) [data-device-note=not-desktop] { display: none; }
html:not(.passkeys) [data-passkey-add], html:not(.passkeys) [data-passkey-sign-in] { display: none; }
html:not(.js) [data-passkey-unsupported], html.passkeys [data-passkey-unsupported] { display: none; }
html.js [data-passkey-rename-form]:not(.is-open) { display: none; }
html.js .bits-rule:has(input[data-reveals]:not(:checked)) .bits-amount { display: none; }
/* For screen readers only. */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* Shown only when reached with the Tab key, on a line of its own above the header. */
.skip { position: absolute; left: -9999px; }
.skip:focus { position: static; display: block; width: fit-content; margin: var(--s1) var(--gutter) 0; padding: var(--s1) 12px; }
/* The header: the DJ logo and the name, then where you can go; the alpha banner is inside it. The line under the bar stops at the frame like the page. */
.site-header { margin-bottom: var(--s4); }
.site-header .site-bar { border-bottom: 1px solid var(--line); }
.site-header .site-bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 4px var(--s3); padding-top: var(--s1); padding-bottom: var(--s1); }
.brand { color: var(--text); font-family: var(--font-ui); font-weight: 600; text-decoration: none; padding: 4px 0; display: inline-flex; align-items: center; gap: 12px; }
/* The DJ logo before the name (docs/brand): the name beside it says what it is, so alt="". */
.brand img { display: block; height: 70px; width: auto; }
.brand-text { display: grid; line-height: 1.15; }
.brand-name { font-size: 28px; }
/* Hidden on a phone, where the larger name needs the row. aria-hidden in the markup keeps the link's name "Mix the Mix". */
.tagline { font-size: 14px; font-weight: 400; color: var(--muted); }
@media (max-width: 699px) { .tagline { display: none; } }
/* On a phone the 28px name leaves no room for the Menu button, so it drops to a second row; the three steps keep it on the row down to 360px. */
/* A broadcaster's row also holds the folded switch beside Menu: the logo and name shrink so all three stay on one row down to 360px. Every account's header shrinks alike, so it does not change between accounts. */
@media (max-width: 479px) { .brand img { height: 48px; } .brand { gap: 8px; } .brand-name { font-size: 20px; } .site-header .site-bar { column-gap: 4px; } .site-bar .site-menu > summary { padding: 0 12px; } }
@media (max-width: 399px) { html .mode-switch.folded .icon.icon { display: none; } .brand img { height: 40px; } .brand-name { font-size: 18px; } }
/* The Menu button opens the items as a panel under the header's row, at any width. Where the browser can show
   a closed details' content (::details-content), a computer shows the items in the row instead (below). */
.site-bar { position: relative; }
.site-menu { margin: 0; }
.site-menu > summary, .nav-menu > summary { list-style: none; }
.site-menu > summary::-webkit-details-marker, .nav-menu > summary::-webkit-details-marker { display: none; }
.site-menu > summary { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s2); border: 1px solid var(--silver); border-radius: 6px; color: var(--silver); font-family: var(--font-ui); font-weight: 500; font-size: 16px; }
.site-menu nav { position: absolute; left: 0; right: 0; top: 100%; z-index: 10; display: grid; padding: var(--s1) var(--gutter); background: var(--bg); border-bottom: 1px solid var(--line); }
.site-header nav a, .site-header nav .nav-button, .nav-menu > summary { font-family: var(--font-ui); font-weight: 500; font-size: 16px; color: var(--muted); text-decoration: none; min-height: 44px; padding: 0 12px; border-radius: 6px; display: inline-flex; align-items: center; background: none; border: 0; cursor: pointer; }
.site-header nav a:hover, .site-header nav .nav-button:hover, .nav-menu > summary:hover { color: var(--text); background: var(--copper-tint); }
.site-header nav a[aria-current=page], .nav-menu > summary.current { color: var(--text); box-shadow: inset 0 -2px 0 var(--copper); border-radius: 6px 6px 0 0; }
.site-header nav a.btn { color: var(--text); background: var(--btn-secondary); border: 1px solid var(--btn-secondary-edge); padding: var(--s1) var(--s2); margin: var(--s1) 0 0; justify-content: center; }
.site-header nav a.btn:hover { color: var(--text); background: var(--btn-secondary-hover); }
.site-header .nav-button, .site-header .mode-switch { line-height: inherit; }
.site-header form { margin: 0; }
.nav-menu { margin: 0; }
.nav-menu > summary::after { content: "▾" / ""; margin-left: 6px; }
.header-picture { margin-right: 8px; width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: none; }
.nav-menu[open] > summary { color: var(--text); }
.menu-items { display: grid; }
.menu-items a, .menu-items .nav-button { width: 100%; justify-content: flex-start; text-align: left; }
.menu-items form { display: contents; }
.menu-items a:has(.menu-hint) { flex-direction: column; align-items: flex-start; justify-content: center; padding: 6px 12px; line-height: 1.3; }
.menu-hint { font-weight: 400; font-size: 14px; color: var(--muted); }
/* On a phone the account menu is listed flat in the panel. */
@media (max-width: 768px) {
    @supports selector(::details-content) {
        .nav-menu > summary { display: none; }
        .account-menu > summary:has(.header-picture:not([data-roles])), html[data-roles~="pictured"] .account-menu > summary { display: inline-flex; pointer-events: none; }
        .account-menu > summary::after { content: none; }
        .nav-menu::details-content { content-visibility: visible; display: contents; }
    }
    .account-items { border-top: 1px solid var(--line); padding-top: var(--s1); margin-top: var(--s1); }
}
/* On a computer the items are in the row and the account menu is a dropdown. */
@media (min-width: 769px) {
    @supports selector(::details-content) {
        .site-menu > summary { display: none; }
        .site-menu::details-content { content-visibility: visible; display: contents; }
        .site-menu nav { position: static; display: flex; flex-wrap: wrap; align-items: center; gap: 0 4px; margin-left: -12px; padding: 0; background: none; border: 0; }
        .site-header nav a.btn { margin: 0 0 0 var(--s1); }
        .nav-menu { position: relative; }
        .menu-items { position: absolute; left: 0; top: 100%; z-index: 5; min-width: 270px; background: var(--surface); border: 1px solid var(--line); border-top: 2px solid var(--copper); border-radius: 0 0 8px 8px; padding: 4px; }
        .account-items { left: auto; right: 0; }
    }
}

/* The Broadcaster Mode switch (role=switch; site.js sets aria-checked) and, while live, the On Air light inside it.
   Beside Menu on a phone with its label folded away; in the panel and the row otherwise. */
.site-header .mode-switch { font-family: var(--font-ui); font-weight: 500; font-size: 16px; color: var(--muted); background: none; border: 0; border-radius: 6px; min-height: 44px; padding: 0 12px; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.site-header .mode-switch:hover { color: var(--text); background: var(--copper-tint); }
.mode-switch[aria-checked=true], html.broadcaster-mode .mode-switch { color: var(--text); }
.mode-switch[aria-checked=true] .icon-eye, .mode-switch[aria-checked=false] .icon-eye-off, html.broadcaster-mode .mode-switch .icon-eye { display: none; }
html.broadcaster-mode .mode-switch .icon-eye-off { display: inline; }
.mode-switch[aria-disabled=true] { cursor: default; }
.mode-track { position: relative; width: 36px; height: 20px; border-radius: 10px; background: var(--line); border: 1px solid var(--muted); flex: none; }
.mode-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--muted); }
.mode-switch[aria-checked=true] .mode-track, html.broadcaster-mode .mode-switch .mode-track { background: var(--copper); border-color: var(--copper); }
.mode-switch[aria-checked=true] .mode-track::after, html.broadcaster-mode .mode-switch .mode-track::after { left: 18px; background: var(--bg); }
@media (forced-colors: active) { .mode-track { border-color: CanvasText; } .mode-track::after { background: CanvasText; } .mode-switch[aria-checked=true] .mode-track { background: Highlight; } }
.mode-group { display: inline-flex; align-items: center; }
.mode-label, .mode-onair-text { white-space: nowrap; }
.mode-switch .icon { flex: none; }
/* The words fold away on a narrow phone so the switch and its ? stay on one row; the light and the name keep saying On Air. */
@media (max-width: 399px) { .mode-onair-text { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); } }
.mode-onair { display: none; align-items: center; gap: 6px; color: var(--text); }
.mode-live .mode-onair { display: inline-flex; }
.site-header .mode-switch.folded { margin-left: auto; padding: 0 8px; }
@media (min-width: 769px) { .site-header .mode-switch.folded { display: none; } }
.site-header .help-text { margin-top: 0; }

/* The footer: four groups that flow with the width; the line above them stops at the frame. */
.site-footer .frame { border-top: 1px solid var(--line); padding-top: var(--s3); padding-bottom: var(--s4); font-family: var(--font-ui); font-size: 15px; }
.footer-groups { display: grid; gap: var(--s3); grid-template-columns: 1fr; }
@media (min-width: 480px) { .footer-groups { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 768px) { .footer-groups { grid-template-columns: repeat(4, 1fr); } }
.footer-groups h2 { font-size: 14px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin: 0 0 4px; }
.footer-groups ul { list-style: none; margin: 0; padding: 0; display: grid; }
.footer-groups li { margin: 0; }
.site-footer a { color: var(--muted); display: inline-flex; align-items: center; min-height: 36px; font-size: inherit; font-family: inherit; text-decoration: none; }
.site-footer a:hover, .site-footer a[aria-current=page] { color: var(--text); text-decoration: underline; }
/* Text. The three type roles (docs/design.md, Type): fonts.css names the families. Titles are
   in the display face; everything you press, name, or find your way by is in the UI face;
   everything you read is in the body face (set on body). The scale: 36 / 22 / 18 / 17 / 15. */
h1 { font-family: var(--font-display); font-weight: 700; font-size: 36px; line-height: 1.1; margin: 0 0 var(--s3); overflow-wrap: anywhere; }
h2, h3, h4, h5, h6, label, legend, th, summary, .brand, .site-header nav, .site-footer, .section-nav, .tag, .app-button, .method { font-family: var(--font-ui); }
h2 { font-size: 22px; font-weight: 600; line-height: 1.25; margin: 0 0 var(--s2); }
h3 { font-size: 18px; font-weight: 600; margin: var(--s3) 0 var(--s1); }
h4 { font-size: 17px; font-weight: 600; margin: var(--s2) 0 var(--s1); }
p { margin: 0 0 var(--s2); }
a { color: var(--silver); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--text); }
li { margin: 4px 0; }
.muted, .hint { color: var(--muted); }
.hint { font-size: 15px; line-height: 1.5; }
.lead { font-size: 19px; }
.error { color: var(--error); }
/* An error always carries a mark, so it is never mistaken for the crimson of live. Screen readers
   skip the mark (its alternative text is empty): the words already say what went wrong. */
p.error::before, .field .error::before, .rows .error::before { content: "! " / ""; font-weight: 700; }
.plain { list-style: none; padding: 0; margin: 0 0 var(--s2); }
:target { scroll-margin-top: var(--s3); }
/* A section's title with its "?" beside it (x-help-button), on one line. */
.section-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0 0 var(--s2); }
.section-head h2 { margin: 0; }
/* The notice about the service as a whole (#180): amber, as a warning is. */
.service-notice { border-color: var(--warning); }
/* The alpha banner (#1325): a strip inside the header's frame, in the flow under the bar, so it never covers a control. */
.notice.alpha-banner { background: var(--copper-light); color: var(--copper-ink); border: 0; border-radius: 6px; margin: var(--s2) 0 0; text-align: center; }
.alpha-banner a { color: var(--copper-ink); text-decoration: underline; }
.alpha-banner a:focus-visible { outline-color: var(--copper-ink); }
@media (forced-colors: active) { .alpha-banner { border: 2px solid CanvasText; } }
.notice ol { margin: var(--s1) 0; padding-left: var(--s3); }
/* Forms: a label above its field, a hint and any error below it. Fields are cut into the panel. */
.stack { display: grid; gap: var(--s2); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); align-items: start; margin: 0 0 var(--s2); }
.stack > * { margin: 0; grid-column: 1 / -1; }
.stack > .field:not(.long) { grid-column: auto; }
/* A run of short fields (not .long) that ends alone, or odd in a column, takes the whole row; buttons and hints may follow, so no :last-child. */
.stack > :not(.field:not(.long)) + .field:not(.long):not(:has(+ .field:not(.long))),
.stack > .field:not(.long):first-child:not(:has(+ .field:not(.long))),
.column .stack > :not(.field:not(.long)) + .field:not(.long) + .field:not(.long) + .field:not(.long):not(:has(+ .field:not(.long))),
.column .stack > .field:not(.long):first-child + .field:not(.long) + .field:not(.long):not(:has(+ .field:not(.long))) { grid-column: 1 / -1; }
.stack > button, .stack > .btn { justify-self: start; }
.field { display: grid; gap: 4px; }
.field > * { margin: 0; }
label.check { display: flex; align-items: flex-start; gap: 10px; font-family: var(--font-body); }
label.check input { width: 20px; height: 20px; margin: 3px 0 0; flex: none; }
/* Refer a Broadcaster (#1997): the two notes side by side from 660px, and the chat email box only while its box is ticked. */
#recommend .refer-notes { display: grid; gap: var(--s2); }
@media (min-width: 660px) {
  #recommend .refer-notes { grid-template-columns: 1fr 1fr; }
  #recommend .refer-notes > .field { grid-row: span 3; grid-template-rows: subgrid; }
}
#recommend .refer-chat { margin: 0; }
#recommend .refer-chat:not(:has(input[name=talk_with_us]:checked)) :is(.field, .refer-chat-hint) { display: none; }
fieldset { border: 0; padding: 0; margin: 0 0 var(--s2); display: grid; gap: var(--s1); }
legend { padding: 0; margin: 0 0 var(--s1); }
/* Buttons side by side, and whatever is said about them underneath. */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s2); margin: 0 0 var(--s2); }
.actions form { margin: 0; }
.actions button.link, td button.link, .rows button.link, .notice button.link { padding: 10px 0; }
/* Something that should not happen by one stray click, or that most people do not need open (the
   password change): the form sits behind a line that opens. */
details { margin: 0 0 var(--s2); }
summary { cursor: pointer; color: var(--silver); padding: 10px 0; width: fit-content; font-weight: 500; }
details[open] > summary { color: var(--text); }
.actions > details { margin: 0; }
details > .inside { background: var(--bg); border-radius: 6px; padding: var(--s2); margin: var(--s1) 0 0; }
details > .inside > :last-child { margin-bottom: 0; }
/* Things to copy: a key, a link, a code. The Copy button appears when the browser can copy. */
code { background: var(--bg); border: 1px solid var(--line); border-radius: 4px; padding: 1px 6px; overflow-wrap: anywhere; font-size: .95em; }
.section-head h3 { margin: 0; }
.service-notice:empty { display: none; }
