/* CuccoStorm - graphite, one gold voice, one lavender voice.
 *
 * Copied from F:/EtherNet/web/css/ethernet.css and
 * F:/HyruleLink/web/css/hyrulelink.css (the family skin: neutral graphite,
 * warm paper-white text, 1px hairlines, depth by tone instead of shadow).
 * What changed: --ether / --link became --cucco (#B594FF, the cucco sprite's
 * shade pixel, docs/design/identity-cucco.md 2); the second page light is
 * lavender; the log class for a line that went into the game is .fired; the
 * kind glyphs, tier pills, sprite boxes and the intro block are new; the
 * billogna bar carries the four-app rule (DESIGN 16.1).
 *
 * Bricolage Grotesque for anything that is a number or a name of something,
 * Schibsted Grotesk for reading, IBM Plex Mono for codes, costs and clocks,
 * Press Start 2P ONLY where the text is literally what the game will draw.
 *
 * Colour discipline (DESIGN 5.1):
 *   gold    the primary action and "yours"; outside services (TikTok, Twitch)
 *   cucco   anything that touches the game: the game lamp, a fired rule,
 *           the HUD strip, timed effects, the Now bar
 *   ok      linked, done, saved          bad   errors, brutal
 * Radius is a scale (3 / 6 / 10 / pill), never one number.
 * Nothing animates at rest: this tab sits beside a game.
 *
 * The class contract other stylesheets and scripts may use is DESIGN 5.4;
 * nobody else redefines these classes. The OBS menu (menu.html) never loads
 * this file.
 */

@font-face { font-family: "Bricolage Grotesque"; font-weight: 600 800; font-display: swap;
  src: url(../fonts/BricolageGrotesque-600.woff2) format("woff2"); }
@font-face { font-family: "Schibsted Grotesk"; font-weight: 400 700; font-display: swap;
  src: url(../fonts/SchibstedGrotesk-400.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: swap;
  src: url(../fonts/IBMPlexMono-Regular.ttf) format("truetype"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 500; font-display: swap;
  src: url(../fonts/IBMPlexMono-Medium.ttf) format("truetype"); }
@font-face { font-family: "Press Start 2P"; font-weight: 400; font-display: swap;
  src: url(../fonts/PressStart2P-Regular.ttf) format("truetype"); }

:root {
  --bg: #0E0E10; --well: #121215; --surface: #17171A; --raised: #1D1D21; --lift: #26262B;
  --hair: rgba(255,255,255,.075); --hair-top: rgba(255,255,255,.12); --hair-strong: rgba(255,255,255,.18);
  --ink: #F3F1EA; --ink2: #BDBBB3; --mute: #918F87; --faint: #5F5E59;
  --gold: #E6B143; --gold-hi: #F1C158; --gold-lo: #C9962F; --on-gold: #171512;
  --gold-wash: rgba(230,177,67,.09); --gold-line: rgba(230,177,67,.42);
  /* the cucco's shade pixel: "this goes into the game" */
  --cucco: #B594FF; --cucco-hi: #C4ABFF; --cucco-lo: #7A52E0; --cucco-deep: #5E3DBF;
  --cucco-wash: rgba(181,148,255,.08); --cucco-line: rgba(181,148,255,.38);
  --ok: #6FCF97; --bad: #E5928D;
  --kind-timed: var(--cucco); --kind-instant: var(--mute); --kind-keep: var(--ink2); --kind-brutal: var(--bad);
  --r-sm: 3px; --r-md: 6px; --r-lg: 10px; --r-pill: 999px;
  --display: "Bricolage Grotesque", "Schibsted Grotesk", "Segoe UI", sans-serif;
  --body: "Schibsted Grotesk", "Segoe UI", system-ui, sans-serif;
  --mono: "IBM Plex Mono", Consolas, monospace;
  --pixel: "Press Start 2P", "IBM Plex Mono", monospace;
  --gutter: 16px;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font: 400 15px/1.5 var(--body);
  font-feature-settings: "ss01";
}
/* One warm light from the upper right, a faint lavender one from the lower
   left, and film grain so the flats are not dead. Fixed layers that never
   repaint. Never overflow-x: hidden on body: it breaks position: sticky. */
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(1100px 620px at 86% -12%, rgba(230, 177, 67, .07), transparent 62%),
    radial-gradient(900px 700px at -10% 110%, rgba(181, 148, 255, .035), transparent 60%);
}
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0; opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
body > * { position: relative; z-index: 1; }

a { color: var(--gold); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--gold-hi); }
h1, h2, h3 { font-family: var(--display); font-weight: 700; letter-spacing: -.015em; margin: 0; }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
/* KEEP. .btn sets display:inline-flex, which beats the browser's own [hidden]
   rule; without !important a hidden button stays on screen. */
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: var(--r-sm); }

/* ---------------------------------------------------------- text helpers */

.label {
  font: 600 11px/1 var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--mute);
}
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.hint { font-size: 13px; color: var(--mute); }
.err { font-size: 13.5px; color: var(--bad); }
.row { display: flex; gap: 8px; align-items: center; min-width: 0; }
/* the clipboard fallback's textarea (CsSite.copy): off screen, still selectable */
.offscreen { position: fixed; top: -2000px; left: 0; opacity: 0; width: 1px; height: 1px; }

/* -------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 18px;
  border: 1px solid var(--hair-strong); border-top-color: rgba(255, 255, 255, .24);
  border-radius: var(--r-md);
  background: var(--raised); color: var(--ink);
  font: 600 14px/1 var(--body); letter-spacing: .01em;
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .06s;
}
a.btn { text-decoration: none; }
a.btn:hover { color: var(--ink); }
.btn:hover { background: var(--lift); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .45; cursor: default; transform: none; }
.btn[disabled]:hover { background: var(--raised); }
.btn.primary {
  background: linear-gradient(180deg, #EFBE52, #DFA93C); color: var(--on-gold);
  border-color: var(--gold-lo); border-top-color: #F6D687;
}
.btn.primary:hover { background: linear-gradient(180deg, #F5C75F, #E7B144); color: var(--on-gold); }
.btn.big { min-height: 52px; padding: 0 28px; font: 700 17px/1 var(--display); letter-spacing: 0; }
.btn.quiet { background: transparent; border-color: var(--hair); color: var(--ink2); }
.btn.quiet:hover { background: var(--raised); color: var(--ink); }
.btn.danger { color: var(--bad); }
.btn.danger.armed { background: rgba(229, 146, 141, .14); border-color: rgba(229, 146, 141, .5); }
.btn.small { min-height: 30px; padding: 0 11px; font-size: 12.5px; }
.btn.on { border-color: var(--gold-line); background: var(--gold-wash); color: var(--gold-hi); }
/* a disabled button that is waiting (a cooldown), not broken */
.btn.waiting[disabled] { opacity: 1; background: transparent; border-style: dashed; border-color: var(--hair-strong);
  color: var(--mute); font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- fields */

.field {
  width: 100%; min-height: 42px; padding: 0 12px;
  background: var(--well); border: 1px solid var(--hair-strong); border-radius: var(--r-md);
  color: var(--ink);
}
.field::placeholder { color: var(--faint); }
.field:focus { outline: none; border-color: var(--gold-line); box-shadow: 0 0 0 3px var(--gold-wash); }
.field[disabled], .field[readonly] { color: var(--ink2); }
select.field { appearance: none; -webkit-appearance: none; padding-right: 30px;
  background-image: linear-gradient(45deg, transparent 50%, var(--mute) 50%), linear-gradient(135deg, var(--mute) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
select.field option { background: var(--surface); color: var(--ink); }
textarea.field { min-height: 84px; padding: 10px 12px; line-height: 1.45; resize: vertical; }
.field.code { font: 500 20px/1 var(--mono); letter-spacing: .24em; text-transform: uppercase; text-align: center; }
/* a URL or a key someone must carry elsewhere: readonly, wraps, never scrolls the page */
.field.mono { font: 400 12.5px/1.4 var(--mono); overflow-wrap: anywhere; text-overflow: ellipsis; }
/* numbers with a unit after them: <input class="field num" type="number"><span class="unit">s</span> */
.field.num { width: 6.5em; min-height: 34px; padding: 0 8px; font: 500 14px/1 var(--mono); text-align: right; }
.unit { font-size: 13px; color: var(--mute); }
/* a field whose words go into the game: the cucco focus */
.field.game:focus { border-color: var(--cucco-line); box-shadow: 0 0 0 3px var(--cucco-wash); }

/* ------------------------------------------------------ check and switch */

.check { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink2); cursor: pointer; }
.check input { accent-color: var(--gold); width: 15px; height: 15px; margin: 0; }

/* on/off: <label class="switch"><input type="checkbox" role="switch"><span>On</span></label> */
.switch { display: inline-flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--ink2); cursor: pointer; user-select: none; }
.switch input {
  appearance: none; -webkit-appearance: none; position: relative; flex: none; margin: 0;
  width: 34px; height: 20px; border-radius: var(--r-pill);
  background: var(--well); border: 1px solid var(--hair-strong); cursor: pointer;
  transition: background .12s, border-color .12s;
}
.switch input::before {
  content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--mute); transition: transform .12s, background .12s;
}
.switch input:checked { background: var(--gold-wash); border-color: var(--gold-line); }
.switch input:checked::before { transform: translateX(14px); background: var(--gold); }
.switch input:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: var(--r-pill); }
.switch input:disabled { opacity: .45; cursor: default; }
.switch input:checked + span { color: var(--ink); }

/* ---------------------------------------------------------------- panels */

.panel {
  background: linear-gradient(180deg, var(--raised), var(--surface));
  border: 1px solid var(--hair); border-top-color: var(--hair-top);
  border-radius: var(--r-lg);
}
/* a titled panel: <section class="panel"><div class="panel-head"><h2>..</h2><span class="label">..</span></div><div class="panel-body">.. */
.panel-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 13px 16px 10px; border-bottom: 1px solid var(--hair); }
.panel-head h2 { font-size: 16px; min-width: 0; }
.panel-body { padding: 8px 16px 14px; }
/* "something needs you": one line, a gold wash, one small button */
.panel.banner { display: flex; gap: 12px; align-items: center; justify-content: space-between; padding: 11px 16px;
  font-size: 14px; border-color: var(--gold-line); background: var(--gold-wash); }
.panel.banner > span { min-width: 0; }
/* yours / the host's: a gold hairline */
.panel.host { border-color: var(--gold-line); }
.panel.host .panel-head .label { color: var(--gold); }

/* ------------------------------------------------ tags, pills and chips */

.tag { display: inline-block; padding: 4px 9px; border: 1px solid var(--hair-strong); border-radius: var(--r-sm);
  font: 500 12px/1.2 var(--mono); color: var(--ink2); }
/* tier pills: .pill.ok HELPS, .pill HURTS, .pill.bad BRUTAL, .pill.dash EXPERIMENTAL */
.pill { display: inline-block; margin-left: 7px; padding: 2px 6px; border-radius: var(--r-sm); vertical-align: 1px;
  font: 600 10px/1.2 var(--body); letter-spacing: .1em; text-transform: uppercase;
  color: var(--mute); border: 1px solid var(--hair-strong); white-space: nowrap; }
.pill.host { color: var(--gold); border-color: var(--gold-line); }
.pill.cucco { color: var(--cucco); border-color: var(--cucco-line); }
.pill.ok { color: var(--ok); border-color: rgba(111, 207, 151, .42); }
.pill.bad { color: var(--bad); border-color: rgba(229, 146, 141, .5); }
.pill.dash { border-style: dashed; }
/* pill-shaped toggles in a row (platform filters, the door's choice) */
.chip { display: inline-flex; align-items: center; min-height: 22px; max-width: 100%; padding: 0 8px;
  border: 1px solid var(--hair-strong); border-radius: var(--r-pill); background: transparent;
  font: 600 11px/1 var(--body); color: var(--mute); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s; }
.chip:hover { color: var(--ink); border-color: rgba(255, 255, 255, .32); }
.chip.on { background: var(--lift); border-color: rgba(255, 255, 255, .28); color: var(--ink); }

/* ------------------------------------------------ status rows with lamps */

/* <div class="panel links"><div class="link"><div class="what"><span class="lamp"></span>Game</div>
     <div class="say">Main line.<small>What it means.</small></div><div class="do">buttons</div></div></div> */
.links { display: grid; }
.links > .link { display: grid; grid-template-columns: 136px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 13px 18px; }
.links > .link + .link { border-top: 1px solid var(--hair); }
.links .what { display: flex; align-items: center; gap: 9px; font: 600 12px/1 var(--body); letter-spacing: .13em; text-transform: uppercase; color: var(--ink2); }
/* faint = off; .wait hollow = waiting or stuck; .gold = an outside service; .ok (cucco) = the game is linked */
.lamp { width: 9px; height: 9px; border-radius: 50%; background: var(--faint); flex: none; }
.lamp.ok { background: var(--cucco); box-shadow: 0 0 0 3px var(--cucco-wash); }
.lamp.gold { background: var(--gold); box-shadow: 0 0 0 3px var(--gold-wash); }
.lamp.wait { background: transparent; border: 2px solid var(--mute); }
.links .say { font-size: 14px; color: var(--ink2); min-width: 0; overflow-wrap: anywhere; }
.links .say small { display: block; font-size: 12.5px; color: var(--mute); margin-top: 2px; }
.links .do { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.links .do .field { min-height: 32px; width: auto; font-size: 13px; }
/* the page's own connection to the server */
.net-lamp { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); flex: none; }
.net-lamp.ok { background: var(--ok); }
.net-lamp.bad { background: var(--bad); }

/* ---------------------------------------------------- dialogs and settings */

dialog { width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; color: var(--ink);
  background: var(--surface); border: 1px solid var(--hair-strong); border-radius: var(--r-lg); }
dialog[open] { display: flex; flex-direction: column; }
dialog.wide { width: min(780px, calc(100vw - 32px)); }
dialog::backdrop { background: rgba(8, 8, 10, .74); }
.dlg-head { flex: none; display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 18px 22px 14px; border-bottom: 1px solid var(--hair); }
.dlg-head h2 { font-size: 20px; min-width: 0; }
.dlg-body { flex: 1 1 auto; min-height: 0; padding: 8px 22px 22px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--lift) transparent; }
.dlg-body h3 { font: 600 11px/1 var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--mute); margin: 20px 0 8px; }
.dlg-body > p:not([class]) { margin-top: 12px; font-size: 14px; color: var(--ink2); }
.dlg-foot { flex: none; display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; padding: 14px 22px; border-top: 1px solid var(--hair); }
.set { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 220px); gap: 14px; align-items: center; padding: 10px 0; border-top: 1px solid var(--hair); }
.set:first-of-type { border-top: 0; }
.set .k { font-size: 14.5px; min-width: 0; }
.set .k small { display: block; color: var(--mute); font-size: 12.5px; margin-top: 2px; }
.set > .btn, .set > .switch, .set > .check { justify-self: end; }
.set .row { flex-wrap: wrap; }
.set .row > .field:not(.num) { flex: 1 1 8em; width: auto; min-width: 0; }
.set.wide { grid-template-columns: 1fr; gap: 7px; }
.set.wide > .btn, .set.wide > .switch, .set.wide > .check { justify-self: start; }
.how { counter-reset: how; display: grid; gap: 0; margin: 4px 0 0; padding: 0; list-style: none; }
.how li { counter-increment: how; display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 6px; padding: 13px 0; border-top: 1px solid var(--hair); color: var(--ink2); font-size: 14.5px; }
.how li:first-child { border-top: 0; }
.how li::before { content: counter(how); font: 700 20px/1.1 var(--display); color: var(--gold); }
.how b { color: var(--ink); }
.how table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 13.5px; }
.how td { padding: 6px 8px 6px 0; border-top: 1px solid var(--hair); vertical-align: top; }
.how td:first-child { color: var(--ink); width: 38%; }

/* ------------------------------------------------------------- the log */

/* newest first; a line is <li class="msg KIND"><span class="t">21:04</span>text</li>.
   The kind is never a layout class name (EtherNet's .chat trap). */
.log { list-style: none; margin: 0; padding: 0; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--lift) transparent; }
.log li.msg { padding: 5px 8px 5px 10px; margin: 1px 0; border-left: 2px solid transparent;
  font-size: 13.5px; line-height: 1.42; color: var(--ink2); overflow-wrap: anywhere; }
.log li.msg .t { float: right; margin-left: 8px; font: 400 11px/1.9 var(--mono); color: var(--faint); }
.log li.msg .who { font-weight: 600; color: var(--ink); }
.log li.fired { color: var(--ink); border-left-color: var(--cucco); background: linear-gradient(90deg, var(--cucco-wash), transparent 75%); }
.log li.fired .who { color: var(--cucco); }
.log li.queued { color: var(--ink2); }
.log li.done, .log li.unmatched, .log li.system { color: var(--mute); }
.log li.refused, .log li.held { color: var(--bad); border-left-color: rgba(229, 146, 141, .55); }
.log li.refused .who, .log li.held .who { color: var(--bad); }

/* ------------------------------------------------------- the HUD strip */

/* Twenty cells, the game's width. The text in here is exactly what the
   game will draw, so it is the one place the pixel face appears. */
.strip {
  display: inline-grid; grid-template-columns: repeat(20, 1fr); gap: 0;
  padding: 7px 8px; background: #08080A; border: 1px solid var(--cucco-line); border-radius: var(--r-sm);
  font: 400 11px/1 var(--pixel); color: #F8F8F8; max-width: 100%;
}
.strip i { width: 13px; height: 13px; display: grid; place-items: center; font-style: normal; }
.strip.idle { border-color: var(--hair-strong); color: var(--faint); }

/* ---------------------------------------------------------------- toasts */

.toasts { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 40; display: grid; gap: 8px;
  width: min(440px, calc(100vw - 32px)); pointer-events: none; }
.toast { padding: 11px 14px; border-radius: var(--r-md); background: var(--lift); border: 1px solid var(--hair-strong); font-size: 14px;
  overflow-wrap: anywhere; animation: toast-in .18s ease-out; }
.toast.bad { border-color: rgba(229, 146, 141, .5); }
.toast.cucco { border-color: var(--cucco-line); }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } }

/* ------------------------------------------------ full-page states */

.cover { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; padding: var(--gutter);
  background: rgba(10, 10, 12, .92); }
.cover .panel { width: min(430px, 100%); padding: 26px; }
.cover h2 { font-size: 24px; }
.cover .sub { margin: 6px 0 18px; color: var(--ink2); }
.cover .btn { width: 100%; margin-top: 10px; }
.cover .err { margin-top: 12px; font-size: 14px; }

/* -------------------------------------------------------- billogna bar */

/* One quiet line above everything: the way back to billogna.lol, and across
   to the other three apps and the tracker (tracker.billogna.lol). People
   pages only - menu.html is an OBS source and gets no chrome. On the desk
   every link opens a new tab, so a stray click mid-stream never leaves the
   page that drives the game. */
.sitebar { background: var(--well); border-bottom: 1px solid var(--hair); }
.sitebar .sb-in {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  max-width: 1080px; margin: 0 auto; min-height: 34px; padding: 0 var(--gutter);
  font: 500 12.5px/1 var(--body);
}
.sitebar a { color: var(--mute); text-decoration: none; padding: 6px 0; white-space: nowrap; }
.sitebar a:hover, .sitebar a:focus-visible { color: var(--ink); }
.sitebar .sb-home b { color: var(--gold); font-weight: 600; margin-right: 6px; }
.sitebar .sb-sibs { display: flex; gap: 18px; }
.sitebar .sb-sibs [aria-current="page"] { color: var(--ink2); box-shadow: inset 0 -1px var(--gold-line); }
@media (max-width: 540px) {
  .sitebar .sb-in { gap: 10px; font-size: 12px; }
  .sitebar .sb-sibs { gap: 10px; }
  /* With five apps the page you are on is already named by its brand right
     under the bar, so its link steps out and the other four plus the way
     home fit from 540 px down. Needs aria-current="page" on every page's
     self link. */
  .sitebar .sb-sibs [aria-current="page"] { display: none; }
}
@media (max-width: 420px) {
  /* ...and a size smaller and tighter under 420 px, so they still fit a
     360 px phone. */
  .sitebar .sb-in { gap: 8px; font-size: 11px; padding: 0 12px; }
  .sitebar .sb-sibs { gap: 6px; }
}

/* ---------------------------------------------------------------- brand */

.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); flex: none; }
.brand:hover { color: var(--ink); }
/* the cucco, pixel for pixel (tools/make_mark.py). 32 px is exactly 2x the
   16 px sprite, so every pixel of it lands on whole screen pixels. */
.brand img { width: 32px; height: 32px; flex: none; image-rendering: pixelated; }
.brand .word { font: 700 20px/1 var(--display); letter-spacing: -.02em; }
.brand .word b { color: var(--gold); font-weight: 700; }

/* ------------------------------------------- the working page's header */

.bar {
  display: flex; align-items: center; gap: 18px; padding: 12px var(--gutter);
  border-bottom: 1px solid var(--hair); background: rgba(14, 14, 16, .9);
  position: sticky; top: 0; z-index: 5;
}
.bar-title { min-width: 0; flex: 1; display: flex; align-items: baseline; gap: 12px; }
.bar-title h1 { font-size: 17px; font-weight: 600; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-title .label { white-space: nowrap; }
.bar-right { display: flex; align-items: center; gap: 8px; }
.code-chip { display: inline-flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 12px;
  background: var(--well); border: 1px solid var(--hair-strong); border-radius: var(--r-md); cursor: pointer; }
.code-chip b { font: 500 15px/1 var(--mono); letter-spacing: .14em; color: var(--gold-hi); }
.code-chip span { font-size: 12.5px; color: var(--mute); white-space: nowrap; }
.code-chip:hover span { color: var(--ink); }

/* ------------------------------------------------------- kind glyphs */

/* <span class="kind timed">20 s</span>: a 12 px glyph in currentColor, then
   the words. timed = a ring with a gap at 1 o'clock (goes in, comes back out);
   instant = a 5 x 9 pixel bolt (one shot); keep = a pin (writes and stays);
   brutal = a notched triangle (can end the run). Drawn as masks so the glyph
   takes the text colour; the same four shapes for everyone who uses .kind. */
.kind { display: inline-flex; align-items: center; gap: 5px; font: 500 12.5px/1 var(--mono); white-space: nowrap; }
.kind::before { content: ""; flex: none; width: 12px; height: 12px; background: currentColor;
  -webkit-mask: var(--kind-glyph) center / 12px 12px no-repeat; mask: var(--kind-glyph) center / 12px 12px no-repeat; }
.kind.timed { color: var(--kind-timed);
  --kind-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M8.6 1.6A5 5 0 1 0 11 6h-1.6A3.4 3.4 0 1 1 7.8 3z'/%3E%3C/svg%3E"); }
.kind.instant { color: var(--kind-instant);
  --kind-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' shape-rendering='crispEdges'%3E%3Cpath d='M6 1h3v1H8v1H7v1h3v1H9v1H8v1H7v1H6v1H5v1H4v-2h1V8h1V7H3V6h1V5h1V4h1V3h1V2H6z'/%3E%3C/svg%3E"); }
.kind.keep { color: var(--kind-keep);
  --kind-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' shape-rendering='crispEdges'%3E%3Cpath d='M3 1h6v5H7v5H5V6H3z'/%3E%3C/svg%3E"); }
.kind.brutal { color: var(--kind-brutal);
  --kind-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 1l5.5 10H.5zM5.3 4.5v3.3h1.4V4.5zM5.3 8.6V10h1.4V8.6z' fill-rule='evenodd'/%3E%3C/svg%3E"); }

/* ------------------------------------------------ fixed pixel-art boxes */

/* the sprite is 32 x 32 (16 x 16 doubled); the box never changes size */
.sprite { display: inline-block; flex: none; width: 32px; height: 32px; object-fit: contain; image-rendering: pixelated;
  vertical-align: middle; }
.sprite.s32 { width: 32px; height: 32px; }
.sprite.s40 { width: 40px; height: 40px; padding: 4px; }

/* -------------------------------------------------------------- narrow */

@media (max-width: 560px) {
  .links > .link { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .links .do { justify-content: flex-start; }
  .set { grid-template-columns: 1fr; gap: 6px; }
  .set > .btn, .set > .switch, .set > .check { justify-self: start; }
  .dlg-head, .dlg-foot { padding-left: 16px; padding-right: 16px; }
  .dlg-body { padding: 8px 16px 18px; }
  .strip { font-size: 9px; padding: 6px; }
  .strip i { width: 11px; height: 12px; }
  .code-chip span { display: none; }
}
/* every non-small button full width on a phone (QuakeCast's rule) */
@media (max-width: 480px) {
  .btn:not(.small) { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* The cucco storm, once per open (js/intro.js; index.html and desk.html,
   never menu.html, operator.html or customize.html, never for reduced
   motion). Only transform, opacity, canvas draws and border-color move. */
.cucco-canvas { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 60;
  image-rendering: pixelated; image-rendering: crisp-edges; }
.cucco-canvas.out { animation: cucco-out .3s steps(3, end) forwards; }
@keyframes cucco-out { from { opacity: 1; } to { opacity: 0; } }
body.cucco-storm .brand img { transform: scale(1.5); transform-origin: left center;
  filter: drop-shadow(0 0 6px var(--cucco)); animation: cucco-hit .28s steps(1, end); }
@keyframes cucco-hit {
  0%   { transform: scale(1.5) translateX(0); }
  25%  { transform: scale(1.5) translateX(2px); }
  50%  { transform: scale(1.5) translateX(-2px); }
  75%  { transform: scale(1.5) translateX(2px); }
  100% { transform: scale(1.5) translateX(0); }
}
.cucco-caught { animation: cucco-caught .45s steps(1, end); }
@keyframes cucco-caught {
  0%, 54%   { border-color: var(--cucco); }
  55%, 100% { border-color: var(--cucco-line); }
}
