/* Values taken from the Figma frame "Table_Design" (node 1:31).
   The file defines no Figma variables, so these are literals. */
:root {
  --blue: #0f7bc1;
  --blue-zebra: rgba(15, 123, 193, 0.2);   /* even-row fill */
  --blue-muted: rgba(15, 123, 193, 0.5);   /* View more border + label */
  --ink: #000000;

  /* Only these two exist in the frame */
  --st-critically-endangered: #c90228;
  --st-endangered: #e47324;
  /* Not in the frame — invented to continue the ramp, see notes */
  --st-vulnerable: #c8860b;
  --st-safe: #57a83a;
  --st-thriving: #1f7a43;

  --gap: 2px;        /* white gutter between every cell, both axes */
  --row-h: 30px;
  --head-h: 50px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: #fff;
  color: var(--ink);
  font: 500 14px/normal 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.svg-defs { display: none; }

.page {
  /* 76.85 + 197.5 + 107.85 + 182.85 + 187 column widths (752), plus six 2px
     gutters (border-spacing also applies at the outer edges), plus padding */
  max-width: 804px;
  margin: 0 auto;
  padding: 40px 20px 56px;
}

/* No overflow here on purpose. `overflow-x: auto` makes this element a scroll
   container, and a sticky <th> then sticks to *it* rather than to the page —
   and since the wrapper is exactly as tall as the table, that means it never
   sticks at all. Both layouts size their columns to fit, so the horizontal
   scroll it provided was only ever a safety net. */
.table-wrap { position: relative; }

.features {
  width: 100%;
  table-layout: fixed;
  /* The frame spaces cells apart rather than sharing borders */
  border-collapse: separate;
  border-spacing: var(--gap);
}

.col-rank     { width: 77px; }
.col-feature  { width: auto; }
.col-category { width: 108px; }
.col-change   { width: 183px; }
.col-status   { width: 187px; }

/* Header ---------------------------------------------------------------- */

.features thead th {
  height: var(--head-h);
  padding: 16px;
  background: var(--blue);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  text-align: left;
  white-space: nowrap;
  vertical-align: middle;
  /* Header rides along as the table scrolls past. `border-collapse: separate`
     is what makes this possible — with collapsed borders a sticky <th> loses
     its background in Chrome, which is why the cell (not the row) is sticky. */
  position: sticky;
  top: 0;
  z-index: 2;
}

/* border-spacing leaves a 2px gutter on every side of every header cell, and
   rows would be visible sliding through those gaps. The outline fills them with
   the same white the gutter already is, and doesn't affect layout. */
.features thead th { outline: var(--gap) solid #fff; }

.th-text { vertical-align: middle; }

/* The whole header is the sort control, so it's a real button for keyboard
   and screen-reader users, styled to look like the plain label it replaced */
.th-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}
.features thead .th-change .th-btn,
.features thead .th-status .th-btn { justify-content: center; }

.th-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.caret {
  width: 7.85px;
  height: 4.73px;
  fill: #fff;
  flex: none;
  opacity: 0.45;                     /* dim until the column is the active sort */
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.is-sorted .caret { opacity: 1; }
/* The glyph points down, so ▼ = descending and ▲ = ascending. Flipped rather
   than rotated — the symbol is preserveAspectRatio="none" on a non-square
   viewBox, which a 180deg rotation visibly skews. */
.is-sorted:not(.is-desc) .caret { transform: scaleY(-1); }

.features thead .th-change,
.features thead .th-status { text-align: center; }

/* Body ------------------------------------------------------------------ */

.features tbody td,
.features tbody th {
  height: var(--row-h);
  padding: 8px 16px;
  font-weight: 500;
  font-size: 14px;
  color: var(--ink);
  text-align: center;
  vertical-align: middle;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Feature is the only left-aligned column, and the only one that wraps */
.features tbody th.feature {
  text-align: left;
  font-weight: 500;
  white-space: normal;
}

/* Zebra striping — even rows only, matching the frame */
.features tbody tr:nth-child(even) td,
.features tbody tr:nth-child(even) th { background: var(--blue-zebra); }

/* Status ---------------------------------------------------------------- */

[data-status="Critically endangered"] { --st: var(--st-critically-endangered); }
[data-status="Endangered"]            { --st: var(--st-endangered); }
[data-status="Vulnerable"]            { --st: var(--st-vulnerable); }
[data-status="Safe"]                  { --st: var(--st-safe); }
[data-status="Thriving"]              { --st: var(--st-thriving); }

/* Full-bleed colour block; the zebra rule must not repaint it */
.features tbody td.status,
.features tbody tr:nth-child(even) td.status {
  background: var(--st);
  color: #fff;
  font-weight: 800;
  /* Figma specifies 16px here, but "Critically endangered" renders 159px wide
     in Poppins ExtraBold and would ellipsise in the 187px column */
  padding: 8px 12px;
}

/* View more ------------------------------------------------------------- */

.table-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding-top: 24px;
}

.view-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8.39px;
  height: 30px;
  padding: 0 16.79px;
  background: #fff;
  border: 1px solid var(--blue-muted);
  border-radius: 0;
  color: var(--blue-muted);
  font-family: inherit;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.view-more .plus {
  width: 12.25px;
  height: 12.25px;
  fill: currentColor;
  flex: none;
}
.view-more:hover {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}
.view-more:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}
.view-more[hidden] { display: none; }

.count {
  margin: 0;
  font-size: 13px;
  color: rgba(0, 0, 0, 0.55);
}

/* Key ------------------------------------------------------------------- */

/* Desktop shows every column at full width — Category spelled out, Status
   labelled inside its colour block — so the key has nothing left to explain.
   It only earns its space on mobile, where both columns collapse to glyphs. */
.key { display: none; }

.key-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
}

.key-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
}

.key-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
  font-weight: 500;
}

.key-list li { display: flex; align-items: center; gap: 7px; }

.key-swatch {
  width: 13px;
  height: 13px;
  background: var(--st);
  flex: none;
}

.key-abbr {
  min-width: 20px;
  padding: 1px 5px;
  background: var(--blue-zebra);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  flex: none;
}

.th-short,
.cat-abbr { display: none; }

/* Mobile ---------------------------------------------------------------- */

@media (max-width: 600px) {
  /* Rank, Cat and Status are square: column width == row height */
  :root { --sq: 28px; }

  .page { padding: 28px 14px 48px; }

  /* Columns no longer fill the viewport, so centre the table. The width is
     pinned to 36+88+36+72+36 plus six 2px gutters — with width:auto the
     headers' min-content would override the colgroup and break the squares. */
  .features { width: 100%; margin: 0 auto; }

  .features thead th {
    height: auto;
    padding: 10px 6px;
    font-size: 11px;
    letter-spacing: normal;
    white-space: normal;
  }
  /* Decorative only, and they cost more width than the narrow headers can spare */
  .caret { display: none; }

  .features tbody td,
  .features tbody th {
    height: var(--sq);
    padding: 4px 6px;
    font-size: 13px;
  }

  .col-rank     { width: var(--sq); }
  .col-feature  { width: 88px; }   /* half its previous 176px */
  .col-category { width: var(--sq); }
  .col-change   { width: 72px; }   /* must hold "-100.00%" without clipping */
  .col-status   { width: 20px; }

  .th-full { display: none; }
  .th-short { display: inline; }

  /* Category collapses to its first letter; the full word stays for
     screen readers */
  .cat-full {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .cat-abbr { display: inline-block; font-weight: 700; }

  /* At 88px, words like "Weatherboarding" exceed the column on their own and
     would be ellipsised, so allow them to break */
  .features tbody th.feature { overflow-wrap: break-word; }

  /* 3-digit ranks need nearly all of the 36px square */
  .features tbody td.rank { padding-left: 3px; padding-right: 3px; }

  /* Status keeps its colour block but drops the label, per the brief */
  .features tbody td.status,
  .features tbody tr:nth-child(even) td.status { padding: 0; }
  .status-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* The status header can't fit "Status" at this width */
  .features thead .th-status .th-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .features thead .th-status .caret { margin-left: 0; }

  .key {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-bottom: 16px;
  }
}

.key-divider {
  width: 100%;
  height: 1px;
  border: 0;
  background: var(--blue-muted);
  margin: 0;
}