/* ───────────────── Front of Heroes · Components ─────────────────
   Every shared building block, with all of its states. Pages compose these and only add layout.
   Catalogue with live examples: #/design-system (src/design_system.rs). Spec: docs/DESIGN.md. */

@layer components {

/* ══ Layout ══════════════════════════════════════════════════════════════════════════════════ */
main { min-height: calc(100vh - var(--nav-h)); min-height: calc(100dvh - var(--nav-h)); overflow-x: clip; } /* clip: the city may reach past a classic scrollbar */
.splash { min-height: 100vh; display: grid; place-items: center; color: var(--text-3); letter-spacing: var(--ls-caps); text-transform: uppercase; font-size: var(--fs-sm); }

.page { position: relative; width: 100%; max-width: var(--page-max); margin: 0 auto; padding: var(--sp-8) var(--page-pad) var(--sp-16);
  display: flex; flex-direction: column; gap: var(--gap); animation: page-in var(--t-slow) var(--ease); }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } }
/* The city in the margins beside the cards: never under them, never past their end, at most a
   screen tall, melting into the page like mist on the side that meets them. The painting is sized
   by the screen, never by the page (each half is about 2:3), so it is the same on every page and a
   short page only shows less of it. */
.page::before, .page::after { content: ""; position: absolute; top: 0; z-index: -1; pointer-events: none;
  /* Margin + the page's padding up to the cards; with no margin (narrow screens) nothing at all. */
  --margin: calc((100vw - 100%) / 2); --backdrop-size: max(100%, 100vh * 2 / 3) auto; width: calc(var(--margin) + min(var(--page-pad), var(--margin) * 100)); height: min(100% - var(--sp-16), 100vh); opacity: var(--backdrop-opacity); mix-blend-mode: var(--backdrop-blend);
  -webkit-mask-image: linear-gradient(var(--mist-to), #000 55%, transparent 100%), linear-gradient(#000 70%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(var(--mist-to), #000 55%, transparent 100%), linear-gradient(#000 70%, transparent);
  mask-composite: intersect; }
.page::before { --mist-to: to right; right: calc(100% - var(--page-pad)); background: var(--backdrop-left) left top / var(--backdrop-size) no-repeat; }
.page::after { --mist-to: to left; left: calc(100% - var(--page-pad)); background: var(--backdrop-right) right top / var(--backdrop-size) no-repeat; }

/* Page header: the title, one line that says what the page is for, and the page's own controls. */
.page-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-4) var(--sp-6); flex-wrap: wrap; padding-bottom: var(--sp-1); }
.page-head > div:first-child { min-width: 0; }
.page-head h1 { color: var(--text); }
.page-head p { margin-top: var(--sp-2); max-width: 64ch; color: var(--text-2); font-size: var(--fs-md); line-height: var(--lh-body); }

/* Section header inside a page: a title (h2) with optional actions on the right. */
.section-head { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.section-head p { color: var(--text-2); font-size: var(--fs-sm); margin-top: 2px; }

.stack { display: flex; flex-direction: column; gap: var(--sp-4); }
.stack.tight { gap: var(--sp-2); }
.stack.loose { gap: var(--sp-6); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.split { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); }
.grow { flex: 1; min-width: 0; }
.cols { display: grid; grid-template-columns: 1.15fr 1fr; gap: var(--gap); }
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
@media (max-width: 900px) { .cols, .cols-2 { grid-template-columns: 1fr; } .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { :root { --page-pad: 16px; --gap: 16px; } .page { padding-top: var(--sp-5); } .page-head h1 { font-size: 1.875rem; } }

/* ══ Card ════════════════════════════════════════════════════════════════════════════════════ */
.card { position: relative; min-width: 0; color: var(--text); background: var(--surface-1); border: 1px solid var(--border-subtle);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1), var(--highlight); }
.card.pad { padding: var(--sp-5); }
@media (min-width: 900px) { .card.pad { padding: var(--sp-6); } }
.card.flat { box-shadow: none; }
.card.inset { background: var(--surface-2); box-shadow: none; }
.card.interactive { cursor: pointer; transition: border-color var(--t-base), transform var(--t-base) var(--ease), box-shadow var(--t-base); }
.card.interactive:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-2), var(--highlight); }
.card.interactive:disabled, .card.interactive[aria-disabled="true"] { cursor: not-allowed; opacity: .55; transform: none; box-shadow: var(--shadow-1), var(--highlight); border-color: var(--border-subtle); }
.card.selected { border-color: var(--brand-border); box-shadow: 0 0 0 1px var(--brand-border), var(--shadow-2); }
.card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.card-head > div { min-width: 0; }
.card-head p { color: var(--text-2); font-size: var(--fs-sm); margin-top: 2px; }
.card-foot { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--border-subtle); }

/* ══ Buttons ═════════════════════════════════════════════════════════════════════════════════
   .btn               secondary: the default action
   .btn.primary       the one hero action of an area (brand yellow)
   .btn.go            the big green call to action (Work, Train, Fight)
   .btn.danger        destructive (fire, delete, leave)
   .btn.ghost         outline, quiet
   .btn.plain         text-only, no frame
   .btn.link          inline text link
   Sizes: .sm 32 · default 40 · .lg 48 · .xl 56 — .wide fills the row — .icon-only is square.
   States: :hover, :active (pressed), :focus-visible (ring), :disabled, .is-loading. */
.btn { --btn-h: var(--h-md); --spinner: var(--text);
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--btn-h); padding: 0 var(--sp-4); border-radius: var(--r-md);
  border: 1px solid var(--btn-border); background: var(--btn-bg); color: var(--text);
  font: var(--fw-semibold) var(--fs-md) / 1.1 var(--font-ui); letter-spacing: .005em; text-align: center; white-space: nowrap; text-decoration: none;
  box-shadow: var(--highlight), 0 1px 2px rgba(0, 0, 0, .16);
  cursor: pointer; user-select: none; -webkit-user-select: none;
  transition: background-color var(--t-fast), background var(--t-fast), border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-base), transform var(--t-fast); }
.btn:hover:not(:disabled), .btn.is-hover { background: var(--btn-bg-hover); border-color: var(--border-strong); color: var(--text); }
.btn:active:not(:disabled), .btn.is-active { transform: translateY(1px); background: var(--btn-bg-active); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .18); }
.btn:focus-visible, .btn.is-focus { outline: 2px solid var(--focus); outline-offset: 2px; }
.btn .icon { width: 18px; height: 18px; }
.btn img { width: 20px; height: 20px; object-fit: contain; }

.btn.primary { --spinner: var(--on-brand); color: var(--on-brand); border-color: var(--brand-edge);
  background: linear-gradient(180deg, #ffe76a 0%, var(--brand) 50%, #edc900 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 1px 0 rgba(0, 0, 0, .12), 0 6px 18px -8px var(--brand-glow); }
.btn.primary:hover:not(:disabled), .btn.primary.is-hover { color: var(--on-brand); border-color: var(--brand-edge); background: linear-gradient(180deg, #fff08f 0%, var(--brand-hover) 50%, #f5d200 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 1px 0 rgba(0, 0, 0, .12), 0 10px 24px -8px var(--brand-glow); }
.btn.primary:active:not(:disabled), .btn.primary.is-active { background: var(--brand-active); box-shadow: inset 0 2px 4px rgba(0, 0, 0, .2); }

.btn.go { --btn-h: var(--h-xl); --spinner: #fff; padding: 0 var(--sp-8); color: #fff; border-color: #0b6b2c;
  font: var(--fw-bold) 1.25rem / 1 var(--font-display); letter-spacing: var(--ls-cta); text-transform: uppercase; text-shadow: 0 1px 1px rgba(0, 40, 12, .45);
  background: linear-gradient(180deg, #4fe07f 0%, #1fae4f 52%, #128f3e 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), 0 1px 0 rgba(0, 0, 0, .15), 0 10px 26px -10px rgba(34, 197, 94, .7); }
.btn.go:hover:not(:disabled), .btn.go.is-hover { color: #fff; border-color: #0b6b2c; background: linear-gradient(180deg, #66ea93 0%, #27bb5a 52%, #14994a 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 1px 0 rgba(0, 0, 0, .15), 0 14px 32px -10px rgba(34, 197, 94, .8); }
.btn.go:active:not(:disabled), .btn.go.is-active { background: #179447; box-shadow: inset 0 2px 5px rgba(0, 0, 0, .25); }

.btn.danger { --spinner: #fff; color: #fff; border-color: #9a1d12;
  background: linear-gradient(180deg, #ff705e 0%, #e5392a 52%, #c62a1c 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 1px 0 rgba(0, 0, 0, .15), 0 6px 18px -8px rgba(255, 75, 58, .6); }
.btn.danger:hover:not(:disabled), .btn.danger.is-hover { color: #fff; border-color: #9a1d12; background: linear-gradient(180deg, #ff8371 0%, #ee4433 52%, #d02f20 100%); }
.btn.danger:active:not(:disabled), .btn.danger.is-active { background: #c42b1d; box-shadow: inset 0 2px 4px rgba(0, 0, 0, .25); }

.btn.ghost { background: transparent; border-color: var(--border); color: var(--text-2); box-shadow: none; }
.btn.ghost:hover:not(:disabled), .btn.ghost.is-hover { background: var(--surface-3); border-color: var(--border-strong); color: var(--text); }
.btn.ghost:active:not(:disabled), .btn.ghost.is-active { background: var(--surface-2); }
.btn.ghost.danger:not(:disabled), .btn.danger.ghost:not(:disabled) { background: transparent; color: var(--red-text); border-color: color-mix(in srgb, var(--red) 40%, transparent); text-shadow: none; }
.btn.ghost.danger:hover:not(:disabled), .btn.danger.ghost:hover:not(:disabled), .btn.ghost.danger.is-hover, .btn.danger.ghost.is-hover { background: var(--red-soft); color: var(--red-text); border-color: var(--red); }

.btn.plain { background: transparent; border-color: transparent; color: var(--text-2); box-shadow: none; }
.btn.plain:hover:not(:disabled), .btn.plain.is-hover { background: var(--surface-3); border-color: transparent; color: var(--text); }

.btn.link { min-height: 0; padding: 0; border: 0; background: none; box-shadow: none; color: var(--brand-text); font-weight: var(--fw-semibold); border-radius: var(--r-xs); }
.btn.link:hover:not(:disabled), .btn.link.is-hover { background: none; color: var(--brand-text); text-decoration: underline; text-underline-offset: 3px; }
.btn.link:active:not(:disabled), .btn.link.is-active { transform: none; background: none; box-shadow: none; }

.btn.sm { --btn-h: var(--h-sm); padding: 0 var(--sp-3); gap: 6px; border-radius: var(--r-sm); font-size: var(--fs-sm); }
.btn.sm .icon { width: 16px; height: 16px; }
.btn.lg { --btn-h: var(--h-lg); padding: 0 var(--sp-6); font-size: var(--fs-lg); border-radius: var(--r-md); }
.btn.xl { --btn-h: var(--h-xl); padding: 0 var(--sp-8); font-size: var(--fs-lg); }
.btn.wide { width: 100%; --btn-h: var(--h-lg); margin-top: var(--sp-4); font-size: var(--fs-lg); }
.btn.block { width: 100%; }
.btn.icon-only { width: var(--btn-h); padding: 0; }

/* Disabled looks the same for every variant: flat, quiet, clearly unavailable. */
.btn:disabled, .btn[aria-disabled="true"] { cursor: not-allowed; color: var(--text-disabled); background: var(--btn-disabled-bg);
  border-color: var(--border-subtle); box-shadow: none; text-shadow: none; transform: none; filter: none; }
.btn.link:disabled, .btn.plain:disabled { background: transparent; border-color: transparent; }

/* Working: the label stays for layout, a spinner replaces it. */
.btn.is-loading { color: transparent !important; text-shadow: none; pointer-events: none; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after { content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--spinner); border-right-color: transparent; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.btn-group { display: inline-flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* Touch screens: no control under 40px, whatever its size class. */
@media (pointer: coarse), (max-width: 720px) {
  .btn.sm, .pagination .btn { --btn-h: var(--h-md); }
  .stepper.small { height: var(--h-md); }
  .stepper.small button { width: 40px; }
  input.sm, select.sm { min-height: var(--h-md); }
}

/* A toggle button that stays lit while on (a like, a vote, a filter): aria-pressed="true". */
.btn[aria-pressed="true"]:not(:disabled) { color: var(--brand-text); background: var(--brand-soft); border-color: var(--brand-border); box-shadow: none; }
.btn[aria-pressed="true"]:hover:not(:disabled), .btn[aria-pressed="true"].is-hover { color: var(--brand-text); background: var(--brand-soft); border-color: var(--brand); }
.btn.plain[aria-pressed="true"] { border-color: transparent; }

/* The close button of a dialog or panel: icon-only, top right. */
.dialog-close { position: absolute; top: var(--sp-3); right: var(--sp-3); z-index: 1; display: grid; place-items: center; width: 36px; height: 36px;
  border-radius: var(--r-md); color: var(--text-3); transition: background-color var(--t-fast), color var(--t-fast); }
.dialog-close:hover, .dialog-close.is-hover { background: var(--surface-3); color: var(--text); }
.dialog-close:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ══ Form controls ═══════════════════════════════════════════════════════════════════════════
   One look for text inputs, selects and text areas. States: :hover, :focus, [aria-invalid=true],
   :disabled, [readonly]. Sizes: .sm 32 · default 40 · .lg 48. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="submit"], [type="button"], [type="reset"], [type="hidden"])),
:where(textarea), .input {
  min-height: var(--h-md); padding: 0 var(--sp-3); border-radius: var(--r-md);
  border: 1px solid var(--input-border); background-color: var(--input-bg); color: var(--text);
  font: var(--fw-medium) var(--fs-md) / 1.3 var(--font-ui); letter-spacing: 0;
  box-shadow: var(--input-shadow); outline: none; min-width: 0;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background-color var(--t-fast); }
:where(textarea) { display: block; width: 100%; padding: var(--sp-3); line-height: var(--lh-body); resize: vertical; min-height: 96px; }
:where(input, textarea, .input):hover:not(:disabled):not(:focus):not([readonly]), :where(input, textarea, .input).is-hover { border-color: var(--input-border-hover); }
:where(input, textarea, .input):focus, :where(input, textarea, .input).is-focus { border-color: var(--focus); box-shadow: var(--input-shadow), var(--focus-ring); }
:where(input, textarea)::placeholder { color: var(--text-3); opacity: 1; font-weight: var(--fw-regular); }
:where(input, textarea, .input):disabled { cursor: not-allowed; color: var(--text-disabled); background-color: var(--surface-3); border-color: var(--border-subtle); box-shadow: none; }
:where(input, textarea)[readonly] { background-color: transparent; border-style: dashed; box-shadow: none; }
:where(input, textarea)[aria-invalid="true"], :where(input, textarea).is-invalid { border-color: var(--red); }
:where(input, textarea)[aria-invalid="true"]:focus, :where(input, textarea).is-invalid:focus { box-shadow: 0 0 0 3px var(--red-soft); }
input.sm, select.sm { min-height: var(--h-sm); font-size: var(--fs-sm); border-radius: var(--r-sm); }
select.sm { padding-top: 6px; padding-bottom: 6px; }
select.lg { padding-top: 14px; padding-bottom: 14px; }
input.lg, select.lg { min-height: var(--h-lg); font-size: var(--fs-lg); }
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="range"] { accent-color: var(--brand); }

/* Select: the closed field matches the inputs, with a chevron. Where the browser lets us
   (appearance: base-select, Chrome 135+) the open list is styled too. */
select {
  -webkit-appearance: none; appearance: none;
  min-height: var(--h-md); padding: 10px 2.5rem 10px var(--sp-3); border-radius: var(--r-md); cursor: pointer;
  border: 1px solid var(--input-border); color: var(--text); font: var(--fw-medium) var(--fs-md) / 18px var(--font-ui);
  background-color: var(--select-bg);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 6l4 4 4-4' fill='none' stroke='%237f8aa1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat; background-position: right .75rem center; background-size: 14px 14px;
  box-shadow: var(--highlight), 0 1px 2px rgba(0, 0, 0, .12);
  text-overflow: ellipsis; white-space: nowrap; overflow: hidden; outline: none; min-width: 0;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background-color var(--t-fast); }
select:hover:not(:disabled), select.is-hover { border-color: var(--input-border-hover); }
select:focus, select:focus-visible, select.is-focus { border-color: var(--focus); box-shadow: var(--focus-ring); outline: none; }
select:disabled { opacity: .55; cursor: not-allowed; }
select option, select optgroup { background: var(--surface-overlay); color: var(--text); font-weight: var(--fw-medium); }
select optgroup { color: var(--text-3); }
@supports (appearance: base-select) {
select, select::picker(select) { appearance: base-select; }
select { position: relative; }
select > button { display: contents; }
/* The chevron stays the background image in both modes (the picker icon does not paint reliably);
   it turns up while the list is open. */
select::picker-icon { display: none; }
select:open { border-color: var(--focus);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 10l4-4 4 4' fill='none' stroke='%237f8aa1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>"); }
select::picker(select) { margin-top: 6px; padding: var(--sp-1); border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-overlay); color: var(--text);
    box-shadow: var(--shadow-3); max-height: min(360px, 60vh); overflow-y: auto; opacity: 0; transform: translateY(-4px);
    transition: opacity var(--t-fast), transform var(--t-fast), overlay var(--t-fast) allow-discrete, display var(--t-fast) allow-discrete; }
select:open::picker(select) { opacity: 1; transform: none; }
@starting-style { select:open::picker(select) { opacity: 0; transform: translateY(-4px); } }
select option { display: flex; align-items: center; gap: var(--sp-2); min-height: 36px; padding: 0 var(--sp-3); border-radius: var(--r-sm); background: transparent; cursor: pointer; font-size: var(--fs-md); }
select option:hover, select option:focus-visible { background: var(--surface-3); outline: none; }
select option:checked { color: var(--brand-text); background: var(--brand-soft); }
select option::checkmark { content: "✓"; order: 1; margin-left: auto; color: var(--brand-text); font-weight: var(--fw-bold); }
select option:disabled { opacity: .45; cursor: not-allowed; }
select optgroup { padding: var(--sp-1) 0; background: transparent; font-size: var(--fs-xs); letter-spacing: var(--ls-caps); text-transform: uppercase; }
}

/* A labelled field: label, control, optional hint or error. */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span:first-child, .field > label:first-child, .field-label { display: inline-flex; align-items: center; gap: var(--sp-1);
  font: var(--fw-semibold) var(--fs-sm) / 1.3 var(--font-ui); color: var(--text-2); letter-spacing: 0; text-transform: none; }
.field > small { font-size: var(--fs-xs); line-height: 1.4; color: var(--text-3); }
.field-error { font-size: var(--fs-xs); color: var(--red-text); font-weight: var(--fw-medium); }
.field > input, .field > select, .field > textarea, .field > .input-group { width: 100%; }
.form-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: flex-end; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--sp-4); align-items: start; }

/* A control with a unit or a button inside its right edge: .input-group > input + .unit / button. */
.input-group, .with-unit, .with-action { position: relative; display: flex; align-items: center; min-width: 0; }
.input-group > input, .with-unit > input, .with-action > input { flex: 1; width: 100%; padding-right: 3.6rem; }
.input-group > .unit, .with-unit > .unit, .with-unit > span:not(.info-tip):last-child { position: absolute; right: var(--sp-3); pointer-events: none; color: var(--text-3); font-size: var(--fs-sm); font-weight: var(--fw-semibold); }
.input-group > button:last-child, .with-action > button:last-child { position: absolute; right: 4px; min-height: calc(var(--h-md) - 10px); padding: 0 var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--brand-text); background: var(--brand-soft); border: 0; }
.input-group > button:last-child:hover:not(:disabled), .with-action > button:last-child:hover:not(:disabled), .input-group > button:last-child.is-hover, .with-action > button:last-child.is-hover { background: var(--brand); color: var(--on-brand); }

.input-group > button:last-child:disabled, .with-action > button:last-child:disabled { color: var(--text-disabled); background: transparent; cursor: not-allowed; }

/* Checkbox and radio. */
input[type="checkbox"]:not(.native), input[type="radio"]:not(.native) {
  -webkit-appearance: none; appearance: none; flex: none; display: inline-grid; place-content: center;
  width: 18px; height: 18px; margin: 0; vertical-align: -4px; cursor: pointer;
  border: 1.5px solid var(--border-strong); border-radius: 5px; background: var(--input-bg) center / 12px 12px no-repeat;
  transition: background-color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast); }
input[type="radio"]:not(.native) { border-radius: 50%; }
input[type="checkbox"]:not(.native):hover:not(:disabled), input[type="radio"]:not(.native):hover:not(:disabled), input[type="checkbox"]:not(.native).is-hover, input[type="radio"]:not(.native).is-hover { border-color: var(--brand-border); }
input[type="checkbox"]:not(.native):checked { border-color: var(--brand-edge); background-color: var(--brand);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' fill='none' stroke='%231d1700' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>"); }
input[type="checkbox"]:not(.native):indeterminate { border-color: var(--brand-edge); background-color: var(--brand);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 8h8' fill='none' stroke='%231d1700' stroke-width='2.4' stroke-linecap='round'/></svg>"); }
input[type="radio"]:not(.native):checked { border-color: var(--brand-edge); background: radial-gradient(var(--on-brand) 0 3px, var(--brand) 3.5px); }
input[type="checkbox"]:not(.native):focus-visible, input[type="radio"]:not(.native):focus-visible { outline: none; box-shadow: var(--focus-ring); }
input[type="checkbox"]:not(.native):disabled, input[type="radio"]:not(.native):disabled { opacity: .4; cursor: not-allowed; }
.choice { display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; font-size: var(--fs-md); color: var(--text); }
.choice:has(input:disabled) { color: var(--text-disabled); cursor: not-allowed; }

/* Choice tile: one option of a set (a quiz answer, a plan). .selected while picked; after the answer
   .right / .wrong. Use a <button> (role="radio" + aria-checked when it is a single choice). */
.choice-tile { display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: var(--h-lg); padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-2); color: var(--text); text-align: left;
  font: var(--fw-medium) var(--fs-md) / 1.35 var(--font-ui); cursor: pointer;
  transition: border-color var(--t-fast), background-color var(--t-fast), color var(--t-fast), transform var(--t-fast); }
.choice-tile:hover:not(:disabled), .choice-tile.is-hover { border-color: var(--border-strong); background: var(--surface-3); }
.choice-tile:active:not(:disabled) { transform: translateY(1px); }
.choice-tile:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.choice-tile.selected, .choice-tile[aria-checked="true"] { border-color: var(--brand-border); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand-border); }
.choice-tile.right { border-color: color-mix(in srgb, var(--green) 55%, transparent); background: var(--green-soft); color: var(--green-text); }
.choice-tile.wrong { border-color: color-mix(in srgb, var(--red) 55%, transparent); background: var(--red-soft); color: var(--red-text); }
.choice-tile:disabled { cursor: default; }
.choice-tile:disabled:not(.right):not(.wrong):not(.selected) { color: var(--text-disabled); }
.choice-tile .icon { flex: none; }

/* An inline text button (names in tables, "show more"): reads as text with an underline. */
button.link:not(.btn, .card), a.link:not(.btn, .card) { display: inline; padding: 0; border: 0; background: none; color: inherit; font: inherit; font-weight: var(--fw-semibold); text-align: left; cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; transition: text-decoration-color var(--t-fast), color var(--t-fast); }
button.link:not(.btn, .card):hover, button.link:not(.btn, .card):focus-visible, a.link:not(.btn, .card):hover, a.link:not(.btn, .card):focus-visible { color: var(--text); text-decoration-color: var(--brand); }

/* Switch: <span class="toggle-track [on]"><span class="toggle-thumb"></span></span>. */
.toggle-track { position: relative; display: inline-block; flex: none; width: 40px; height: 24px; border-radius: var(--r-pill);
  background: var(--surface-3); border: 1px solid var(--border-strong); transition: background var(--t-base), border-color var(--t-base); }
.toggle-track.on { background: var(--brand); border-color: var(--brand-edge); }
.toggle-thumb { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .35); transition: transform var(--t-base) var(--ease); }
.toggle-track.on .toggle-thumb { transform: translateX(16px); }

/* Number stepper: [−][ 12 ][+]. */
.stepper { display: inline-flex; align-items: stretch; height: var(--h-md); border-radius: var(--r-md); border: 1px solid var(--input-border); background: var(--input-bg); overflow: hidden; box-shadow: var(--input-shadow); }
.stepper button { width: 40px; display: grid; place-items: center; color: var(--text-2); font-size: var(--fs-lg); font-weight: var(--fw-semibold); transition: background var(--t-fast), color var(--t-fast); }
.stepper button:hover:not(:disabled), .stepper button.is-hover { background: var(--surface-3); color: var(--text); }
.stepper button:disabled { color: var(--text-disabled); }
.stepper input { width: 56px; min-height: 0; height: auto; padding: 0; text-align: center; border: 0; border-radius: 0; background: transparent; box-shadow: none;
  font: var(--fw-semibold) var(--fs-lg) / 1 var(--font-ui); font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.stepper input:focus { box-shadow: none; }
.stepper:focus-within { border-color: var(--focus); box-shadow: var(--focus-ring); }

/* ══ Tabs (segmented) ═══════════════════════════════════════════════════════════════════════
   <div class="tabs" role="tablist"><button class="tab active" role="tab">…</button></div>
   The selected tab is lifted, never yellow: yellow is kept for the area's main action. */
.tabs { display: inline-flex; align-items: center; gap: 2px; padding: 3px; max-width: 100%; overflow-x: auto; scrollbar-width: none;
  border-radius: calc(var(--r-md) + 3px); background: var(--surface-sunken); border: 1px solid var(--border-subtle); }
.tabs::-webkit-scrollbar { display: none; }
.tab { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); flex: none; min-height: 34px; padding: 0 var(--sp-4);
  border-radius: var(--r-md); color: var(--text-2); font: var(--fw-semibold) var(--fs-ui) / 1 var(--font-ui); white-space: nowrap;
  transition: color var(--t-fast), background-color var(--t-fast), box-shadow var(--t-base); }
.tab:hover:not(.active):not(:disabled), .tab.is-hover { color: var(--text); background: var(--surface-3); }
.tab.active, .tab[aria-selected="true"] { color: var(--text); background: var(--surface-raised); box-shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 2px 8px rgba(0, 0, 0, .12), var(--highlight); }
.tab:focus-visible, .tab.is-focus { outline: 2px solid var(--focus); outline-offset: -2px; }
.tab:disabled { color: var(--text-disabled); cursor: not-allowed; }
.tab .icon { width: 16px; height: 16px; }
.tab img { width: 20px; height: 20px; object-fit: contain; }
.tabs { align-self: flex-start; }
.tabs.block { display: flex; width: 100%; align-self: stretch; } .tabs.block .tab { flex: 1; }
.tabs.lg .tab { min-height: 40px; font-size: var(--fs-md); padding: 0 var(--sp-5); }
@media (max-width: 560px) { .tabs { display: flex; width: 100%; } .tabs .tab { flex: 1 0 auto; } }

/* ══ Badges, pills, chips ═══════════════════════════════════════════════════════════════════ */
/* Count bubble. */
.badge { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
  font: var(--fw-semibold) var(--fs-xs) / 1 var(--font-ui); font-variant-numeric: tabular-nums; background: var(--surface-3); color: var(--text-2); }
.tab.active .badge { background: var(--brand-soft); color: var(--brand-text); }
.badge.brand { background: var(--brand); color: var(--on-brand); }
.badge.bad { background: var(--red); color: #fff; }

/* Status pill: .pill + .ok | .warn | .bad | .info | .brand | .gold | .friend | .enemy. Optional .dot inside. */
.pill { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 var(--sp-2); border-radius: var(--r-pill); white-space: nowrap;
  font: var(--fw-semibold) var(--fs-xs) / 1 var(--font-ui); letter-spacing: .02em; color: var(--text-2); background: var(--surface-3); border: 1px solid var(--border-subtle); }
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.ok { color: var(--green-text); background: var(--green-soft); border-color: color-mix(in srgb, var(--green) 30%, transparent); }
.pill.warn { color: var(--amber-text); background: var(--amber-soft); border-color: color-mix(in srgb, var(--amber) 30%, transparent); }
.pill.bad, .pill.enemy { color: var(--red-text); background: var(--red-soft); border-color: color-mix(in srgb, var(--red) 30%, transparent); }
.pill.info, .pill.friend { color: var(--blue-text); background: var(--blue-soft); border-color: color-mix(in srgb, var(--blue) 30%, transparent); }
.pill.brand { color: var(--brand-text); background: var(--brand-soft); border-color: var(--brand-border); }
.pill.gold { color: var(--gold-text); background: var(--gold-soft); border-color: color-mix(in srgb, var(--gold) 40%, transparent); }
.pill.live .dot { animation: live 1.6s ease-in-out infinite; }
@keyframes live { 50% { opacity: .3; } }

/* Value chip: an icon and a number (money, counts) in a capsule. */
.chip, .chip-stat { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: 32px; padding: 0 var(--sp-3); border-radius: var(--r-pill); white-space: nowrap;
  font: var(--fw-semibold) var(--fs-sm) / 1 var(--font-ui); font-variant-numeric: tabular-nums; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border-subtle); }
.chip img, .chip-stat img { width: 18px; height: 18px; object-fit: contain; }
.chip small, .chip-stat small { margin: 0; color: var(--text-3); font-size: var(--fs-xs); font-weight: var(--fw-medium); }
.chip b, .chip-stat b { font-weight: var(--fw-semibold); }
.chip-stat.reward { color: var(--gold-text); }
a.chip, button.chip:not(.res) { cursor: pointer; transition: border-color var(--t-fast), background-color var(--t-fast); }
a.chip:hover, button.chip:not(.res):hover { border-color: var(--border-strong); background: var(--surface-3); color: var(--text); }

/* Quality stars: <span class="stars"><i class="on">★</i>…</span> (companies::stars). Earned stars in
   gold, the rest as faint outlines of the same shape. Pages only set the size. */
.stars { display: inline-flex; gap: 1px; font-size: var(--fs-md); line-height: 1; white-space: nowrap; }
.stars i { font-style: normal; color: var(--border-strong); }
.stars i.on { color: var(--gold); }

/* ══ Stat tiles ══════════════════════════════════════════════════════════════════════════════ */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
.stat { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md); background: var(--surface-2); border: 1px solid var(--border-subtle); min-width: 0; }
.stat img { width: 32px; height: 32px; object-fit: contain; flex: none; }
.stat > .icon, .stat-ico { flex: none; display: grid; place-items: center; width: 36px; height: 36px; padding: 8px; border-radius: var(--r-md); color: var(--text-2); background: var(--surface-3); }
.stat.friend > .icon { color: var(--blue-text); background: var(--blue-soft); }
.stat.ok > .icon { color: var(--green-text); background: var(--green-soft); }
.stat.warn > .icon { color: var(--amber-text); background: var(--amber-soft); }
.stat.gold > .icon { color: var(--gold-text); background: var(--gold-soft); }
.stat > div { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.stat small { font: var(--fw-semibold) var(--fs-xs) / 1.2 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); margin: 0; }
.stat b { font: var(--fw-semibold) 1.375rem / 1.1 var(--font-display); font-variant-numeric: tabular-nums; letter-spacing: .01em; }

.facts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-3); }
.fact { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); padding: var(--sp-5) var(--sp-3); text-align: center; min-width: 0; }
.fact > div { min-width: 0; }
.fact img { width: 32px; height: 32px; object-fit: contain; }
.fact .flag { width: 36px; height: 24px; margin: 4px 0; }
.fact .ico { display: grid; place-items: center; width: 32px; height: 32px; font-size: var(--fs-h2); color: var(--text-2); }
.fact small { display: block; margin-bottom: 2px; font: var(--fw-semibold) var(--fs-xs) / 1.3 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); }
.fact b { font: var(--fw-semibold) 1.25rem / 1.2 var(--font-display); letter-spacing: .01em; overflow-wrap: anywhere; }
.fact.link { color: inherit; text-decoration: none; cursor: pointer; transition: border-color var(--t-base), transform var(--t-base) var(--ease); }
.fact.link:hover { border-color: var(--border-strong); transform: translateY(-2px); color: inherit; }

/* ══ Tables ══════════════════════════════════════════════════════════════════════════════════
   <table class="table"> for real tables; .trade-table is the same look built from grid rows
   (.row / .row.head), with each page setting its columns. */
.table, .lb-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-ui); }
.table th, .lb-table th { height: 40px; padding: 0 var(--sp-4); text-align: left; white-space: nowrap; background: transparent;
  font: var(--fw-semibold) var(--fs-xs) / 1.2 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); border-bottom: 1px solid var(--border); }
.table td, .lb-table td { height: 52px; padding: var(--sp-2) var(--sp-4); vertical-align: middle; border-bottom: 1px solid var(--border-subtle); font-variant-numeric: tabular-nums; }
.table tbody tr, .lb-table tbody tr { transition: background-color var(--t-fast); }
.table tbody tr:hover, .lb-table tbody tr:hover { background: var(--surface-2); }
.table tbody tr:last-child td, .lb-table tbody tr:last-child td { border-bottom: 0; }
.table .num, .table th.num { text-align: right; }
/* The player's own row: a brand edge on the left and a faint tint. */
.table tr.is-me td, .lb-table tr.is-me td, .trade-table .row.is-me { background: var(--brand-soft); }
.table tr.is-me td:first-child, .lb-table tr.is-me td:first-child, .trade-table .row.is-me { box-shadow: inset 3px 0 0 var(--brand); }
/* A name with a caption under it (citizen + country, party + leader). */
.who-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.who-cell small { font-size: var(--fs-xs); line-height: 1.35; color: var(--text-3); }
/* Wide tables scroll inside their card on phones instead of widening the page. */
/* position: relative keeps absolutely placed bits (.sr-only labels) inside the scroller. */
.table-scroll, .table-wrap { position: relative; overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
.table-scroll > .table { min-width: 560px; }
/* Show or hide something by screen size. */
@media (max-width: 720px) { .hide-phone { display: none !important; } }
@media (min-width: 721px) { .only-phone { display: none !important; } }

.trade-table { display: flex; flex-direction: column; transition: opacity var(--t-base); font-size: var(--fs-ui); }
.trade-table.dim { opacity: .5; }
.trade-table .row { display: grid; gap: var(--sp-3); align-items: center; min-height: 52px; padding: var(--sp-2) var(--sp-1); border-bottom: 1px solid var(--border-subtle); font-variant-numeric: tabular-nums; transition: background-color var(--t-fast); }
.trade-table .row:not(.head):hover { background: var(--surface-2); }
.trade-table .row:last-child { border-bottom: 0; }
.trade-table .row.head { min-height: 36px; font: var(--fw-semibold) var(--fs-xs) / 1.2 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); border-bottom-color: var(--border); }
/* A column header that sorts: label plus an arrow that flips (up = ascending). */
.th-sort { display: inline-flex; align-items: center; gap: var(--sp-1); color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; border-radius: var(--r-xs); transition: color var(--t-fast); }
.th-sort:hover { color: var(--text); }
.th-sort .th-sort-ico { display: inline-grid; place-items: center; transition: transform var(--t-base) var(--ease); }
.th-sort .th-sort-ico.down { transform: rotate(180deg); }
.trade-table .who { font-weight: var(--fw-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ══ Progress ════════════════════════════════════════════════════════════════════════════════ */
.meter { position: relative; height: 10px; border-radius: var(--r-pill); background: var(--surface-sunken); overflow: hidden; box-shadow: inset 0 1px 2px rgba(0, 0, 0, .3); }
.meter.thin { height: 6px; } .meter.thick { height: 14px; }
.meter .fill { position: relative; height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--blue), color-mix(in srgb, var(--blue) 55%, #fff)); transition: width .9s var(--ease); overflow: hidden; }
.meter .fill::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%); transform: translateX(-100%); animation: shimmer 3.2s ease-in-out infinite; }
@keyframes shimmer { 60%, 100% { transform: translateX(100%); } }
.energy-meter .fill { background: linear-gradient(90deg, #4d7c0f, var(--lime) 60%, #bef264); }
.gold-meter .fill { background: linear-gradient(90deg, #b8860b, var(--brand) 70%, #fff3a0); }
.danger-meter .fill { background: linear-gradient(90deg, #b42318, var(--red)); }

/* Two-sided score bar: <div class="scorebar"><span class="friend" style="width:58%"></span><span class="enemy" style="width:42%"></span></div>.
   Your side is blue, the enemy red, a battle you are not in .neutral (both halves grey). */
.scorebar { display: flex; height: 10px; border-radius: var(--r-pill); overflow: hidden; background: var(--surface-sunken); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .3); }
.scorebar.thick { height: 14px; }
.scorebar > span { height: 100%; transition: width .9s var(--ease); }
.scorebar > .friend { background: linear-gradient(90deg, color-mix(in srgb, var(--blue) 70%, #000), var(--blue)); }
.scorebar > .enemy { background: linear-gradient(90deg, var(--red), color-mix(in srgb, var(--red) 70%, #000)); }
.scorebar > .friend + .enemy { box-shadow: inset 2px 0 0 var(--surface-1); }
.scorebar.neutral > span { background: color-mix(in srgb, var(--text-3) 70%, transparent); }
.scorebar.neutral > span + span { background: color-mix(in srgb, var(--text-3) 40%, transparent); }

/* Combo: a text field with a filtered list under it (country pickers). */
.combo { position: relative; width: 100%; }
.combo > input { width: 100%; }
.combo-list { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: var(--z-dropdown); margin: 0; padding: var(--sp-1); list-style: none; max-height: min(320px, 50vh); overflow-y: auto;
  border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface-overlay); box-shadow: var(--shadow-3); }
.combo-list li { padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); color: var(--text); font-weight: var(--fw-medium); cursor: pointer; }
.combo-list li { display: flex; align-items: center; gap: var(--sp-2); }
.combo-list li small { margin-left: auto; color: var(--text-3); font-size: var(--fs-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.combo-list .combo-label { min-width: 0; }
.combo > .combo-flag { position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%); pointer-events: none; }
.combo.has-flag > input { padding-left: calc(var(--sp-3) + 28px); }
.combo-list li.active { background: var(--surface-3); }
.combo-list li[aria-selected="true"] { color: var(--brand); }
.combo-list .combo-empty { color: var(--text-3); cursor: default; }

/* Back to top: appears after a long scroll, bottom right (above the tab bar on phones). */
.scroll-top { position: fixed; right: var(--sp-5); bottom: var(--sp-6); z-index: calc(var(--z-nav) - 1); display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border-radius: 50%; background: var(--surface-overlay); color: var(--text); border: 1px solid var(--border-strong); box-shadow: var(--shadow-3); cursor: pointer;
  opacity: 0; transform: translateY(8px); visibility: hidden; transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease), visibility var(--t-slow), background var(--t-fast) var(--ease); }
.scroll-top.show { opacity: 1; transform: none; visibility: visible; }
.scroll-top:hover { border-color: var(--brand-edge); }
.scroll-top:active { transform: translateY(1px); }
.scroll-top:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ══ Feedback ════════════════════════════════════════════════════════════════════════════════ */
/* Toasts: bottom centre, an accent bar for success or failure. */
.toasts { position: fixed; left: 50%; bottom: var(--sp-6); transform: translateX(-50%); z-index: var(--z-toast); width: min(92vw, 460px);
  display: flex; flex-direction: column; gap: var(--sp-2); align-items: stretch; pointer-events: none; }
.toast-item { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-3);
  border-radius: var(--r-md); background: var(--surface-overlay); color: var(--text); border: 1px solid var(--border);
  font-size: var(--fs-md); font-weight: var(--fw-medium); line-height: 1.4; box-shadow: var(--shadow-3); animation: toast-in var(--t-slow) var(--ease); }
.toast-item::before { content: "✓"; flex: none; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  font-size: var(--fs-sm); font-weight: var(--fw-bold); color: #fff; background: var(--green); }
.toast-item.bad::before { content: "!"; background: var(--red); }
.toast-item.info::before { content: "i"; background: var(--blue); }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(.98); } }
/* Toast v2 (docs/EMOTIONAL_DESIGN.md §3): a reward shows its icon and gain; a refusal can offer the fix. */
.toast-item.has-icon::before { display: none; }
.toast-item .toast-icon { flex: none; width: 34px; height: 34px; object-fit: contain; filter: var(--art-shadow); animation: toast-icon-in .5s var(--ease); }
.toast-item .toast-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.toast-item .toast-value { font: var(--fw-bold) 1.25rem / 1.1 var(--font-display); letter-spacing: .02em; color: var(--gold-text); }
.toast-item.reward { border-color: color-mix(in srgb, var(--gold) 45%, var(--border)); box-shadow: var(--shadow-3), 0 0 0 1px color-mix(in srgb, var(--gold) 20%, transparent), 0 10px 30px -12px color-mix(in srgb, var(--gold) 60%, transparent); }
.toast-item .toast-act { flex: none; pointer-events: auto; }
@keyframes toast-icon-in { 0% { transform: scale(.4) rotate(-20deg); opacity: 0; } 60% { transform: scale(1.2) rotate(6deg); opacity: 1; } }

/* Share on Facebook (src/share.rs): Facebook's own blue, the only place it appears, since it is
   their brand mark, not one of our sides. */
.btn.fb-share { color: #fff; border-color: #0d5fc7; background: linear-gradient(180deg, #2d8bff 0%, #1877f2 55%, #1466d1 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 6px 18px -8px rgba(24, 119, 242, .7); }
.btn.fb-share:hover:not(:disabled) { color: #fff; border-color: #0d5fc7; background: linear-gradient(180deg, #4a9cff 0%, #2a85f5 55%, #1872de 100%); }
.btn.fb-share.ghost { color: #4a9cff; background: transparent; border-color: color-mix(in srgb, #1877f2 55%, transparent); box-shadow: none; }
.btn.fb-share.ghost:hover:not(:disabled) { color: #fff; background: #1877f2; }
.btn.fb-share .fb-logo { flex: none; }

/* A refusal shakes what was pressed; a small confirm pops (src/ui.rs `shake_active`, `pop_from`). */
.shake-a { animation: shake-a .32s var(--ease-in-out); } .shake-b { animation: shake-b .32s var(--ease-in-out); }
@keyframes shake-a { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }
@keyframes shake-b { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }
.pop-a { animation: pop-a .28s var(--ease); } .pop-b { animation: pop-b .28s var(--ease); }
@keyframes pop-a { 40% { transform: scale(1.22); } }
@keyframes pop-b { 40% { transform: scale(1.22); } }
.pop-a::after, .pop-b::after { content: ""; position: absolute; inset: -6px; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 0 2px var(--brand-border); opacity: 0; animation: pop-ring .45s var(--ease); }
@keyframes pop-ring { 0% { opacity: .9; transform: scale(.8); } 100% { opacity: 0; transform: scale(1.35); } }

/* A reward flying into its top-bar chip (src/ui.rs `fly_to`). */
.fly-coin { position: fixed; z-index: calc(var(--z-toast) + 1); width: 28px; height: 28px; pointer-events: none; filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .45));
  transition: transform .75s cubic-bezier(.5, -0.2, .3, 1), opacity .75s ease-in; }

/* A resource that rolls to its new value and floats the gain off itself (src/ui.rs `Rolling`). */
.rolling { position: relative; display: inline-flex; }
.gain-float { position: absolute; left: 50%; top: -2px; transform: translateX(-50%); pointer-events: none; white-space: nowrap;
  font: var(--fw-bold) var(--fs-sm) / 1 var(--font-display); letter-spacing: .02em; color: var(--gold-text); text-shadow: 0 1px 2px rgba(0, 0, 0, .4); }
.gain-float.g0 { animation: gain-up-a 1.3s var(--ease) forwards; } .gain-float.g1 { animation: gain-up-b 1.3s var(--ease) forwards; }
.gain-float.energy { color: var(--lime-text); } .gain-float.money { color: var(--green-text); }
@keyframes gain-up-a { 0% { opacity: 0; transform: translate(-50%, 4px); } 15% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -26px); } }
@keyframes gain-up-b { 0% { opacity: 0; transform: translate(-50%, 4px); } 15% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -26px); } }

/* Callout: an inline note that needs attention. .info | .warn | .bad | .ok */
.callout { display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--border-subtle); color: var(--text-2); font-size: var(--fs-sm); line-height: 1.5; }
.callout .icon { margin-top: 1px; }
.callout b { color: var(--text); }
.callout.info { background: var(--blue-soft); border-color: color-mix(in srgb, var(--blue) 28%, transparent); } .callout.info .icon { color: var(--blue-text); }
.callout.warn { background: var(--amber-soft); border-color: color-mix(in srgb, var(--amber) 28%, transparent); } .callout.warn .icon { color: var(--amber-text); }
.callout.bad { background: var(--red-soft); border-color: color-mix(in srgb, var(--red) 28%, transparent); } .callout.bad .icon { color: var(--red-text); }
.callout.ok { background: var(--green-soft); border-color: color-mix(in srgb, var(--green) 28%, transparent); } .callout.ok .icon { color: var(--green-text); }

/* Contest strip: a callout floating over the page's bottom-left corner, with a closing ✕
   (invite::ContestStrip). Elevated so it reads above any page; never wider than a card. */
.contest-strip { position: fixed; left: var(--sp-5); bottom: var(--sp-5); z-index: var(--z-dropdown); width: min(380px, calc(100vw - 2 * var(--sp-4)));
  align-items: flex-start; box-shadow: var(--shadow-3); animation: contest-strip-in var(--t-slow) var(--ease) both; }
.contest-strip p { flex: 1; margin: 0; }
.contest-strip a { color: var(--brand-text); font-weight: var(--fw-semibold); white-space: nowrap; }
.contest-strip > .btn { flex: none; margin: calc(-1 * var(--sp-1)) calc(-1 * var(--sp-2)) 0 0; }
/* Floating over pictures: the soft tint is laid on a solid surface. */
.callout.info.contest-strip { background: linear-gradient(var(--blue-soft), var(--blue-soft)), var(--surface); }
@keyframes contest-strip-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .contest-strip { animation: none; } }

/* Explanations: a muted line under a heading, and the ⓘ that opens more on hover or focus. */
.hint { color: var(--text-2); font-size: var(--fs-sm); line-height: 1.5; font-weight: var(--fw-regular); }
.info-tip { position: relative; display: inline-flex; align-items: center; vertical-align: middle; margin-left: var(--sp-1); cursor: help; outline: none;
  text-transform: none; letter-spacing: 0; font-weight: var(--fw-regular); }
.info-ico { display: inline-grid; place-items: center; width: 16px; height: 16px; color: var(--text-3); transition: color var(--t-fast); }
.info-ico .icon { width: 16px; height: 16px; }
.info-tip:hover .info-ico, .info-tip:focus-visible .info-ico { color: var(--brand-text); }
.info-tip:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 50%; }
.info-bubble { display: none; position: absolute; left: 50%; bottom: calc(100% + 10px); z-index: var(--z-tooltip); width: max-content; max-width: min(300px, 80vw);
  padding: var(--sp-3); border-radius: var(--r-md); background: var(--surface-overlay); border: 1px solid var(--border);
  box-shadow: var(--shadow-3); color: var(--text); font: var(--fw-regular) var(--fs-sm) / 1.5 var(--font-ui); text-align: left; white-space: normal;
  pointer-events: none; transform: translateX(-50%); }
.info-tip:hover .info-bubble, .info-tip:focus .info-bubble { display: block; animation: tip-in var(--t-fast) var(--ease); }
.info-tip.start .info-bubble { left: -6px; transform: none; }
.info-tip.end .info-bubble { left: auto; right: -6px; transform: none; }
/* Lift the card while its tip is open so later neighbours (and their shadows) don't cover the bubble. */
.card:has(.info-tip:hover, .info-tip:focus), .table-wrap:has(.info-tip:hover) { z-index: var(--z-tooltip); }
.table-wrap:has(.info-tip:hover, .info-tip:focus) { overflow: visible !important; } /* !important: page layers would otherwise win */
/* In a dialog (which clips what leaves it) the bubble opens downward: the icons sit near its top. */
.dialog .info-bubble { bottom: auto; top: calc(100% + 10px); }
@keyframes tip-in { from { opacity: 0; translate: 0 4px; } }

/* Empty state. .nothing is the short inline one; .empty has an icon, a title and an action. */
.nothing { color: var(--text-3); padding: var(--sp-6) var(--sp-4); text-align: center; font-size: var(--fs-md); }
.empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding: var(--sp-10) var(--sp-4); text-align: center; color: var(--text-2); }
.empty > .icon, .empty > img { width: 40px; height: 40px; color: var(--text-3); margin-bottom: var(--sp-2); object-fit: contain; }
.empty h3 { color: var(--text); }
.empty p { max-width: 44ch; font-size: var(--fs-sm); }
.empty .btn { margin-top: var(--sp-3); }

/* Loading placeholder. */
.skeleton { display: block; border-radius: var(--r-sm); background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%); background-size: 200% 100%; animation: skeleton 1.4s ease-in-out infinite; }
/* A placeholder line as tall as the text it stands for (the type scale), so a page keeps its
   shape when the text arrives. The width stays per use. */
.skeleton.sk-xs { height: var(--fs-xs); } .skeleton.sk-ui { height: var(--fs-ui); } .skeleton.sk-h3 { height: var(--fs-h3); }
.skeleton.sk-h2 { height: var(--fs-h2); } .skeleton.sk-stat { height: var(--fs-stat); } .skeleton.sk-h1 { height: var(--fs-h1); }
/* Blocks: a progress bar, a list row, a card, a panel, a whole list. They fill the width unless a
   use narrows them. */
.skeleton.sk-bar { height: 6px; } .skeleton.sk-row { height: 6rem; } .skeleton.sk-card { height: 7.5rem; }
.skeleton.sk-panel { height: 10rem; } .skeleton.sk-list { height: 13.75rem; }
.skeleton:is(.sk-row, .sk-card, .sk-panel, .sk-list) { width: 100%; }
@keyframes skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* Pagination. */
.pagination { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--sp-1); padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--border-subtle); }
.pagination .btn { --btn-h: var(--h-sm); min-width: var(--h-sm); padding: 0 var(--sp-2); font-size: var(--fs-md); border-radius: var(--r-sm); }
.pag-info { padding: 0 var(--sp-3); min-width: 6rem; text-align: center; white-space: nowrap; font-size: var(--fs-sm); color: var(--text-3); font-variant-numeric: tabular-nums; }
.pag-info b { color: var(--text); font-weight: var(--fw-semibold); }

/* ══ Overlays ════════════════════════════════════════════════════════════════════════════════ */
.modal { position: fixed; inset: 0; z-index: var(--z-modal); display: grid; place-items: center; padding: var(--sp-4); background: var(--scrim);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: fade-in var(--t-base) ease-out; }
@keyframes fade-in { from { opacity: 0; } }
.dialog { position: relative; width: min(480px, 100%); max-height: calc(100vh - 32px); overflow-y: auto; padding: var(--sp-6);
  border-radius: var(--r-xl); background: var(--surface-overlay); border: 1px solid var(--border); box-shadow: var(--shadow-3), var(--highlight);
  animation: dialog-in var(--t-slow) var(--ease); }
.dialog h2 { margin-bottom: var(--sp-2); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-6); }
@keyframes dialog-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }

/* Dropdown menu panel (account menu, nav menus). */
.menu-panel { padding: var(--sp-1); border-radius: var(--r-lg); background: var(--surface-overlay); border: 1px solid var(--border); box-shadow: var(--shadow-3); }
.menu-item { display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: 38px; padding: 0 var(--sp-3); border-radius: var(--r-sm);
  color: var(--text); font: var(--fw-medium) var(--fs-ui) / 1.2 var(--font-ui); text-align: left; white-space: nowrap; transition: background-color var(--t-fast), color var(--t-fast); }
.menu-item .icon { width: 17px; height: 17px; color: var(--text-3); transition: color var(--t-fast); }
.menu-item:hover { background: var(--surface-3); color: var(--text); }
.menu-item:hover .icon { color: var(--text); }
.menu-item.active { color: var(--brand-text); background: var(--brand-soft); }
.menu-item.active .icon { color: var(--brand-text); }
.menu-item.danger { color: var(--red-text); } .menu-item.danger .icon { color: var(--red-text); }
.menu-item.danger:hover { background: var(--red-soft); }
.menu-head { padding: var(--sp-2) var(--sp-3) var(--sp-1); font: var(--fw-semibold) var(--fs-xs) / 1.3 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); }
.menu-sep { height: 1px; margin: var(--sp-1) var(--sp-2); background: var(--border-subtle); }

/* ══ Media ═══════════════════════════════════════════════════════════════════════════════════ */
.flag { width: 26px; height: 18px; object-fit: cover; border-radius: 3px; box-shadow: 0 0 0 1px var(--border); vertical-align: -3px; display: inline-block; }
.flag.big { width: 72px; height: 48px; border-radius: 6px; box-shadow: 0 0 0 1px var(--border), var(--shadow-1); }
.flag.none { display: inline-block; width: auto; height: auto; box-shadow: none; }

/* The logo (src/brand.rs): inline SVGs from scripts/draw_logo.py, coloured by the theme. Size them
   by height; the width follows the drawing. Never stretch, recolour or put an effect inside them. */
.brand-mark, .brand-wordmark { display: inline-flex; flex: none; line-height: 0; }
.brand-mark svg, .brand-wordmark svg { display: block; width: auto; height: 100%; }
.brand-mark { height: 32px; aspect-ratio: 1; }
.brand-wordmark { height: 18px; }
.brand-mark .foh-mark { fill: var(--logo-mark); }
.brand-wordmark .foh-word { fill: var(--text); }
.brand-wordmark .foh-of { fill: var(--text-2); }
}

@layer components {
.battle-scope { display: contents; }
.overline { display: block; font: var(--fw-semibold) var(--fs-xs) / 1.3 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-3); }
.stepper.off { opacity: .4; pointer-events: none; }
.stepper.small { height: var(--h-sm); }
.stepper.small button { width: 32px; }
.stepper.small b { display: grid; place-items: center; min-width: 34px; text-align: center; font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; }
}

/* ══ Citizen picture, load more, answer box ══════════════════════════════════════════════════ */
@layer components {
/* A small round citizen picture, or their initials on a soft tone (ui.rs `Picture`). */
.pic { position: relative; flex: none; display: inline-grid; place-items: center; width: 40px; height: 40px; overflow: hidden; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border-subtle); }
.pic img { width: 100%; height: 100%; object-fit: cover; }
.pic.fallback { background: linear-gradient(150deg, color-mix(in srgb, var(--tone) 52%, var(--surface-raised)), color-mix(in srgb, var(--tone) 18%, var(--surface-raised))); }
.pic .initials { font: var(--fw-bold) var(--fs-md) / 1 var(--font-display); letter-spacing: var(--ls-display); color: var(--text); }

/* The button under a cursor-paged list (ui.rs `LoadMore`). */
.load-more { display: flex; justify-content: center; padding: var(--sp-5) var(--feed-pad, var(--sp-5)); }

/* Accept and Deny for something somebody asks of you (ui.rs `AnswerButtons`): what is asked above,
   the buttons and a note below. */
.answer-box { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-4);
  border: 1px solid var(--border-subtle); border-radius: var(--r-md); background: var(--surface-2); }
.answer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.answer .t-caption { flex-basis: 100%; color: var(--text-3); }
@media (max-width: 560px) { .answer .btn { flex: 1 1 auto; } }
}
