/* ============================================================
   Components — crisp and compact (the widget rail sets the tone):
   36px controls, 13px labels, hairline borders, light shadows.
   ============================================================ */

/* ---------- buttons ---------- */
.btn {
  --btn-h: 36px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: var(--btn-h); padding: 0 14px; border-radius: var(--r);
  font-weight: 700; font-size: var(--fs-sm); line-height: 1; white-space: nowrap;
  border: 1px solid transparent; position: relative; user-select: none;
  transition: background-color var(--t), border-color var(--t), color var(--t), box-shadow var(--t), transform var(--t-fast), opacity var(--t), filter var(--t);
}
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled, .btn.is-disabled { opacity: .5; pointer-events: none; }
/* (one that says why it can't be pressed yet, Start now with one player, still shows its tip: a disabled button gets
   no clicks anyway) */
.btn:disabled[data-tip] { pointer-events: auto; cursor: not-allowed; opacity: 1; background: var(--hover); border-color: transparent; color: var(--text-3); box-shadow: none; }   /* (still pointed at, so its tip says why it's off; faded by colour) */
.btn:disabled[data-tip] svg { opacity: .6; }
.btn-sm { --btn-h: 30px; padding: 0 11px; font-size: calc(12px * var(--fs-scale)); border-radius: var(--r); gap: 6px; }
.btn-sm svg { width: 14px; height: 14px; }
.btn-xs { --btn-h: 26px; padding: 0 9px; font-size: var(--fs-xs); border-radius: var(--r-sm); gap: 5px; }
.btn-xs svg { width: 13px; height: 13px; }
.btn-lg { --btn-h: 42px; padding: 0 18px; font-size: var(--fs-md); border-radius: var(--r-md); }
.btn-block { width: 100%; }
.btn-primary { background: var(--accent-grad); color: var(--on-accent); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 6px 16px -8px var(--accent-glow); text-shadow: 0 1px 1px rgba(0, 0, 0, .16); }
.btn-primary:hover { filter: brightness(1.1) saturate(1.06); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .26), 0 10px 24px -10px color-mix(in srgb, var(--accent-2) 65%, transparent); }
.btn-secondary { background: var(--hover); color: var(--text); border-color: var(--border-strong); }
.btn-secondary:hover { background: var(--hover-2); border-color: var(--border-hover); }
.btn-ghost { color: var(--text-2); }
.btn-ghost:hover { background: var(--hover); color: var(--text); }
.btn-outline { color: var(--accent-text); border-color: var(--accent-line); background: var(--accent-softer); }
.btn-outline:hover { background: var(--accent-soft); }
.btn-danger { background: color-mix(in srgb, var(--red) 84%, #000); color: #fff; }   /* (white on the plain red is 3.8:1; this is 5:1) */
.btn-danger:hover { filter: brightness(1.08); }
.btn-danger-ghost { color: var(--red-text); }
.btn-danger-ghost:hover { background: var(--red-soft); }
.btn-success { background: var(--green-soft); color: var(--green-text); border-color: color-mix(in srgb, var(--green) 30%, transparent); }
.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: ''; position: absolute; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid currentColor; border-color: rgba(255, 255, 255, .9) rgba(255, 255, 255, .25) rgba(255, 255, 255, .25); animation: spin .7s linear infinite;
}
.btn-secondary.is-loading::after, .btn-ghost.is-loading::after, .btn-outline.is-loading::after { border-color: var(--text) var(--track) var(--track); }

.icon-btn {
  width: 36px; height: 36px; border-radius: var(--r); display: inline-grid; place-items: center; flex-shrink: 0;
  color: var(--text-2); background: var(--hover); border: 1px solid var(--border); position: relative;
  transition: background-color var(--t), color var(--t), border-color var(--t);
}
.icon-btn:hover { background: var(--hover-2); color: var(--text); border-color: var(--border-strong); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn.sm { width: 30px; height: 30px; border-radius: var(--r); }
.icon-btn.sm svg { width: 15px; height: 15px; }
.icon-btn.plain { background: transparent; border-color: transparent; }
.icon-btn.plain:hover { background: var(--hover); }
.icon-btn.active, .icon-btn.on { color: var(--accent-text); background: var(--accent-soft); border-color: var(--accent-line); }

.link { color: var(--accent-text); font-weight: 600; }
.link:hover { text-decoration: underline; text-underline-offset: 3px; }
.link-muted { color: var(--text-2); font-weight: 600; font-size: var(--fs-sm); }
.link-muted:hover { color: var(--text); }

/* ---------- form fields ---------- */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > label:not(.check), .field-label { font-size: var(--fs-sm); font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 0 6px; flex-wrap: wrap; }
/* (what sits at a label's right: "optional", a count, whether a name is free, a link such as "Forgot password?". The
   rest reads as one line of text, so "Type <b>name</b> to confirm" isn't pulled apart across the row) */
.field > label > :is(.opt, .faint, .charcount, .avail), .field-label > :is(.opt, .faint, .charcount, .avail, .link) { margin-left: auto; }
.field > label .opt, .field-label .opt { font-weight: 500; color: var(--text-3); }
.field-hint { font-size: var(--fs-xs); color: var(--text-3); line-height: 1.45; }
.field-error { font-size: var(--fs-xs); color: var(--red-text); font-weight: 600; display: none; }
.field.has-error .field-error { display: block; }
.field.has-error .input, .field.has-error .textarea, .field.has-error .select { border-color: color-mix(in srgb, var(--red) 60%, transparent); }

.input, .textarea, .select {
  width: 100%; min-height: 38px; padding: 8px 12px; border-radius: var(--r);
  background: var(--input); border: 1px solid var(--border-strong); color: var(--text);
  font-size: calc(13px * var(--fs-scale)); transition: border-color var(--t), box-shadow var(--t), background-color var(--t);
}
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--border-hover); }
.input:focus, .textarea:focus, .select:focus { border-color: var(--focus); box-shadow: var(--ring); background-color: color-mix(in srgb, var(--surface-solid) 60%, transparent); }
.textarea { min-height: 88px; line-height: 1.5; resize: vertical; }
.select { appearance: none; padding-right: 34px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239a9bab' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 15px; }
.select option { background: var(--surface-solid); color: var(--text); }
.input-group { position: relative; display: flex; align-items: center; }
.input-group > svg { position: absolute; left: 12px; width: 16px; height: 16px; color: var(--text-3); pointer-events: none; }
.input-group > .input { padding-left: 36px; }
.input-group > .input-suffix { position: absolute; right: 6px; }
.input-addon { display: flex; align-items: stretch; }
.input-addon > span { display: grid; place-items: center; padding: 0 11px; background: var(--surface-2); border: 1px solid var(--border-strong); border-right: 0; border-radius: var(--r) 0 0 var(--r); color: var(--text-3); font-size: var(--fs-sm); }
.input-addon > .input { border-radius: 0 var(--r) var(--r) 0; }
.charcount { font-size: var(--fs-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.charcount.over { color: var(--red-text); font-weight: 700; }

/* switch */
.switch { position: relative; display: inline-flex; flex-shrink: 0; width: 36px; height: 21px; }
.switch input { position: absolute; inset: 0; opacity: 0; cursor: pointer; z-index: 1; margin: 0; }
.switch .track { position: absolute; inset: 0; border-radius: var(--r-sm); background: var(--track); transition: background-color var(--t); }
.switch .track::after { content: ''; position: absolute; top: 3px; left: 3px; width: 15px; height: 15px; border-radius: var(--r-xs); background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .35); transition: transform var(--t) var(--ease); }
.switch input:checked + .track { background: var(--accent-grad); }
.switch input:checked + .track::after { transform: translateX(15px); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 2px var(--surface-solid), 0 0 0 4px var(--focus); }
.switch input:disabled + .track { opacity: .5; }

/* checkbox */
.check { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: calc(13px * var(--fs-scale)); }
.check input { appearance: none; width: 17px; height: 17px; border-radius: var(--r-xs); border: 1.5px solid var(--border-hover); background: var(--input); display: grid; place-items: center; flex-shrink: 0; transition: background-color var(--t), border-color var(--t); cursor: pointer; }
.check input:checked { background: var(--accent); border-color: var(--accent); }
.check input:checked::after { content: ''; width: 9px; height: 5px; border-left: 2px solid var(--on-accent); border-bottom: 2px solid var(--on-accent); transform: rotate(-45deg) translate(1px, -1px); }
.check input:focus-visible { box-shadow: 0 0 0 2px var(--surface-solid), 0 0 0 4px var(--focus); }

/* segmented control */
.segmented { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--r); background: var(--surface-sunken); border: 1px solid var(--border); }
.segmented button { padding: 6px 12px; border-radius: var(--r-sm); font-size: var(--fs-sm); font-weight: 700; color: var(--text-2); display: inline-flex; align-items: center; gap: 6px; transition: background-color var(--t), color var(--t); }
.segmented button svg { width: 15px; height: 15px; }
.segmented button:hover { color: var(--text); }
.segmented button.on { background: var(--surface-3); color: var(--text); box-shadow: var(--shadow-sm); }

/* option cards (radio as cards) */
.option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.option-card { display: flex; flex-direction: column; gap: 3px; padding: 11px 12px; border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface-2); cursor: pointer; text-align: left; transition: border-color var(--t), background-color var(--t); }
.option-card:hover { border-color: var(--border-hover); }
.option-card.on { border-color: var(--accent-line); background: linear-gradient(160deg, var(--accent-soft), var(--accent-softer)); box-shadow: inset 0 0 0 1px var(--accent-line); }
/* the report dialog's word on what to do next (ui/report.js), only for the reasons that have one */
.rp-note:empty { display: none; }
/* the rules line where pictures and clips go up (ui/uploadrules.js) */
.upload-rules { display: flex; align-items: flex-start; gap: 6px; margin: 0; font-size: var(--fs-xs); line-height: 1.45; color: var(--text-2); }
.upload-rules svg { width: 13px; height: 13px; flex-shrink: 0; margin-top: 2px; color: var(--accent-text); }
.upload-rules a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }
.option-card b { font-size: calc(13px * var(--fs-scale)); }
.option-card span { font-size: var(--fs-xs); color: var(--text-2); }

/* ---------- avatars ---------- */
.avatar {
  --size: 40px;
  width: var(--size); height: var(--size); border-radius: 50%; flex-shrink: 0; position: relative;
  display: inline-grid; place-items: center; font-family: var(--font-display); font-weight: 700;
  font-size: calc(var(--size) * .36); color: #fff; letter-spacing: .01em; user-select: none;
  background: linear-gradient(135deg, hsl(var(--h, 270) 78% 62%), hsl(calc(var(--h, 270) + 40) 72% 48%));
}
.avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
/* (a picture has nothing behind it: the player's colour showed through its round edge as a thin ring, plain to see round a
   dark picture. Initials, when the picture fails, take the colour back) */
.avatar:has(> img) { background: none; }
.avatar.xs { --size: 22px; } .avatar.sm { --size: 30px; } .avatar.md { --size: 40px; } .avatar.lg { --size: 54px; } .avatar.xl { --size: 88px; } .avatar.xxl { --size: 124px; }
.avatar.square { border-radius: var(--r-md); }
/* (an account that's gone, or a comment taken back: a plain figure, not two letters that look like someone's) */
.avatar.gone { background: var(--hover-2); color: var(--text-3); box-shadow: inset 0 0 0 1px var(--border); }
.avatar.gone svg { width: 54%; height: 54%; }
.avatar .presence { position: absolute; right: 0; bottom: 0; width: 28%; height: 28%; min-width: 9px; min-height: 9px; border-radius: 50%; background: var(--presence-online); box-shadow: 0 0 0 2.5px var(--ring-bg, var(--surface-solid)); }
.avatar .presence.away { background: var(--presence-away); }
.avatar .presence.dnd { background: var(--presence-dnd); }
/* who's hosting (hostBlock() in ui/parts.js): their picture, a square, beside their name and "Host" */
.host-block { display: flex; align-items: center; gap: 10px; align-self: flex-start; min-width: 0; max-width: 100%; }
.host-block > .avatar { --size: 32px; border-radius: 0; flex-shrink: 0; font-size: calc(12px * var(--fs-scale)); }
.host-block-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.host-block-txt .name-line { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: var(--fs-md); line-height: 1.2; }
.host-block-txt .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; color: var(--text); unicode-bidi: isolate; }
.host-block-txt a.name:hover { text-decoration: underline; text-underline-offset: 2px; }
.host-block-txt > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-xs); color: var(--text-3); }
.host-block-txt > span a { color: var(--text-2); font-weight: 600; }
.host-block-txt > span a:hover { color: var(--text); }
/* (on a session's or a tournament's own page, a size up) */
.ss-hero .host-block, .tn-hero .host-block { margin: 4px 0 2px; }
.ss-hero .host-block > .avatar, .tn-hero .host-block > .avatar { --size: 40px; font-size: calc(14px * var(--fs-scale)); }
.ss-hero .host-block-txt .name-line, .tn-hero .host-block-txt .name-line { font-size: var(--fs-base); }
/* level rings (perks) */
.avatar.ring-silver { box-shadow: 0 0 0 2px var(--ring-bg, var(--surface-solid)), 0 0 0 4px #c9ced8; }
.avatar.ring-gold { box-shadow: 0 0 0 2px var(--ring-bg, var(--surface-solid)), 0 0 0 4px var(--gold); }
.avatar.ring-prism { box-shadow: 0 0 0 2px var(--ring-bg, var(--surface-solid)); }
/* (the colours turn round the ring, not the ring itself: a square avatar's corners stay where they are. The ring is a
   2px band masked out of a box over the avatar, outside the gap: under it, the avatar's own shadow and the glass of the
   rows it sits in covered it, and a filter on the avatar (a hover) turned the whole avatar into the rainbow) */
@property --ring-turn { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.avatar.ring-prism::before { content: ''; position: absolute; inset: -4px; padding: 2px; border-radius: inherit; pointer-events: none; background: conic-gradient(from var(--ring-turn), #f472b6, #a855f7, #38bdf8, #34d399, #fbbf24, #f472b6);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: ringTurn 6s linear infinite; }
@keyframes ringTurn { to { --ring-turn: 360deg; } }
/* name styles from the shop (Flair): gradient text wherever the name shows */
.ns-sunset, .ns-aurora, .ns-gold { -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.ns-sunset { background-image: linear-gradient(90deg, #fb923c, #f472b6 60%, #e879f9); }
.ns-aurora { background-image: linear-gradient(90deg, #4ade80, #22d3ee 50%, #a78bfa); }
.ns-gold { background-image: linear-gradient(100deg, #b8862b 0%, #fde68a 30%, #f5c542 50%, #fffbe6 62%, #d4a12a 80%); background-size: 220% 100%; animation: nsShine 5s linear infinite; }
@keyframes nsShine { from { background-position: 100% 0; } to { background-position: -120% 0; } }
:root[data-reduce-motion="true"] .ns-gold { animation: none; }
a.ns-sunset:hover, a.ns-aurora:hover, a.ns-gold:hover { filter: brightness(1.15); }
/* (light theme: the bright stops are 1.0-2.7:1 on white, so darker stops of the same hues; your canvas card, the
   signed-out profile's card and the shop's preview stay dark glass and keep the bright ones) */
:root[data-theme="light"] .ns-sunset:not(.p-card *, .guest .gp-id *, .fl-stage *) { background-image: linear-gradient(90deg, #c2410c, #be185d 60%, #a21caf); }
:root[data-theme="light"] .ns-aurora:not(.p-card *, .guest .gp-id *, .fl-stage *) { background-image: linear-gradient(90deg, #15803d, #0e7490 50%, #6d28d9); }
:root[data-theme="light"] .ns-gold:not(.p-card *, .guest .gp-id *, .fl-stage *) { background-image: linear-gradient(100deg, #7a5a03 0%, #a16207 30%, #8f6904 50%, #946c05 62%, #6b4e02 80%); }
:root[data-theme="light"] a:is(.ns-sunset, .ns-aurora, .ns-gold):not(.p-card *, .guest .gp-id *, .fl-stage *):hover { filter: brightness(.85); }

/* streaming on Twitch right now: a red ring that beats a level ring */
.avatar.is-live { box-shadow: 0 0 0 2px var(--ring-bg, var(--surface-solid)), 0 0 0 4px #ef4444; }
.avatar.is-live::before { display: none; }
.live-tag { display: inline-flex; align-items: center; flex-shrink: 0; padding: 1px 6px; border-radius: var(--r-xs); font-size: calc(9.5px * var(--fs-scale)); font-weight: 800; letter-spacing: .08em; line-height: 1.5; color: #fff; background: #dc2626; }
.live-tag:hover { background: #b91c1c; color: #fff; }
.avatar-stack { display: inline-flex; }
.avatar-stack .avatar { box-shadow: 0 0 0 2px var(--surface-solid); }
.avatar-stack .avatar + .avatar { margin-left: -8px; }

/* ---------- badges ---------- */
.badge { display: inline-flex; align-items: center; gap: 4px; height: 19px; padding: 0 7px; border-radius: var(--r-sm); font-size: var(--fs-2xs); font-weight: 800; letter-spacing: .02em; line-height: 1; white-space: nowrap; background: var(--hover-2); color: var(--text-2); }
.badge svg { width: 11px; height: 11px; }
.badge-accent, .badge-level { background: var(--accent-soft); color: var(--accent-text); }
.badge-green { background: var(--green-soft); color: var(--green-text); }
.badge-amber { background: var(--amber-soft); color: var(--amber-text); }
.badge-red { background: var(--red-soft); color: var(--red-text); }
.badge-blue { background: var(--blue-soft); color: var(--blue-text); }
.badge-outline { background: transparent; border: 1px solid var(--border-strong); }
.verified { display: inline-flex; width: 15px; height: 15px; color: var(--accent-hi); flex-shrink: 0; }
.verified svg { width: 100%; height: 100%; }
.count-badge { position: absolute; top: -5px; right: -5px; min-width: 17px; height: 17px; padding: 0 5px; border-radius: var(--r-sm); background: var(--accent-grad); color: var(--on-accent); font-size: calc(10px * var(--fs-scale)); font-weight: 800; display: grid; place-items: center; box-shadow: 0 0 0 2px var(--bg); font-variant-numeric: tabular-nums; }
.dot-badge { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--bg); }
.count-badge.as-dot { min-width: 0; width: 9px; height: 9px; padding: 0; top: -2px; right: -2px; }

/* ---------- cards ---------- */
.card { background: var(--sheen), var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--highlight), var(--shadow-card); min-width: 0; }
.card-pad { padding: 18px; }
.card-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 12px; }   /* (a narrow card puts its buttons under the title rather than cutting them off) */
.card-head h3, .card-title { font-size: calc(14.5px * var(--fs-scale)); font-weight: 700; font-family: var(--font-display); letter-spacing: -.01em; }
/* (a title that starts with an icon keeps it on the line, before the words: svgs are blocks by default, base.css) */
.card-title > svg:first-child { display: inline-block; width: 1.1em; height: 1.1em; margin-right: 6px; vertical-align: -.18em; }
.card-head .link { font-size: var(--fs-sm); }
.card-sub { font-size: var(--fs-sm); color: var(--text-2); }
.card-hover { transition: border-color var(--t), transform var(--t), background-color var(--t); }
.card-hover:hover { border-color: var(--border-strong); background: var(--sheen), var(--surface-2); transform: translateY(-1px); }
.card-link { cursor: pointer; }

/* section header */
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin: 28px 0 12px; }
.section-head:first-child { margin-top: 0; }
.section-head h2 { font-size: calc(17px * var(--fs-scale)); letter-spacing: -.02em; }
.section-head p { color: var(--text-2); font-size: var(--fs-sm); margin-top: 3px; }

/* page header */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
.page-head h1 { font-size: var(--fs-3xl); display: flex; align-items: center; gap: 12px; letter-spacing: -.03em; }
.page-head h1 .ph-icon { width: 36px; height: 36px; border-radius: var(--r); display: grid; place-items: center; color: var(--on-accent); background: var(--accent-grad); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 8px 20px -10px var(--accent-glow); }
.page-head h1 .ph-icon svg { width: 18px; height: 18px; }
.page-head p { color: var(--text-2); font-size: calc(13px * var(--fs-scale)); margin-top: 5px; max-width: 560px; }
.page-head .actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* a tab's own line under its page's title and tabs: what it shows, and its tools */
.sub-head { display: flex; align-items: center; justify-content: space-between; gap: 10px 16px; flex-wrap: wrap; margin-bottom: 16px; }
.sub-head p { flex: 1 1 300px; min-width: 0; color: var(--text-2); font-size: calc(13px * var(--fs-scale)); line-height: 1.5; }
.sub-head .actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab { position: relative; padding: 10px 12px; font-size: calc(13px * var(--fs-scale)); font-weight: 700; color: var(--text-2); white-space: nowrap; display: inline-flex; align-items: center; gap: 7px; transition: color var(--t); }
.tab svg { width: 15px; height: 15px; flex-shrink: 0; }
.tab:hover { color: var(--text); }
.tab.on { color: var(--text); }
.tab.on::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: var(--r-xs); background: var(--accent-grad); box-shadow: 0 0 10px var(--accent-glow); }
.tab .tab-count { font-size: var(--fs-2xs); font-weight: 800; padding: 1px 6px; border-radius: var(--r-sm); background: var(--hover-2); color: var(--text-2); }
.tab.on .tab-count { background: var(--accent-soft); color: var(--accent-text); }
.tab-count:empty { display: none; }
/* (phones: closer tabs, so a page's strip of four or five fits the screen instead of cutting the last one off) */
@media (max-width: 767px) { .tab { padding: 10px 8px; gap: 6px; } .tab.on::after { left: 6px; right: 6px; } }

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chips.scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.chips.scroll::-webkit-scrollbar { display: none; }
.chip { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: var(--r-sm); font-size: var(--fs-sm); font-weight: 700; color: var(--text-2); border: 1px solid var(--border-strong); background: var(--hover); white-space: nowrap; transition: background-color var(--t), border-color var(--t), color var(--t); }
.chip svg { width: 14px; height: 14px; }
.chip:hover { color: var(--text); border-color: var(--border-hover); background: var(--hover-2); }
.chip.on { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 22%, transparent), color-mix(in srgb, var(--accent-2) 12%, transparent)); color: var(--text); border-color: var(--accent-line); }
.chip.sm { height: 26px; padding: 0 10px; font-size: var(--fs-xs); }
.chip.static { cursor: default; pointer-events: none; }
.chip .x { width: 16px; height: 16px; margin-right: -6px; border-radius: 50%; display: grid; place-items: center; }
.chip .x:hover { background: var(--hover-2); }
.chip-count { font-size: var(--fs-2xs); font-weight: 800; padding: 1px 6px; border-radius: var(--r-sm); background: var(--hover-2); color: var(--text-3); margin-right: -4px; }
.chip.on .chip-count { background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent-text); }
.tag { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--r-sm); font-size: var(--fs-xs); font-weight: 700; background: var(--hover); color: var(--text-2); border: 1px solid var(--border); white-space: nowrap; }
.tag svg { width: 11px; height: 11px; }

/* ---------- menus / dropdowns ---------- */
.menu {
  position: fixed; z-index: calc(var(--z-modal) + 2); min-width: 210px; max-width: 320px; padding: 5px; max-height: calc(100vh - 16px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--sheen), var(--surface-solid);
  border: 1px solid var(--border-strong); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  animation: pop-in var(--t) var(--ease-out); transform-origin: top right;
}
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; border-radius: var(--r-sm); font-size: calc(13px * var(--fs-scale)); font-weight: 600; color: var(--text-body); text-align: left; transition: background-color var(--t-fast), color var(--t-fast); }
.menu-item svg { width: 16px; height: 16px; color: var(--text-2); flex-shrink: 0; }
.menu-item:hover, .menu-item.active { background: var(--hover-2); color: var(--text); }
.menu-item:hover svg { color: var(--text); }
.menu-item.danger { color: var(--red-text); }
.menu-item.danger svg { color: var(--red-text); }
.menu-item.danger:hover { background: var(--red-soft); }
.menu-item .kbd, .menu-item .meta { margin-left: auto; font-size: var(--fs-xs); color: var(--text-3); }
.menu-item .check-mark { margin-left: auto; color: var(--accent-text); }
.menu-sep { height: 1px; margin: 5px 4px; background: var(--border); }
.menu-label { padding: 7px 10px 4px; font-size: calc(10px * var(--fs-scale)); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.menu-head { display: flex; align-items: center; gap: 10px; padding: 9px 10px 11px; }

/* ---------- modal ---------- */
.modal-root { position: fixed; inset: 0; z-index: var(--z-modal); display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: 24px; }   /* (one column no wider than the screen: a long unbroken line can't stretch a phone's sheet past it) */
.modal-backdrop { position: absolute; inset: 0; background: var(--overlay); -webkit-backdrop-filter: blur(6px) saturate(1.2); backdrop-filter: blur(6px) saturate(1.2); animation: fade-in var(--t) ease both; }
.modal {
  position: relative; width: 100%; max-width: 500px; max-height: calc(100vh - 48px); display: flex; flex-direction: column;
  background: var(--sheen), var(--surface-solid);
  border: 1px solid var(--border-strong); border-radius: var(--r-lg); box-shadow: var(--highlight), var(--shadow-lg);
  animation: pop-in var(--t-slow) var(--ease-out) both;
}
.modal.sm { max-width: 400px; } .modal.lg { max-width: 660px; } .modal.xl { max-width: 880px; } .modal.full { max-width: 1100px; height: calc(100vh - 48px); }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 18px 20px 12px; }
.modal-head h2 { font-size: calc(17px * var(--fs-scale)); flex: 1; min-width: 0; }
.modal-head .sub { display: block; font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--text-2); font-weight: 500; letter-spacing: 0; margin-top: 3px; }
.modal-body { padding: 4px 20px 20px; overflow-y: auto; flex: 1; min-height: 0; }
.modal-body.flush { padding: 0; }
.modal-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 13px 20px; border-top: 1px solid var(--border); }
.modal-foot .left { margin-right: auto; }
.modal .lead { color: var(--text-2); font-size: calc(13px * var(--fs-scale)); margin-bottom: 14px; }
.danger-zone { border: 1px solid color-mix(in srgb, var(--red) 35%, transparent); background: var(--red-soft); border-radius: var(--r-md); padding: 12px 14px; color: var(--text-body); font-size: var(--fs-sm); }

/* ---------- toasts ---------- */
.toasts { position: fixed; z-index: var(--z-toast); left: 50%; bottom: calc(24px + var(--bottom-nav-h)); transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; width: min(92vw, 420px); }
.toast { pointer-events: auto; display: flex; align-items: center; gap: 10px; padding: 9px 13px 9px 10px; border-radius: var(--r-md); background: var(--sheen), var(--surface-solid); border: 1px solid var(--border-strong); box-shadow: var(--shadow-lg); color: var(--text); font-size: calc(13px * var(--fs-scale)); font-weight: 600; animation: pop-in var(--t-slow) var(--ease-out) both; max-width: 100%; }
.toast .t-icon { width: 24px; height: 24px; border-radius: var(--r-sm); display: grid; place-items: center; flex-shrink: 0; background: var(--accent-soft); color: var(--accent-text); }
.toast .t-icon svg { width: 14px; height: 14px; }
.toast.success .t-icon { background: var(--green-soft); color: var(--green-text); }
.toast.error .t-icon { background: var(--red-soft); color: var(--red-text); }
.toast.reward .t-icon { background: var(--amber-soft); color: var(--amber-text); }
.toast .t-action { margin-left: 6px; color: var(--accent-text); font-weight: 800; font-size: var(--fs-sm); white-space: nowrap; }
.toast.leaving { animation: fade-in var(--t) reverse both; }

/* ---------- tooltips ----------
   data-tip="…": one bubble on <body> (ui/tips.js), placed where it fits, so no box an element sits in cuts its
   words off and none go past the screen's edge. (A bubble inside each element was cut off by every card that
   hides what pokes out of it, and its own box counted as page width.) */
[data-tip] { position: relative; }
.tip-bubble { position: fixed; z-index: calc(var(--z-toast) + 10); width: max-content; max-width: min(280px, calc(100vw - 12px)); padding: 5px 8px;
  border-radius: var(--r-sm); background: var(--surface-solid); border: 1px solid var(--border-strong); color: var(--text);
  font-size: var(--fs-xs); font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; pointer-events: none; box-shadow: var(--shadow);
  animation: tip-in var(--t) var(--ease) both; }
.tip-bubble[hidden] { display: none; }
@keyframes tip-in { from { opacity: 0; translate: 0 4px; } to { opacity: 1; translate: 0 0; } }
/* the icon-only sidebar's names (shell.js): one bubble outside the sidebar, which clips anything that pokes out */
.side-tip { position: fixed; z-index: var(--z-drop); transform: translateY(-50%); padding: 5px 8px; border-radius: var(--r-sm); background: var(--surface-solid); border: 1px solid var(--border-strong); color: var(--text);
  font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; pointer-events: none; box-shadow: var(--shadow); animation: tip-in var(--t) var(--ease) .25s both; }

/* ---------- skeletons / spinners ---------- */
.skel { background: linear-gradient(90deg, var(--hover) 0%, color-mix(in srgb, var(--accent) 10%, var(--hover-2)) 50%, var(--hover) 100%); background-size: 800px 100%; animation: shimmer 1.4s linear infinite; border-radius: var(--r-sm); }
.skel-line { height: 12px; border-radius: var(--r-sm); }
.skel-circle { border-radius: 50%; }
.spinner { width: 20px; height: 20px; border-radius: 50%; border: 2.5px solid var(--track); border-top-color: var(--accent); animation: spin .7s linear infinite; }
.spinner.sm { width: 16px; height: 16px; border-width: 2px; }
.loading-block { display: grid; place-items: center; padding: 40px 0; }
.typing-dots { display: inline-flex; gap: 4px; align-items: center; }
.typing-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--text-2); animation: pulse-dot 1.1s infinite; }
.typing-dots i:nth-child(2) { animation-delay: .15s; } .typing-dots i:nth-child(3) { animation-delay: .3s; }

/* ---------- empty state ---------- */
.empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 36px 20px; }
.empty .e-icon { width: 46px; height: 46px; border-radius: var(--r-md); display: grid; place-items: center; color: var(--accent-hi); margin-bottom: 4px;
  background: radial-gradient(120% 120% at 30% 20%, color-mix(in srgb, var(--accent-2) 28%, transparent), transparent 60%), var(--accent-soft);
  border: 1px solid var(--accent-line); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08); }
.empty .e-icon svg { width: 21px; height: 21px; }
.empty h3 { font-size: calc(15px * var(--fs-scale)); font-family: var(--font-ui); letter-spacing: 0; }
.empty p { color: var(--text-2); max-width: 360px; font-size: calc(13px * var(--fs-scale)); }
.empty .btn { margin-top: 6px; }
.empty.compact { padding: 24px 16px; }
.empty.compact .e-icon { width: 38px; height: 38px; border-radius: var(--r-md); }
.empty.compact .e-icon svg { width: 18px; height: 18px; }

/* ---------- progress ---------- */
.progress { height: 5px; border-radius: var(--r-sm); background: var(--track); overflow: hidden; }
.progress > i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width var(--t-slow) var(--ease); }
.progress.sm { height: 4px; }
.progress.lg { height: 8px; }
.progress.green > i { background: var(--green); }
.progress.gold > i { background: linear-gradient(90deg, #f59e0b, var(--gold)); }

/* ---------- list rows ---------- */
.list { display: flex; flex-direction: column; }
.list-row { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: var(--r); min-width: 0; transition: background-color var(--t-fast); }
.list-row.clickable { cursor: pointer; }
.list-row.clickable:hover { background: var(--hover); }
.list-row .lr-main { flex: 1; min-width: 0; }
.list-row .lr-title { font-weight: 700; font-size: calc(13px * var(--fs-scale)); color: var(--text); display: flex; align-items: center; gap: 6px; min-width: 0; }
.list-row .lr-sub { font-size: var(--fs-xs); color: var(--text-2); margin-top: 1px; }
.list-row .sd-icon { width: 32px; height: 32px; border-radius: var(--r); display: grid; place-items: center; background: var(--hover-2); color: var(--text-2); flex-shrink: 0; }
.list-row .sd-icon svg { width: 16px; height: 16px; }
.list-row:disabled { opacity: .55; cursor: default; }
.divider { height: 1px; background: var(--border); margin: 12px 0; border: 0; }
.divided > * + * { border-top: 1px solid var(--border); }

/* ---------- stats: a compact tile — icon beside the number, like a widget row ---------- */
.stat { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.stat b { font-family: var(--font-display); font-size: var(--fs-xl); font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; line-height: 1.15; }
.stat span { font-size: var(--fs-xs); color: var(--text-2); font-weight: 600; }

/* ---------- misc ---------- */
.kbd { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; border-radius: var(--r-sm); border: 1px solid var(--border-strong); background: var(--surface-2); font-size: var(--fs-2xs); font-weight: 700; color: var(--text-2); font-family: var(--font-ui); }
.callout { display: flex; gap: 10px; padding: 12px 14px; border-radius: var(--r-md); background: var(--accent-softer); border: 1px solid var(--accent-line); font-size: var(--fs-sm); color: var(--text-body); }
.callout > svg { width: 17px; height: 17px; color: var(--accent-text); flex-shrink: 0; margin-top: 1px; }
.callout.warn { background: var(--amber-soft); border-color: color-mix(in srgb, var(--amber) 40%, transparent); }
.callout.warn > svg { color: var(--amber-text); }
.callout.danger { background: var(--red-soft); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.callout.danger > svg { color: var(--red-text); }
.callout.ok { background: var(--green-soft); border-color: color-mix(in srgb, var(--green) 40%, transparent); }
.callout.ok > svg { color: var(--green-text); }
.code-box { font-family: var(--font-mono); font-size: var(--fs-sm); padding: 11px 13px; border-radius: var(--r); background: var(--surface-sunken); border: 1px solid var(--border-strong); word-break: break-all; color: var(--text-body); }
/* game art; with none anywhere, a designed tile (not a "missing image") */
.cover { position: relative; overflow: hidden;
  background: radial-gradient(120% 90% at 0% 0%, hsl(var(--h, 260) 72% 46% / .55), transparent 58%), radial-gradient(100% 90% at 100% 100%, hsl(calc(var(--h, 260) + 60) 78% 42% / .5), transparent 62%), linear-gradient(140deg, hsl(var(--h, 260) 45% 17%), hsl(calc(var(--h, 260) + 40) 52% 8%)); }
.cover > img { width: 100%; height: 100%; object-fit: cover; }
/* (a picture that doesn't suit its box, shown whole: centred on the game's tinted tile, at most its own size; set by
   the load watcher in ui/parts.js) */
.cover.cover.fit-whole { background: #08070e; }
.cover.cover.fit-whole > img { position: absolute; inset: 0; margin: auto; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; }
.cover .cover-fallback { position: absolute; inset: 0; display: grid; place-items: center; padding: 12px; text-align: center; font-family: var(--font-display); font-weight: 700; color: #fff; font-size: calc(13px * var(--fs-scale)); line-height: 1.15; letter-spacing: -.01em; text-shadow: 0 2px 14px rgba(0, 0, 0, .55); }
.cover .cover-fallback::before { content: ''; position: absolute; inset: 0; z-index: -1; background: repeating-linear-gradient(135deg, rgba(255, 255, 255, .035) 0 2px, transparent 2px 10px); }
.cover .cover-fallback::after { content: ''; position: absolute; right: 8%; bottom: 8%; width: 30%; max-width: 64px; aspect-ratio: 1; opacity: .16; z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='6' width='20' height='12' rx='6'/%3E%3Cpath d='M7 10v4M5 12h4M15 11h.01M18 13h.01'/%3E%3C/svg%3E") center / contain no-repeat; }
.cover .cover-fallback { isolation: isolate; }
.hr-label { display: flex; align-items: center; gap: 12px; color: var(--text-3); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.hr-label::before, .hr-label::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* ---------- boost: the one way to lift what someone made. Up only: lit when you gave one (ui/boost.js) ---------- */
.boost { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; flex-shrink: 0; }
.boost-btn { width: 34px; height: 34px; display: grid; place-items: center; border: 1px solid var(--border-strong); border-radius: var(--r-sm); background: color-mix(in srgb, var(--surface-2) 70%, transparent); color: var(--text-2);
  transition: color .2s ease, border-color .2s ease, background .2s ease, box-shadow .3s ease, transform .2s var(--ease-out); }
.boost-btn svg { width: 16px; height: 16px; transition: transform .25s var(--ease-out); }
.boost-btn:hover:not([aria-disabled="true"]) { color: var(--text); border-color: var(--accent-line); }
.boost-btn:hover:not([aria-disabled="true"]) svg { transform: translateY(-1px); }
.boost-btn.on { border-color: transparent; background: var(--accent-grad); color: var(--on-accent); box-shadow: 0 0 18px -4px var(--accent-glow); }
.boost-btn[aria-disabled="true"] { cursor: default; opacity: .62; }
.boost-btn.pop svg { animation: boost-pop .5s var(--ease-out); }
@keyframes boost-pop { 0% { transform: translateY(0); } 35% { transform: translateY(-5px); } 100% { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .boost-btn.pop svg { animation: none; } }
.boost-n { font-size: var(--fs-sm); font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text); line-height: 1; }
.boost.row, .boost.sm { flex-direction: row; gap: 7px; }
/* (one light-edged chip: the arrow and the count together, the height of the chips beside it) */
.boost.chip { flex-direction: row; gap: 0; height: 26px; border: 1px solid var(--border-strong); }
.boost.chip .boost-btn { width: 26px; height: 24px; border: 0; background: transparent; box-shadow: none; }
.boost.chip .boost-btn svg { width: 13px; height: 13px; }
.boost.chip .boost-n { padding: 0 9px 0 1px; font-size: var(--fs-xs); }
.boost.chip:has(.boost-btn.on) { border-color: var(--accent-line); background: var(--accent-soft); }
.boost.chip .boost-btn.on, .boost.chip:has(.boost-btn.on) .boost-n { color: var(--accent-text); }
.boost.row .boost-btn { width: 32px; height: 32px; }
.boost-w { margin-left: -3px; font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.boost.sm .boost-btn { width: 26px; height: 26px; }
.boost.sm .boost-btn svg { width: 13px; height: 13px; }
.boost.sm .boost-n { font-size: var(--fs-xs); }
.boost-count { display: inline-flex; align-items: center; gap: 3px; flex-shrink: 0; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text-2); }
.boost-count svg { width: 13px; height: 13px; }
.boost-count.on { color: var(--accent-text); }
/* over a picture (a page's hero): glass, as the buttons beside it */
.boost.glass { flex-direction: row; gap: 0; height: 36px; border: 1px solid rgba(255, 255, 255, .2); background: rgba(6, 6, 9, .62); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.boost.glass .boost-btn { width: 34px; height: 34px; border: 0; background: transparent; color: #f2f1f7; }
.boost.glass .boost-btn.on { background: var(--accent-grad); color: var(--on-accent); }
.boost.glass .boost-n { padding: 0 11px 0 3px; color: #fff; }
/* (no count while there are none; "Boost" in its place where the count shows elsewhere on the page) */
.boost-n[data-n="0"] { display: none; }
.boost-l { font-size: var(--fs-sm); font-weight: 700; color: var(--text-2); }
.boost-btn.on + .boost-l { color: var(--accent-text); }
