/*
  /hunts — the bestiary, as a table you can sort and sift.

  Loaded *after* style.css and on top of `body.doc`, which is the long-copy shell
  the privacy policy and support pages use: left-aligned, regular weight, 20px
  Pixel Operator. Everything here either widens that shell to fit a twelve-column
  table or dresses the controls above it.

  The palette is the app's (`PixelKit.swift`) rather than a second one invented for
  the web: parchment, ink, and the six secondary colours the trait dots borrow.
*/

/* The UA stylesheet's `[hidden] { display: none }` loses to any rule here that
   sets `display` on the same element — which is how the gallery, a `display:
   grid`, went on showing its forty-seven cards *under* the table after a switch
   back to it. Everything the page hides is hidden by this attribute, so the
   attribute has to win. */
[hidden] { display: none !important; }

:root {
  --parchment-deep: #e7dcc2;
  --accent: #bc462f;
  --rule: rgba(42, 38, 34, 0.18);

  /* One colour per monster trait, so forty-seven rows can be scanned by eye
     rather than read. These are `PixelKit`'s secondary set, used here for the
     only job the app does not have for them. */
  --t-undead: #a070a8;
  --t-mortal: #bc462f;
  --t-spirit: #008ea5;
  --t-beast: #7fb061;
  --t-wyrm: #f5a100;
  --t-giant: #e8721a;
}

/* Twelve columns come to about 1,170px, so this page gets a wider measure than
   the 680px of prose the other documents use. The copy above it keeps its own,
   or a paragraph would set eighty words to a line. */
body.hunts {
  max-width: 1240px;
}
body.hunts > p,
body.hunts > h2 + p,
body.hunts .lede {
  max-width: 680px;
}

body.hunts h2 {
  margin-top: 56px;
}

/* ---------------------------------------------------------------------------
   The controls — a row sitting on top of the table, not a panel beside it
   --------------------------------------------------------------------------- */

/* No border, no fill, and the same width as the table it governs: these *are*
   the table's current state, and a box around them makes them read as a form you
   fill in before going to look at something else. They end where the table's top
   rule begins, which is the whole of the relationship. */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 40px 0 12px;
}
.resultbar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}
.resultbar .views {
  display: flex;
  gap: 8px;
  flex: none;
}

.controls input[type="search"] {
  flex: 1 1 260px;
  min-width: 0;
  font: inherit;
  font-weight: 400;
  color: var(--ink);
  background: #fff;
  border: 4px solid var(--line);
  padding: 8px 12px 6px;
  -webkit-appearance: none;
  appearance: none;
  border-radius: 0;
}
.controls input[type="search"]::placeholder { color: var(--muted); }

.controls select {
  font: inherit;
  font-weight: 400;
  color: var(--ink);
  background: #fff;
  border: 4px solid var(--rule);
  padding: 8px 10px 6px;
  border-radius: 0;
  max-width: 100%;
}
.controls select:hover { border-color: var(--line); }
/* A dropdown that is filtering something has to look different from one that is
   not, or a reader who forgot they had Dread selected is reading a table that is
   quietly lying to them. */
.controls select.on {
  font-weight: 700;
  border-color: var(--line);
  background: var(--parchment-deep);
}

/* The view switch, and the only pair of buttons on the page: it is not a filter,
   it is which of two drawings of the same rows you are looking at, and two states
   worth one tap each should not be a dropdown. */
.chip {
  font: inherit;
  font-weight: 400;
  color: var(--ink);
  background: transparent;
  border: 4px solid var(--rule);
  padding: 4px 12px 2px;
  cursor: pointer;
  border-radius: 0;
}
.chip:hover { border-color: var(--line); }
.chip[aria-pressed="true"] {
  font-weight: 700;
  border-color: var(--line);
  background: var(--parchment-deep);
}

.dot {
  width: 14px;
  height: 14px;
  background: var(--dot, var(--muted));
  flex: none;
}
/* The dots are on the rows and the cards. They are deliberately not in the trait
   dropdown: an <option> cannot carry a swatch that renders the same way twice
   across browsers, and a filter that looks different from the thing it filters
   is worse than one with no colour in it at all. */
.t-undead { --dot: var(--t-undead); }
.t-mortal { --dot: var(--t-mortal); }
.t-spirit { --dot: var(--t-spirit); }
.t-beast  { --dot: var(--t-beast); }
.t-wyrm   { --dot: var(--t-wyrm); }
.t-giant  { --dot: var(--t-giant); }

/* Off-screen but readable: the sprite column's heading, which has nothing to
   draw and still has to have a name. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.count {
  color: var(--muted);
  font-weight: 400;
  margin: 0;
}
.count b { color: var(--ink); }

/* The lock toggle, set inside the sentence it changes rather than standing as a
   control of its own — it has nothing to do until a squad level is picked. */
.linky {
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   The table
   --------------------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
  border-top: 4px solid var(--line);
  border-bottom: 4px solid var(--line);
}

/* Once the table fits, the wrapper stops being a scroll container — which is
   the only way the sticky header can stick to the *page* rather than to a
   scrollport that scrolls away with it. Narrower than this the header goes with
   the rows, which is the price of not cutting a column off. */
@media (min-width: 1300px) {
  .table-wrap { overflow-x: visible; }
}

table.hunts {
  width: 100%;
  /* Below this the columns start squeezing into each other and the wrapper
     scrolls instead, which is the better of the two bad options. */
  min-width: 1020px;
  border-collapse: collapse;
  font-weight: 400;
  line-height: 1.3;
}

table.hunts th {
  text-align: left;
  font-weight: 700;
  white-space: nowrap;
  padding: 0;
  border-bottom: 4px solid var(--line);
  background: var(--parchment);
  position: sticky;
  top: 0;
  z-index: 1;
}

/* The header is a button so it is reachable from the keyboard and announces its
   own sort state; it fills the cell so the whole heading is the target. */
table.hunts th button {
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  background: none;
  border: 0;
  padding: 12px 8px 10px;
  width: 100%;
  text-align: inherit;
  cursor: pointer;
  white-space: nowrap;
}
/* The sort mark is drawn rather than set. Pixel Operator has no arrow glyph, so
   a `\2191` would fall out of the page's one typeface into whatever the system
   has — and a solid triangle is closer to the game's language than an arrow is
   anyway. The space is reserved on every heading so that sorting a column does
   not shove the ones beside it. */
table.hunts th button::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 8px;
  vertical-align: 0.15em;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
}
table.hunts th[aria-sort="ascending"] button::after { border-bottom: 8px solid var(--ink); }
table.hunts th[aria-sort="descending"] button::after { border-top: 8px solid var(--ink); }
table.hunts th.num, table.hunts td.num { text-align: right; }
table.hunts th.num button { text-align: right; }

table.hunts td {
  padding: 8px;
  border-bottom: 2px solid var(--rule);
  vertical-align: middle;
}
table.hunts tbody tr.row:hover { background: rgba(255, 255, 255, 0.5); }
table.hunts tbody tr.row.open { background: var(--parchment-deep); }

.sprite {
  display: block;
  width: 56px;
  height: 56px;
  /* Nearest-neighbour on the way back up, which is what `.pixelArt()` does in
     the app. Without it a browser smooths the sprite and the pixel art stops
     being pixel art. */
  image-rendering: pixelated;
}
td.art { width: 76px; padding-right: 0; }

/* Wider since the Steps column came off: more of an epithet fits before the
   ellipsis, and the whole of it is in the tooltip and the gallery either way. */
td.who { width: 300px; }
.name { font-weight: 700; }
/* One line, cut with an ellipsis. A four-line epithet — *La Patasola, the Hoof
   in the Hills of Tolima* — made its row four times the height of the goblin's,
   and a table whose rows are all different heights cannot be scanned. The whole
   of it is in the tooltip, the expanded row and the gallery. */
.epithet {
  display: block;
  color: var(--muted);
  font-weight: 400;
  max-width: 284px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.trait-cell { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }

/* A monster the squad has not reached yet, when a squad level is picked. Faded
   rather than removed, because the ladder above you is the point of the ladder. */
.locked { opacity: 0.4; }
.locked td.art .sprite { filter: grayscale(1); }

.who-cell { display: block; }

/* The expedition table. Same bones as the hunts one — it is the same page and
   the same kind of reading — with a wide scene where the square sprite goes. */
table.expeditions { min-width: 900px; }
td.scene { width: 200px; padding-right: 0; }
.scene-img {
  display: block;
  width: 180px;
  height: auto;
  image-rendering: pixelated;
  /* The scenes are full-bleed art rather than a sprite on parchment, so they
     take an edge; without one the dark ones bleed into the row. */
  border: 2px solid var(--rule);
}
table.expeditions td.who { width: 260px; }
table.expeditions .epithet { max-width: 244px; }

/* ---------------------------------------------------------------------------
   The gallery
   --------------------------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
}
.card {
  border: 4px solid var(--line);
  background: rgba(255, 255, 255, 0.35);
  padding: 14px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.card .sprite {
  width: 128px;
  height: 128px;
  margin: 0 auto 4px;
}
.card .who { font-weight: 700; }
.card .meta { color: var(--muted); font-weight: 400; }
.card .terms { margin-top: auto; padding-top: 8px; }
.card.locked { opacity: 0.45; }

.empty {
  padding: 48px 0;
  color: var(--muted);
  font-weight: 400;
  text-align: center;
}

/* ---------------------------------------------------------------------------
   The reference tables — the walls and clocks that are not on a squad's board
   --------------------------------------------------------------------------- */

table.plain {
  width: 100%;
  border-collapse: collapse;
  font-weight: 400;
  margin-bottom: 8px;
}
table.plain th {
  text-align: left;
  font-weight: 700;
  padding: 10px;
  border-bottom: 4px solid var(--line);
  white-space: nowrap;
}
table.plain td {
  padding: 10px;
  border-bottom: 2px solid var(--rule);
  vertical-align: top;
}
table.plain td.num, table.plain th.num { text-align: right; white-space: nowrap; }
.source {
  color: var(--muted);
  font-weight: 400;
}

/* ---------------------------------------------------------------------------
   Narrow screens: the table becomes a list of cards.

   A twelve-column table on a phone is either a horizontal scroll nobody finds or
   type too small to read. Each row becomes a block and each cell labels itself
   from `data-label`, so the markup — and the sort, and the filters — stay
   exactly the same.
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
  body.hunts { padding-left: 16px; padding-right: 16px; }

  /* The search takes its own line: sharing one with a dropdown leaves it too
     narrow to read its own placeholder. */
  .controls input[type="search"] { flex: 1 1 100%; }

  .table-wrap { overflow-x: visible; border: 0; }

  table.hunts thead { display: none; }
  table.hunts, table.hunts tbody, table.hunts tr, table.hunts td { display: block; width: auto; }
  /* The desktop floor has to come off with the table shape, or every card is
     1,120px wide and its values sit off the right of the screen. */
  table.hunts { min-width: 0; }
  table.hunts td.who { width: auto; }
  .epithet { max-width: none; white-space: normal; overflow: visible; }

  table.hunts tbody tr.row {
    border: 4px solid var(--line);
    margin-bottom: 14px;
    padding: 14px;
    display: grid;
    grid-template-columns: 72px 1fr;
    gap: 2px 14px;
    background: rgba(255, 255, 255, 0.35);
  }
  table.hunts tbody tr.row > td { border: 0; padding: 0; }
  /* The sprite claims the left column down the whole card; the name sits beside
     it and everything else runs under both. */
  table.hunts td.art { grid-row: 1 / span 3; width: auto; }
  table.hunts td.art .sprite { width: 72px; height: 72px; }
  table.hunts td.who { grid-column: 2; }
  table.hunts tbody tr.row > td:not(.art):not(.who) {
    grid-column: 2;
    display: flex;
    justify-content: space-between;
    gap: 12px;
    text-align: left;
  }
  table.hunts tbody tr.row > td[data-label]:not(.art):not(.who)::before {
    content: attr(data-label);
    color: var(--muted);
  }
  table.hunts tbody tr.row > td.num { text-align: left; }

  /* The scene is wide, so the expedition card stacks rather than putting art
     beside a name the way the square monster sprite does. */
  table.expeditions { min-width: 0; }
  table.expeditions tbody tr.row { grid-template-columns: 1fr; }
  table.expeditions td.scene { grid-row: auto; width: auto; margin-bottom: 8px; }
  table.expeditions .scene-img { width: 100%; }
  table.expeditions td.who { width: auto; }

  .gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .card .sprite { width: 104px; height: 104px; }

  /* The reference tables are only four columns, so they keep their shape and
     take a scroll instead. */
  .plain-wrap { overflow-x: auto; }
  table.plain { min-width: 620px; }
}

@media (prefers-reduced-motion: no-preference) {
  table.hunts tbody tr.row { transition: background 120ms linear; }
}
