/* CodeBoard — front end styles.
 *
 * Namespaced under .codeboard-root so themes don't fight it, and deliberately the
 * same vocabulary as CodeChat: warm paper, hairline cards, monospace for labels
 * and anything countable, prose for anything a person wrote. The two plugins sit
 * on the same site and must read as one product.
 *
 * Three schemes, same as the room — Light, Dark, BIOS — and the same rule about
 * them: each block covers exactly the same classes, so a fourth scheme is a copy
 * of one of them and never a hunt for what got missed.
 */

.codeboard-root {
	--cb-accent: #44423d;
	--cb-bg: #f7f6f3;
	--cb-panel: #fffefc;
	--cb-line: #e6e3dd;
	--cb-ink: #2b2a27;
	--cb-quiet: #7c7972;
	--cb-faint: #8e8b84;
	--cb-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
	box-sizing: border-box;
	display: block;
	/* Set inline by the shortcode's width= attribute; the fallback matters because a
	   cached page from before that attribute existed has no custom property on it. */
	max-width: var(--cb-width, 1200px);
	/* Equal above and below, always. Themes put wildly different amounts of air
	   around a shortcode and the block ends up sitting high in its own space; one
	   margin on both sides is what makes it read as centred. */
	margin: var(--cb-gap, 32px) auto;
	background: var(--cb-bg);
	color: var(--cb-ink);
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	font-size: 15px;
	line-height: 1.5;
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	border: 1px solid var(--cb-line);
	border-radius: 14px;
	overflow: hidden;
	-webkit-font-smoothing: antialiased;
}
/* -------------------------------------------------------------------------
 * Breaking out of the theme's column
 *
 * width= is a ceiling, not a floor: a theme whose content area is 1000px wide
 * keeps the board at 1000px however wide it asks to be, because the container is
 * the one doing the measuring. bleed="yes" centres the board against the
 * viewport instead — 50% of the parent, then half its own width back — so the
 * requested width is the width, whatever column it happens to sit in.
 *
 * The 100vw cap with an allowance either side is what keeps it off the screen
 * edges (and stops a horizontal scrollbar appearing) when the width asked for is
 * larger than the display.
 * ---------------------------------------------------------------------- */
.codeboard-root.cb-bleed {
	width: var(--cb-width, 1200px);
	max-width: calc(100vw - 48px);
	margin-left: 50%;
	transform: translateX(-50%);
}
/* The gate is a small form in a big field; it should not follow the board out. */
.codeboard-root.cb-bleed.cb-gated { width: 460px; }
@media (max-width: 640px) {
	/* On a phone the theme's column IS the screen, so the break-out has nothing to
	   escape and its allowance only makes the board narrower than the page. */
	.codeboard-root.cb-bleed { width: auto; max-width: none; margin-left: auto; transform: none; }
}

.codeboard-root *, .codeboard-root *::before, .codeboard-root *::after { box-sizing: border-box; }
.cb-boot { padding: 40px 22px; text-align: center; color: var(--cb-quiet); font-family: var(--cb-mono); font-size: 12px; }

/* The gate is a small form, so the shell shrinks to it rather than holding the
   board's full width open around it. */
.codeboard-root.cb-gated { max-width: 460px; border-radius: 18px; }

.cb-shell { display: flex; flex-direction: column; padding: 0 26px; }

/* -------------------------------------------------------------------------
 * Breadcrumbs and refresh
 *
 * Above the header's rule rather than inside it, so the first line of the frame
 * still reads as the top of the board. Small on purpose: this is the row you look
 * at when you want to know where you are, and never otherwise.
 * ---------------------------------------------------------------------- */

.cb-crumbs { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 2px 0; }
.cb-crumb-trail { display: flex; align-items: center; gap: 5px; min-width: 0; overflow: hidden; }
.cb-crumb { flex: none; max-width: 34ch; padding: 0; font: inherit; font-size: 10.5px; letter-spacing: .02em; color: var(--cb-faint); background: none; border: none; cursor: pointer; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cb-crumb:hover { color: var(--cb-ink); text-decoration: underline; text-underline-offset: 2px; }
/* The end of the trail is where you already are, so it is not a link and does not
   pretend to be one — but it is the one crumb worth reading, so it is the darker. */
.cb-crumb-here { flex: 0 1 auto; min-width: 0; color: var(--cb-quiet); cursor: default; }
.cb-crumb-here:hover { color: var(--cb-quiet); text-decoration: none; }
.cb-crumb-sep { flex: none; font-family: var(--cb-mono); font-size: 9px; color: var(--cb-line); }
.cb-refresh { flex: none; display: inline-flex; align-items: center; gap: 5px; padding: 0; font: inherit; font-size: 10.5px; color: var(--cb-faint); background: none; border: none; cursor: pointer; }
.cb-refresh:hover { color: var(--cb-ink); }
.cb-refresh-icon { display: inline-block; font-size: 11px; line-height: 1; }
.cb-refresh-busy { color: var(--cb-quiet); }
.cb-refresh-busy .cb-refresh-icon { animation: cb-spin .7s linear infinite; }
@keyframes cb-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cb-refresh-busy .cb-refresh-icon { animation: none; } }
@media (max-width: 640px) {
	.cb-crumbs { padding-top: 8px; }
	.cb-crumb { max-width: 18ch; }
}

/* -------------------------------------------------------------------------
 * Formatted post bodies
 *
 * The whole vocabulary a post can use: weight, slant, underline, a colour, a
 * size, and a quote. Styled here rather than left to the theme, because a theme's
 * blockquote is usually a pull-quote — large, centred, decorative — and this one
 * is somebody else's sentence being answered.
 * ---------------------------------------------------------------------- */
.cb-text b, .cb-text strong { font-weight: 700; }
.cb-text u { text-underline-offset: 3px; }
.cb-text p { margin: 0 0 .6em; }
.cb-text p:last-child { margin-bottom: 0; }
/* A quote is a small panel one step up from the post it sits in — borrowed words,
   visibly held apart from the answer around them. The left edge keeps the heavier
   rule the chat room quotes with, so it still reads as a quotation and not as a
   callout. */
.cb-text blockquote,
.cb-editable blockquote {
	margin: .55em 0 .7em;
	padding: 10px 13px;
	color: #6b6862;
	background: var(--cb-panel);
	border: 1px solid var(--cb-line);
	border-left: 2px solid #cfc9c0;
	border-radius: 10px;
	/* One size for every quote, a step under the post's own text. Whatever size the
	   original was set at is not part of what is being quoted — and a quote that
	   arrives larger than the reply answering it inverts the whole point. */
	font-size: 14px;
	line-height: 1.55;
	font-weight: 400;
	/* Italic, because it is somebody else's voice inside your paragraph. Set on the
	   block and forced through the children for the same reason the size is: the
	   carried-over markup brings its own. */
	font-style: italic;
}
.cb-text blockquote *,
.cb-editable blockquote * { font-style: inherit; }
/* important because the carried-over markup brings the author's own inline sizes
   with it, and an inline style beats an ordinary rule. This is the one place the
   plugin overrules a person's formatting, and it does it for legibility. */
.cb-text blockquote *,
.cb-editable blockquote * { font-size: inherit !important; }
/* Attribution stays upright — it is a label on the quote, not part of the quoted
   voice. */
.cb-text blockquote[data-author]::before,
.cb-editable blockquote[data-author]::before {
	display: block;
	margin-bottom: 4px;
	content: attr(data-author);
	font-family: var(--cb-mono);
	font-size: 10px;
	font-style: normal;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cb-faint);
}

/* -------------------------------------------------------------------------
 * Gate
 * ---------------------------------------------------------------------- */

/* Bottom padding runs short of the top on purpose: the block ends in the notes
   list, whose last line carries descender space below its ink, while the top
   starts on small-caps that have almost none. The 8px is the optical correction. */
.cb-gate { display: flex; flex-direction: column; align-items: center; gap: 26px; padding: 40px 22px 32px; width: 100%; }
.cb-gate-head { display: flex; flex-direction: column; gap: 8px; align-items: center; text-align: center; width: 100%; max-width: 400px; }
.cb-eyebrow { font-family: var(--cb-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--cb-quiet); }
.cb-gate-title { margin: 0; width: 100%; font-size: 30px; font-weight: 600; letter-spacing: -.02em; overflow-wrap: anywhere; text-wrap: balance; }
.cb-gate-sub { margin: 0; width: 100%; color: #5c5a55; font-size: 15px; text-wrap: pretty; }
.cb-card { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 400px; padding: 22px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 14px; box-shadow: 0 8px 24px rgba(0,0,0,.04); }
.cb-label { font-family: var(--cb-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--cb-quiet); }
.cb-label-spaced { margin-top: 6px; }
/* 16px floor on every field: anything under it makes mobile browsers magnify the
   page on focus. */
.cb-input { width: 100%; padding: 12px 14px; font: inherit; font-size: max(16px, 1rem); color: var(--cb-ink); background: #fff; border: 1px solid #d9d5ce; border-radius: 11px; outline: none; }
.cb-input:focus { border-color: var(--cb-accent); box-shadow: 0 0 0 3px rgba(68,66,61,.14); }
.cb-input-code { font-family: var(--cb-mono); font-size: 20px; letter-spacing: .08em; text-transform: uppercase; }
.cb-input:not(.cb-input-code)::placeholder { font-size: clamp(12px, 3.4vw, 15px); }
/* Wrapping declared outright: a host theme only has to set white-space on a
   descendant selector for this line to run out of the card. */
.cb-error { width: 100%; min-width: 0; padding: 9px 11px; font-size: 13px; color: #8c2f1c; background: #fbeae6; border-radius: 7px; white-space: normal; overflow-wrap: anywhere; text-wrap: pretty; }
/* Not everything the archive has to say back is a failure. “That name is yours?
   Prove it” is an instruction to carry on, and red would tell the one person who
   is entitled to the name that they had done something wrong. Same shape as the
   error box so the card does not jump when one replaces the other. */
.cb-notice { width: 100%; min-width: 0; padding: 9px 11px; font-size: 13px; color: #6b4a2f; background: #fdf6ec; border-radius: 7px; white-space: normal; overflow-wrap: anywhere; text-wrap: pretty; }
.cb-notes { display: block; margin: 0; padding: 0 0 0 18px; width: 100%; max-width: 400px; text-align: left; list-style: decimal outside; }
.cb-note { display: list-item; margin: 0 0 3px; font-size: 11.5px; line-height: 1.5; color: var(--cb-quiet); }
.cb-note:last-child { margin-bottom: 0; }
.cb-note::marker { font-family: var(--cb-mono); font-size: 10px; color: var(--cb-faint); }

.cb-btn { padding: 12px 16px; font: inherit; font-size: 15px; font-weight: 500; color: #fff; background: var(--cb-accent); border: none; border-radius: 11px; cursor: pointer; }
.cb-btn:disabled { opacity: .6; cursor: default; }
.cb-btn-sm { padding: 7px 12px; font: inherit; font-size: 13px; color: #3a3833; background: #fff; border: 1px solid var(--cb-line); border-radius: 7px; cursor: pointer; }
.cb-btn-sm:hover { border-color: #b9b4ab; }
.cb-btn-sm:disabled { opacity: .55; cursor: default; }

/* -------------------------------------------------------------------------
 * Header
 * ---------------------------------------------------------------------- */

/* Top padding is small because the breadcrumb row above already supplies the air. */
.cb-head { display: flex; align-items: center; gap: 12px; padding: 10px 2px 14px; border-bottom: 1px solid var(--cb-line); }
.cb-head-left { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.cb-head-title { font-size: 17px; font-weight: 600; letter-spacing: -.01em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-family: var(--cb-mono); font-size: 10.5px; color: var(--cb-quiet); }
.cb-sep { color: #cdc9c1; }
.cb-chip { display: inline-flex; align-items: center; height: 30px; padding: 0 6px; font-family: var(--cb-mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--cb-quiet); background: transparent; border: 1px solid transparent; border-radius: 7px; cursor: pointer; text-decoration: none; }
.cb-chip:hover { color: var(--cb-ink); }
/* The header's controls centre on the header, not on the meta line under the
   title — three controls at three heights is what per-control nudges produce. */
.cb-head > .cb-chip, .cb-head > .cb-themes { align-self: center; flex: none; }

/* -------------------------------------------------------------------------
 * Scheme switch — one bar of three touching rectangles showing the schemes
 * themselves, with a thumb that slides to the chosen one.
 *
 * The bar owns ONE width; segments and thumb are exact thirds of it. Sizing them
 * separately in px is what puts a tick a couple of pixels off its own segment:
 * two numbers that have to agree. Thirds cannot disagree.
 * ---------------------------------------------------------------------- */
/* The scheme bar keeps a soft corner like everything else. */
.cb-themes { position: relative; display: flex; align-items: stretch; width: 78px; height: 20px; border: 1px solid #cfc9c0; border-radius: 5px; overflow: hidden; }
.cb-swatch { flex: 1 1 0; min-width: 0; padding: 0; background-clip: padding-box; border: none; cursor: pointer; }
/* Hairlines BETWEEN segments only, drawn as an inset shadow rather than a border:
   a border is layout, and 1px added to segments two and three is 1px the thumb's
   whole-segment travel does not know about. */
.cb-swatch + .cb-swatch { box-shadow: inset 1px 0 0 #cfc9c0; }
.cb-swatch:hover { box-shadow: inset 0 0 0 2px rgba(0,0,0,.22); }
.cb-swatch[data-scheme="dark"]:hover, .cb-swatch[data-scheme="bios"]:hover { box-shadow: inset 0 0 0 2px rgba(255,255,255,.45); }
.cb-swatch + .cb-swatch:hover { box-shadow: inset 1px 0 0 #cfc9c0, inset 0 0 0 2px rgba(0,0,0,.22); }
.cb-swatch + .cb-swatch[data-scheme="dark"]:hover,
.cb-swatch + .cb-swatch[data-scheme="bios"]:hover { box-shadow: inset 1px 0 0 #cfc9c0, inset 0 0 0 2px rgba(255,255,255,.45); }
.cb-swatch:focus-visible { outline: 2px solid var(--cb-accent); outline-offset: 2px; }
.cb-themes-thumb {
	position: absolute; top: 0; left: 0;
	width: calc(100% / 3); height: 100%;
	box-shadow: inset 0 0 0 2px currentColor;
	pointer-events: none;
	transition: transform .22s cubic-bezier(.4, 0, .2, 1), color .22s linear;
}
@media (prefers-reduced-motion: reduce) { .cb-themes-thumb { transition: none; } }

/* -------------------------------------------------------------------------
 * Board index
 * ---------------------------------------------------------------------- */

.cb-toolbar { display: flex; align-items: center; gap: 10px; padding: 18px 2px 4px; }
.cb-search { flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; padding: 0 14px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 12px; }
.cb-search:focus-within { border-color: var(--cb-accent); box-shadow: 0 0 0 3px rgba(68,66,61,.14); }
.cb-search-icon { flex: none; font-size: 13px; color: var(--cb-faint); }
.cb-search-field { flex: 1; min-width: 0; padding: 11px 0; font: inherit; font-size: max(16px, 1rem); color: var(--cb-ink); background: transparent; border: none; outline: none; }
.cb-x { flex: none; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; line-height: 1; color: #c9c4bb; background: transparent; border: none; border-radius: 6px; cursor: pointer; }
.cb-x:hover { color: var(--cb-ink); background: #e8e5df; }
.cb-x[disabled] { opacity: .5; cursor: default; }
.cb-new { flex: none; padding: 12px 16px; font: inherit; font-size: 14px; font-weight: 500; color: #fff; background: var(--cb-accent); border: none; border-radius: 12px; cursor: pointer; }

.cb-section { display: flex; flex-direction: column; gap: 8px; padding: 20px 2px 0; }
.cb-section-last { padding-bottom: 22px; }
.cb-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cb-sorts { display: flex; gap: 14px; }
.cb-sort { padding: 0; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: #a8a49d; background: transparent; border: none; cursor: pointer; }
.cb-sort:hover { color: var(--cb-quiet); }
.cb-sort-on { color: var(--cb-ink); }

.cb-list { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.cb-item { margin: 0; }
/* Rows are big enough to be thumbed: this list exists mainly to be tapped. */
.cb-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; width: 100%; padding: 15px 17px; text-align: left; color: var(--cb-ink); background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 14px; cursor: pointer; font: inherit; transition: border-color .15s, background .15s; }
.cb-row:hover { border-color: #c3bdb3; background: #f6f4f0; }
.cb-row-pinned { border-color: #cfc9c0; }
.cb-row-main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.cb-row-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 16px; font-weight: 500; text-wrap: pretty; }
.cb-row-byline { font-family: var(--cb-mono); font-size: 10.5px; color: var(--cb-quiet); }
.cb-row-metas { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; }
.cb-metaflag { font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-quiet); white-space: nowrap; }
.cb-metaflag-quiet { color: var(--cb-faint); }
.cb-hit { font-size: 14px; line-height: 1.5; color: #6b6862; text-wrap: pretty; }
.cb-hit mark { color: inherit; background: #f0ecdf; box-shadow: 0 0 0 1px #e2dbc4; }

/* Quiet by design: it should read as a credential, not a decoration. Fixed height
   so the pill centres on the name whatever script the name is written in. */
.cb-badge { flex: none; display: inline-flex; align-items: center; height: 17px; padding: 0 6px; font-family: var(--cb-mono); font-size: 9px; line-height: 1; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; text-indent: .14em; color: #c2650f; background: #e9e7e2; border: 1.5px solid #e07a1f; border-radius: 5px; }

.cb-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 44px 4px 48px; }
.cb-empty-1 { font-size: 15px; color: var(--cb-quiet); }
.cb-empty-2 { font-family: var(--cb-mono); font-size: 11px; color: var(--cb-faint); }
.cb-empty .cb-new { margin-top: 16px; }
.cb-foot { display: flex; justify-content: space-between; gap: 12px; padding: 9px 4px 0; font-family: var(--cb-mono); font-size: 10px; color: var(--cb-faint); }
.cb-more { display: flex; justify-content: center; padding: 12px 0 0; }

/* -------------------------------------------------------------------------
 * Thread
 * ---------------------------------------------------------------------- */

.cb-modwrap { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.cb-modtoggle { display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; padding: 0; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-faint); background: none; border: none; cursor: pointer; }
.cb-modtoggle:hover { color: var(--cb-quiet); }
.cb-modtoggle-caret { font-size: 8px; line-height: 1; }
.cb-modbar { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; padding: 13px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 11px; }

.cb-posts { display: flex; flex-direction: column; padding: 16px 2px 8px; }
@keyframes cb-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cb-op, .cb-cm { animation: none; } }

/* The opening post. A card, because it is the thing being discussed rather than
   one of the discussing. */
.cb-op { padding: 15px 17px 11px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 12px; animation: cb-in .18s ease-out; }
.cb-op .cb-text { max-width: 68ch; font-size: 15.5px; }
/* Two panes, 60/40, divided by a rule rather than by a gap alone — the reader has
   to be able to tell a second body from a wide first one. One pane keeps the
   reading measure; two panes drop it, because the column is already the measure. */
.cb-panes { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
.cb-panes-two { grid-template-columns: 6fr 4fr; }
.cb-pane { min-width: 0; }
.cb-panes-two .cb-text { max-width: none; }
.cb-panes-two .cb-pane-b { padding-left: 22px; margin-left: 22px; border-left: 1px solid var(--cb-line); }
.cb-pane-head { margin-bottom: 5px; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; text-align: center; color: var(--cb-faint); overflow-wrap: anywhere; }

/* -------------------------------------------------------------------------
 * Audio clips
 *
 * The same instrument CodeChat puts under a voice note — play, waveform, clock,
 * save — because somebody who has used the room already knows how to work it.
 * Sits in the first pane's column, under its text.
 * ---------------------------------------------------------------------- */

.cb-clips { display: flex; flex-direction: column; gap: 9px; margin-top: 14px; }
.cb-clip { display: flex; flex-direction: column; gap: 5px; }
.cb-clip-label { font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-faint); overflow-wrap: anywhere; }
.cb-player { display: flex; align-items: center; gap: 10px; padding: 9px 11px 9px 9px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 11px; }
.cb-play { flex: none; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--cb-ink); background: var(--cb-bg); border: 1px solid var(--cb-line); border-radius: 50%; cursor: pointer; }
.cb-play:hover { border-color: var(--cb-quiet); }
/* min-width matters: with a zero basis the fixed gaps can eat the row on a narrow
   screen and collapse every bar to nothing. */
.cb-wave { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; height: 26px; cursor: pointer; overflow: hidden; }
.cb-bar { --cb-bar-off: var(--cb-line); --cb-bar-on: var(--cb-accent); flex: 1 1 auto; min-width: 2px; border-radius: 2px; background: var(--cb-bar-off); }
.cb-bar-on { background: var(--cb-bar-on); }
/* The one bar the playhead is inside, filled to the exact fraction played so the
   waveform agrees with what is being heard. */
.cb-bar-part { background: linear-gradient(to right, var(--cb-bar-on) var(--cb-bar-fill, 0%), var(--cb-bar-off) var(--cb-bar-fill, 0%)); }
/* The fill is a position readout, not decoration: it must land where the audio is,
   on the frame it is told to. A site-wide transition or animation rule — the
   "* { transition: all .3s }" that ships in a great many themes and speed plugins —
   eases every one of these colour changes instead of switching it, and the whole
   fill then glides along behind the sound at a rate of the theme's choosing, which
   is indistinguishable from a broken player. Nothing outside this file gets a vote. */
.codeboard-root .cb-bar,
.codeboard-root .cb-bar-on,
.codeboard-root .cb-bar-part { transition: none !important; animation: none !important; }
.cb-clock { flex: none; min-width: 34px; text-align: right; font-family: var(--cb-mono); font-size: 10.5px; color: var(--cb-quiet); }
.cb-clip-dl, .cb-clip-x { flex: none; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1; color: var(--cb-quiet); background: transparent; border: 1px solid transparent; border-radius: 7px; cursor: pointer; text-decoration: none; }
.cb-clip-dl:hover, .cb-clip-x:hover { color: var(--cb-ink); border-color: var(--cb-line); }
.cb-clip-status { font-family: var(--cb-mono); font-size: 10.5px; color: #8c2f1c; }
.cb-clip-dbg { font-family: var(--cb-mono); font-size: 10px; line-height: 1.5; color: var(--cb-quiet); overflow-wrap: anywhere; }
.cb-clip-cap { display: flex; flex-direction: column; gap: 6px; }
/* The invitation sits below the player, quieter than the caption it writes — it is
   scaffolding only moderators see, and it should not compete with the clip. */
.cb-clip-caplink { align-self: flex-start; padding: 0; font: inherit; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--cb-faint); background: none; border: none; cursor: pointer; }
.cb-clip-caplink:hover { color: var(--cb-quiet); }
.cb-clip-caprow { display: flex; gap: 7px; }

/* The moderator's end of it. Dashed, like the password offer: a control that is
   only there for the few people who can use it should not read as furniture. */
.cb-clipadd { display: flex; flex-direction: column; gap: 8px; padding: 12px 13px 13px; background: var(--cb-panel); border: 1px dashed var(--cb-line); border-radius: 11px; }
.cb-clipadd-head { font-size: 12.5px; font-weight: 600; }
.cb-clipadd-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cb-clipfile { flex: 1 1 190px; min-width: 0; font-family: var(--cb-mono); font-size: 11px; color: var(--cb-quiet); }
.cb-clipfile::file-selector-button { margin-right: 8px; padding: 7px 10px; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--cb-ink); background: var(--cb-bg); border: 1px solid var(--cb-line); border-radius: 8px; cursor: pointer; }
.cb-clipnote { font-family: var(--cb-mono); font-size: 10px; line-height: 1.55; color: var(--cb-faint); text-wrap: pretty; }
/* Drawn always, shown only where there is no room for two columns. */
.cb-pane-toggle { display: none; }

/* -------------------------------------------------------------------------
 * Tablet portrait and narrower
 *
 * 1024px is iPad-portrait width, and 40% of it is a column two words wide. The
 * second pane folds behind a disclosure instead: the toggle carries the pane's
 * own heading, and the panel below it is visibly one piece with the button so
 * nobody has to wonder what opened.
 * ---------------------------------------------------------------------- */
@media (max-width: 1024px) {
	.cb-panes-two { grid-template-columns: minmax(0, 1fr); }
	.cb-panes-two .cb-pane-b { display: none; margin: 0; padding: 12px 13px 13px; border: 1px solid var(--cb-line); border-top: none; border-radius: 0 0 10px 10px; }
	.cb-panes-two.cb-panes-open .cb-pane-b { display: block; }
	/* The heading is already the label on the button above it. */
	.cb-panes-two .cb-pane-b .cb-pane-head { display: none; }
	.cb-pane-toggle { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 44px; margin-top: 14px; padding: 10px 13px; text-align: left; font: inherit; color: var(--cb-ink); background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 10px; cursor: pointer; }
	.cb-pane-toggle:hover { border-color: var(--cb-quiet); }
	.cb-panes-open .cb-pane-toggle { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
	.cb-pane-toggle-label { min-width: 0; font-family: var(--cb-mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--cb-quiet); overflow-wrap: anywhere; }
	.cb-pane-caret { flex: none; font-size: 11px; line-height: 1; color: var(--cb-faint); transition: transform .16s ease-out; }
	.cb-panes-open .cb-pane-caret { transform: rotate(180deg); }
}
@media (prefers-reduced-motion: reduce) {
	.cb-pane-caret { transition: none; }
}
/* The post being answered, while it is being answered. Enough to find it,
   nothing like a highlight. */
.cb-op-target { border-color: var(--cb-quiet); box-shadow: inset 2px 0 0 var(--cb-quiet); }

/* One byline shape everywhere: who, standing, when. Centred rather than
   baseline-aligned because the row mixes a pill, Latin text, Hangul and
   monospace digits, and only centring lines all four up. */
.cb-byline { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 5px; }
/* The name must never be the thing that gives: a squeezed Hangul name breaks one
   glyph per line, so it stays intrinsic and the rest of the row wraps instead. */
.cb-author { font-size: 13px; font-weight: 600; letter-spacing: .01em; flex: 0 0 auto; min-width: max-content; white-space: nowrap; word-break: keep-all; }
.cb-dot { font-size: 11px; color: var(--cb-faint); }
.cb-time { font-family: var(--cb-mono); font-size: 10.5px; color: var(--cb-faint); }
.cb-edited { font-family: var(--cb-mono); font-size: 10.5px; font-style: italic; color: var(--cb-faint); }
.cb-text { max-width: 72ch; font-size: 15px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; text-wrap: pretty; }
/* Under the post, not beside it: a board's controls are a row of quiet words on
   their own line. Pulled left by the button's own padding so the first word
   lines up with the text above it. */
.cb-acts { display: flex; align-items: center; gap: 2px; margin: 7px 0 0 -6px; }

/* The comment stream */
.cb-cmhead { display: flex; align-items: baseline; gap: 10px; margin-top: 4px; padding: 4px 2px 7px; border-bottom: 1px solid var(--cb-line); }
.cb-cmcount { font-size: 13px; font-weight: 600; }
.cb-cmsort { font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-faint); }
.cb-cmempty { padding: 20px 4px 10px; font-size: 13.5px; color: var(--cb-quiet); }
.cb-stream { display: flex; flex-direction: column; }
/* Tight rows, no cards, no rules between them — the rail is what separates one
   voice from the next, the way a board has always done it. */
.cb-cm { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 0 9px; padding: 11px 0 9px; animation: cb-in .18s ease-out; }
.cb-cm .cb-byline { margin-bottom: 2px; }
.cb-cm .cb-author { font-size: 12.5px; }
.cb-cm .cb-text { font-size: 14.5px; line-height: 1.5; }
.cb-cm .cb-acts { margin-top: 5px; }
.cb-cm-target { box-shadow: inset 2px 0 0 var(--cb-quiet); }
.cb-cm-target > .cb-rail { padding-left: 4px; }

/* The collapse rail. The knob says what will happen; the spine is the same
   control at arm's length, because on a long post the line beside the text is
   the thing under the cursor. */
.cb-rail { display: flex; flex-direction: column; align-items: center; gap: 4px; padding-top: 1px; }
.cb-rail-btn { flex: none; display: flex; align-items: center; justify-content: center; width: 18px; height: 18px; padding: 0; font-family: var(--cb-mono); font-size: 11px; line-height: 1; color: var(--cb-faint); background: transparent; border: 1px solid var(--cb-line); border-radius: 4px; cursor: pointer; }
.cb-rail-btn:hover { color: var(--cb-ink); border-color: var(--cb-quiet); }
.cb-spine { flex: 1 1 auto; width: 18px; min-height: 8px; padding: 0; background: transparent; border: none; cursor: pointer; }
.cb-spine::before { content: ''; display: block; width: 1px; height: 100%; margin: 0 auto; background: var(--cb-line); }
.cb-spine:hover::before { background: var(--cb-quiet); }
.cb-cm-body { min-width: 0; }
/* Folded: the byline stays, so the thread still reads as a list of who spoke. */
.cb-cm-collapsed { padding: 5px 0; }
.cb-cm-collapsed .cb-cm-main { display: none; }
.cb-cm-collapsed .cb-byline { margin-bottom: 0; }
.cb-cm-collapsed .cb-author { color: var(--cb-quiet); }
.cb-cm-collapsed .cb-spine { display: none; }

@media (max-width: 640px) {
	.cb-cm { grid-template-columns: 16px minmax(0, 1fr); gap: 0 7px; }
	.cb-rail-btn, .cb-spine { width: 16px; }
	.cb-rail-btn { height: 16px; }
	/* A card inside a card, with a phone's width to share between them. The frame
	   around the whole view already says where the entry begins, so the opening post
	   drops its own walls and gives the text back the 34px they were holding. The
	   rule under it does the separating instead. */
	.cb-op { padding: 2px 0 12px; background: none; border: none; border-radius: 0; border-bottom: 1px solid var(--cb-line); }
	.cb-op-target { border-color: transparent; border-bottom-color: var(--cb-quiet); }
	/* The disclosure keeps its own frame — it is a control, and needs an edge to be
	   pressable — but sits flush with the text now that nothing is inset. */
	.cb-panes-two .cb-pane-b { padding-left: 13px; padding-right: 13px; }
}
.cb-word { flex: none; height: 22px; padding: 0 6px; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: #bdb8af; background: transparent; border: none; border-radius: 6px; cursor: pointer; }
.cb-word:hover { color: var(--cb-ink); background: #efece6; }
/* Tapping × reveals the confirmation beside it rather than recolouring the ×: a
   word says what happens next, a colour only says something changed. */
.cb-xnow { flex: none; padding: 2px 7px; font-family: var(--cb-mono); font-size: 10.5px; color: #8c2f1c; background: #fbeae6; border: none; border-radius: 5px; cursor: pointer; }
.cb-xnow:hover { color: #fff; background: #b0605a; }

/* A moderator is marked in the byline rather than by position: on a board every
   voice sits in the same column, and standing is a label, not a side. */
.cb-cm-mod > .cb-rail .cb-rail-btn { border-color: var(--cb-quiet); }

/* Writing and editing an entry: the same 60/40 the reader gets, so what you type
   in is laid out where it will end up. */
.cb-twocol { display: grid; grid-template-columns: 6fr 4fr; gap: 14px 20px; }
.cb-twocol-a, .cb-twocol-b { min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.cb-headfield { width: 100%; padding: 7px 10px; font: inherit; font-family: var(--cb-mono); font-size: 11px; letter-spacing: .08em; color: var(--cb-ink); background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 8px; outline: none; }
.cb-headfield:focus { border-color: var(--cb-accent); }
.cb-headfield::placeholder { letter-spacing: 0; color: var(--cb-faint); }

/* -------------------------------------------------------------------------
 * The recovery-password offer
 *
 * Quiet enough to skip past, explicit enough that skipping is a decision rather
 * than an oversight. It sits under the form until the name has a password, and
 * then is never drawn again — so it is allowed to spend a few lines explaining
 * itself the handful of times it appears.
 * ---------------------------------------------------------------------- */

.cb-pw { display: flex; flex-direction: column; gap: 7px; margin-top: 14px; padding: 13px 15px 14px; background: var(--cb-panel); border: 1px dashed var(--cb-line); border-radius: 11px; }
.cb-pw-inline { margin-top: 10px; }
.cb-pw-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.cb-pw-title { font-size: 12.5px; font-weight: 600; }
.cb-pw-opt { font-family: var(--cb-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--cb-faint); }
.cb-pw-why { max-width: 68ch; margin: 6px 0 0; font-size: 12.5px; line-height: 1.65; color: var(--cb-quiet); text-wrap: pretty; word-break: keep-all; }
.cb-pw-why-btn { display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; margin-top: 8px; padding: 0; font: inherit; font-size: 11.5px; color: var(--cb-quiet); background: none; border: none; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--cb-line); cursor: pointer; word-break: keep-all; }
.cb-pw-why-btn:hover { color: var(--cb-ink); text-decoration-color: var(--cb-quiet); }
.cb-pw-why-caret { font-size: 8px; line-height: 1; color: var(--cb-faint); }

/* The set/change panel on the board list. Same materials as the inline offer, but
   solid rather than dashed — this one was asked for. */
.cb-pwpanel { display: flex; flex-direction: column; gap: 9px; margin: 14px 0 4px; padding: 15px 17px 16px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 12px; }
.cb-pwpanel .cb-pw-why { margin: 0; }
.cb-pwpanel .cb-pw-field { width: 100%; }
.cb-pwpanel .cb-pw-row { margin-top: 0; }
.cb-pwpanel .cb-editrow { margin-top: 2px; }
.cb-pw-row { display: flex; align-items: stretch; gap: 8px; margin-top: 3px; }
.cb-pw-field { flex: 1 1 auto; min-width: 0; padding: 9px 12px; font: inherit; font-size: 14px; color: var(--cb-ink); background: var(--cb-bg); border: 1px solid var(--cb-line); border-radius: 9px; outline: none; }
.cb-pw-field:focus { border-color: var(--cb-accent); }
.cb-pw-field::placeholder { color: var(--cb-faint); }
.cb-pw-eye { flex: none; min-width: 62px; padding: 0 12px; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-quiet); background: var(--cb-bg); border: 1px solid var(--cb-line); border-radius: 9px; cursor: pointer; }
.cb-pw-eye:hover { color: var(--cb-ink); border-color: var(--cb-quiet); }

@media (max-width: 640px) {
	.cb-pw-row { flex-wrap: wrap; }
	.cb-pw-field { flex: 1 1 100%; }
	.cb-pw-eye { min-height: 40px; }
}

/* Writing keeps both panes on screen, stacked — a field somebody is meant to fill
   is the one thing that must not be hidden behind a tap. This sits after the rule
   it overrides: same specificity, so source order is what decides it. */
@media (max-width: 1024px) {
	.cb-twocol { grid-template-columns: minmax(0, 1fr); }
}

/* Editing in place. The frame is the same one the composer wears, so it reads as
   "this is a field now" without anything moving. */
.cb-editbox { max-width: 62ch; display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; background: var(--cb-panel); border: 1px solid var(--cb-accent); border-radius: 12px; box-shadow: 0 0 0 3px rgba(68,66,61,.14); }
.cb-editbox .cb-editable { width: 100%; min-height: 90px; max-height: 320px; padding: 0; }
/* Editing the opening post: two panes, so the box runs the full width of the card
   and each pane keeps a column of its own. */
.cb-editbox-wide { max-width: none; }
.cb-editbox-wide .cb-twocol .cb-editable { padding: 10px 12px; background: var(--cb-bg); border: 1px solid var(--cb-line); border-radius: 10px; }
.cb-editbox-wide .cb-twocol .cb-editable:focus { border-color: var(--cb-accent); }
.cb-editbox .cb-tools { padding: 0 0 2px; }
.cb-editrow { display: flex; align-items: center; gap: 8px; }
.cb-editnote { margin-left: auto; font-family: var(--cb-mono); font-size: 10px; color: var(--cb-faint); }
.cb-edittitle { width: 100%; padding: 0 0 8px; font: inherit; font-size: 17px; font-weight: 600; color: var(--cb-ink); background: transparent; border: none; border-bottom: 1px solid var(--cb-line); outline: none; }

/* -------------------------------------------------------------------------
 * Composer
 * ---------------------------------------------------------------------- */

.cb-composer { padding: 14px 0 4px; }

/* -------------------------------------------------------------------------
 * The editor
 *
 * One control strip, used by the composer, the in-place edit and the new-thread
 * form alike — a formatting button that moves between them would be a formatting
 * button somebody has to find twice.
 *
 * Buttons carry the mark they make: B is bold, I is italic, U is underlined. A
 * toolbar of identical-looking letters is a toolbar you have to read.
 * ---------------------------------------------------------------------- */
.cb-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 0 2px 8px; }
.cb-tool { flex: none; min-width: 28px; height: 28px; padding: 0 7px; font-family: var(--cb-mono); font-size: 12px; line-height: 1; color: var(--cb-quiet); background: transparent; border: 1px solid transparent; border-radius: 7px; cursor: pointer; }
.cb-tool:hover { color: var(--cb-ink); background: #efece6; }
.cb-tool-on { color: var(--cb-ink); background: #e8e5df; }
.cb-tool-b { font-weight: 700; }
.cb-tool-i { font-style: italic; }
.cb-tool-u { text-decoration: underline; text-underline-offset: 2px; }
/* Sizes read as sizes: S, M and L are set at the size they apply. */
.cb-tool-s { font-size: 10px; }
.cb-tool-m { font-size: 12px; }
.cb-tool-l { font-size: 15px; }
.cb-tool-div { flex: none; width: 1px; height: 18px; margin: 0 4px; background: var(--cb-line); }
/* A colour button IS its colour — a swatch, not a letter. The set is one flex item
   so the row can only break before it, never through it. */
.cb-swatch-set { flex: none; display: flex; align-items: center; gap: 4px; }
.cb-swatch-ink { flex: none; width: 20px; height: 20px; padding: 0; border: 1px solid var(--cb-line); border-radius: 50%; cursor: pointer; }
.cb-swatch-ink:hover { box-shadow: 0 0 0 2px rgba(0,0,0,.12); }

/* The typing surface. Same box as the old textarea wore, so nothing moved when
   formatting arrived; contenteditable rather than a textarea because marks have
   to be visible while they are being made. */
.cb-editable { flex: 1; min-width: 0; max-height: 260px; padding: 9px 0; font-size: max(16px, 1rem); line-height: 1.55; color: var(--cb-ink); outline: none; overflow-y: auto; overflow-wrap: anywhere; scrollbar-width: none; -ms-overflow-style: none; }
.cb-editable::-webkit-scrollbar { width: 0; height: 0; }
/* Placeholders do not exist on a contenteditable, so the empty state draws its
   own — keyed off a class the script sets, not :empty, which a stray <br> defeats. */
.cb-editable-empty::before { content: attr(data-placeholder); color: #a8a49d; pointer-events: none; }
.cb-editable b, .cb-editable strong { font-weight: 700; }

/* Replying to somebody: the bar names them and holds the quote control. It is the
   only place quoting is offered, because a quote without a reply attached is just
   a copy of something already on screen. */
.cb-replybar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 8px; padding: 8px 10px; background: #f2f0ec; border: 1px solid var(--cb-line); border-radius: 10px; }
.cb-replybar-who { flex: 1 1 auto; min-width: 0; font-family: var(--cb-mono); font-size: 11px; color: var(--cb-quiet); overflow-wrap: anywhere; }
.cb-replybar-who b { color: var(--cb-ink); }
.cb-quote-btn { flex: none; height: 28px; padding: 0 10px; font-family: var(--cb-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-ink); background: #fff; border: 1px solid var(--cb-line); border-radius: 7px; cursor: pointer; }
.cb-quote-btn:hover:not(:disabled) { border-color: #b9b4ab; }
/* Disabled until there is a selection to carry over. Told, not merely dimmed:
   the hint beside it says what would switch it on. */
.cb-quote-btn:disabled { color: #b3afa7; background: transparent; cursor: default; }
.cb-quote-hint { flex: 1 1 100%; font-family: var(--cb-mono); font-size: 10px; line-height: 1.5; color: var(--cb-faint); }


.cb-bar-row { display: flex; align-items: flex-end; gap: 8px; padding: 8px 8px 8px 14px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 12px; }
/* Chrome on Android paints a standing scrollbar thumb in the composer, which
   reads as a stray grey rule beside the placeholder. Scrolling still works. */
.cb-send { flex: none; height: 38px; min-height: 0; padding: 0 16px; font: inherit; font-size: 14px; font-weight: 500; color: #fff; background: var(--cb-accent); border: none; border-radius: 12px; cursor: pointer; }
.cb-send:disabled { opacity: .6; cursor: default; }
.cb-note { display: flex; justify-content: space-between; gap: 12px; padding: 7px 4px 0; font-family: var(--cb-mono); font-size: 10px; color: var(--cb-faint); }
.cb-note-over { color: #8c2f1c; }
.cb-locked { margin-bottom: 8px; padding: 10px; text-align: center; font-family: var(--cb-mono); font-size: 11px; color: var(--cb-quiet); background: #f2f0ec; border: 1px solid var(--cb-line); border-radius: 10px; }

/* New-thread form */
.cb-form { display: flex; flex-direction: column; gap: 10px; margin: 20px 2px 22px; padding: 22px; background: var(--cb-panel); border: 1px solid var(--cb-line); border-radius: 14px; }
.cb-form-editable { width: 100%; min-height: 132px; max-height: none; padding: 12px 14px; background: #fff; border: 1px solid #d9d5ce; border-radius: 11px; }
.cb-form-editable:focus { border-color: var(--cb-accent); box-shadow: 0 0 0 3px rgba(68,66,61,.14); }
.cb-form-title { width: 100%; padding: 12px 14px; font: inherit; font-size: max(16px, 1.06rem); color: var(--cb-ink); background: #fff; border: 1px solid #d9d5ce; border-radius: 11px; outline: none; }
.cb-form-title:focus { border-color: var(--cb-accent); box-shadow: 0 0 0 3px rgba(68,66,61,.14); }
.cb-form-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.cb-form-note { font-family: var(--cb-mono); font-size: 10px; line-height: 1.5; color: var(--cb-faint); }

/* -------------------------------------------------------------------------
 * Phone
 * ---------------------------------------------------------------------- */

@media (max-width: 640px) {
	/* Wider than the theme's column on purpose: the gutters either side are the
	   theme's, and on a 360px screen they are room the board can better use. The
	   board's own padding keeps the text off the glass. */
	.codeboard-root { margin-inline: -14px; border-radius: 10px; }
	.cb-shell { padding: 0 11px; }
	/* Same reasoning as the opening post: a card inside the view's frame, with a
	   phone's width to share between them. The fields all carry their own borders,
	   so the form reads perfectly well without a wall around the set. */
	.cb-form { margin: 16px 0 20px; padding: 0; background: none; border: none; border-radius: 0; }
	/* Two rows, not one squeezed one. The header carries a title, a status line, a
	   theme switch and up to two chips; at this width the old rule held them all on
	   one line by shrinking the title to 38%, which left “Archive” as “A..” and broke
	   a Hangul name one syllable per line. Title and status take the full width; the
	   controls get a line of their own beneath them. */
	.cb-head { flex-wrap: wrap; gap: 4px 8px; padding: 14px 2px 12px; }
	.cb-head-left { flex: 1 1 100%; min-width: 0; }
	.cb-head-title { font-size: 16px; white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; word-break: keep-all; text-wrap: pretty; }
	/* Names are the thing that must never be broken mid-word: without this a Hangul
	   name wraps one syllable per line, which is how the meta line became a column. */
	.cb-meta { gap: 5px 7px; }
	.cb-meta > span { white-space: nowrap; word-break: keep-all; }
	/* Pushed right so the row reads as controls rather than as more header text. */
	.cb-head > .cb-themes,
	.cb-head > .cb-chip { align-self: center; }
	.cb-head > .cb-themes { width: 76px; height: 22px; margin: 2px 0 0; margin-left: auto; }
	.cb-head > .cb-themes + .cb-chip { margin-left: 0; }
	.cb-head > .cb-chip { height: 40px; padding: 0 7px; font-size: 10px; }
	/* Sole control on the entry screen — nothing to sit beside, so it keeps the
	   right edge to itself. */
	.cb-head > .cb-themes:last-child { margin-right: 0; }
	/* Stacked: a title and its status will not sit on one line at this width
	   without one of them being cut. */
	.cb-row { flex-direction: column; align-items: flex-start; gap: 7px; }
	.cb-row-metas { justify-content: flex-start; }
	.cb-search { min-height: 44px; }
	.cb-new { min-height: 44px; }
	.cb-text { font-size: 15px; }
	.cb-posts { padding: 14px 0 10px; }
	.cb-gate { gap: 16px; padding: 22px 12px 17px; }
	.cb-gate-title { font-size: 25px; }
	.cb-gate-sub { font-size: 14px; }
	/* Thumb-sized: they are the only controls on a post. */
	.cb-x { width: 30px; height: 30px; font-size: 16px; }
	.cb-word { height: 30px; }
	.cb-send { height: 44px; }
	.cb-modbar button { flex: 1; min-height: 44px; justify-content: center; }
	/* Thumbs on the toolbar too — a 28px target is a cursor's size, not a finger's. */
	.cb-tool { min-width: 36px; height: 36px; }
	.cb-swatch-ink { width: 26px; height: 26px; }
	.cb-quote-btn { height: 36px; }
}

/* -------------------------------------------------------------------------
 * Dark
 * ---------------------------------------------------------------------- */

.codeboard-root.cb-dark {
	/* Dark paints its own surface. In light the board deliberately inherits the
	   page; inheriting a light page while the ink turns light leaves unreadable
	   text on paper. */
	background: #16171b;
	color: #e9e7e2;
	/* Form controls, scrollbars and focus rings come from the UA; telling it the
	   surface is dark is the only way those match. */
	color-scheme: dark;
	--cb-bg: #16171b;
	--cb-panel: #1d1f24;
	--cb-line: #2e313a;
	--cb-ink: #e9e7e2;
	--cb-quiet: #98958e;
	--cb-faint: #8e8b84;
}
.codeboard-root.cb-dark .cb-gate-sub { color: #b4b0a9; }
/* The field's own surface, not just its focus ring: the base rule paints white
   paper under near-black ink, and on a dark page that leaves light ink on white. */
.codeboard-root.cb-dark .cb-input,
.codeboard-root.cb-dark .cb-form-title,
.codeboard-root.cb-dark .cb-form-editable { color: var(--cb-ink); background: #23262c; border-color: #363a43; }
.codeboard-root.cb-dark .cb-input::placeholder,
.codeboard-root.cb-dark .cb-form-title::placeholder { color: #8e8b84; }
.codeboard-root.cb-dark .cb-input:focus,
.codeboard-root.cb-dark .cb-form-title:focus,
.codeboard-root.cb-dark .cb-form-editable:focus,
.codeboard-root.cb-dark .cb-search:focus-within { box-shadow: 0 0 0 3px rgba(91,120,232,.22); }
.codeboard-root.cb-dark .cb-error { color: #f0b7ab; background: #3a1f1a; }
.codeboard-root.cb-dark .cb-notice { color: #e8c89a; background: #33291c; }
.codeboard-root.cb-dark .cb-play { background: #16171b; }
/* The played colour has to be its own colour on a dark panel. The light scheme's
   accent is a warm grey — near enough to the unplayed bars here that the fill was
   painting invisibly, which reads as a player that has stopped following the audio.
   Same orange CodeChat settled on, so the two plugins behave alike. */
.codeboard-root.cb-dark .cb-bar { --cb-bar-off: #34383f; --cb-bar-on: #f59120; background: var(--cb-bar-off); }
.codeboard-root.cb-dark .cb-bar-on { background: var(--cb-bar-on); }
.codeboard-root.cb-dark .cb-clipfile::file-selector-button { color: #ddd9d2; background: #23262c; border-color: #2e313a; }
.codeboard-root.cb-dark .cb-clip-status { color: #f0b7ab; }
.codeboard-root.cb-dark .cb-btn-sm { color: #ddd9d2; background: #23262c; }
.codeboard-root.cb-dark .cb-btn-sm:hover { border-color: #4a4e58; }
.codeboard-root.cb-dark .cb-chip:hover { color: var(--cb-ink); }
.codeboard-root.cb-dark .cb-sep { color: #4b4f58; }
.codeboard-root.cb-dark .cb-row:hover { border-color: #4a4e58; background: #23262c; }
.codeboard-root.cb-dark .cb-row-pinned { border-color: #4a4e58; }
.codeboard-root.cb-dark .cb-hit { color: #a8a49d; }
.codeboard-root.cb-dark .cb-hit mark { color: #e9e7e2; background: #3a3524; box-shadow: 0 0 0 1px #4d4630; }
/* The badge takes the field of the controls around it, so the byline reads as one
   set rather than a pill from another scheme parked beside them. Pure white on
   both the text and the 2px edge: on this field warm orange is the one thing that
   does not belong, and a credential wants to be unambiguous. */
.codeboard-root.cb-dark .cb-badge { color: #fff; background: #23262c; border: 2px solid #fff; }
.codeboard-root.cb-dark .cb-word { color: #6f6c66; }
.codeboard-root.cb-dark .cb-word:hover { color: var(--cb-ink); background: #23262c; }
.codeboard-root.cb-dark .cb-x { color: #6f6c66; }
.codeboard-root.cb-dark .cb-x:hover { color: var(--cb-ink); background: #23262c; }
.codeboard-root.cb-dark .cb-xnow { color: #f0b7ab; background: #3a1f1a; }
.codeboard-root.cb-dark .cb-xnow:hover { color: #fff; background: #a8524c; }
.codeboard-root.cb-dark .cb-sort { color: #6f6c66; }
.codeboard-root.cb-dark .cb-sort-on { color: var(--cb-ink); }
.codeboard-root.cb-dark .cb-locked { background: #23262c; }
.codeboard-root.cb-dark .cb-tool { color: #98958e; }
.codeboard-root.cb-dark .cb-tool:hover { color: var(--cb-ink); background: #23262c; }
.codeboard-root.cb-dark .cb-tool-on { color: var(--cb-ink); background: #2b2e36; }
.codeboard-root.cb-dark .cb-swatch-ink { border-color: #3b3f48; }
.codeboard-root.cb-dark .cb-editable-empty::before { color: #7b7871; }
.codeboard-root.cb-dark .cb-form-editable { background: #23262c; border-color: #363a43; }
.codeboard-root.cb-dark .cb-replybar { background: #21242b; }
.codeboard-root.cb-dark .cb-quote-btn { color: #ddd9d2; background: #23262c; }
.codeboard-root.cb-dark .cb-quote-btn:hover:not(:disabled) { border-color: #4a4e58; }
.codeboard-root.cb-dark .cb-quote-btn:disabled { color: #6f6c66; background: transparent; }
.codeboard-root.cb-dark .cb-text blockquote,
.codeboard-root.cb-dark .cb-editable blockquote { color: #a8a49d; background: #23262c; border-color: #2e313a; border-left-color: #4a4e58; }
.codeboard-root.cb-dark .cb-editbox { border-color: #5b78e8; }
.codeboard-root.cb-dark .cb-edittitle { border-bottom-color: #363a43; }
.codeboard-root.cb-dark .cb-note-over { color: #f0a89b; }
/* The hairline contrasts with the field, not with the square's own fill, so all
   three segments keep their shape whichever scheme is showing. */
.codeboard-root.cb-dark .cb-themes { border-color: rgba(255,255,255,.38); }
.codeboard-root.cb-dark .cb-swatch + .cb-swatch { box-shadow: inset 1px 0 0 rgba(255,255,255,.38); }

/* -------------------------------------------------------------------------
 * BIOS
 *
 * A setup screen from a 1990s PC: saturated field, white text, yellow accents,
 * cyan for everything secondary. The palette is the 16-colour EGA/VGA set on
 * purpose — the pleasure of it is the restraint, so nothing here is a tint or a
 * blend. Monospace throughout, square corners everywhere (a rounded BIOS is not
 * a BIOS), and no antialiasing, so type keeps the hard edge those screens had.
 * ---------------------------------------------------------------------- */

.codeboard-root.cb-bios {
	background: #24413a;
	color: #eceef3;
	color-scheme: dark;
	--cb-bg: #24413a;
	--cb-panel: #1e3733;
	--cb-line: #56786f;
	--cb-ink: #eceef3;
	--cb-quiet: #93bfc4;
	/* Cyan is right for the meta line but too loud for a timestamp on every row.
	   EGA light grey is quiet against the field and still legible at 10.5px. */
	--cb-faint: #a5a7af;
	--cb-accent: #d6c173;
	font-family: var(--cb-mono);
	border-color: #56786f;
	/* Corners stay rounded in every scheme. A true BIOS was square, but half the
	   board's containers keep their radius from the shared rules and the eye reads
	   the mixture as unfinished rather than as period detail — so the scheme is
	   carried by the palette, the monospace and the phosphor glow instead. */
	-webkit-font-smoothing: none;
	font-smooth: never;
}
/* The phosphor bloom, everywhere text appears.
 *
 * currentColor is the whole trick: every element glows in its own hue — amber
 * posts, white names, cyan meta — without a table of colours to keep in step
 * with the palette above. Two shadows, no offset: a tight one that thickens the
 * stems the way a slightly out-of-focus beam did, a wide faint one for the halo
 * the glass threw. Excluded: type set ON a light fill, where a halo in the
 * text's own dark ink reads as a smudge. The single-shadow declaration is the
 * fallback for browsers without color-mix(). */
.codeboard-root.cb-bios,
.codeboard-root.cb-bios *:not(.cb-btn):not(.cb-send):not(.cb-new):not(.cb-badge) {
	text-shadow: 0 0 1px currentColor;
	text-shadow:
		0 0 1px color-mix(in srgb, currentColor 50%, transparent),
		0 0 8px color-mix(in srgb, currentColor 26%, transparent);
}
/* Names in white, posts in amber — the reverse of the usual arrangement, and
   right here: a name is a label and wants no colour of its own, while the words
   are what you came to read. A pixel down from the other schemes, because mono
   sets wider and bold sets heavier. */
.codeboard-root.cb-bios .cb-author { color: #eceef3; }
.codeboard-root.cb-bios .cb-text {
	color: #f0a257;
	font-weight: 700;
	font-size: 15px;
	text-shadow: 0 0 1px rgba(240,162,87,.55), 0 0 9px rgba(240,162,87,.30);
}
.codeboard-root.cb-bios .cb-gate-sub { color: #93bfc4; }
.codeboard-root.cb-bios .cb-input,
.codeboard-root.cb-bios .cb-form-title,
.codeboard-root.cb-bios .cb-form-editable { color: #eceef3; background: #182b28; border-color: #56786f; }
.codeboard-root.cb-bios .cb-input::placeholder,
.codeboard-root.cb-bios .cb-form-title::placeholder { color: #56786f; font-weight: 400; }
.codeboard-root.cb-bios .cb-input:focus,
.codeboard-root.cb-bios .cb-form-title:focus,
.codeboard-root.cb-bios .cb-form-editable:focus,
.codeboard-root.cb-bios .cb-search:focus-within { border-color: #d6c173; box-shadow: 0 0 0 2px rgba(214,193,115,.35); }
.codeboard-root.cb-bios .cb-error { color: #eceef3; background: #7a3a34; }
/* BIOS has no tan in it; the amber that carries every body of text in this scheme
   is the right voice for a prompt, on the panel colour rather than a warning red. */
.codeboard-root.cb-bios .cb-notice { color: #f0a257; background: #182b28; }
/* Square, like everything else in this scheme, and the wave takes the amber the
   rest of the reading text wears. */
.codeboard-root.cb-bios .cb-player,
.codeboard-root.cb-bios .cb-clipadd { border-radius: 0; background: #182b28; }
.codeboard-root.cb-bios .cb-play { border-radius: 0; background: #24413a; color: #eceef3; }
.codeboard-root.cb-bios .cb-bar { --cb-bar-off: #56786f; --cb-bar-on: #f0a257; background: var(--cb-bar-off); border-radius: 0; }
.codeboard-root.cb-bios .cb-bar-on { background: var(--cb-bar-on); }
.codeboard-root.cb-bios .cb-clip-dl:hover, .codeboard-root.cb-bios .cb-clip-x:hover { color: #d6c173; border-radius: 0; }
.codeboard-root.cb-bios .cb-clipfile::file-selector-button { border-radius: 0; color: #eceef3; background: #24413a; border-color: #56786f; }
.codeboard-root.cb-bios .cb-clip-status { color: #f0a257; }
.codeboard-root.cb-bios .cb-btn,
.codeboard-root.cb-bios .cb-send,
.codeboard-root.cb-bios .cb-new { color: #24413a; background: #d6c173; }
.codeboard-root.cb-bios .cb-btn:hover,
.codeboard-root.cb-bios .cb-send:hover,
.codeboard-root.cb-bios .cb-new:hover { background: #eceef3; }
.codeboard-root.cb-bios .cb-btn-sm { color: #eceef3; background: #182b28; border-color: #56786f; }
.codeboard-root.cb-bios .cb-btn-sm:hover { color: #d6c173; border-color: #d6c173; }
.codeboard-root.cb-bios .cb-chip:hover { color: #d6c173; }
.codeboard-root.cb-bios .cb-sep { color: #56786f; }
.codeboard-root.cb-bios .cb-eyebrow { color: #d6c173; }
.codeboard-root.cb-bios .cb-row:hover { border-color: #d6c173; background: #182b28; }
.codeboard-root.cb-bios .cb-row-pinned { border-color: #d6c173; }
.codeboard-root.cb-bios .cb-hit { color: #93bfc4; }
.codeboard-root.cb-bios .cb-hit mark { color: #24413a; background: #d6c173; box-shadow: none; }
.codeboard-root.cb-bios .cb-badge { color: #24413a; background: #d6c173; border: none; }
.codeboard-root.cb-bios .cb-word { color: #a5a7af; }
.codeboard-root.cb-bios .cb-word:hover { color: #eceef3; background: #182b28; }
.codeboard-root.cb-bios .cb-x { color: #93bfc4; }
.codeboard-root.cb-bios .cb-x:hover { color: #eceef3; background: #182b28; }
.codeboard-root.cb-bios .cb-xnow { color: #eceef3; background: #7a3a34; }
.codeboard-root.cb-bios .cb-xnow:hover { background: #c07a70; }
.codeboard-root.cb-bios .cb-sort { color: #a5a7af; }
.codeboard-root.cb-bios .cb-sort-on { color: #d6c173; }
.codeboard-root.cb-bios .cb-locked { color: #93bfc4; background: #182b28; }
.codeboard-root.cb-bios .cb-editbox { border-color: #d6c173; }
.codeboard-root.cb-bios .cb-edittitle { border-bottom-color: #56786f; }
/* The draft matches the post it becomes — bold going in, bold coming out — so the
   composer is not a lighter weight than the thread above it. The placeholder
   stays regular: it is a prompt, not content. */
.codeboard-root.cb-bios .cb-msg,
.codeboard-root.cb-bios .cb-msg::placeholder,
.codeboard-root.cb-bios .cb-note-over { color: #c07a70; }
.codeboard-root.cb-bios .cb-tool { color: #93bfc4; }
.codeboard-root.cb-bios .cb-tool:hover { color: #d6c173; background: #182b28; }
.codeboard-root.cb-bios .cb-tool-on { color: #24413a; background: #d6c173; }
.codeboard-root.cb-bios .cb-swatch-ink { border-color: #56786f; }
.codeboard-root.cb-bios .cb-editable-empty::before { color: #56786f; font-weight: 400; }
.codeboard-root.cb-bios .cb-form-editable { background: #182b28; border-color: #56786f; }
.codeboard-root.cb-bios .cb-replybar { background: #182b28; }
.codeboard-root.cb-bios .cb-quote-btn { color: #eceef3; background: #182b28; border-color: #56786f; }
.codeboard-root.cb-bios .cb-quote-btn:hover:not(:disabled) { color: #d6c173; border-color: #d6c173; }
.codeboard-root.cb-bios .cb-quote-btn:disabled { color: #56786f; background: transparent; }
/* The quote steps back from the amber it is quoting — cyan on the sunk surface,
   regular weight, so the reply above it stays the thing being read. */
.codeboard-root.cb-bios .cb-text blockquote,
.codeboard-root.cb-bios .cb-editable blockquote { color: #93bfc4; background: #182b28; border-color: #56786f; border-left-color: #d6c173; text-shadow: none; }
.codeboard-root.cb-bios .cb-themes { border-color: #56786f; }
.codeboard-root.cb-bios .cb-swatch + .cb-swatch { box-shadow: inset 1px 0 0 #56786f; }
