/* swordshine.online — the public portal.

   Same visual language as the desktop launcher (launcher/web/styles.css): the tokens
   below are copied from it verbatim so the two stay one product. Everything is CSS, so
   the site ships no image assets and there is nothing to keep in sync.

   The one structural difference from the launcher: there, the rail and the content each
   scroll inside a fixed window. Here the document scrolls and the rail is sticky, which
   is what a browser expects and what lets the layout fold flat on a phone. */

:root {
  --bg: #0f1017;
  --rail: #14151d;
  --panel: #191b25;
  --panel-2: #1f2130;
  --line: #2a2d3d;
  --text: #e8eaf2;
  --muted: #9aa0b5;
  --gold: #f3c14a;
  --gold-deep: #b8801c;
  --violet: #7c5cff;
  --green: #3fd08a;
  --red: #ff6b6b;
  --rail-w: 224px;
}

* { box-sizing: border-box; }

html { height: 100%; }

body {
  display: flex;
  min-height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 "Segoe UI", system-ui, sans-serif;
}

a { color: inherit; text-decoration: none; }

.skip {
  position: absolute;
  top: -60px;
  left: 8px;
  z-index: 40;
  padding: 10px 14px;
  border-radius: 9px;
  background: var(--gold);
  color: #241a04;
  font-weight: 700;
}

.skip:focus { top: 8px; }

/* ---------- left rail ---------- */

.rail {
  position: sticky;
  top: 0;
  display: flex;
  flex: 0 0 var(--rail-w);
  flex-direction: column;
  height: 100vh;
  align-self: flex-start;
  border-right: 1px solid var(--line);
  background: var(--rail);
}

.brand {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 16px 14px;
  border-bottom: 1px solid var(--line);
}

/* The emblem is a gold ring on an opaque black square, so it is clipped to a circle:
   that drops the corners without needing a transparent source. */
img.brand-mark {
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  border-radius: 50%;
  object-fit: cover;
}

.brand-mark {
  display: grid;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  border-radius: 9px;
  background: linear-gradient(145deg, var(--gold), var(--gold-deep));
  color: #241a04;
  font-weight: 800;
  letter-spacing: .5px;
  place-items: center;
}

.brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.brand-text b { font-size: 15px; }
.brand-text i { color: var(--muted); font-size: 11px; font-style: normal; letter-spacing: .4px; text-transform: uppercase; }

.rail-games { flex: 1; overflow-y: auto; padding: 10px 8px; }
.rail-foot { padding: 10px 8px; border-top: 1px solid var(--line); }

.rail-item {
  display: flex;
  gap: 10px;
  align-items: center;
  width: 100%;
  padding: 9px 10px;
  border-radius: 9px;
  color: var(--muted);
}

.rail-item:hover { background: var(--panel-2); color: var(--text); }

.rail-item.is-active {
  background: linear-gradient(90deg, rgba(243, 193, 74, .16), transparent);
  box-shadow: inset 2px 0 0 var(--gold);
  color: var(--text);
}

/* Unlaunched games stay clickable — the page explains itself — but read as pending. */
.rail-item.is-soon:not(.is-active) { opacity: .62; }

.glyph { width: 20px; flex: 0 0 20px; font-size: 15px; text-align: center; }
.rail-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag { margin-left: auto; color: var(--muted); font-size: 10px; letter-spacing: .6px; text-transform: uppercase; }

/* ---------- main column ---------- */

.main { display: flex; min-width: 0; flex: 1; flex-direction: column; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 0 18px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

.tabs { display: flex; gap: 4px; }

.tab {
  padding: 14px 12px;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font-size: 12.5px;
  letter-spacing: .8px;
  text-transform: uppercase;
}

a.tab:hover { color: var(--text); }
.tab.is-active { border-bottom-color: var(--gold); color: var(--gold); }

.status { display: flex; gap: 8px; align-items: center; margin: 0 0 0 auto; padding: 8px 0; color: var(--muted); font-size: 12px; }
.dot { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--muted); }
.status.is-online .dot { background: var(--green); box-shadow: 0 0 8px var(--green); }
.status.is-offline .dot { background: var(--red); }

.scroll { flex: 1; padding: 18px; }

/* ---------- hero ---------- */

.hero {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: radial-gradient(120% 140% at 78% 20%, #3a1f63 0%, #1b1430 45%, #12121c 100%);
}

.hero-art { position: absolute; inset: 0; }

.orb { position: absolute; border-radius: 50%; filter: blur(38px); opacity: .55; }
.orb-a { top: -60px; right: 60px; width: 260px; height: 260px; background: #8a4bff; }
.orb-b { right: -40px; bottom: -80px; width: 300px; height: 300px; background: #ff6a3d; opacity: .32; }
.orb-c { top: 40px; right: 280px; width: 160px; height: 160px; background: var(--gold); opacity: .22; }

.hero-body { position: relative; max-width: 660px; padding: 34px 32px 30px; }

.kicker { margin: 0; color: var(--muted); font-size: 11px; letter-spacing: 3px; text-transform: uppercase; }

.wordmark {
  margin: 6px 0 4px;
  background: linear-gradient(180deg, #ffe9a8, var(--gold) 45%, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-size: 46px;
  font-weight: 800;
  letter-spacing: 1px;
  line-height: 1.08;
  text-shadow: 0 2px 18px rgba(243, 193, 74, .18);
}

/* Drawn wordmark: the gradient-text treatment above has nothing to clip to, so reset it
   and let the image carry the type. Width is capped rather than fixed so it shrinks with
   the column instead of overflowing on a narrow viewport. */
.wordmark-img {
  background: none;
  text-shadow: none;
  line-height: 0;
}

.wordmark-img img {
  width: min(420px, 100%);
  height: auto;
}

@media (max-width: 900px) {
  .wordmark-img img { width: min(320px, 100%); }
}

.tagline { margin: 0 0 8px; color: #cfd3e4; }
.blurb { max-width: 52ch; margin: 0 0 22px; color: var(--muted); font-size: 13px; }

/* ---------- buttons ---------- */

.cta { display: flex; flex-wrap: wrap; gap: 12px; }

.btn {
  display: block;
  min-width: 168px;
  padding: 12px 20px;
  border: 1px solid transparent;
  border-radius: 11px;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}

.btn:not(.is-disabled):hover { transform: translateY(-2px); }
.btn-title { display: block; font-size: 15px; font-weight: 700; }
.btn-sub { display: block; margin-top: 1px; font-size: 11px; letter-spacing: .3px; opacity: .72; text-transform: uppercase; }

.btn-play {
  border-color: #8f1f1f;
  background: linear-gradient(180deg, #b5232a, #7c1119);
  box-shadow: 0 6px 20px rgba(181, 35, 42, .32);
}
.btn-play:not(.is-disabled):hover { box-shadow: 0 10px 26px rgba(181, 35, 42, .45); }

.btn-make {
  border-color: #1f6d4a;
  background: linear-gradient(180deg, #1f8a58, #12603c);
  box-shadow: 0 6px 20px rgba(31, 138, 88, .28);
}

.btn-alt { border-color: var(--line); background: rgba(255, 255, 255, .06); }
.btn-alt:not(.is-disabled):hover { border-color: var(--gold); }

.btn.is-disabled { box-shadow: none; cursor: default; filter: grayscale(.7); opacity: .45; }

/* ---------- notice + strip ---------- */

.notice {
  margin: 18px 0 0;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 10px;
  background: var(--panel-2);
  color: #cfd3e4;
  font-size: 13px;
}

.strip {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  padding: 14px 4px 12px;
  border-bottom: 1px solid var(--line);
  margin-top: 18px;
}

.strip-label { color: var(--text); font-size: 11.5px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; }
.strip-note { color: var(--muted); font-size: 12.5px; }

/* ---------- news ---------- */

.news {
  display: grid;
  /* The topbar is sticky, so the News tab's #news jump has to clear it. */
  scroll-margin-top: 68px;
  padding: 18px 0 8px;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}

.card {
  display: flex;
  overflow: hidden;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--panel);
  transition: transform .12s ease, border-color .12s ease;
}

.card:hover { border-color: #3a3f57; transform: translateY(-3px); }

.card-art {
  display: grid;
  align-content: end;
  height: 122px;
  padding: 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .7);
  text-transform: uppercase;
}

.card-body { display: flex; flex: 1; flex-direction: column; gap: 8px; padding: 12px 13px 13px; }
.card-title { margin: 0; font-size: 14.5px; }
.card-meta { margin: 0; color: var(--muted); font-size: 11.5px; overflow-wrap: anywhere; }
/* The summary under a news headline, from site_news.Body. */
.card-text { margin: 0; color: var(--muted); font-size: 12.5px; }
.card-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; }

.chip {
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: 11.5px;
}

a.chip:hover { border-color: var(--gold); color: var(--gold); }
.chip.is-disabled { cursor: default; opacity: .5; }

.empty {
  padding: 34px;
  border: 1px dashed var(--line);
  border-radius: 13px;
  color: var(--muted);
  grid-column: 1 / -1;
  text-align: center;
}

/* ---------- narrow screens ----------

   The game is a 960x550 desktop stage, but the site around it is not, so the rail folds
   from a column into a scrollable row of chips above the content. */

@media (max-width: 900px) {
  body { display: block; }

  .rail {
    position: static;
    display: block;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .brand { border-bottom: 0; padding-bottom: 10px; }

  .rail-games,
  .rail-foot {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 0 10px 10px;
    border-top: 0;
    -webkit-overflow-scrolling: touch;
  }

  /* Keep the hairline between "games" and the site links, now that they are two rows
     of identical-looking chips rather than two ends of a column. */
  .rail-foot { padding: 10px; border-top: 1px solid var(--line); }

  .rail-item {
    width: auto;
    flex: 0 0 auto;
    border: 1px solid var(--line);
    white-space: nowrap;
  }

  .rail-item.is-active { box-shadow: none; border-color: var(--gold-deep); }
  .tag { margin-left: 4px; }

  .topbar { position: static; padding: 0 16px; }
  .scroll { padding: 16px; }
  .hero-body { padding: 26px 20px 24px; }
  .wordmark { font-size: 34px; }
  .orb-c { display: none; }
  .btn { min-width: 0; flex: 1 1 200px; }
}

@media (max-width: 420px) {
  .wordmark { font-size: 28px; }
  .cta { display: grid; }
  .news { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .btn:hover, .card:hover { transform: none; }
}

/* ---------- download page ----------

   The steps and the facts are the same card vocabulary as .news, narrowed to text: no
   art, no chips, so they carry their own small block rather than reusing .card. */

.step-list {
  max-width: 78ch;
  margin: 22px 0 0;
  padding: 0;
  counter-reset: step;
  list-style: none;
}

.step-list li {
  position: relative;
  margin-bottom: 14px;
  padding: 14px 18px 14px 56px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  color: var(--muted);
  font-size: 13px;
}

.step-list li b { color: var(--text); }
.step-list li i { color: #cfd3e4; font-style: normal; }

.step-list li::before {
  position: absolute;
  top: 13px;
  left: 16px;
  display: grid;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--panel-2);
  color: var(--gold);
  content: counter(step);
  counter-increment: step;
  font-size: 12px;
  font-weight: 700;
  place-items: center;
}

.facts {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  margin-top: 22px;
}

.fact {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}

.fact h2 { margin: 0 0 6px; color: var(--text); font-size: 14px; }
.fact p { margin: 0; color: var(--muted); font-size: 13px; }

code {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--panel-2);
  color: #cfd3e4;
  font-size: 12px;
  word-break: break-all;
}

.checksum { margin-top: 26px; }
.checksum h2 { margin: 0 0 6px; font-size: 12px; letter-spacing: 1.4px; text-transform: uppercase; }
.checksum p { margin: 0 0 6px; color: var(--muted); font-size: 13px; }
.checksum-help { font-size: 12px; }

/* ---------- character pages ---------- */

/* The search box sits at the far end of the tab bar, where the status pill sits on a
   game page -- same row, same visual weight. */
.finder { display: flex; gap: 6px; margin: 0 0 0 auto; padding: 8px 0; }

.finder input {
  width: min(260px, 46vw);
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.finder input:focus { border-color: var(--gold-deep); outline: none; }

.finder button {
  padding: 7px 14px;
  border: 1px solid var(--gold-deep);
  border-radius: 8px;
  background: linear-gradient(180deg, #d8a63a, var(--gold-deep));
  color: #241a04;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.char-head { padding-bottom: 24px; }
.char-name { font-size: 40px; }

.badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }

.badge {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
  color: #cfd3e4;
  font-size: 11px;
  letter-spacing: .4px;
}

.badge-staff { border-color: var(--violet); color: #cbbcff; }
.badge-member { border-color: var(--gold-deep); color: var(--gold); }

/* The preview movie is a fixed 715x455 stage. Scale it to the column rather than letting
   it overflow, and keep its aspect so the hero is never squashed. */
.portrait {
  overflow: hidden;
  width: 100%;
  max-width: 715px;
  margin: 16px 0 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  aspect-ratio: 715 / 455;
  background: #12121c;
}

.portrait object,
.portrait ruffle-object,
.portrait ruffle-embed,
.portrait ruffle-player { display: block !important; width: 100% !important; height: 100% !important; }

.panels {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  margin-top: 16px;
}

.panel {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}

.panel h2 { margin: 0 0 12px; color: var(--muted); font-size: 11px; letter-spacing: 1.6px; text-transform: uppercase; }

.stat-grid { display: grid; gap: 8px 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; }
.stat-grid div { display: flex; justify-content: space-between; gap: 10px; }
.stat-grid dt { color: var(--muted); font-size: 12px; }
.stat-grid dd { margin: 0; color: var(--text); font-size: 13px; font-weight: 700; }

.gear { margin: 0; padding: 0; list-style: none; }
.gear li { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--line); font-size: 13px; }
.gear li:first-child { border-top: 0; }
.gear-slot { color: var(--muted); font-size: 11px; letter-spacing: 1px; text-transform: uppercase; }
.gear-item { color: var(--text); text-align: right; }

.accordion {
  margin-top: 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}

.accordion summary { padding: 14px 18px; color: var(--text); cursor: pointer; font-size: 13px; font-weight: 700; }
.accordion[open] summary { border-bottom: 1px solid var(--line); }

.inventory {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  padding: 18px;
}

.category h3 { margin: 0 0 6px; color: var(--gold); font-size: 12px; letter-spacing: 1px; text-transform: uppercase; }
.category ul { margin: 0; padding: 0; list-style: none; }
.category li { padding: 2px 0; color: var(--muted); font-size: 13px; }
.category li span { opacity: .7; }
/* Equipped items are called out here because the panel above only names one per slot. */
.category li.is-equipped { color: var(--text); font-weight: 700; }

.notice a { color: var(--gold); text-decoration: underline; }

@media (max-width: 900px) {
  .char-name { font-size: 30px; }
  .finder { width: 100%; margin: 0 0 10px; }
  .finder input { width: 100%; }
}
