:root {
  /* Sampled from The Final Initiative's own d20 logo (purples/oranges/
     reds/gold) rather than a generic tavern-brown theme -- the hub now
     hosts multiple games with their own art, so the chrome stays out of
     the way of each game's card. */
  --bg-darkest: #0e0813;
  --bg-dark: #150c17;
  --bg-panel: #1a0e19;
  --bg-panel-light: #26141f;
  --wood: #4b2521;
  --parchment: #ece3d6;
  --parchment-dim: #b7a898;
  --accent-gold: #d99a4f;
  --accent-rust: #c96a3f;
  --accent-rust-dark: #9f4c2e;
  /* Hub chrome type: a small-caps display face for nav/labels that suits
     the d20 logo, and its sans sibling for reading. Each game card and
     trophy room swaps in its own game's fonts. */
  --font-display: 'Alegreya SC', Georgia, serif;
  --font-body: 'Alegreya Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

* {
  box-sizing: border-box;
}

/* Paints the canvas dark too, so no light gap can show past the body's
   fixed background on a long page. */
html {
  background: var(--bg-darkest);
}

body {
  margin: 0;
  min-height: 100vh;
  background:
    linear-gradient(rgba(14, 8, 19, 0.55), rgba(14, 8, 19, 0.82)),
    url('../assets/table-bg.webp') center / cover fixed no-repeat;
  color: var(--parchment);
  font-family: var(--font-body);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4rem 1.5rem;
}

.hub-header {
  text-align: center;
  margin-bottom: 3rem;
}

.hub-logo {
  max-width: min(90vw, 420px);
  height: auto;
}

.hub-subtitle {
  margin: 0.5rem 0 0;
  color: var(--parchment-dim);
  font-style: italic;
}

.game-list {
  width: 100%;
  max-width: 640px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
}

/* Two columns once there's room for two readable cards side by side. */
@media (min-width: 900px) {
  .game-list {
    max-width: 1080px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.game-card {
  display: flex;
  gap: 1.25rem;
  align-items: center;
  background: var(--bg-panel);
  border: 1px solid var(--wood);
  border-radius: 10px;
  padding: 1.5rem;
  font-family: var(--card-font-body, var(--font-body));
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.game-card:hover {
  transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
  .game-card { transition: none; }
  .game-card:hover { transform: none; }
}

.game-card-body {
  flex: 1;
  min-width: 0;
}

.game-card-icon {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: cover;
}

.game-card h2 {
  margin: 0 0 0.5rem;
  color: var(--accent-gold);
  font-family: var(--card-font-display, var(--font-display));
  font-weight: 400;
  font-size: 1.7rem;
  line-height: 1.15;
}

.game-tagline {
  margin: 0 0 1rem;
  color: var(--parchment-dim);
}

.game-envs {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.env-link {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border-radius: 6px;
  text-decoration: none;
  font-weight: bold;
  background: var(--accent-rust-dark);
  color: var(--parchment);
  border: 1px solid var(--accent-rust);
  transition: background 0.15s ease;
}

.env-link:hover {
  background: var(--accent-rust);
}

.env-link--soon {
  background: transparent;
  color: var(--parchment-dim);
  border: 1px dashed var(--wood);
  cursor: default;
}

.changelog-link {
  display: inline-block;
  margin-top: 0.75rem;
  color: var(--parchment-dim);
  text-decoration: none;
  font-style: italic;
  font-size: 0.9rem;
}

.changelog-link:hover {
  color: var(--accent-gold);
}

/* A signed-in player's progress in this game (js/hub.js). */
.game-progress {
  margin-top: 1rem;
}

.game-progress[hidden] {
  display: none;
}

.game-progress-link {
  display: grid;
  gap: 0.35rem;
  text-decoration: none;
}

.game-progress-bar {
  display: block;
  height: 6px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--progress-track, rgba(0, 0, 0, 0.35));
}

.game-progress-bar i {
  display: block;
  height: 100%;
  background: var(--progress-fill, var(--accent-gold));
}

.game-progress-text {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.85rem;
  color: var(--parchment-dim);
  font-variant-numeric: tabular-nums;
}

.game-progress-link:hover .game-progress-text {
  color: var(--accent-gold);
}

.game-progress-soon {
  font-style: italic;
}

/* ---------- per-game card themes ---------- */
/* Each game on the hub keeps its own look on its card (per the "chrome
   stays out of the way of each game's card" intent above) rather than
   all cards sharing the hub's tavern palette. Scoped by overriding the
   same custom properties .game-card already reads, so no selectors
   above need touching as more games/themes are added. */
.game-card[data-theme="kings-charter"] {
  /* King's Charter's own in-game palette (see that repo's css/style.css) --
     ember-orange and flame-gold on a warm dark wood-brown, distinct from
     the hub's own default rust/gold tavern tones even though both read
     as "medieval." Added alongside the tavern-game -> kings-charter /
     Authentik -> tfi-auth migration (2026-09) -- didn't have a theme
     override before this, unlike hustle. */
  --bg-panel: #2a1c12;
  --wood: #4a311f;
  --accent-gold: #e8a33d;
  --parchment-dim: #b8a583;
  --accent-rust-dark: #8a3d0c;
  --accent-rust: #c9540c;
  --card-font-display: 'IM Fell English', Georgia, serif;
  --card-font-body: 'Work Sans', system-ui, sans-serif;
  --progress-track: #1b120c;
  --progress-fill: linear-gradient(90deg, #c9540c, #e8a33d);
  background-image: linear-gradient(160deg, #332316 0%, #2a1c12 70%);
  /* A gilded band, like a framed charter (King's Charter Trello card "Wood
     Frame around website card"): a gold edge, a dark gap, and a fine inner
     gold line, with a warm glow. */
  border: 2px solid #e8a33d;
  box-shadow:
    inset 0 0 0 1px #5f402a,
    inset 0 0 0 5px #2a1c12,
    inset 0 0 0 6px rgba(232, 163, 61, 0.55),
    0 0 24px rgba(232, 163, 61, 0.2);
}

.game-card[data-theme="kings-charter"]:hover {
  box-shadow:
    inset 0 0 0 1px #5f402a,
    inset 0 0 0 5px #2a1c12,
    inset 0 0 0 6px rgba(232, 163, 61, 0.7),
    0 0 34px rgba(232, 163, 61, 0.32);
}

.game-card[data-theme="kings-charter"] .game-card-icon {
  box-shadow: 0 0 0 3px #e8a33d, 0 0 0 5px #4a311f;
}

.game-card[data-theme="kings-charter"] .env-link--soon {
  border-color: #c9540c;
  color: #e8a33d;
}

.game-card[data-theme="hustle"] {
  /* Hustle's own After Hours synthwave theme (see hustle's css/style.css) --
     deep purple bg, hot magenta / electric cyan neon accents. */
  --bg-panel: #150f2e;
  --wood: #ff3fa4;
  --accent-gold: #2fe6ff;
  --parchment-dim: #b8a8e0;
  --accent-rust-dark: #2a1f4d;
  --accent-rust: #2fe6ff;
  --card-font-display: 'Audiowide', system-ui, sans-serif;
  --card-font-body: 'Outfit', system-ui, sans-serif;
  --progress-track: #291f5e;
  --progress-fill: linear-gradient(90deg, #ff3fa4, #2fe6ff);
  background-image: linear-gradient(160deg, #1b1240 0%, #150f2e 70%);
  border: 1.5px solid #ff3fa4;
  box-shadow:
    0 0 0 1px rgba(255, 63, 164, 0.25),
    0 0 22px rgba(255, 63, 164, 0.35),
    inset 0 0 18px rgba(255, 63, 164, 0.12);
}

.game-card[data-theme="hustle"]:hover {
  box-shadow:
    0 0 0 1px rgba(255, 63, 164, 0.4),
    0 0 32px rgba(255, 63, 164, 0.5),
    inset 0 0 20px rgba(255, 63, 164, 0.16);
}

.game-card[data-theme="hustle"] h2 {
  text-shadow: 0 0 12px rgba(47, 230, 255, 0.45);
}

.game-card[data-theme="hustle"] .env-link {
  font-family: var(--card-font-body);
}

.game-card[data-theme="daydreamers-library"] {
  /* Daydreamers Library's own desk: a manila borrower's card with a brass
     band, ink text and the stamp-purple accent (see that repo's
     css/style.css tokens). The one light card on the hub, on purpose -- it's
     the only game set in daylight. */
  --bg-panel: #efdcae;
  --wood: #c48f32;
  --accent-gold: #7b5c9e;
  --parchment: #fdf7ea;
  --parchment-dim: #6b5a47;
  --accent-rust-dark: #7b5c9e;
  --accent-rust: #5f4580;
  --card-font-display: 'Berkshire Swash', Georgia, serif;
  --card-font-body: 'Karla', system-ui, sans-serif;
  --progress-track: rgba(74, 59, 44, 0.18);
  --progress-fill: linear-gradient(90deg, #7b5c9e, #c48f32);
  color: #4a3b2c;
  background-image: linear-gradient(160deg, #f5e6c2 0%, #efdcae 55%, #e2ca93 100%);
  border: 2px solid #c48f32;
  box-shadow:
    inset 0 0 0 4px #efdcae,
    inset 0 0 0 5px rgba(196, 143, 50, 0.6),
    0 10px 26px rgba(0, 0, 0, 0.35);
}

.game-card[data-theme="daydreamers-library"]:hover {
  box-shadow:
    inset 0 0 0 4px #efdcae,
    inset 0 0 0 5px rgba(196, 143, 50, 0.8),
    0 14px 34px rgba(0, 0, 0, 0.45);
}

.game-card[data-theme="daydreamers-library"] .env-link {
  color: #fdf7ea;
}

.game-card[data-theme="daydreamers-library"] .env-link:hover {
  background: #5f4580;
}

.game-card[data-theme="daydreamers-library"] .game-progress-link:hover .game-progress-text,
.game-card[data-theme="daydreamers-library"] .changelog-link:hover {
  color: #7b5c9e;
}

.game-card[data-theme="hustle"] .env-link--soon {
  border-color: #ff3fa4;
  color: #ff3fa4;
}

/* One top bar for the nav and the login button, on pages that opt in with
   <body class="has-topbar"> and a .topbar wrapper (home and Achievements).
   Other pages keep the older fixed-corner layout below. */
body.has-topbar {
  padding-top: 1rem;
}

.topbar {
  position: sticky;
  top: 0.75rem;
  z-index: 20;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto 2.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.55rem 0.8rem 0.55rem 1.1rem;
  background: rgba(21, 12, 23, 0.78);
  border: 1px solid rgba(75, 37, 33, 0.9);
  border-radius: 12px;
  backdrop-filter: blur(6px);
}

.topbar .hub-nav,
.topbar .auth-menu {
  position: static;
}

.topbar .hub-nav a {
  font-family: var(--font-display);
  font-size: 1.02rem;
  letter-spacing: 0.02em;
}

.hub-nav {
  position: fixed;
  top: 1.25rem;
  left: 1.25rem;
  z-index: 20;
  display: flex;
  gap: 1.25rem;
}

.hub-nav a {
  color: var(--parchment-dim);
  text-decoration: none;
  font-weight: bold;
  font-size: 0.9rem;
  padding-bottom: 0.2rem;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.hub-nav a:hover {
  color: var(--accent-gold);
}

.hub-nav a.active {
  color: var(--accent-gold);
  border-bottom-color: var(--accent-gold);
}

.auth-menu {
  position: fixed;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 20;
}

.auth-button {
  padding: 0.5rem 1rem;
  border-radius: 6px;
  background: var(--bg-panel);
  color: var(--parchment);
  border: 1px solid var(--wood);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 0.15s ease;
}

.auth-button:hover {
  background: var(--bg-panel-light);
}

/* Anchored under .auth-button (logged-in state only -- logged out just
   opens the login modal directly, no menu to show). Reuses the modal
   panel's own color/border tokens rather than a new palette. */
.auth-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  min-width: 180px;
  display: flex;
  flex-direction: column;
  background: var(--bg-panel);
  border: 1px solid var(--wood);
  border-radius: 8px;
  overflow: hidden;
}

.auth-dropdown[hidden] {
  display: none;
}

.auth-dropdown-item {
  display: block;
  width: 100%;
  padding: 0.6rem 1rem;
  background: none;
  border: none;
  border-bottom: 1px solid var(--wood);
  color: var(--parchment);
  font-family: inherit;
  font-size: 0.9rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
}

.auth-dropdown-item:last-child {
  border-bottom: none;
}

/* Same specificity as .auth-dropdown-item's own `display:block`, so
   without this the [hidden] attribute (used to conditionally show
   Admin Panel) would silently lose to it -- author rules always beat
   the UA stylesheet's `[hidden]{display:none}` regardless of selector
   match, this just makes that explicit. */
.auth-dropdown-item[hidden] {
  display: none;
}

.auth-dropdown-item:hover {
  background: var(--bg-panel-light);
  color: var(--accent-gold);
}

.auth-modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

/* Higher specificity than the bare class rules above so the [hidden]
   attribute actually hides these -- otherwise author CSS's `display`
   beats the UA stylesheet's `[hidden] { display: none }`. */
.auth-modal[hidden],
.auth-form[hidden] {
  display: none;
}

.auth-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(27, 18, 12, 0.75);
}

.auth-modal-panel {
  position: relative;
  width: min(90vw, 380px);
  background: var(--bg-panel);
  border: 1px solid var(--wood);
  border-radius: 8px;
  padding: 2rem 1.75rem 1.5rem;
}

.auth-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.75rem;
  background: none;
  border: none;
  color: var(--parchment-dim);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.auth-modal-close:hover {
  color: var(--accent-gold);
}

.auth-tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.auth-tab {
  flex: 1;
  padding: 0.5rem;
  background: none;
  border: 1px solid var(--wood);
  border-radius: 6px;
  color: var(--parchment-dim);
  font-family: inherit;
  cursor: pointer;
}

.auth-tab.active {
  background: var(--bg-panel-light);
  color: var(--accent-gold);
  border-color: var(--accent-rust);
}

.auth-tab-disabled,
.auth-tab-disabled:hover {
  background: none;
  color: var(--parchment-dim);
  border-color: var(--wood);
  opacity: 0.5;
  cursor: not-allowed;
}

.auth-form-closed {
  padding: 0.5rem 0;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.auth-form label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  color: var(--parchment-dim);
  font-size: 0.9rem;
}

.auth-form input {
  padding: 0.5rem 0.6rem;
  border-radius: 4px;
  border: 1px solid var(--wood);
  background: var(--bg-darkest);
  color: var(--parchment);
  font-family: inherit;
}

.auth-form button[type="submit"] {
  padding: 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--accent-rust);
  background: var(--accent-rust-dark);
  color: var(--parchment);
  font-weight: bold;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease;
}

.auth-form button[type="submit"]:hover {
  background: var(--accent-rust);
}

.auth-form-link {
  background: none;
  border: none;
  color: var(--parchment-dim);
  text-decoration: underline;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
  align-self: flex-start;
}

.auth-form-link:hover {
  color: var(--accent-gold);
}

.auth-form-hint {
  margin: 0;
  color: var(--parchment-dim);
  font-size: 0.85rem;
}

.auth-form-error {
  margin: 0;
  color: var(--accent-rust);
  font-size: 0.85rem;
  min-height: 1.1em;
}

.auth-form-success {
  margin: 0;
  color: var(--accent-gold);
  font-size: 0.85rem;
  min-height: 1.1em;
}

.game-card[data-theme="rock-festival-tycoon"] {
  /* Rock Festival Tycoon's own palette (the game's scripts/ui/ui.gd): a black
     stage, blood-red marquee, gold for money and stars, warm bone text, and a
     red stage-lip line along the bottom edge. */
  --bg-panel: #0e0e10;
  --wood: #2c2c31;
  --accent-gold: #f4c542;
  --parchment: #ece6da;
  --parchment-dim: #9a948a;
  --accent-rust-dark: #7a0f0f;
  --accent-rust: #d62828;
  --card-font-display: 'Metal Mania', Impact, serif;
  --card-font-body: 'Oswald', 'Arial Narrow', sans-serif;
  --progress-track: rgba(236, 230, 218, 0.12);
  --progress-fill: linear-gradient(90deg, #d62828, #f4c542);
  color: #ece6da;
  background-image:
    radial-gradient(80% 60% at 50% -10%, rgba(214, 40, 40, 0.28), transparent 65%),
    linear-gradient(180deg, #19171b 0%, #0e0e10 60%, #070708 100%);
  border: 1px solid #2c2c31;
  box-shadow:
    inset 0 -3px 0 #d62828,
    0 10px 26px rgba(0, 0, 0, 0.45);
}

.game-card[data-theme="rock-festival-tycoon"]:hover {
  box-shadow:
    inset 0 -3px 0 #d62828,
    0 0 0 1px rgba(244, 197, 66, 0.45),
    0 14px 34px rgba(0, 0, 0, 0.55);
}

.game-card[data-theme="rock-festival-tycoon"] .env-link {
  background: #d62828;
  color: #fff4e6;
  font-family: var(--card-font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.game-card[data-theme="rock-festival-tycoon"] .env-link:hover {
  background: #ef4343;
}

.game-card[data-theme="rock-festival-tycoon"] .env-link--soon {
  background: transparent;
  border-color: #f4c542;
  color: #f4c542;
}

.game-card[data-theme="rock-festival-tycoon"] .game-progress-link:hover .game-progress-text,
.game-card[data-theme="rock-festival-tycoon"] .changelog-link:hover {
  color: #f4c542;
}

.game-card[data-theme="salt-the-rift"] {
  /* Salt the Rift's own palette (that repo's css/style.css tokens): an
     obsidian panel lit by a lava glow from below, rift-teal accent, sulfur
     coins, and a blood-red Bastion line along the bottom edge. */
  --bg-panel: #171214;
  --wood: #3e3134;
  --accent-gold: #35d4c2;
  --parchment: #f1e8e3;
  --parchment-dim: #b7a7a1;
  --accent-rust-dark: #35d4c2;
  --accent-rust: #1fa898;
  --card-font-display: 'Black Ops One', Impact, sans-serif;
  --card-font-body: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --progress-track: rgba(241, 232, 227, 0.12);
  --progress-fill: linear-gradient(90deg, #35d4c2, #c6df57);
  color: #f1e8e3;
  background-image:
    radial-gradient(90% 70% at 85% 110%, rgba(255, 90, 36, 0.28), transparent 60%),
    linear-gradient(180deg, #211a1c 0%, #171214 60%, #0c0a0b 100%);
  border: 1px solid #3e3134;
  box-shadow:
    inset 0 -3px 0 #e2334b,
    0 10px 26px rgba(0, 0, 0, 0.45);
}

.game-card[data-theme="salt-the-rift"]:hover {
  box-shadow:
    inset 0 -3px 0 #e2334b,
    0 0 0 1px rgba(53, 212, 194, 0.45),
    0 14px 34px rgba(0, 0, 0, 0.55);
}

.game-card[data-theme="salt-the-rift"] .env-link {
  color: #062a26;
  font-family: var(--card-font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.game-card[data-theme="salt-the-rift"] .env-link:hover {
  background: #5ee3d5;
}

.game-card[data-theme="salt-the-rift"] .env-link--soon {
  border-color: #35d4c2;
  color: #35d4c2;
}

.game-card[data-theme="salt-the-rift"] .game-progress-link:hover .game-progress-text,
.game-card[data-theme="salt-the-rift"] .changelog-link:hover {
  color: #35d4c2;
}
