/* PANTS house theme: marcdeller.com brand tokens.
   British English, mobile responsive, sticky header that does not overlap content. */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Roboto+Mono:wght@400;500&display=swap');

:root {
  --md-primary:       #1e73be;
  --md-primary-dark:  #155a9c;
  --md-primary-light: #4a9fd4;

  --md-bg:            #ffffff;
  --md-bg-alt:        #f4f7fb;
  --md-surface:       #ffffff;
  --md-border:        #dde4ed;

  --md-text:          #1a1a2e;
  --md-text-muted:    #6b7c93;
  --md-text-light:    #ffffff;

  --md-accent-green:  #00d084;
  --md-accent-orange: #ff6900;
  --md-accent-purple: #9b51e0;
  --md-accent-amber:  #fcb900;

  --md-shadow-sm:     6px 6px 9px rgba(0,0,0,0.12);
  --md-radius:        8px;
  --md-radius-lg:     16px;

  /* Environment colours, used consistently in tables, plots and the viewer. */
  --env-compost:   #00d084;
  --env-marine:    #1e73be;
  --env-landfill:  #ff6900;
  --env-waste:     #9b51e0;
  --env-gut:       #e5195f;   /* human gut: the therapeutic-relevant environment */
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0; overflow-x: hidden;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 15px; line-height: 1.6;
  color: var(--md-text); background: var(--md-bg);
}
code, pre, .mono { font-family: 'Roboto Mono', monospace; }
a { color: var(--md-primary); }
img, canvas, svg { max-width: 100%; }

/* ---------- layout ---------- */
.md-main { max-width: 1400px; margin: 0 auto; padding: 24px; }
.md-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.md-card {
  background: var(--md-surface); border: 1px solid var(--md-border);
  border-radius: var(--md-radius); padding: 20px; box-shadow: var(--md-shadow-sm);
}
.md-card h2 { margin-top: 0; font-size: 18px; }
.kpi { font-size: 30px; font-weight: 700; color: var(--md-primary); line-height: 1.1; }
.kpi-label { font-size: 13px; color: var(--md-text-muted); }
.muted { color: var(--md-text-muted); font-size: 13px; }

/* ---------- caveat callout: this project has a lot to disclose ---------- */
.caveat {
  border-left: 4px solid var(--md-accent-amber);
  background: #fffbea; padding: 12px 16px; border-radius: 0 var(--md-radius) var(--md-radius) 0;
  font-size: 14px; margin: 16px 0;
}
.caveat strong { color: #8a6d00; }

/* ---------- tables ---------- */
.tbl-wrap { overflow-x: auto; }
table.data { border-collapse: collapse; width: 100%; font-size: 14px; }
table.data th, table.data td { padding: 8px 10px; border-bottom: 1px solid var(--md-border); text-align: left; }
table.data th { background: var(--md-bg-alt); font-weight: 600; white-space: nowrap; cursor: pointer; user-select: none; }
/* The literal character, not a \2195 escape: written through a shell heredoc the
   backslash got doubled and CSS printed the escape as text in every header. */
table.data th[data-sort]::after { content: ' \2195'; color: var(--pv-dim); font-size: 11px; opacity: .6; }
table.data tbody tr:hover { background: var(--md-bg-alt); }
td.num, th.num { text-align: right; font-family: 'Roboto Mono', monospace; }

.pill { display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px; font-weight: 600; color: #fff; }
.pill.compost  { background: var(--env-compost); }
.pill.marine_plastisphere { background: var(--env-marine); }
.pill.landfill { background: var(--env-landfill); }
.pill.wastewater { background: var(--env-waste); }
.pill.human_gut { background: var(--env-gut); }
.pill.unknown  { background: var(--md-text-muted); }

/* ---------- structure viewer ---------- */
.viewer-shell { display: grid; grid-template-columns: 1fr 260px; gap: 16px; }
#viewer {
  position: relative; width: 100%; height: 560px;
  border: 1px solid var(--md-border); border-radius: var(--md-radius); overflow: hidden; background: #101418;
}
.viewer-controls { font-size: 13px; }
.viewer-controls h3 { font-size: 14px; margin: 0 0 8px; }
.viewer-controls label { display: flex; align-items: center; gap: 8px; margin: 6px 0; cursor: pointer; }
.swatch { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }
.viewer-note { margin-top: 12px; font-size: 12px; color: var(--md-text-muted); }

@media (max-width: 900px) {
  .viewer-shell { grid-template-columns: 1fr; }
  #viewer { height: 380px; }
}
@media (max-width: 768px) {
  .md-card { padding: 14px; }
  .md-main { padding: 16px; }
  .hide-mobile { display: none !important; }
}

footer.md-footer {
  text-align: center; padding: 24px; color: var(--md-text-muted); font-size: 13px;
  border-top: 1px solid var(--md-border); margin-top: 32px;
}

/* ======================================================================
   Direction 04 "Diffraction": PANTS's own surface, distinct from the
   sibling apps. The brand bar above stays constant (that is Marc's
   identity across every app); everything below it is this project's.
   Chosen because PANTS's centrepiece is a 3D viewport, and a dark ground
   stops the viewer looking like a hole cut in a white page.
   ====================================================================== */
:root {
  --pv-bg:       #0d0f1a;
  --pv-panel:    #141929;
  --pv-border:   #262e4d;
  --pv-text:     #c3c9e4;
  --pv-dim:      #6e78a6;
  --pv-accent:   #8fb4ff;   /* primary: structure, values */
  --pv-accent-2: #c48cff;   /* secondary: labels, eyebrows */
}

body {
  background: var(--pv-bg);
  color: var(--pv-text);
  /* Reciprocal-lattice dot grid. Fixed so it reads as ground, not texture
     that scrolls with the content. */
  background-image: radial-gradient(circle at 1px 1px, rgba(122,162,255,.14) 1px, transparent 0);
  background-size: 18px 18px;
  background-attachment: fixed;
}
a { color: var(--pv-accent); }


.md-card {
  background: rgba(20,25,41,.82);
  border: 1px solid var(--pv-border);
  box-shadow: none;
  border-radius: 3px;
}
.md-card h2 { color: var(--pv-text); }
.kpi { color: var(--pv-accent); font-variant-numeric: tabular-nums; }
.kpi-label, .muted { color: var(--pv-dim); }

table.data th { background: transparent; color: var(--pv-dim); border-bottom: 1px solid var(--pv-border); }
table.data td { border-bottom: 1px solid #1a2038; }
table.data tbody tr:hover { background: rgba(122,162,255,.07); }
td.num, th.num { font-variant-numeric: tabular-nums; }

.caveat {
  background: rgba(196,140,255,.09);
  border-left-color: var(--pv-accent-2);
  color: var(--pv-text);
}
.caveat strong { color: var(--pv-accent-2); }

select, button, input[type="checkbox"] { accent-color: var(--pv-accent); }
select, button {
  background: var(--pv-panel); color: var(--pv-text);
  border: 1px solid var(--pv-border); border-radius: 3px; padding: 5px 10px;
  font-family: inherit; font-size: 13px; cursor: pointer;
}
button:hover { border-color: var(--pv-accent); color: var(--pv-accent); }
:focus-visible { outline: 2px solid var(--pv-accent); outline-offset: 2px; }

#viewer { border-color: var(--pv-border); background: #0a0c14; }
footer.md-footer { border-top-color: var(--pv-border); color: var(--pv-dim); }



/* ======================================================================
   MASTHEAD: one slab, no internal seams.
   Replaces three stacked bands (brand bar / tab strip / banner) that each
   had their own background, so the eye read three unrelated strips before
   reaching any content. The banner and the strapline share a baseline
   instead of the banner floating centred in an empty band, and the tabs
   hang off the bottom of the same block.
   The wordmark is also stated ONCE now: the ASCII says PANTS, the h1 says
   what PANTS is. Previously both said PANTS.
   ====================================================================== */
.md-slab {
  background: linear-gradient(180deg, #070912 0%, #12172b 100%);
  border-bottom: 2px solid var(--pv-accent);
  box-shadow: 0 10px 30px rgba(0,0,0,.45);
}
.md-slab-inner { max-width: 1400px; margin: 0 auto; padding: 0 24px; }

/* --- credit line --- */
.md-credit {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 0 0; flex-wrap: wrap;
}
.md-credit > a {
  display: flex; align-items: center; gap: 8px;
  color: var(--pv-dim); text-decoration: none;
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em; white-space: nowrap;
}
.md-credit > a:hover { color: var(--pv-accent); }
/* The amber dot is the one colour constant across every app: enough to
   signal authorship without dictating a palette. */
.md-logo-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--md-accent-amber); box-shadow: 0 0 8px rgba(252,185,0,.55);
  flex-shrink: 0;
}
.md-credit-links { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.md-credit-links a {
  /* Fixed height + flex centring, not padding. Padding alone left the text sitting high
     in the pill, because the 11px glyphs occupy less than their line box and the leftover
     leading all fell to the bottom. Centring in a known box puts it exactly in the middle
     and lets the pill be shorter. */
  display: inline-flex; align-items: center; justify-content: center;
  height: 19px; box-sizing: border-box;
  font-size: 11px; line-height: 1; color: var(--pv-dim); text-decoration: none;
  border: 1px solid var(--pv-border); border-radius: 20px; padding: 0 10px;
  white-space: nowrap;
}
.md-credit-links a:hover {
  color: var(--pv-accent); border-color: var(--pv-accent);
  background: rgba(143,180,255,.08);
}

/* Source and data badges, wearing the same pill as the contact links: identical height,
   border, radius and colour, so the whole row reads as one set of controls.

   The awkward part is the shield's OWN vertical padding. A shields.io badge is 20px tall
   around 11px text, so roughly 4.5px of air top and bottom. Scaling the image down to fit
   a 19px pill would shrink its text to about 9px, noticeably smaller than the 11px beside
   it. So the image keeps its natural size and the padding is CLIPPED instead: a negative
   vertical margin pulls the layout box in to 14px while the image still paints at 20px,
   and overflow:hidden on the anchor trims what spills. The 11px text sits inside the kept
   band, so nothing of it is cut and it stays the same size as its neighbours. */
.md-credit-links a.md-badge {
  padding: 0 5px;          /* the shield carries its own horizontal padding as well */
  overflow: hidden;
}
.md-credit-links a.md-badge img {
  display: block; height: 20px; width: auto;
  margin: -3px 0;
  mix-blend-mode: screen;
  /* Tint, not opacity. Opacity blends toward the backdrop and can only make a neutral
     grey: it matched the pills' lightness while missing their blue by 36 points on the
     blue channel. The matrix in base.html scales channels independently and lands white
     on --pv-dim exactly. */
  filter: url(#pv-dim-tint);
}
.md-credit-links a.md-badge:hover img { filter: url(#pv-dim-tint) brightness(1.7); }

/* --- banner + strapline, sharing a baseline --- */
.md-masthead {
  display: flex; align-items: flex-end; gap: 20px;
  padding: 8px 0 0; flex-wrap: wrap;
}
/* Every rule here is load-bearing, learned across six rounds on FlexAppeal:
     text-align:left  the parent may centre; without this each ROW centres
                      separately and short rows slide sideways.
     line-height:1    figlet strokes continue across the break; any leading
                      chops diagonals into dashes.
     whole-number px  a fractional advance drifts columns per glyph.
     system mono      Roboto Mono's underscore is narrower than its advance.
     font-weight:400  500 makes the browser smear a synthetic bold sideways.
   banner3 is additionally 0% underscore characters, so it cannot suffer the
   detached-underscore failure at all. Art stays byte-identical to pyfiglet. */
.md-banner {
  margin: 0;
  text-align: left;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;
  font-size: 11px;
  line-height: 1;
  font-weight: 400;
  white-space: pre;
  color: var(--pv-accent);
  flex: 0 0 auto;
}
.md-strap {
  margin: 0 0 3px;
  font-size: 13px; font-weight: 500;
  letter-spacing: .1em;
  /* NOT uppercased. The capitals in "PETase ANnotation and Triage System" are
     what spell out PANTS: transforming the case destroys the only place the
     acronym is explained. */
  color: var(--pv-accent-2);
}
.md-tagline {
  margin: 4px 0 0;
  font-size: 12px;
  font-style: italic;
  color: var(--pv-dim);
  max-width: 62ch;
}

/* --- tabs, hanging off the bottom of the slab --- */
.md-nav { display: flex; gap: 22px; padding: 12px 0 0; overflow-x: auto; }
.md-nav a {
  padding: 0 0 9px; text-decoration: none;
  color: var(--pv-dim); font-size: 13.5px; font-weight: 500;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.md-nav a:hover { color: var(--pv-accent); }
.md-nav a.active { color: var(--pv-accent); border-bottom-color: var(--pv-accent); }

@media (max-width: 820px) {
  .md-slab-inner { padding: 0 16px; }
  .md-banner { font-size: 9px; }
  .md-masthead { gap: 12px; }
}
@media (max-width: 560px) {
  .md-banner { font-size: 6px; }
  .md-strap { font-size: 11px; letter-spacing: .06em; }
  .md-tagline { font-size: 11px; }
  .md-nav { gap: 16px; }
  .md-credit-links a { padding: 1px 8px; }
  /* The shields are fixed-width images and cannot shed text, so they wrap to their own
     row rather than shrinking. Scaled down slightly so two fit side by side on a phone
     instead of stacking into two more rows. */
  .md-credit-links a { height: 18px; padding: 0 8px; }
}

/* Strapline and tagline move as one block beside the banner, so they wrap
   together instead of the tagline detaching on a narrow viewport. */
.md-titles { padding-bottom: 2px; }

/* The KPI row carries five tiles. auto-fit at minmax(280px,1fr) fits only four at
   1400px, leaving the fifth stranded on its own line; 220px fits five and still
   collapses sensibly on narrow viewports. */
.md-grid.kpis { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
