/* ==========================================================================
   CARD FORGE :: the card database

   Cards mode shows the cards themselves, drawn by the real renderer into a tile
   and scaled to fit, so the database cannot show something the card would not.
   Table mode shows the same records as data. Both open the editor on click.
   ========================================================================== */

.cards-page {
  position: relative;
  z-index: 1;
  margin: 16px clamp(10px, 2.5vw, 28px) 48px;
}

.cards-head {
  --chamfer: 11px;
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  padding: 10px 16px;
  flex-wrap: wrap;
}
.cards-head h2 {
  margin-right: 2px;
}
.cards-status {
  margin-right: auto;
}

/* the page's own actions live on the second bar, right-aligned */
.cards-head__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex-wrap: wrap;
}

/* the card filter */
.card-filter {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  background: var(--ink-900);
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--text-faint);
}
.card-filter:focus-within {
  border-color: var(--amber-dim);
  color: var(--amber);
}
.card-filter input {
  width: 160px;
  font-family: var(--font);
  font-size: 0.68rem;
  color: var(--text);
  background: transparent;
  border: 0;
  outline: none;
}
.card-filter input::placeholder {
  color: var(--text-faint);
}
.card-filter input::-webkit-search-cancel-button {
  filter: invert(0.6);
  cursor: pointer;
}

/* the display size of a card, in pixels; the default is a Euro-mini card */
.card-size {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.card-size input[type='range'] {
  width: 150px;
  height: 4px;
  appearance: none;
  background: var(--line);
  border-radius: 2px;
  cursor: pointer;
}
.card-size input[type='range']::-webkit-slider-thumb {
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--amber);
  border: 2px solid var(--ink-900);
  cursor: grab;
}
.card-size input[type='range']::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--amber);
  border: 2px solid var(--ink-900);
  cursor: grab;
}
.card-size__out {
  min-width: 108px;
  font-family: var(--font);
  font-size: 0.6rem;
  color: var(--amber);
  text-align: right;
}
.cards-head h2 {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
}
.cards-status {
  margin: 0;
  font-size: 0.64rem;
  color: var(--text-faint);
}
.cards-status.is-ok {
  color: var(--green);
}
.cards-status.is-err {
  color: var(--red);
}

.cards-empty {
  margin: 0;
  padding: 30px;
  font-size: 0.72rem;
  color: var(--text-dim);
  background: var(--ink-800);
  border: 1px dashed var(--line);
  border-radius: 4px;
  text-align: center;
}

/* ------------------------------------------------------------- view toggle */

.view-toggle {
  display: inline-flex;
  padding: 2px;
  background: var(--ink-900);
  border: 1px solid var(--line);
  border-radius: 3px;
}
.view-toggle__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-family: var(--font);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: transparent;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.view-toggle__btn:hover {
  color: var(--text);
}
.view-toggle__btn[aria-pressed='true'] {
  color: var(--ink-900);
  background: var(--amber);
}

/* -------------------------------------------------------------- cards mode */

.cards-grid {
  display: grid;
  /* A fixed track, not a flexible one. The card is scaled to its host's width, and
     a flexible track lets that width grow to fit the card -- the next render then
     measures the bigger width and scales up again, so the card creeps larger with
     every edit. A fixed width makes the measurement stable. */
  grid-template-columns: repeat(auto-fill, var(--card-w, 166px));
  gap: 18px;
}

/* the card is the tile: no caption, no controls, nothing but the card */
/* No frame, no background, no padding: the card is the only thing in the tile,
   so the database shows the card and nothing else. */
.card-tile {
  position: relative;
  width: var(--card-w, 166px);
  /* a card is a physical thing here: pick it up and put it down elsewhere */
  cursor: grab;
  /* the card follows the pointer itself; the other tiles slide via animateReflow,
     so this element must not also animate its transform */
  touch-action: none;
}
.card-tile:active {
  cursor: grabbing;
}
/* the card in hand: lifted off the page, and still holding the slot it came from */
.card-tile.is-dragging {
  z-index: 5;
  cursor: grabbing;
  filter: drop-shadow(0 18px 26px rgba(0, 0, 0, 0.6));
}
/*
 * The phantom slot at the end of the list: what a new card would look like, at half
 * opacity, as an invitation rather than a thing. It is not in the data, so it cannot
 * be dragged, deleted, exported or picked up by a filter.
 */
.card-tile.is-phantom {
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.12s;
}
.card-tile.is-phantom:hover,
.card-tile.is-phantom:focus-visible {
  opacity: 0.8;
  outline: none;
}
.cards-table tr.is-phantom {
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.12s;
}
.cards-table tr.is-phantom:hover,
.cards-table tr.is-phantom:focus-visible {
  opacity: 0.8;
  outline: none;
}

/* The preview inside the phantom is inert: every element on a card is editable, and
   those handlers stop the click from reaching the tile. Without this, clicking the
   slot edits its own fake cost or name instead of making a card. */
.card-tile.is-phantom .card {
  pointer-events: none;
}

/* A card with no trigger shows the word "none", which is right for a real card and
   wrong for an invitation: the phantom leaves the slot blank. */
.card-tile.is-phantom .slot.trigger {
  visibility: hidden;
}

/* the card under the pointer does not need its own affordance: the dragged card's
   gap shows where it will land */

.card-tile:hover {
  transform: translateY(-2px);
}

.card-tile__stage {
  display: flex;
  justify-content: center;
  overflow: visible;
  width: 100%;
}
/* the renderer builds .card-fit / .card inside this host */
.card-tile__stage > div {
  width: 100%;
}

/* delete sits on the card's corner and only shows for the tile under the pointer */
.card-delete {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  font-size: 0.92rem;
  color: #fff;
  background: rgba(20, 18, 20, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 3px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s, background 0.12s, border-color 0.12s;
}
.card-tile:hover .card-delete,
.card-tile:focus-within .card-delete,
.card-delete:focus-visible {
  opacity: 1;
}
.card-delete:hover {
  background: var(--red);
  border-color: var(--red);
}

/* -------------------------------------------------------------- table mode */

.cards-table-wrap {
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}

.cards-table {
  width: 100%;
  border-collapse: collapse;
  /* larger type in a shorter row: the height comes from padding and the line box,
     not from the font size, so both are pulled in while the text goes up */
  font-size: 0.78rem;
  line-height: 1.3;
}
/* Every column but the text shrinks to fit its widest content, and the text column
   absorbs the rest.
   Percentages do not do this: under the default table layout they are only a hint,
   so the browser sizes by content and then spreads the leftover width across every
   column -- which is what left dead space in the name column. A width of 1% with
   no wrapping is the reliable way to say "as small as my content allows". */
.cards-table th:not(:nth-child(6)),
/*
 * Every column but the effect sizes to its content.
 *
 * `width: 1px` is the trick, not a typo: with `white-space: nowrap` and auto layout the
 * browser grows the column to fit its widest line and then stops, because the requested
 * width is smaller than anything it could honour. `1%` instead reads as a minimum, and
 * the spare width was then shared out by max-content -- which handed the Trigger column
 * several hundred pixels.
 */
.cards-table td:not(:nth-child(6)),
.cards-table th:not(:nth-child(6)) {
  width: 1px;
  white-space: nowrap;
}
.cards-table th:nth-child(6),
.cards-table td:nth-child(6) {
  /*
   * 100%, not auto. Every other column asks for 1%, and in a table with auto layout
   * those percentages are minimums -- the spare width is then shared out in proportion
   * to what each column *could* hold, which gave the Trigger column several hundred
   * pixels it had no use for. Asking this one for everything makes the rest shrink to
   * their content.
   */
  width: 100%;
  white-space: normal;
}

/* Shrinking to content made these two tight against their neighbours, so they get
   their own breathing space on top of the cell padding. */
.cards-table th:nth-child(1),
.cards-table td:nth-child(1) {
  padding-right: 26px;
}
.cards-table th:nth-child(4),
.cards-table td:nth-child(4) {
  padding-right: 26px;
}

.cards-table th {
  padding: 6px 10px;
  text-align: left;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber);
  background: var(--ink-800);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  vertical-align: middle;
}
.cards-table td {
  padding: 5px 10px;
  color: var(--text-dim);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.cards-table tbody tr {
  transition: background 0.1s;
}
.cards-table td[role='button'] {
  cursor: text;
  border-radius: 2px;
}
.cards-table td[role='button']:hover {
  background: rgba(251, 176, 64, 0.1);
  color: var(--text);
  box-shadow: inset 0 0 0 1px rgba(251, 176, 64, 0.4);
}
.cards-table td[role='button']:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: -2px;
}
.cards-table td.is-toggles {
  cursor: default;
  box-shadow: none !important;
  background: none !important;
}
.toggle-chip {
  display: inline-block;
  margin-right: 4px;
  padding: 2px 6px;
  font-family: var(--font);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--ink-900);
  border: 1px solid var(--line);
  border-radius: 2px;
  cursor: pointer;
}
.toggle-chip[data-state='on'] {
  color: var(--amber);
  border-color: var(--amber-dim);
  background: rgba(251, 176, 64, 0.1);
}
.toggle-chip:hover {
  border-color: var(--amber);
}
.cards-table tbody tr:last-child td {
  border-bottom: 0;
}
.cards-table tbody tr:hover,
.cards-table tbody tr:focus-visible {
  background: var(--ink-700);
  outline: none;
}
.cards-table tbody tr:hover td {
  color: var(--text);
}
/* the name reads as the identifier of the row */
.cards-table td:first-child {
  color: var(--text);
  font-weight: 700;
  white-space: nowrap;
}
.cards-table .is-text {
  /*
   * No cap. The other seven columns are pinned to 1% so they stay tight, and the table's
   * remaining width goes to whichever column can take it -- which was the effect cell
   * while it was capped, so the slack overflowed into the trigger column and pushed
   * everything out of place.
   */
  max-width: none;
  line-height: 1.6;
}
.cards-table .is-actions {
  width: 1%;
  padding: 4px 8px;
  text-align: right;
}
/* in a table the delete button has no card corner to sit on, so it is inline */
.cards-table .card-delete {
  position: static;
  opacity: 0;
}
.cards-table tbody tr:hover .card-delete,
.cards-table .card-delete:focus-visible {
  opacity: 1;
}

/* ------------------------------------------------- table cells, as on a card */

/* the name reads like the name plate's type */
.cards-table td.is-name {
  /*
   * The table's own font. Orbitron and Bungee are display faces: at 0.8rem, in a dense
   * column of names, they read as noise rather than as emphasis -- and every other cell
   * in the row is already the table's monospace.
   */
  font-family: var(--font);
  font-size: 0.8rem;
  font-weight: 600;
  /* the card's own name is plain light text; the faction is where colour belongs */
  color: var(--paper);
  letter-spacing: 0.02em;
}

/* cost and power use the same face as the numbers on the card */
.cards-table td.is-stat {
  /* the numbers are part of the row, not a display heading */
  font-family: var(--font);
  font-size: 1.1rem;
  color: #f3f3f4;
  text-align: center;
}

/* the physical switch */
.mini-toggle {
  display: inline-block;
  vertical-align: middle;
  width: 34px;
  height: 26px;
  margin-right: 2px;
  vertical-align: middle;
  padding: 0;
  background: center / 100% 100% no-repeat;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.95;
  transition: opacity 0.12s, transform 0.1s;
}
.mini-toggle:hover {
  opacity: 1;
  transform: translateY(-1px);
}
.mini-toggle[data-state='off'] {
  opacity: 0.5;
}

/* a keyword as its symbol and name -- the same shape the keyword menu uses */
.kw-summary {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--tag-color, var(--text));
  white-space: nowrap;
}
.kw-summary__glyph {
  display: grid;
  place-items: center;
  width: 17px;
  height: 17px;
  flex: none;
}
.kw-summary__glyph svg {
  height: 17px;
  width: auto;
  display: block;
}
.kw-summary__glyph i {
  font-size: 12px;
}

/* the card text with its real tags */
/* The body text is the thing you actually read in this table, so it is set larger
   than the surrounding cells and at full contrast rather than the muted cell
   colour. The tags follow it, and the row is still shorter than the toggles. */
.cards-table td.is-text {
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text);
  /* No pre-wrap here: the table is a list of records, so the effect reads as one
     run of text and any breaks typed for the card collapse to spaces. */
}

/* while a card is in hand, nothing on the page should be selectable */
body.is-dragging-card,
body.is-dragging-card * {
  user-select: none;
  -webkit-user-select: none;
}

/* the faction column: a name, or a quiet "none" */
.cards-table td.is-faction {
  color: var(--text);
  white-space: nowrap;
  cursor: pointer;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}
.cards-table td.is-faction.is-none {
  color: var(--text-dim);
  font-style: italic;
  text-transform: none;
  letter-spacing: 0;
}
.cards-table td.is-faction:hover {
  color: var(--amber-hi);
}

/* the faction column is a chip: mark and name side by side, never stacked */
.cards-table td.is-faction {
  white-space: nowrap;
  width: 1%;          /* shrink to the content, then let the table give it that */
}
.cards-table td.is-faction .faction-chip {
  white-space: nowrap;
}

/* ------------------------------------------------- the table's faction column

   The same relationship the forge's filter chips have: mark, then name, in one pill.
   Here rather than in forge.css because the card DB draws this table too, and does not
   load that stylesheet.
*/

.faction-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  padding: 3px 8px 3px 5px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.03);
}
.faction-chip__name {
  white-space: nowrap;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--paper);
}
