/*
  No @import here, deliberately.

  Two reasons, and the second one cost a debugging session: @import serialises the
  download (the browser cannot even discover the imported file until this one has
  parsed), and the imported URL bypasses asset fingerprinting — so a stale
  components.css sat in the browser cache while a freshly fingerprinted app.css
  loaded beside it, and every rule added to the imported file was invisible.

  App.razor links the three files itself, each through the asset helper, each
  fingerprinted, all fetched in parallel.
*/

/* ── Reset ────────────────────────────────────────────────────────────────────
   Only what is load-bearing. A 300-line reset mostly re-states defaults that
   every current browser already agrees on. */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Offset for the sticky header, so an in-page anchor does not land underneath it. */
  scroll-padding-top: calc(var(--header-height) + var(--space-4));
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* Stops a long unbroken token — a hash, a URL — from widening the whole page. */
  overflow-wrap: break-word;
}

img, picture, svg, video, canvas { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
a { color: var(--brand-300); text-decoration-color: oklch(0.58 0.21 285 / 0.4); text-underline-offset: 0.2em; }
a:hover { color: var(--brand-200); text-decoration-color: currentColor; }

h1, h2, h3, h4 { line-height: var(--leading-tight); text-wrap: balance; font-weight: 650; letter-spacing: -0.015em; }
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }
p  { text-wrap: pretty; }

ul, ol { padding-inline-start: 1.25em; }
:where(ul, ol).unstyled { list-style: none; padding: 0; }

/*
  Motion is opt-out at the OS level, and that setting is an accessibility need
  (vestibular disorders), not a preference. Kept to a near-zero duration rather
  than 0 so transitionend handlers still fire.
*/
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Focus ────────────────────────────────────────────────────────────────────
   :focus-visible, never :focus — a ring on every mouse click trains people to
   ignore the ring, and it is the only thing a keyboard user has to navigate by. */
:focus-visible {
  outline: 2px solid var(--brand-400);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* Bypass the whole header in one keystroke. Visible only when focused, which is
   the only time it is useful. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(var(--space-4) * -6);
  z-index: calc(var(--z-header) + 10);
  padding: var(--space-3) var(--space-5);
  background: var(--brand-500);
  color: var(--text-on-brand);
  border-radius: var(--radius);
  font-weight: 600;
  transition: top var(--dur) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

/* Visually hidden but announced. For labels that a sighted user reads from
   context and a screen reader cannot. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Layout ───────────────────────────────────────────────────────────────────
   Container queries rather than media queries wherever a component can appear in
   more than one column width: a card in a sidebar and the same card in the main
   column need to respond to their own box, not to the viewport. */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
/* Variants inherit the centring and the gutters; only the ceiling changes. Declaring
   just a max-width here was what left the footer hugging the left edge. */
.container-wide {
  width: 100%;
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.container-text { max-width: var(--container-text); }

@media (min-width: 768px) {
  .container { padding-inline: var(--space-6); }
}

.stack     { display: flex; flex-direction: column; gap: var(--space-4); }
.stack-sm  { gap: var(--space-2); }
.stack-lg  { gap: var(--space-6); }
.row       { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.row-tight { gap: var(--space-2); }
.between   { justify-content: space-between; }
.grow      { flex: 1 1 auto; min-width: 0; }

/* auto-fit + minmax: the column count follows the available width with no
   breakpoints to keep in sync. */
.grid-auto {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}
.grid-auto-sm { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.grid-auto-lg { grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr)); }

.section { padding-block: var(--space-7); }
@media (min-width: 768px) { .section { padding-block: var(--space-8); } }

/* ── Page shell ───────────────────────────────────────────────────────────── */

.app-main { flex: 1 1 auto; }

.page-head {
  padding-block: var(--space-6) var(--space-5);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(120% 100% at 50% 0%, oklch(0.58 0.21 285 / 0.10), transparent 60%),
    var(--bg);
}
.page-head h1 { margin-block-end: var(--space-2); }
.page-head .lede {
  color: var(--text-muted);
  font-size: var(--text-lg);
  max-width: var(--container-text);
}

/* ── Utilities ────────────────────────────────────────────────────────────── */

.muted   { color: var(--text-muted); }
.subtle  { color: var(--text-subtle); }
.mono    { font-family: var(--font-mono); font-size: 0.9em; }
.nowrap  { white-space: nowrap; }
.center  { text-align: center; }

/* Numbers that change in place must not shift the layout under the reader —
   tabular figures keep every digit the same width. */
.tabular { font-variant-numeric: tabular-nums; }

.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.clamp-3 { display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

.hide-sm { display: none; }
@media (min-width: 640px) { .hide-sm { display: revert; } .only-sm { display: none; } }

/* ── Adições dos microfrontends ────────────────────────────────────────────────
   Vivem no fim de app.css, e não em CSS isolado de componente, porque estilizam
   elementos que o Blazor NÃO carimba com o atributo de escopo — o que um componente
   filho renderiza (NavLink, EmptyState) fica fora do alcance do isolamento. Foi
   exatamente assim que a navegação do shell apareceu sem estilo nenhum. */

.forum-layout {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: 1fr;
}

@media (min-width: 60rem) {
    .forum-layout { grid-template-columns: minmax(0, 1fr) 20rem; }
}

.cat { display: flex; align-items: center; gap: var(--space-4); }
.cat-icon { font-size: 1.75rem; line-height: 1; }
.cat-desc, .cat > .grow > * { display: block; }
.cat-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.cat-count { font-size: var(--text-lg); font-weight: 700; }

.thread-row { display: flex; align-items: center; gap: var(--space-3); }
.thread-marks { display: flex; gap: 4px; min-width: 1.5rem; }
.thread-title { display: block; }
.thread-row .subtle { display: block; font-size: var(--text-sm); }
.thread-stats, .thread-last { display: flex; flex-direction: column; align-items: flex-end; font-size: var(--text-sm); }

.post-head { display: flex; align-items: center; gap: var(--space-3); margin-block-end: var(--space-3); }
.post-delete { margin-inline-start: auto; }

/* Quebra em qualquer ponto: sem isto uma URL colada de 300 caracteres empurra a
   largura do cartão e a página inteira ganha rolagem horizontal. */
.post-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.post-removed { opacity: 0.6; }

.package-grid {
    display: grid;
    gap: var(--space-4);
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.package { display: flex; flex-direction: column; gap: var(--space-2); position: relative; }
.package.is-popular { border-color: var(--brand-500); }
.package-flag {
    position: absolute; inset-block-start: calc(var(--space-3) * -1); inset-inline-start: var(--space-4);
    background: var(--brand-500); color: var(--text-on-brand);
    padding: 2px var(--space-3); border-radius: var(--radius-full);
    font-size: var(--text-xs); font-weight: 700;
}
.package-diamonds { font-size: var(--text-2xl); font-weight: 700; margin: 0; }
.package-bonus { color: var(--ok-500); font-size: var(--text-sm); margin: 0; }
.package-price { font-size: var(--text-lg); font-weight: 600; margin: 0; }
.package-unit { font-size: var(--text-xs); margin: 0; }
.package-summary { font-size: var(--text-sm); flex-grow: 1; }

.honest-card { border-inline-start: 3px solid var(--brand-500); }
.balance-card { align-items: center; }
.balance-card strong { display: block; }

.receipt { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2) var(--space-4); margin: 0; }
.receipt dt { color: var(--text-muted); }
.receipt dd { margin: 0; text-align: right; }

.ledger-row { align-items: center; }
.ledger-row .subtle { display: block; font-size: var(--text-sm); }
.delta-in { color: var(--ok-500); font-weight: 700; }
.delta-out { color: var(--text-muted); font-weight: 600; }

.ticket-row { align-items: center; gap: var(--space-3); }
.ticket-row .subtle { display: block; font-size: var(--text-sm); }

.faq dt { font-weight: 600; margin-block-start: var(--space-3); }
.faq dd { margin: 0; font-size: var(--text-sm); }

.account-grid { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 60rem) {
    .account-grid { grid-template-columns: minmax(0, 1fr) 20rem; }
}

.stat-row { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }

.char { display: flex; align-items: center; gap: var(--space-3); }
.char-mark {
    width: 2.5rem; height: 2.5rem; display: grid; place-items: center;
    border-radius: var(--radius); background: var(--bg-raised); font-weight: 700;
}
.char .subtle { display: block; font-size: var(--text-sm); }

.notice { padding: var(--space-4); border-radius: var(--radius); border-inline-start: 3px solid; }
.notice p { margin: var(--space-2) 0 0; font-size: var(--text-sm); }
.notice-info { background: var(--bg-raised); border-color: var(--brand-500); }
.notice-success { background: var(--bg-raised); border-color: var(--ok-500); }
.notice-warning { background: var(--bg-raised); border-color: var(--warn-500); }

.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.grow { flex-grow: 1; min-width: 0; }
.narrow { max-width: 44rem; }

/* ── Telas de autenticação ─────────────────────────────────────────────────── */

.auth-section { display: grid; place-items: center; min-block-size: 60vh; }
.auth-card { max-width: 26rem; margin-inline: auto; }
.auth-card .field { margin-block-end: var(--space-4); }
.auth-alt { text-align: center; font-size: var(--text-sm); }

.check { display: flex; align-items: flex-start; gap: var(--space-2); font-size: var(--text-sm); }
.check input { margin-block-start: 3px; }

/* Barra de força: cor E largura. Só cor exclui quem não distingue verde de vermelho —
   e essa é justamente a informação que o campo está tentando dar. */
.strength {
    block-size: 4px; background: var(--bg-inset);
    border-radius: var(--radius-full); overflow: hidden; margin-block-start: var(--space-2);
}
.strength-bar { block-size: 100%; transition: width var(--dur) var(--ease-out); }
.strength-bar.is-weak { background: var(--danger-500); }
.strength-bar.is-fair { background: var(--warn-500); }
.strength-bar.is-strong { background: var(--ok-500); }

/* ── Criação de personagem ─────────────────────────────────────────────────── */

.choice-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }

.choice-card {
    display: flex; flex-direction: column; gap: var(--space-2);
    text-align: start; cursor: pointer;
    border: 1px solid var(--line); background: var(--bg-raised);
    transition: border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.choice-card:hover:not(:disabled) { border-color: var(--brand-400); transform: translateY(-2px); }

/* Escolhido = borda E anel. Só a borda muda pouco para quem enxerga pouco contraste,
   e a escolha feita precisa ser óbvia sem esforço. */
.choice-card.is-picked { border-color: var(--brand-500); box-shadow: 0 0 0 2px var(--brand-500) inset; }
.choice-card .muted { font-size: var(--text-sm); }

.choice-row { display: flex; gap: var(--space-2); }
.choice {
    padding: var(--space-2) var(--space-5); cursor: pointer;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--bg-raised); color: var(--text);
}
.choice.is-picked { border-color: var(--brand-500); background: var(--brand-500); color: var(--text-on-brand); }

.hint-ok { color: var(--ok-500); }
.hint-bad { color: var(--danger-500); }

.char-card { display: flex; align-items: center; gap: var(--space-3); }
.char-card .subtle { display: block; font-size: var(--text-sm); }

.session-row { align-items: center; }
.session-row .subtle { display: block; font-size: var(--text-sm); }
