/* Classic SWG expertise window: dark panel, gold rules, chunky skill boxes. */
:root {
  --bg: #0a0c0f;
  --panel: #14181e;
  --panel-2: #1b212a;
  --edge: #2b3542;
  --gold: #d9b45b;
  --gold-dim: #8a7233;
  --text: #d7dee7;
  --muted: #7d8a9a;
  --ok: #5fb87a;
  --warn: #d9843b;
  --cell: 56px;
  --gap: 10px;
  --gate: 28px;      /* row-gate gutter */
  --summary-w: 260px;
  --pad: 16px;       /* panel inner padding */

  /* The grid has a natural width, so derive the window width from it rather
     than guessing: gate gutter + 7 cells + 7 gaps, then panel padding/border,
     the summary column, and the outer gutter. */
  --grid-w: calc(var(--gate) + (7 * var(--cell)) + (7 * var(--gap)));
  --app-w: calc(var(--grid-w) + (2 * var(--pad)) + 4px + var(--summary-w) + 16px + 36px);

  /* 5 rows + gaps + padding + the hint line. The summary is capped to this so a
     long modifier list scrolls instead of stretching the window past the tree. */
  --tree-h: calc((5 * var(--cell)) + (4 * var(--gap)) + (2 * var(--pad)) + 34px);
}

/* Centred fixed-width window, like the in-game expertise panel. */
.app {
  max-width: var(--app-w);
  margin: 0 auto;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: radial-gradient(1200px 600px at 50% -10%, #131a24 0%, var(--bg) 70%);
  color: var(--text);
  font: 14px/1.45 "Segoe UI", system-ui, sans-serif;
  min-height: 100vh;
}

/* ---- header ---- */
.chrome {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 12px 18px;
  background: linear-gradient(#1c232d, #11161d);
  border-bottom: 1px solid var(--gold-dim);
}
.chrome h1 {
  margin: 0; font-size: 17px; font-weight: 600;
  color: var(--gold); letter-spacing: .06em; text-transform: uppercase;
}
.controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

select, button {
  font: inherit; color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--edge); border-radius: 4px;
  padding: 6px 12px; cursor: pointer;
}
select:hover, button:hover { border-color: var(--gold-dim); }
select:focus-visible, button:focus-visible, .skill:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}
button { color: var(--gold); }
button.ghost { color: var(--muted); }

.pts {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 12px;
  background: var(--panel); border: 1px solid var(--edge); border-radius: 4px;
}
.pts-label { font-size: 11px; text-transform: uppercase; color: var(--muted); letter-spacing: .08em; }
#points { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--gold); }
#points.spent { color: var(--warn); }

/* ---- notices ---- */
.notice {
  margin: 8px 18px 0; padding: 8px 12px;
  border-radius: 4px; border: 1px solid var(--edge);
  background: var(--panel-2); font-size: 13px;
}
.notice.warn { border-color: var(--warn); color: #f0c08a; }
.notice.ok { border-color: var(--ok); color: #a9dcb8; }

/* ---- tabs ---- */
.tabs { display: flex; gap: 4px; padding: 12px 18px 0; flex-wrap: wrap; }
.tab {
  display: flex; align-items: center; gap: 8px;
  border-radius: 4px 4px 0 0; border-bottom: none;
  padding: 8px 16px; color: var(--muted);
}
.tab.active { background: var(--panel); color: var(--gold); border-color: var(--gold-dim); }
.tab-pts {
  min-width: 20px; padding: 1px 5px; border-radius: 8px;
  background: #0c1015; color: var(--text);
  font-size: 11px; font-variant-numeric: tabular-nums; text-align: center;
}

/* ---- layout ---- */
.layout {
  display: grid; grid-template-columns: minmax(0, 1fr) var(--summary-w);
  gap: 16px; align-items: start;
  padding: 0 18px 24px;
}
.tree, .summary {
  background: var(--panel);
  border: 1px solid var(--gold-dim);
  border-radius: 0 4px 4px 4px;
  padding: var(--pad);
}
.summary { border-radius: 4px; max-height: var(--tree-h); overflow-y: auto; }

/* ---- grid ---- */
/* align-items centres the fixed-width rows if the panel is ever wider. */
.grid { display: flex; flex-direction: column; gap: var(--gap); align-items: center; }
.row {
  display: grid;
  grid-template-columns: var(--gate) repeat(7, var(--cell));
  gap: var(--gap); align-items: center;
}
.row.locked { opacity: .82; }
.row-gate {
  font-size: 10px; color: var(--muted); text-align: right;
  font-variant-numeric: tabular-nums; cursor: help;
}
.row.locked .row-gate { color: var(--gold-dim); }

.cell { width: var(--cell); height: var(--cell); }
.cell.empty { visibility: hidden; }

.skill {
  position: relative; display: grid; place-items: center;
  background: #0c1015;
  border: 2px solid #333d4b; border-radius: 3px;
  cursor: pointer; transition: border-color .12s, transform .06s, filter .12s;
}
.skill img { width: 40px; height: 40px; image-rendering: auto; }
.skill img.noicon { visibility: hidden; }
.skill:active { transform: scale(.95); }

/* The art already carries the state: i<Name>.gif is the desaturated "untrained"
   version, a<Name>.gif the lit one. Filtering on top of that turns the icons to
   mud, so state is shown with the border and a light dim only. */
.skill.locked { border-color: #262e39; cursor: not-allowed; opacity: .45; }
.skill.available { border-color: var(--gold-dim); opacity: .9; }
.skill.available:hover { border-color: var(--gold); opacity: 1; }
.skill.trained {
  border-color: var(--gold);
  box-shadow: 0 0 8px rgba(217, 180, 91, .35), inset 0 0 12px rgba(217, 180, 91, .12);
}

.rank {
  position: absolute; right: -3px; bottom: -6px;
  padding: 0 4px; border-radius: 3px;
  background: #05070a; border: 1px solid var(--edge);
  font-size: 10px; font-variant-numeric: tabular-nums; color: var(--muted);
}
.skill.trained .rank { color: var(--gold); border-color: var(--gold-dim); }

/* Prereq indicator: a short tick rising toward the required skill above. */
.link-up {
  position: absolute; top: calc(-1 * var(--gap) - 2px); left: 50%;
  width: 2px; height: var(--gap); margin-left: -1px;
  background: var(--gold-dim);
}
.skill.trained .link-up { background: var(--gold); }

.hint { margin: 14px 0 0; color: var(--muted); font-size: 12px; }

/* ---- summary ---- */
.summary h3 {
  margin: 0 0 8px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold); border-bottom: 1px solid var(--edge); padding-bottom: 5px;
}
.summary h3:not(:first-child) { margin-top: 16px; }
.summary ul { list-style: none; margin: 0; padding: 0; }
.mods li {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 3px 0; font-size: 13px;
}
.mods b { color: var(--gold); font-variant-numeric: tabular-nums; }
.abils li { padding: 4px 0; font-size: 13px; cursor: help; }
.abils em { display: block; color: var(--muted); font-size: 11px; font-style: normal; }
.muted { color: var(--muted); font-size: 13px; margin: 0; }

/* ---- tooltip ---- */
.tip {
  position: fixed; top: 0; left: 0; z-index: 50;
  width: 280px; padding: 12px;
  background: #060809f2; border: 1px solid var(--gold-dim); border-radius: 4px;
  box-shadow: 0 8px 28px #000a; pointer-events: none;
  backdrop-filter: blur(2px);
}
.tip h4 { margin: 0; color: var(--gold); font-size: 14px; }
.tip p { margin: 6px 0; font-size: 12px; color: #b9c4d1; }
.t-rank { font-size: 11px; color: var(--muted); }
.t-mod { display: flex; gap: 6px; align-items: baseline; font-size: 12px; padding: 2px 0; }
.t-mod span { flex: 1; color: var(--muted); }
.t-mod b { color: var(--gold); }
.t-mod i { color: var(--ok); font-style: normal; }
.t-ability { font-size: 12px; color: var(--ok); padding: 3px 0; }
.t-ability span { display: block; color: var(--muted); font-size: 11px; }
.t-block { margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--edge); color: var(--warn); font-size: 11px; }

/* ---- overlay / embed mode ---- */
body.embed {
  background: #0a0c0fea;
  --cell: 46px;
  --gap: 7px;
  /* --grid-w must be REDECLARED here, not just inherited: a custom property's
     var() references resolve against the element it is declared on, so the
     :root copy would keep using the 56px desktop cell and overshoot the width. */
  --grid-w: calc(var(--gate) + (7 * var(--cell)) + (7 * var(--gap)));
}
/* No summary column in embed, so the window is the grid plus its gutters. */
body.embed .app { max-width: calc(var(--grid-w) + (2 * var(--pad)) + 24px); }
body.embed .chrome { padding: 8px 10px; }

/* The narrow embed window can't fit the full-size controls on one row, and a
   wrapped Reset button eats vertical space the overlay doesn't have. */
body.embed .controls { gap: 6px; width: 100%; flex-wrap: nowrap; }
body.embed select { flex: 1; min-width: 0; padding: 5px 6px; }
body.embed .pts { padding: 4px 8px; }
body.embed .pts-label { display: none; }
body.embed button { padding: 5px 9px; }
body.embed .chrome h1 { display: none; }
body.embed .tabs { padding: 8px 10px 0; }
body.embed .layout { grid-template-columns: minmax(0, 1fr); padding: 0 10px 10px; gap: 10px; }
body.embed .summary { max-height: 190px; overflow-y: auto; }
body.embed .hint { display: none; }

/* ---- transparent mode (?bg=none) ----
   Lets an embedding page paint the background. Declared last so it wins over
   the body/embed background rules regardless of source order. The .tree and
   .summary panels keep their own fills, so only the gutter goes clear. */
body.bg-none,
body.bg-none.embed { background: transparent; }

/* ---- responsive ---- */
@media (max-width: 900px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .tree { overflow-x: auto; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
