/* German Eiland -- shared design tokens + base layout.
 *
 * Ported from the donor site's /_shared.css (design-language reference
 * only; the donor tree was never modified). Two deliberate departures
 * from the donor file, both required by this backend's fixed CSP
 * (backend/security.py SecurityHeadersMiddleware -- style-src 'self',
 * font-src 'self', no 'unsafe-inline'; this build's writable scope is
 * C:\JollyBeansWeb only, so the CSP itself is out of scope to change):
 *   1. No @import of Google Fonts (style-src 'self' would block the
 *      cross-origin stylesheet and font-src 'self' would block the woff2
 *      files -- both would silently fail and spam console errors). Font
 *      stacks below use the SAME already-proven local/system fonts
 *      JollyBeansWeb's own site.css uses, in the same three-tier
 *      display/body/mono rhythm the donor design relies on.
 *   2. DEFAULT accent is Ember (#ff6a1f) per the build brief, not the
 *      donor's own default Jade -- see assets/theme.js.
 *
 * SOURCE OF TRUTH for these tokens: assets/theme.js (accent overrides) +
 * this file (everything else). Every ported/restyled page loads this file.
 */

:root {
  --bg-0:#0a0806;
  --bg-1:#1a1310;
  --bone:#f5e9d8;
  --bone-80:rgba(245,233,216,0.80);
  --bone-62:rgba(245,233,216,0.62);
  --bone-34:rgba(245,233,216,0.34);
  --bone-18:rgba(245,233,216,0.18);
  --bone-08:rgba(245,233,216,0.08);

  --accent:#ff6a1f;
  --accent-2:#ffb37a;
  --accent-deep:#a83f0f;
  --accent-glow:rgba(255,106,31,.55);
  --accent-rgb:255,106,31;
  --crimson:#c42021;
  --crimson-glow:rgba(196,32,33,0.55);

  --glass:rgba(255,255,255,0.06);
  --glass-2:rgba(255,255,255,0.04);
  --glass-border:rgba(245,233,216,0.18);
  --glass-border-lit:rgba(var(--accent-rgb),0.50);

  --ok:var(--accent);
  --err:#c42021;
  --warn:#ffb347;
  --amber:#ffb347;
  --amber-hot:#ffc472;
  --amber-glow:rgba(255,179,71,0.45);

  --display:"Bahnschrift Condensed", "Arial Narrow", "Franklin Gothic Medium", sans-serif;
  --ui:Tahoma, Verdana, "Segoe UI", sans-serif;
  --mono:"Cascadia Mono", Consolas, monospace;
  --ease:cubic-bezier(0.16, 1, 0.3, 1);

  /* ── legacy token ALIASES ──────────────────────────────────────────
   * JollyBeansWeb's PRE-rework page-specific stylesheets (wallet.css,
   * spin.css, shop.css, skins.css, garage.css, live.css, editor.css,
   * popcontrol.css) are kept UNCHANGED by this rework (their page bodies'
   * fetch/data logic is preserved exactly) and were written against the
   * OLD site.css token names below. Rather than hand-edit eight files'
   * internal `var(--x)` references, alias every old name onto this file's
   * new donor-derived tokens so those stylesheets resolve correctly
   * as-is. Do not remove without re-auditing every page-specific CSS file
   * for lingering references first. */
  color-scheme: dark;
  --ink: var(--bone);
  --muted: var(--bone-62);
  --dim: var(--bone-34);
  --black: #050403;
  --charcoal: var(--bg-0);
  --charcoal-2: var(--bg-1);
  --charcoal-3: #221a13;
  --line: var(--glass-border);
  --crimson-hot: #e2434a;
  --crimson-soft: rgba(196, 32, 33, 0.16);
  --gold: var(--amber);
  --gold-hot: var(--amber-hot);
  --gold-soft: rgba(255, 179, 71, 0.14);
  --danger: var(--crimson);
  --teal: var(--accent-2);
  --teal-soft: rgba(var(--accent-rgb), 0.14);
  --rarity-common: #9aa3c8;
  --rarity-rare: #5b8def;
  --rarity-epic: #b083f0;
  --rarity-prime: var(--amber-hot);
  --body: Tahoma, Verdana, "Segoe UI", sans-serif;
  /* 0, not the old 86px: that was the fixed-width LEFT site-rail nav, which
   * this rework replaces sitewide with topbar.js's fixed TOP bar (see
   * assets/topbar.css). voice/voice-theme.css still reads --rail for its
   * own `margin-left`/`left` offset (to clear the old sidebar) -- 0 keeps
   * that rule a harmless no-op instead of leaving a stray 86px gap. */
  --rail: 0px;
  --cut: polygon(0 0, calc(100% - 13px) 0, 100% 13px, 100% 100%, 13px 100%, 0 calc(100% - 13px));
}

* { box-sizing:border-box; }
/* Guarantee the native `hidden` attribute always wins over any component
 * class's own `display` value (e.g. .modal-backdrop{display:grid} would
 * otherwise beat the UA stylesheet's [hidden]{display:none} on equal
 * specificity+later source order -- ported from the pre-rework site.css
 * reset that every kept page's modals/panels rely on). */
[hidden] { display: none !important; }
html, body {
  margin:0; min-height:100%;
  background:radial-gradient(ellipse at 50% 0%, var(--bg-1) 0%, var(--bg-0) 65%);
  color:var(--bone-80); font-family:var(--ui);
  -webkit-font-smoothing:antialiased;
}
a { color:var(--accent); text-decoration:none; }
a:hover { text-decoration:underline; }
button, input, select, textarea { font: inherit; }
button { color: inherit; }

main {
  max-width:1100px; margin:0 auto;
  padding:32px 24px 96px;
}

h1.title {
  font-family:var(--display); font-size:48px;
  letter-spacing:0.18em; color:var(--bone);
  margin:8px 0 4px;
}
.subtitle {
  font-size:12px; letter-spacing:0.22em; text-transform:uppercase;
  color:var(--bone-62); margin-bottom:32px;
}

/* glass buttons */
button, .btn {
  font:inherit; font-size:13px;
  padding:10px 16px; border-radius:8px;
  background:var(--glass-2); color:var(--bone);
  border:1px solid var(--glass-border);
  cursor:pointer;
  transition:border-color 0.18s var(--ease), background 0.18s var(--ease),
             transform 0.12s ease, box-shadow 0.18s var(--ease);
  letter-spacing:0.02em;
}
button:hover, .btn:hover { border-color:var(--glass-border-lit); background:rgba(var(--accent-rgb),0.06); }
button:active { transform:scale(0.97); }
button:disabled { opacity:0.4; cursor:not-allowed; }

button.primary {
  background:linear-gradient(180deg, rgba(var(--accent-rgb),0.20) 0%, rgba(var(--accent-rgb),0.08) 100%);
  border:1px solid var(--accent);
  color:var(--bone);
  font-weight:600; letter-spacing:0.18em; text-transform:uppercase;
  box-shadow:0 8px 22px -8px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,0.06);
  padding:14px 24px;
}
button.primary:hover {
  background:linear-gradient(180deg, rgba(var(--accent-rgb),0.30) 0%, rgba(var(--accent-rgb),0.14) 100%);
}

/* card grid (landing systems + generic use) */
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(260px, 1fr));
  gap:20px;
}
.card {
  position:relative;
  display:flex; flex-direction:column; gap:8px;
  padding:24px;
  background:var(--glass);
  border:1px solid var(--glass-border);
  border-radius:14px;
  backdrop-filter:blur(10px) saturate(110%);
  -webkit-backdrop-filter:blur(10px) saturate(110%);
  text-decoration:none; color:inherit;
  transition:border-color 0.2s var(--ease), transform 0.2s var(--ease);
  min-height:160px;
}
.card:hover {
  border-color:var(--glass-border-lit);
  transform:translateY(-2px);
  text-decoration:none;
}
.card .name {
  font-family:var(--display); font-size:24px; letter-spacing:0.18em; color:var(--bone);
}
.card .meta {
  font-size:11px; letter-spacing:0.16em; text-transform:uppercase;
  color:var(--bone-62);
}
.card .blurb { font-size:13px; color:var(--bone-80); line-height:1.5; margin-top:4px; }

/* small inputs */
input[type="number"], input[type="text"] {
  font:inherit; font-family:var(--mono); font-size:14px;
  padding:10px 12px; border-radius:8px;
  background:var(--bg-1); color:var(--bone);
  border:1px solid var(--glass-border);
  width:100%;
}
input:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(var(--accent-rgb),0.18); }

.notice {
  padding:12px 16px; border-radius:8px;
  border:1px solid var(--crimson); color:var(--crimson);
  background:rgba(196,32,33,0.06);
  font-size:13px;
}
.notice.warn { border-color:var(--warn); color:var(--warn); background:rgba(255,179,71,0.06); }
.notice.ok   { border-color:var(--accent); color:var(--accent); background:rgba(var(--accent-rgb),0.06); }

/* First-paint fade: matches by VALUE ([data-embedded="true"]), not mere
 * presence, so pages that ship a static data-embedded="auto" default still
 * fade in normally; only truly-embedded pooled-module frames skip it. */
@media (prefers-reduced-motion:no-preference){
  body:not([data-embedded="true"]){animation:gePageIn .18s ease-out}
  @keyframes gePageIn{from{opacity:.01}to{opacity:1}}
}

/* ══════════════════════════════════════════════════════════════════════
 * Cross-page utility classes carried over from JollyBeansWeb's PRE-rework
 * assets/css/site.css (kept page bodies -- wallet.js/spin.js/shop.js/
 * skins.js/garage.js/live.js/popcontrol.js/editor.js and their HTML -- were
 * NOT rewritten and still emit these exact class names). Re-themed onto
 * this file's donor-derived tokens (--bone/--accent/--glass*) instead of
 * the old --gold/--crimson/--charcoal-2/--line/--cut vocabulary, but the
 * selectors, structure, and behavior are unchanged so every kept page's
 * existing markup renders correctly without any HTML/JS edits.
 * ══════════════════════════════════════════════════════════════════════ */

.skip-link {
  position: fixed; z-index: 1300; left: 12px; top: -80px;
  padding: 10px 14px; background: var(--accent); color: #1a0a02;
  border-radius: 6px;
}
.skip-link:focus { top: 12px; }

/* Buttons: JB page bodies use class="button" (+ .primary/.gold/.danger),
 * not this file's own `.btn` -- extend the same glass/accent treatment to
 * both selectors so every kept <button>/<a class="button"> matches. */
.button, button.button, a.button {
  display: inline-flex; min-height: 43px; align-items: center; justify-content: center; gap: 8px;
  padding: 0 18px; border-radius: 8px;
  background: var(--glass-2); color: var(--bone);
  border: 1px solid var(--glass-border);
  cursor: pointer; text-decoration: none;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease), transform 0.12s ease, box-shadow 0.18s var(--ease);
  text-transform: uppercase; font: 700 11px/1 var(--display); letter-spacing: 0.10em;
}
.button:hover, a.button:hover { border-color: var(--glass-border-lit); background: rgba(var(--accent-rgb), 0.08); text-decoration: none; }
.button:active { transform: scale(0.97); }
.button.primary {
  border-color: var(--accent);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.28) 0%, rgba(var(--accent-rgb), 0.10) 100%);
  box-shadow: 0 8px 22px -10px var(--accent-glow);
  color: var(--bone);
}
.button.primary:hover { background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.38) 0%, rgba(var(--accent-rgb), 0.16) 100%); }
.button.gold { border-color: var(--amber); color: var(--amber-hot); }
.button.gold:hover { background: rgba(255, 179, 71, 0.10); }
.button.danger { border-color: var(--crimson); color: #ff9a92; background: rgba(196, 32, 33, 0.12); }
.button.danger:hover { background: var(--crimson); color: var(--bone); }
.button:disabled, .button[disabled] { opacity: 0.42; cursor: not-allowed; }

/* Generic glass panel wrapper (wallet balance card, Prime board, garage
 * action sections, ...). */
.panel {
  border: 1px solid var(--glass-border);
  background: var(--glass);
  border-radius: 14px;
  backdrop-filter: blur(10px) saturate(110%);
  -webkit-backdrop-filter: blur(10px) saturate(110%);
}

/* Inline status/help text used on every kept page. */
.status-note { color: var(--bone-62); font-size: 13px; }
.status-note.ok { color: var(--ok); }
.status-note.error { color: var(--crimson); }

/* Eyebrow label above a page/section heading. */
.eyebrow {
  margin: 0 0 12px; color: var(--accent);
  text-transform: uppercase; font: 700 10px/1 var(--mono); letter-spacing: 0.24em;
}

/* Data Chips currency chip (shop/skins/wallet toolbars). */
.chips-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border: 1px solid var(--accent);
  color: var(--accent-2); background: rgba(var(--accent-rgb), 0.10);
  font: 700 12px/1 var(--mono); letter-spacing: 0.04em; border-radius: 999px;
}

/* Rarity ribbons (dino/skin shop cards). */
.rarity-ribbon {
  display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 4px;
  text-transform: uppercase; font: 700 9px/1 var(--mono); letter-spacing: 0.14em;
  border: 1px solid currentColor;
}
.rarity-ribbon.common { color: #9aa3c8; }
.rarity-ribbon.rare { color: #5b8def; }
.rarity-ribbon.epic { color: #b083f0; }
.rarity-ribbon.prime { color: var(--amber-hot); }

/* Species/skin card grid (shop + skins sections). */
.card-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px; padding: 4px 0;
}
.item-card {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: 16px; border: 1px solid var(--glass-border); background: var(--glass);
  border-radius: 12px;
}
.item-card h3 { margin: 0; font: 800 18px/1.1 var(--display); text-transform: uppercase; color: var(--bone); }
.item-card .item-media {
  height: 140px; display: grid; place-items: center;
  background: radial-gradient(circle at 50% 30%, rgba(var(--accent-rgb), 0.14), transparent 70%), var(--bg-1);
  border: 1px solid var(--glass-border); border-radius: 8px; overflow: hidden;
}
.item-card .item-media img, .item-card .item-media video { max-width: 100%; max-height: 100%; object-fit: contain; }
.item-card .item-price { color: var(--accent-2); font: 700 14px/1 var(--mono); }
.item-card .item-row, .item-card .item-buy-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; }
.item-card .item-locked { color: var(--crimson); font: 700 10px/1 var(--mono); text-transform: uppercase; }

/* Admin-only per-item edit affordance (shop price editor, skin catalog):
 * hidden until topbar.js/page JS confirms an admin session via
 * /api/admin/session and sets body[data-admin="1"] (shop.js does this
 * itself; see frontend\shop\shop.js loadAdmin()). */
.admin-edit-chip {
  position: absolute; top: 10px; right: 10px; display: none;
  min-height: 28px; padding: 0 10px; align-items: center;
  border: 1px solid var(--amber); color: var(--amber-hot);
  background: rgba(10, 9, 8, 0.88);
  text-transform: uppercase; font: 700 9px/1 var(--mono); letter-spacing: 0.1em;
  cursor: pointer; border-radius: 6px;
}
body[data-admin="1"] .admin-edit-chip { display: inline-flex; }

/* Species disabled in the shop (contract: the non-playable apex species) --
 * players never see these at all (filtered client-side); admins see them
 * greyed out with the edit control still active. */
.item-card.shop-disabled { opacity: 0.45; filter: grayscale(0.6); }
.item-card.shop-disabled .item-buy-row .button { cursor: not-allowed; }
.shop-disabled-row { opacity: 0.5; }
.shop-disabled-badge {
  margin-left: 6px; color: var(--crimson);
  text-transform: uppercase; font: 700 9px/1 var(--mono); letter-spacing: 0.06em;
}

/* Confirm/edit dialogs (shop price edit, garage slay confirm). */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 1250;
  display: grid; place-items: center; background: rgba(4, 5, 6, 0.72);
}
.modal-card {
  width: min(420px, 92vw); padding: 22px; border-radius: 12px;
  border: 1px solid var(--accent); background: var(--bg-1);
  display: grid; gap: 12px;
}
.modal-card h3 { margin: 0; font: 800 18px/1 var(--display); text-transform: uppercase; color: var(--bone); }
.modal-card p { margin: 0; color: var(--bone-62); font-size: 13px; }
.modal-card label { display: grid; gap: 4px; font: 600 11px/1 var(--mono); color: var(--bone-62); text-transform: uppercase; letter-spacing: 0.08em; }
.modal-card input, .modal-card select {
  min-height: 38px; padding: 0 10px; border-radius: 6px;
  border: 1px solid var(--glass-border); background: var(--bg-0); color: var(--bone); font: 14px/1.4 var(--ui);
}
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }

/* Ledger / stored-dino / species-cap tables. */
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table th, .data-table td { padding: 8px 10px; border-bottom: 1px solid var(--glass-border); text-align: left; color: var(--bone-80); }
.data-table th { color: var(--bone-34); text-transform: uppercase; font: 700 9px/1 var(--mono); letter-spacing: 0.1em; }
