/* ============ Star Wars D6 character generator ============ */
:root {
  --bg: #0b0d17;
  --bg2: #121527;
  --card: #181c33;
  --card2: #1f2440;
  --border: #2c3358;
  --text: #e8eaf6;
  --muted: #9aa1c9;
  --accent: #ffe81f;
  --accent-dim: #c9b719;
  --green: #6fe08c;
  --red: #ff6b6b;
  --blue: #6db3ff;
  --inset: #0e1122;      /* inset fields and chips (selects, badges ...) */
  --hover: #2a3054;      /* hover on buttons and menu rows */
  --rowhover: #1b2038;   /* hover on table and list rows */
  /* Side margin of the content. It is a variable because the sheet preview
     has to know it in order to shrink onto the width that is left. */
  --page-pad: 20px;
}

/* ---------- themes (via data-theme on <html>, see theme.js) ---------- */
/* Light: pale background, dark type, a stronger gold for contrast */
:root[data-theme="light"] {
  --bg: #eceef6; --bg2: #e0e3f0; --card: #ffffff; --card2: #f3f5fc;
  --border: #c6cbe4; --text: #1a1d2e; --muted: #565d84;
  --accent: #b89400; --accent-dim: #8f7400;
  --green: #1f9d4d; --red: #d63a3a; --blue: #2f6fd0;
  --inset: #e6e9f5; --hover: #d7dcf0; --rowhover: #eaedf9;
}
/* OLED: pure black, easy on AMOLED displays */
:root[data-theme="oled"] {
  --bg: #000000; --bg2: #080810; --card: #0e0e16; --card2: #15151f;
  --border: #29293a; --text: #e8eaf6; --muted: #9aa1c9;
  --accent: #ffe81f; --accent-dim: #c9b719;
  --green: #6fe08c; --red: #ff6b6b; --blue: #6db3ff;
  --inset: #0b0b12; --hover: #1c1c28; --rowhover: #141420;
}
/* Bespin: warm Cloud City tones with an orange accent */
:root[data-theme="bespin"] {
  --bg: #1c1610; --bg2: #261d14; --card: #2c2118; --card2: #362819;
  --border: #4d3a26; --text: #f2e8d6; --muted: #c7b391;
  --accent: #ff9d3c; --accent-dim: #c9791e;
  --green: #8fd08c; --red: #ff7a5c; --blue: #e0a86d;
  --inset: #241c14; --hover: #3a2c1c; --rowhover: #2c2119;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  background-image: radial-gradient(circle at 20% 10%, var(--bg2) 0%, transparent 40%),
                    radial-gradient(circle at 80% 90%, var(--bg2) 0%, transparent 45%);
  color: var(--text);
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: 15px;
  min-height: 100vh;
}

/* ---------- header ---------- */
#topbar {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  background: linear-gradient(180deg, var(--bg2), var(--card));
  border-bottom: 2px solid var(--accent);
}
.title-block h1 {
  margin: 0; font-size: 26px; letter-spacing: 3px; color: var(--accent);
  font-weight: 900; text-shadow: 0 0 18px rgba(255, 232, 31, .35);
}
.title-block h1 span { color: var(--text); font-weight: 300; }
.subtitle { color: var(--muted); font-size: 12px; letter-spacing: 1px; }
.page-nav { margin-top: 4px; display: flex; gap: 4px; }
.page-nav a {
  color: var(--muted); text-decoration: none; font-size: 12.5px;
  padding: 2px 10px; border: 1px solid var(--border); border-radius: 12px;
}
.page-nav a:hover { color: var(--text); border-color: var(--accent-dim); }
.page-nav a.active { color: var(--accent); border-color: var(--accent-dim); font-weight: 700; }
.dicectl input { padding: 5px 6px; }
.char-manager { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.char-manager .sep { width: 1px; height: 24px; background: var(--border); margin: 0 4px; }

button {
  background: var(--card2); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 7px 12px; cursor: pointer; font-size: 13px;
  transition: background .15s, border-color .15s;
}
button:hover { background: var(--hover); border-color: #3d4677; }
button.accent { background: var(--accent); color: #14140a; font-weight: 700; border-color: var(--accent-dim); }
button.accent:hover { background: #fff268; }
button.mini { padding: 2px 9px; font-size: 14px; line-height: 1.3; font-weight: 700; }
button.danger { color: var(--red); }
select, input[type=text], input[type=number], textarea {
  background: var(--inset); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 7px 9px; font-size: 14px; font-family: inherit;
}
select:focus, input:focus, textarea:focus { outline: 1px solid var(--accent-dim); }
/* Left alone, a select grows as wide as its longest entry and does not
   shrink back. With entries like "Turbocharger +1D - install: 4,500 Cr" it
   burst the card on a phone, and with it the page width. */
select { max-width: 100%; }
input[type=number] { width: 90px; }
input[type=checkbox] { accent-color: var(--accent); width: 16px; height: 16px; }
textarea { width: 100%; resize: vertical; min-height: 70px; }
label { color: var(--muted); font-size: 12px; display: block; margin-bottom: 3px; letter-spacing: .4px; text-transform: uppercase; }

/* ---------- options menu ---------- */
.options-wrap { position: relative; }
#optionsMenu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 50;
  background: var(--card2); border: 1px solid var(--accent-dim);
  border-radius: 8px; padding: 10px 14px; min-width: 270px; max-width: 320px;
  box-shadow: 0 8px 24px rgba(0,0,0,.6);
  max-height: calc(100vh - 80px); overflow-y: auto;
}
#optionsMenu input[type=url] {
  width: 100%; margin: 2px 0 6px; font-size: 12.5px; padding: 5px 7px;
}
#optionsMenu .opt-label {
  color: var(--text); font-size: 12px; display: block; margin-top: 2px;
  text-transform: none; letter-spacing: 0;
}
#optionsMenu .opt-hint { color: var(--muted); font-size: 11px; margin-top: 4px; line-height: 1.35; }
#optionsMenu.hidden { display: none; }
#optionsMenu .opt-title {
  color: var(--accent); font-weight: 700; font-size: 13px;
  letter-spacing: 1px; text-transform: uppercase;
  border-bottom: 1px solid var(--border); padding-bottom: 6px; margin-bottom: 8px;
  /* No pointer, no hover: the heading should not look like a button. Only
     suppress text selection on a double click. */
  user-select: none; -webkit-user-select: none;
}

/* ---------- vector window (the hidden extra) ---------- */
.arcade-box {
  background: #000; border: 2px solid #39ff7a; border-radius: 6px;
  padding: 8px; box-shadow: 0 0 24px rgba(57, 255, 122, .25);
  max-width: 96vw;
}
.arcade-head {
  display: flex; align-items: center; justify-content: space-between;
  color: #39ff7a; font-family: monospace; letter-spacing: 3px;
  font-size: 14px; margin-bottom: 6px;
}
.arcade-box canvas {
  display: block; background: #000; width: 640px; height: 480px;
  max-width: 92vw; max-height: 69vw;      /* keeps the 4:3 ratio */
}
.arcade-help {
  color: #39ff7a; opacity: .7; font-family: monospace; font-size: 11px;
  text-align: center; margin-top: 6px;
}
#optionsMenu .opt-section { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; margin: 6px 0 4px; }
#optionsMenu .opt-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 4px;
  color: var(--text); font-size: 14px; cursor: pointer; border-radius: 5px;
  text-transform: none; letter-spacing: 0; margin: 0;
}
#optionsMenu .opt-row:hover { background: var(--hover); }

/* ---------- Tabs ---------- */
#tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  padding: 10px 20px 0; border-bottom: 1px solid var(--border);
  background: var(--bg2);
}
#tabs button {
  border: 1px solid var(--border); border-bottom: none;
  border-radius: 8px 8px 0 0; background: transparent; color: var(--muted);
  padding: 9px 16px; font-size: 14px;
}
#tabs button:hover { color: var(--text); background: var(--card); }
#tabs button.active {
  background: var(--card); color: var(--accent);
  border-color: var(--accent-dim); font-weight: 700;
}

main { padding: 18px var(--page-pad) 60px; max-width: 1500px; margin: 0 auto; }
.tab { display: none; }
.tab.active { display: block; animation: fadein .18s ease; }
@keyframes fadein { from { opacity: 0; transform: translateY(4px);} to { opacity: 1; transform: none; } }

/* ---------- Cards / layout ---------- */
.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; padding: 16px; margin-bottom: 16px;
}
.card h2 {
  margin: 0 0 12px; font-size: 15px; color: var(--accent);
  letter-spacing: 1.5px; text-transform: uppercase;
  border-bottom: 1px solid var(--border); padding-bottom: 8px;
}
.card h3 { margin: 14px 0 8px; font-size: 13px; color: var(--blue); letter-spacing: 1px; text-transform: uppercase; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.formgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.formgrid .wide { grid-column: 1 / -1; }
@media (max-width: 900px) { .grid2, .grid3 { grid-template-columns: 1fr; } }

.hint { color: var(--muted); font-size: 12.5px; }

/* "hidden" as a general utility. It used to be spelled out only for
   #optionsMenu and .modal-overlay, so on every OTHER element the class did
   nothing at all - the JavaScript added it, the element stayed on screen.
   That is why the "Administration" entry in the gear menu showed for every
   signed-in user although updateAdminButton() marks it hidden for
   non-admins (the server refused them, so it only ever misled). */
.hidden { display: none !important; }
.warn { color: var(--red); font-weight: 600; }
.ok { color: var(--green); font-weight: 600; }
/* The counterpart to .ok - rejected sheets in the game rounds. Deliberately
   here and not as a general .neg: that name is already taken inside the pool
   banners. */
.no { color: var(--red); font-weight: 600; }
.badge.danger { color: var(--red); border-color: var(--red); }
.badge {
  display: inline-block; background: var(--inset); border: 1px solid var(--border);
  border-radius: 5px; padding: 1px 8px; font-size: 12px; color: var(--muted); margin: 1px 2px;
}
.badge.gold { color: var(--accent); border-color: var(--accent-dim); }

.dice {
  font-family: Consolas, monospace; font-weight: 700; color: var(--accent);
  background: var(--inset); border: 1px solid var(--accent-dim);
  border-radius: 6px; padding: 2px 10px; display: inline-block; min-width: 62px; text-align: center;
}
.dice.plain { color: var(--text); border-color: var(--border); }

.pool-banner {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap; gap: 20px; align-items: center;
  background: var(--card2); border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 8px; padding: 10px 16px; margin-bottom: 16px;
  box-shadow: 0 4px 14px rgba(0,0,0,.45);
}
.pool-banner b { color: var(--accent); font-size: 17px; font-family: Consolas, monospace; }
.pool-banner .neg b { color: var(--red); }

/* ---------- Attribute rows ---------- */
.attr-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 6px; border-bottom: 1px solid #232849;
}
.attr-row:last-child { border-bottom: none; }
.attr-row .aname { flex: 0 0 150px; font-weight: 700; font-size: 15px; }
.attr-row .alimits { color: var(--muted); font-size: 12px; flex: 0 0 130px; }
.stepper { display: inline-flex; align-items: center; gap: 5px; }

/* ---------- Skill table ---------- */
.skill-section { margin-bottom: 6px; }
.skill-head {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  background: var(--card2); padding: 9px 14px; border: 1px solid var(--border);
  border-radius: 8px; user-select: none;
}
.skill-head:hover { border-color: var(--accent-dim); }
.skill-head .aname { font-weight: 700; color: var(--accent); letter-spacing: 1px; }
.skill-body { padding: 4px 8px 10px; }
.skill-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 5px 8px; border-bottom: 1px dashed #232849;
}
.skill-row:hover { background: var(--rowhover); }
.skill-row .sname { flex: 1 1 220px; }
.skill-row .sname .tag { font-size: 11px; color: var(--blue); }
.skill-row.spec .sname { padding-left: 26px; font-style: italic; }
.skill-row.improved .sname::after { content: " ★"; color: var(--accent); }
.cost-hint { font-size: 11.5px; color: var(--muted); min-width: 72px; }

/* ---------- Tables ---------- */
table.list { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.list th {
  text-align: left; color: var(--muted); font-weight: 600; font-size: 12px;
  text-transform: uppercase; letter-spacing: .5px;
  border-bottom: 1px solid var(--border); padding: 6px 8px;
}
table.list td { padding: 6px 8px; border-bottom: 1px solid #20264a; vertical-align: top; }
table.list tr:hover td { background: var(--rowhover); }
table.list td.num, table.list th.num { text-align: right; white-space: nowrap; }
.table-scroll { overflow-x: auto; }

/* ---------- Force powers ---------- */
.power-row { display: flex; gap: 10px; align-items: flex-start; padding: 7px 8px; border-bottom: 1px dashed #232849; }
.power-row:hover { background: var(--rowhover); }
.power-row input { margin-top: 3px; }
.power-row .pname { font-weight: 600; }
.power-row .pmeta { font-size: 12px; color: var(--muted); }
.power-row.learned .pname { color: var(--accent); }
.power-row .dark { color: var(--red); }

/* ---------- Sub-tabs (weapons) ---------- */
.subtabs { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.subtabs button.active { background: var(--accent); color: #14140a; font-weight: 700; }

/* ---------- character portrait ---------- */
.portrait-drop {
  width: 190px; height: 235px; flex: 0 0 190px;
  border: 2px dashed var(--border); border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; cursor: pointer; background: var(--inset);
  transition: border-color .15s;
}
.portrait-drop:hover { border-color: var(--accent-dim); }
.portrait-drop img { width: 100%; height: 100%; object-fit: contain; }
.portrait-empty { color: var(--muted); font-size: 12.5px; }
.filebtn {
  display: inline-block; background: var(--card2); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 7px 12px; cursor: pointer; font-size: 13px;
  text-transform: none; letter-spacing: 0; margin: 0;
}
.filebtn:hover { background: var(--hover); border-color: #3d4677; }

/* ---------- online modal ---------- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(5, 7, 15, .75);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 16px; overflow-y: auto;
}
.modal-overlay.hidden { display: none; }
.modal-box {
  background: var(--card); border: 1px solid var(--accent-dim);
  border-radius: 12px; padding: 18px 22px; width: 100%; max-width: 560px;
  box-shadow: 0 12px 40px rgba(0,0,0,.7);
}
/* User administration has a wide table - more room, and scrollable. */
.modal-box.admin-box { max-width: 820px; max-height: 90vh; overflow-y: auto; }
.modal-head { display: flex; justify-content: space-between; align-items: center;
  border-bottom: 1px solid var(--border); padding-bottom: 8px; margin-bottom: 10px; }
.modal-head h2 { margin: 0; font-size: 16px; color: var(--accent); letter-spacing: 1px; text-transform: uppercase; }
.modal-box label { margin-top: 10px; }
.modal-box input[type=text], .modal-box input[type=password] { width: 100%; }
.modal-box h3 { margin: 16px 0 6px; font-size: 13px; color: var(--blue); letter-spacing: 1px; text-transform: uppercase; }
.modal-msg {
  background: var(--rowhover); border: 1px solid var(--accent-dim); border-radius: 6px;
  padding: 7px 10px; font-size: 13px;
}
.qr-wrap { background: #fff; border-radius: 8px; padding: 8px; display: inline-block; }
.qr-wrap svg { display: block; }
.mono-secret {
  font-family: Consolas, monospace; font-size: 14px; letter-spacing: 1px;
  background: var(--inset); border: 1px solid var(--border); border-radius: 6px;
  padding: 8px 10px; word-break: break-all; user-select: all;
}
.share-row { background: var(--rowhover); font-size: 13px; }
.share-row .badge a { color: var(--red); text-decoration: none; margin-left: 3px; }
.nowrap { white-space: nowrap; }
#btnOnline { display: none; }

/* a game round's invite code */
.rcode { font-family: monospace; font-size: 16px; letter-spacing: 2px;
  background: var(--rowhover); padding: 2px 8px; border-radius: 4px; color: var(--accent); }

/* Approval note on the character sheet (the GM has approved the character
   for the round). In the accent colour on screen, discreetly framed in
   print. */
.round-stamps { display: flex; flex-wrap: wrap; gap: 4px; margin: 2mm 0; }
.round-stamp { display: inline-block; font-size: 8.5pt; font-weight: 600;
  color: var(--accent); border: 1px solid var(--accent-dim);
  border-radius: 4px; padding: 1px 8px; }
@media print {
  .round-stamp { color: #000; border-color: #000; }
}

/* ---------- legal notice / privacy policy ---------- */
.legal-doc { max-width: 720px; }
.legal-doc h3 { margin: 4px 0 10px; font-size: 17px; color: var(--accent);
  letter-spacing: .5px; text-transform: none; }
.legal-doc h4 { margin: 16px 0 4px; font-size: 13.5px; color: var(--blue);
  letter-spacing: .3px; text-transform: none; }
.legal-doc p { margin: 6px 0; font-size: 13.5px; line-height: 1.55; }
#legalSetBox input { width: 100%; }
#legalSetBox textarea { width: 100%; }

/* ---------- about + the Star Wars crawl ---------- */
#optionsMenu .opt-btn { width: 100%; margin-top: 6px; text-align: left; }
.about-box { max-width: 760px; }
.sw-crawl {
  position: relative;
  height: 460px;
  margin: 8px 0 12px;
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border);
  border-radius: 8px;
  /* A shallower perspective = the text shrinks less and stays readable */
  perspective: 420px;
}
.sw-crawl::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 34%;
  background: linear-gradient(#000 2%, transparent);
  z-index: 3; pointer-events: none;
}
.sw-crawl-content {
  position: absolute;
  top: 100%;
  left: 5%; right: 5%;
  transform-origin: 50% 100%;
  color: #ffe81f;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 20px;
  font-weight: bold;
  line-height: 1.55;
  text-align: justify;
  animation: sw-crawl 52s linear infinite;
}
.sw-crawl-content .sw-title {
  text-align: center;
  font-size: 30px;
  letter-spacing: 2px;
  margin-bottom: 24px;
  text-shadow: 0 0 14px rgba(255, 232, 31, .5);
}
.sw-crawl-content p { margin: 0 0 20px; }
@keyframes sw-crawl {
  0%   { top: 100%; transform: rotateX(22deg) translateZ(0); opacity: 1; }
  92%  { opacity: 1; }
  100% { top: -330%; transform: rotateX(26deg) translateZ(-460px); opacity: 0; }
}
/* Narrow screens: a flatter perspective and more text width, or the type
   turns unreadable in the small frame and the title wraps */
@media (max-width: 620px) {
  /* On a phone, 20 pixels of margin on each side is 10 per cent of the
     width - width the cards then do not have. */
  :root { --page-pad: 10px; }

  /* The options menu hangs on the gear icon with position:absolute and
     right:0. When the button moves left on narrow screens, into the wrapped
     toolbar, right:0 pushes the 270-pixel card out of view - on an iPhone
     62 pixels of it stood off to the left. So on narrow screens it is
     aligned to the WINDOW instead of to the button. */
  #optionsMenu {
    position: fixed; left: 8px; right: 8px; top: 8px;
    min-width: 0; max-width: none; width: auto;
    max-height: calc(100vh - 16px);
  }

  .sw-crawl { height: 380px; perspective: 700px; }
  .sw-crawl-content {
    left: 3%; right: 3%;
    font-size: 15px; line-height: 1.5;
    text-align: left;
  }
  .sw-crawl-content .sw-title { font-size: 19px; letter-spacing: .5px; margin-bottom: 16px; }
  .sw-crawl-content p { margin: 0 0 14px; }
}
.about-info p { margin: 5px 0; font-size: 13.5px; }
.about-info a { color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .sw-crawl-content { animation-duration: 100s; }
}

/* ---------- footer ---------- */
/* The Groupfinder badge above the footer. The SVG deliberately lives LOCALLY
   in the project and is not loaded from groupfinder.gg - otherwise their
   server would see every visitor's IP without anyone being asked. */
.gf-badge { padding: 18px 0 4px; text-align: center; }
.gf-badge a { display: inline-block; opacity: .72; transition: opacity .15s; }
.gf-badge a:hover { opacity: 1; }
.gf-badge img { display: block; border: 0; }

footer { padding: 14px 20px 26px; color: #565d85; font-size: 11.5px; text-align: center; }
footer a { color: var(--accent-dim); text-decoration: none; }
footer a:hover { color: var(--accent); text-decoration: underline; }

/* =============================================================
   CHARACTER SHEET (on-screen preview + print)
   ============================================================= */
#sheet-print { display: none; }
.sheet-page {
  background: #fff; color: #111;
  width: 210mm; min-height: 285mm;
  margin: 0 auto 18px; padding: 10mm 11mm;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 10.2pt; line-height: 1.25;
  box-shadow: 0 4px 24px rgba(0,0,0,.6);
  position: relative;
}
.sheet-page * { color: #111; }
.sp-header { text-align: center; border-bottom: 3px double #111; padding-bottom: 4px; margin-bottom: 8px; }
.sp-header .sw { font-size: 21pt; font-weight: 900; letter-spacing: 5px; font-family: "Arial Black", Arial, sans-serif; }
.sp-header .st { font-size: 9pt; letter-spacing: 3px; text-transform: uppercase; }
.sp-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 4px 10px; }
.sp-field { border-bottom: 1px solid #111; padding: 1px 2px 0; min-height: 15pt; }
.sp-field .lbl { font-size: 6.6pt; text-transform: uppercase; letter-spacing: .6px; color: #444 !important; display: block; }
.sp-field .val { font-size: 10pt; font-weight: 600; min-height: 12px; display: block; }
.sp-box { border: 1.6px solid #111; border-radius: 4px; padding: 5px 7px; margin-top: 7px; }
.sp-box h4 {
  margin: -5px -7px 5px; padding: 3px 7px;
  background: #111; color: #fff !important; font-size: 8.6pt;
  letter-spacing: 1.6px; text-transform: uppercase; font-family: Arial, sans-serif;
  border-radius: 2px 2px 0 0;
}
.sp-cols3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 7px; align-items: start; }
.sp-cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; align-items: start; }
.sp-attr { margin-bottom: 4px; }
.sp-attr .ah {
  display: flex; justify-content: space-between; font-weight: 900;
  font-family: Arial, sans-serif; font-size: 9.5pt; text-transform: uppercase;
  border-bottom: 1.5px solid #111; margin-bottom: 2px;
}
.sp-skill { display: flex; justify-content: space-between; font-size: 8.8pt; padding: .5px 0 .5px 6px; }
.sp-skill.spec { padding-left: 14px; font-style: italic; }
.sp-skill .d { font-family: Consolas, monospace; }
table.sp-table { width: 100%; border-collapse: collapse; font-size: 8.6pt; }
table.sp-table th { border-bottom: 1.2px solid #111; text-align: left; font-family: Arial, sans-serif; font-size: 7.4pt; text-transform: uppercase; padding: 1px 3px; }
table.sp-table td { border-bottom: .6px solid #999; padding: 1.5px 3px; vertical-align: top; }
table.sp-table td.num { text-align: right; white-space: nowrap; }
.sp-lines { min-height: 34pt; font-size: 9pt; white-space: pre-wrap; }
.sp-stat { text-align: center; }
.sp-stat .big { font-size: 13pt; font-weight: 900; font-family: Consolas, monospace; border: 1.4px solid #111; border-radius: 4px; padding: 2px 6px; display: inline-block; min-width: 48px; }
.sp-stat .lbl { font-size: 6.8pt; text-transform: uppercase; display: block; margin-top: 1px; }
.sp-footer { position: absolute; bottom: 5mm; left: 11mm; right: 11mm; font-size: 7pt; color: #666 !important; display: flex; justify-content: space-between; }
.sp-portrait {
  flex: 0 0 32mm; min-height: 40mm; max-height: 52mm;
  border: 1.6px solid #111; border-radius: 4px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.sp-portrait img { max-width: 100%; max-height: 52mm; object-fit: contain; }
.sp-portrait span { font-size: 6.6pt; color: #999 !important; text-transform: uppercase; letter-spacing: 1px; }

/* The sheet is an A4 page and therefore 210 mm wide - on screen that is
   roughly 794 pixels. On a phone the screen is half that. So the sheet not
   only failed to fit, it stretched the whole page to its own width: the
   browser then zoomed the entire interface out, and header, tabs and forms
   went tiny.

   Rather than rebuild the sheet, it is scaled down. That is the right answer
   here, because it is a print preview - it should look like the paper that
   comes out of the printer afterwards, only smaller. Unlike transform, zoom
   also shrinks the space the element takes up; no empty strip is left below
   it, and multi-page sheets go on stacking neatly.

   The factor needs no JavaScript: atan2 turns two lengths into an angle, and
   tan turns that back into their ratio - the available width divided by
   210 mm. min(1, ...) makes sure a sheet that fits anyway stays at full
   size. */
@media (max-width: 860px) {
  .sheet-page {
    zoom: min(1, tan(atan2(calc(100vw - 2 * var(--page-pad) - 2px), 210mm)));
  }
}

/* ---------- print ---------- */
@media print {
  @page { size: A4 portrait; margin: 0; }
  body { background: #fff; }
  .no-print, #topbar, #tabs, main, footer { display: none !important; }
  #sheet-print { display: block; }
  .sheet-page {
    box-shadow: none; margin: 0; width: 210mm; min-height: 0;
    page-break-after: always; padding: 9mm 11mm;
    /* Printing from a phone, the browser reports a narrow page width and
       the rule above would apply - the printout would then come out half
       size. On paper, A4 is always A4. */
    zoom: 1;
  }
  .sheet-page:last-child { page-break-after: auto; }
}

/* ---------- support / ticket system ---------- */
.tk-thread { display: flex; flex-direction: column; gap: 10px; margin: 8px 0; }
.tk-msg { background: var(--card2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
.tk-msg.tk-admin { border-color: var(--accent-dim); }
.tk-meta { font-size: 12px; margin-bottom: 4px; }
.tk-text { line-height: 1.45; }
.tk-img { max-width: 100%; max-height: 320px; margin-top: 6px; border-radius: 6px; border: 1px solid var(--border); display: block; }
/* Badge for unread tickets: a red number on the cloud button and in the
   ticket list. Red rather than gold, so it stands apart from the interface's
   usual accent. */
.notify-badge {
  display: inline-block; min-width: 17px; padding: 0 5px; margin-left: 4px;
  background: #d33; color: #fff; border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 17px; text-align: center;
  vertical-align: middle;
}
.tk-unread td { font-weight: 600; }

/* ---------- dice page ---------- */
.roll-pools { display: flex; flex-wrap: wrap; gap: 6px; }
.roll-pool { background: var(--card2); border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 10px; font-size: 13px; cursor: pointer; }
.roll-pool:hover { border-color: var(--accent-dim); }
.roll-pool b { color: var(--accent); margin-left: 4px; }
.roll-head { color: var(--muted); font-size: 13px; }
.roll-total { font-size: 44px; font-weight: 900; color: var(--accent); line-height: 1.1; }
.roll-dice { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin: 6px 0; }
.roll-dice .die { display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 6px; background: var(--inset);
  border: 1px solid var(--border); font-weight: 700; }
.roll-dice .die.six { border-color: var(--green); color: var(--green); }
.roll-dice .die.one { border-color: var(--red); color: var(--red); }
.roll-dice .die.wild { border-width: 2px; border-color: var(--accent); }
.roll-dice .pips { color: var(--muted); }
.roll-warn { color: var(--red); font-weight: 600; margin: 6px 0; }

/* ---------- NPC group generator: compact cards ---------- */
/* Fleet composition in the NPC ship generator: one row per class holding the
   count, the "identical" flag and the number of templates available. No
   colour scheme of its own - the fields inherit accent colour and row height
   from the other options. */
.npc-fleet { grid-column: 1 / -1; }
.npc-fleet-rows { display: flex; flex-direction: column; gap: 6px; padding: 6px 0 2px; }
.npc-fleet-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.npc-fleet-name { min-width: 9em; font-weight: bold; }
.npc-fleet-row input[type="number"] { width: 5em; }
.npc-fleet-avail { color: var(--muted); font-size: 12px; }
.npc-size-opt { display: inline-flex; align-items: center; gap: 6px; font-weight: normal; cursor: pointer; }
.npc-size-opt input { width: auto; margin: 0; accent-color: var(--accent); }
.npc-fleet-row input:disabled, .npc-fleet-row input:disabled + span { opacity: .45; cursor: not-allowed; }

.npc-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 10px; margin-top: 14px;
}
.npc-card {
  background: var(--card2); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px; font-size: 13px; line-height: 1.4;
}
.npc-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin-bottom: 4px; }
.npc-name { font-weight: 700; color: var(--accent); font-size: 15px; }
.npc-name-in {
  font-weight: 700; font-size: 14px; width: 44%; min-width: 120px;
  background: var(--card); border: 1px solid var(--border); color: var(--text);
  border-radius: 4px; padding: 1px 5px;
}
.npc-sub { color: var(--muted); font-size: 12px; }
.npc-actions { margin-left: auto; white-space: nowrap; }
.npc-attrs { display: flex; flex-wrap: wrap; gap: 4px 8px; margin: 4px 0; }
.npc-attr {
  font-size: 12px; background: var(--card); border: 1px solid var(--border);
  border-radius: 4px; padding: 0 6px; white-space: nowrap;
}
.npc-attr b { color: var(--muted); font-weight: 600; margin-right: 2px; }
.npc-line { margin: 2px 0; }
.npc-line b { color: var(--muted); font-weight: 600; }
.npc-sheet-title { font-weight: 700; margin: 2mm 0 3mm; font-size: 12pt; }

/* On the printed sheet: denser, multi-column, black on white */
.npc-grid.print { grid-template-columns: repeat(2, 1fr); gap: 4mm; margin-top: 3mm; }
.npc-sheet .npc-card { background: #fff; border: 1px solid #000; font-size: 8.6pt; break-inside: avoid; }
.npc-sheet .npc-name { color: #000; font-size: 9.6pt; }
.npc-sheet .npc-attr { background: #fff; border-color: #999; }
.npc-sheet .npc-attr b, .npc-sheet .npc-sub, .npc-sheet .npc-line b { color: #333; }

/* ---------- workshop: mishap result (ship page) ---------- */
.ws-result {
  margin-top: 14px; padding: 12px 14px;
  background: var(--card2); border: 1px solid var(--border);
  border-left-width: 4px; border-radius: 6px;
}
.ws-result p { margin: 8px 0 0; line-height: 1.5; }
.ws-result-head {
  display: flex; flex-wrap: wrap; gap: 16px;
  font-size: 12.5px; color: var(--muted); letter-spacing: 1px; text-transform: uppercase;
}
.ws-result-head b { color: var(--text); font-family: Consolas, monospace; font-size: 14px; }
.ws-minor        { border-left-color: var(--green); }
.ws-moderate     { border-left-color: var(--accent); }
.ws-catastrophic { border-left-color: var(--red); }

/* Left alone, select lists with very long entries (the ship and weapon
   catalogues) grow as wide as their longest entry - they then burst out of
   their space and push the button beside them underneath. */
#tplSelect, #wpnSelect, #tplEra, #wpnScale {
  width: 100%;
  max-width: 100%;
}

/* An explanatory box in the modifications - not an error but a note about
   a case the rules do not cover. */
.hint.warnbox {
  margin-top: 10px; padding: 10px 12px;
  background: var(--card2); border: 1px solid var(--border);
  border-left: 4px solid var(--accent); border-radius: 6px;
  line-height: 1.5;
}
/* Highlight worn armor, so what counts is clear at a glance. */
table.list tr.worn > td { background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* ---------- the table-top (mini VTT) ---------- */
.vtt-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 14px; align-items: start; }
.vtt-side { display: flex; flex-direction: column; gap: 14px; }
.vtt-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.vtt-bar-spacer { flex: 1; }
.vtt-mapname { font-weight: 600; color: var(--accent); }
#vttStatus.neg { color: var(--red); }

/* The stage keeps the map's own proportions: the picture sets the height,
   the tokens sit on top of it in per-cent coordinates. Any other approach
   needs the natural size in JavaScript before it can place anything. */
.vtt-stage {
  position: relative; width: 100%; background: var(--inset);
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  min-height: 220px; touch-action: none; user-select: none;
}
.vtt-stage img#mapImg { display: block; width: 100%; height: auto; }
.vtt-grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.18) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.18) 1px, transparent 1px);
}

/* The fog canvas holds one pixel per cell and is stretched over the map by
   CSS. image-rendering keeps the cell edges crisp instead of smearing the
   mask into a soft cloud - a wall should end where the wall ends.
   It never takes pointer events: while the GM paints, the stage itself
   handles the brush, so a stroke may start on top of a token. */
.vtt-fog {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; image-rendering: pixelated;
}
.vtt-stage.painting { cursor: crosshair; }
.vtt-stage.painting .vtt-token { pointer-events: none; }
.fog-modes { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.fog-modes .opt-row { text-transform: none; }

/* A token is placed by its CENTRE, hence the translate - otherwise it would
   hang below and to the right of the spot you dropped it on. */
.vtt-token {
  position: absolute; transform: translate(-50%, -50%);
  width: calc(38px * var(--tok-size, 1)); height: calc(38px * var(--tok-size, 1));
  border-radius: 50%; border: 2px solid var(--accent);
  background: var(--card2); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #10121f;
  box-shadow: 0 2px 6px rgba(0,0,0,.5); cursor: default;
}
.vtt-token img { width: 100%; height: 100%; object-fit: cover; }
.vtt-token.mine { cursor: grab; }
.vtt-token.drag { cursor: grabbing; box-shadow: 0 0 0 3px var(--accent), 0 4px 12px rgba(0,0,0,.6); }
/* Ships and droids get a different outline, so a glance at the map tells
   you what is standing there even on the default tokens. */
.vtt-token.kind-ship { border-radius: 6px; }
.vtt-token.kind-droid { border-style: dashed; }
.vtt-token.kind-npc { border-color: var(--muted); }

.au-now { margin: 8px 0; color: var(--accent); font-size: 13px; }
/* The YouTube player stays visible on purpose: their terms require the
   embedded player not to be hidden or covered. Small and out of the way is
   allowed, invisible is not - so it sits here at the size YouTube asks for
   rather than being tucked away with display:none. */
.au-yt { margin: 8px 0; }
.au-yt iframe { border: 0; border-radius: 6px; display: block; }
#auEl { width: 100%; margin-top: 6px; }

.vtt-log { max-height: 320px; overflow-y: auto; }
.vtt-log-row { padding: 3px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.vtt-log-row b { color: var(--accent); }

/* On a phone the map takes the whole width and the controls go underneath -
   side by side there would leave neither of them usable. */
@media (max-width: 900px) {
  .vtt-layout { grid-template-columns: minmax(0, 1fr); }
  .vtt-side { order: 2; }
  .vtt-token { width: calc(30px * var(--tok-size, 1)); height: calc(30px * var(--tok-size, 1)); }
}
