:root{
  color-scheme:light;
  --ground:#e3e1e8; --surface:#fff; --surface-2:#f2f2f2; --surface-3:#d7d8e6;
  --line:#b8bcc9; --line-soft:#d7d8e6;
  --ink:#17171e; --ink-2:#505472; --ink-3:#6b7085;
  --accent:#3751a1; --accent-soft:#dfe3f2; --accent-line:#8f9ccd; --on-accent:#fff;
  --blue:#2b3680; --blue-soft:#e5e7f4;
  --shadow:0 1px 2px rgba(23,23,30,.07), 0 10px 28px -20px rgba(23,23,30,.45);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark; --ground:#17171e; --surface:#20212a; --surface-2:#282a35; --surface-3:#32343f;
    --line:#3a3f45; --line-soft:#2c2e39;
    --ink:#d7d8e6; --ink-2:#cdceda; --ink-3:#8a8fa3;
    --accent:#8b9ee8; --accent-soft:#242844; --accent-line:#454d7d; --on-accent:#17171e;
    --blue:#9fb0ec; --blue-soft:#202436;
    --shadow:0 1px 2px rgba(0,0,0,.45), 0 10px 28px -20px rgba(0,0,0,.9);
  }
}
:root[data-theme="dark"]{
  color-scheme:dark; --ground:#17171e; --surface:#20212a; --surface-2:#282a35; --surface-3:#32343f;
  --line:#3a3f45; --line-soft:#2c2e39;
  --ink:#d7d8e6; --ink-2:#cdceda; --ink-3:#8a8fa3;
  --accent:#8b9ee8; --accent-soft:#242844; --accent-line:#454d7d; --on-accent:#17171e;
  --blue:#9fb0ec; --blue-soft:#202436;
  --shadow:0 1px 2px rgba(0,0,0,.45), 0 10px 28px -20px rgba(0,0,0,.9);
}

*{box-sizing:border-box}
[hidden]{display:none!important}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:"Bai Jamjuree",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:15px; font-weight:400; line-height:1.62; -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1600px; margin:0 auto; padding:0 24px 80px}
a{color:var(--accent)}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:1px}

/* ---------- masthead ---------- */
/* the masthead runs straight into the first section head on every page, so it
   carries no closing rule and no bottom padding to stand one off */
.mast{
  display:flex; align-items:flex-start; gap:26px;
  padding:38px 0 0;
  margin-bottom:26px;
}
.plate{
  flex:0 0 auto; font-family:"Bai Jamjuree",sans-serif; font-weight:300;
  font-size:66px; line-height:.8; letter-spacing:-.02em;
  color:var(--accent); font-variant-numeric:tabular-nums;
  text-decoration:none;
}
/* only the per-scenario page's plate links anywhere (back to the index) — the
   index's own plate is plain text, so this has no effect on it */
a.plate:hover,a.plate:focus-visible{color:var(--ink)}
.plate small{
  display:block; font-size:9px; letter-spacing:.24em; font-weight:600;
  color:var(--ink-3); margin-bottom:9px; text-transform:uppercase;
}
.mast-body{min-width:0; flex:1}
.mast h1{
  font-family:"Bai Jamjuree",sans-serif; font-weight:300; font-size:30px; line-height:1.2;
  letter-spacing:-.005em; margin:0 0 9px; text-wrap:balance; color:var(--ink);
}
/* the mast body is flex:1, so dropping the measure cap lets the intro
   paragraph run the full page width alongside the plate number */
.mast p{margin:0; color:var(--ink-2); max-width:none; font-size:14.5px}
.mast-meta{
  margin-top:14px; display:flex; flex-wrap:wrap; gap:6px;
  font-family:"IBM Plex Mono",monospace; font-size:11px;
}
.tag{
  padding:3px 9px; border:1px solid var(--line); border-radius:1px;
  background:var(--surface); color:var(--ink-2); white-space:nowrap; letter-spacing:.01em;
}
.tag.k{border-color:var(--accent-line); background:var(--accent-soft); color:var(--accent)}
.tag.b{border-color:var(--accent-line); background:var(--blue-soft); color:var(--blue)}

/* ---------- download banner ---------- */
/* one banner in two halves, flush: the dataset download on the accent, the
   generator on the deeper blue of the same hue. The narrow quarter holds just
   the name and its link, on one line. */
.dl-split{
  display:grid; grid-template-columns:minmax(0,3fr) minmax(0,1fr);
  border-radius:1px; box-shadow:var(--shadow); overflow:hidden;
}
.dl-band{
  display:flex; flex-wrap:wrap; align-items:center; gap:14px 28px; padding:16px 20px;
  background:var(--accent); color:var(--on-accent);
}
.dl-band.src{background:var(--blue)}
.dl-copy{flex:1 1 260px; min-width:0}
.dl-band.src .dl-copy{flex:1 1 auto}
.dl-copy b{display:block; font-size:17px; font-weight:600; line-height:1.35}
.dl-copy span{display:block; font-size:13.5px; opacity:.85}
.dl-copy small{display:block; font-size:9.5px; letter-spacing:.2em; text-transform:uppercase; font-weight:600; opacity:.8}
.dl-copy b.dl-name{font-size:26px; line-height:1.1; letter-spacing:.01em}
.dl-go{
  flex:0 0 auto; padding:9px 16px; border-radius:1px; background:var(--on-accent); color:var(--accent);
  text-decoration:none; font-weight:600; font-size:14px;
}
.dl-band.src .dl-go{color:var(--blue)}
.dl-go:hover,.dl-band.src .dl-go:hover{background:var(--ink); color:var(--surface)}
.dl-band a:focus-visible{outline-color:var(--on-accent)}
@media (max-width:1240px){ .dl-split{grid-template-columns:1fr} }

/* ---------- section heads ---------- */
.shead{display:flex; align-items:baseline; gap:14px; margin:38px 0 14px}
.shead h2{
  font-family:"Bai Jamjuree",sans-serif; font-weight:600; font-size:11px;
  letter-spacing:.2em; text-transform:uppercase; margin:0; color:var(--ink);
  white-space:nowrap;
}
.shead .rule{flex:1; height:1px; background:var(--line)}
.shead .hint{
  font-size:11px; color:var(--ink-3); font-family:"IBM Plex Mono",monospace; white-space:nowrap;
}

/* ---------- card figure ---------- */
figure.card{
  margin:0; background:var(--surface); border:1px solid var(--line);
  border-radius:1px; box-shadow:var(--shadow); overflow:hidden;
}
figure.card img{display:block; width:100%; height:auto; background:#f5f5f5}

/* ---------- card lightbox ---------- */
/* the card is a 1920px plot shown at ~990px, so it is worth enlarging */
button.zoom{
  display:block; width:100%; padding:0; margin:0; border:0;
  background:none; font:inherit; color:inherit; cursor:zoom-in;
}
dialog.lb{
  padding:0; border:0; background:transparent;
  max-width:96vw; max-height:96vh; width:auto; overflow:visible;
}
/* a scrim is not theme-dependent, so this one colour is deliberate */
dialog.lb::backdrop{background:rgba(15,16,20,.88)}
dialog.lb img{
  display:block; width:auto; height:auto; max-width:96vw; max-height:96vh;
  background:#f5f5f5; border:1px solid var(--line); cursor:zoom-out;
}
dialog.lb .lb-close{
  position:fixed; top:12px; right:16px; width:34px; height:34px;
  display:flex; align-items:center; justify-content:center;
  border:1px solid var(--line); border-radius:1px; cursor:pointer;
  background:var(--surface); color:var(--ink);
  font-family:"IBM Plex Mono",monospace; font-size:15px; line-height:1;
}
dialog.lb .lb-close:hover{border-color:var(--accent-line); color:var(--accent)}
@media (prefers-reduced-motion:no-preference){
  dialog.lb[open]{animation:lb-in .18s ease-out}
  @keyframes lb-in{from{opacity:0} to{opacity:1}}
}

/* Card (16:9) beside video (1:1), flush against each other. The columns are
   sized in proportion to the two aspect ratios, so both panes come out exactly
   the same height; the shared edge is the left figure's right border. */
.media{display:grid; grid-template-columns:1.7778fr 1fr; gap:0}
.media > figure.card + figure.card{border-left:0}
/* stretch both figures to the taller one, then let each legend absorb the
   difference — since the panes above are equal, the legends end up equal too */
.media > figure.card{display:flex; flex-direction:column}
.media > figure.card > .legend{flex:1}
.vidbox{display:flex; justify-content:center; background:var(--surface-2)}
.vidbox video{display:block; width:100%; aspect-ratio:1/1; background:#000}
@media (max-width:1000px){
  /* stacked: cap the square video so it does not run a full screen tall */
  .media{grid-template-columns:1fr; gap:16px}
  .media > figure.card + figure.card{border-left:1px solid var(--line)}
  .vidbox{padding:18px}
  .vidbox video{max-width:660px; border:1px solid var(--line)}
}
.legend{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  border-top:1px solid var(--line-soft);
  /* when the legend is stretched to match its neighbour, the row and its
     dividers fill the extra height instead of leaving a blank strip */
  align-content:stretch;
}
.legend div{
  padding:13px 17px; border-right:1px solid var(--line-soft);
  font-size:12.5px; color:var(--ink-2); line-height:1.55;
}
.legend div:last-child{border-right:0}
/* stacked variant: one cell per row, for a legend carrying a long passage */
.legend.stack{grid-template-columns:1fr}
.legend.stack div{border-right:0; border-bottom:1px solid var(--line-soft)}
.legend.stack div:last-child{border-bottom:0}
.legend b{
  display:block; font-family:"Bai Jamjuree",sans-serif; font-size:9.5px; letter-spacing:.17em;
  text-transform:uppercase; color:var(--ink-3); font-weight:600; margin-bottom:4px;
}
.nocard{
  background:var(--surface); border:1px solid var(--line); border-left:3px solid var(--accent-line);
  border-radius:1px; padding:17px 20px; color:var(--ink-2); font-size:13.5px; box-shadow:var(--shadow);
}

/* ---------- panels ---------- */
/* 420px minimum holds the panel grid at three columns on the 1600px page, so a
   wider page widens the cards (507px) instead of adding a fourth narrow one.
   auto-fit still collapses unused tracks, so two-panel sections stay full width. */
.grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(420px,1fr)); gap:16px}
/* four across in a single row — below the 420px auto-fit minimum, so this
   section states its column count outright instead of letting it be derived */
.grid.cols4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1320px){ .grid.cols4{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:700px){ .grid.cols4{grid-template-columns:1fr} }
/* flush row: no gap, matching the zero vertical distance to the block above.
   The shared edge is the left panel's right border, so it stays a single rule. */
.grid.flush{gap:0}
.grid.flush > .panel + .panel{border-left:0}
@media (max-width:860px){
  /* once the row wraps to one column the panels need their own edges back */
  .grid.flush{gap:16px}
  .grid.flush > .panel + .panel{border-left:1px solid var(--line)}
}
.panel{
  background:var(--surface); border:1px solid var(--line); border-radius:1px;
  box-shadow:var(--shadow); display:flex; flex-direction:column; overflow:hidden;
}
.panel > h3{
  font-family:"Bai Jamjuree",sans-serif; font-weight:600; font-size:10px;
  letter-spacing:.19em; text-transform:uppercase; margin:0;
  padding:12px 16px; color:var(--ink-2);
  background:var(--surface-2); border-bottom:1px solid var(--line-soft);
}
dl{margin:0; padding:5px 16px 12px}
dl > div{
  display:grid; grid-template-columns:minmax(0,44%) minmax(0,56%);
  gap:10px; padding:6px 0; border-bottom:1px solid var(--line-soft);
}
dl > div:last-child{border-bottom:0}
dt{color:var(--ink-3); font-size:12.5px; min-width:0}
dd{
  margin:0; font-family:"IBM Plex Mono",monospace; font-size:12px;
  font-variant-numeric:tabular-nums; overflow-wrap:anywhere; color:var(--ink);
}
dd.sans{font-family:"Bai Jamjuree",sans-serif; font-size:12.5px; font-variant-numeric:normal}
dd em,dt em{font-style:normal; color:var(--ink-3)}
/* a quaternion, one component per line. The cell is mono, so a leading space
   on a positive value puts its digits under the digits of a negative one. */
.quat{display:grid; gap:1px}
.quat > span{display:grid; grid-template-columns:13px minmax(0,1fr); align-items:baseline}
.quat i{font-style:normal; color:var(--ink-3)}
.quat b{font-weight:400}
dd .off{color:var(--ink-3)}
.sub{
  margin:0; padding:9px 16px 10px; background:var(--surface-2);
  border-top:1px solid var(--line-soft); border-bottom:1px solid var(--line-soft);
  font-family:"Bai Jamjuree",sans-serif; font-size:9.5px; letter-spacing:.17em;
  text-transform:uppercase; color:var(--ink-3); font-weight:600;
}

/* ---------- mono blocks ---------- */
pre.mono{
  margin:0; padding:14px 16px; background:var(--surface-2);
  border-top:1px solid var(--line-soft);
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; line-height:1.8;
  overflow-x:auto; color:var(--ink);
}
pre.mono .c{color:var(--ink-3)}
/* fit-to-panel modifier: for blocks whose lines are a fixed width that just
   overshoots the panel at 11.5px (a TLE line is exactly 69 characters) */
pre.tight{font-size:10.5px}

/* ---------- table ---------- */
.tblwrap{
  overflow-x:auto; background:var(--surface); border:1px solid var(--line);
  border-radius:1px; box-shadow:var(--shadow);
}
table{border-collapse:collapse; width:100%; font-size:12.5px}
th,td{padding:8px 12px; text-align:left; border-bottom:1px solid var(--line-soft); white-space:nowrap}
th{
  font-family:"Bai Jamjuree",sans-serif; font-size:9.5px; letter-spacing:.15em; text-transform:uppercase;
  color:var(--ink-3); font-weight:600; background:var(--surface-2); position:sticky; top:0;
  border-bottom:1px solid var(--line);
}
td{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; color:var(--ink-2); font-size:12px}
td.n{font-weight:600}
td.n a{color:var(--accent); text-decoration:none}
td.n a:hover{text-decoration:underline}
td.t{font-family:"Bai Jamjuree",sans-serif; font-size:12.5px; white-space:normal; min-width:280px; color:var(--ink)}
/* field-reference table: narrow sans group label, wrapping monospace name list,
   wide prose note — the three share the full page width */
td.g{
  font-family:"Bai Jamjuree",sans-serif; font-size:12.5px; color:var(--ink);
  white-space:normal; width:12%; min-width:130px; vertical-align:top;
}
td.f{white-space:normal; width:40%; min-width:300px; line-height:1.8; color:var(--ink); vertical-align:top}
td.g ~ td.t{width:48%; vertical-align:top}
tbody tr:hover{background:var(--surface-2)}

/* ---------- contact sheet ---------- */
/* 112px minimum holds 13 tiles across the 1600px page; auto-fill reflows to
   fewer, wider tiles on a narrower one rather than clipping */
.sheetgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(112px,1fr)); gap:6px; margin-bottom:14px}
a.tile{
  display:block; overflow:hidden; text-decoration:none;
  background:var(--surface); border:1px solid var(--line); border-radius:1px; box-shadow:var(--shadow);
}
/* The whole card is unreadable at tile size, so the tile crops to the band that
   carries the trajectory signature — the translation and optical-axis plots,
   centred at 64% of the card's height. object-fit does the crop, so the tile
   and the hover preview share one image and the preview still shows all of it.
   The ratio is declared, so the grid never reflows as the images arrive. */
a.tile img{
  display:block; width:100%; aspect-ratio:16/5; background:#f5f5f5;
  object-fit:cover; object-position:center 64%;
}
/* the number sits under the plot rather than over it — at this height a badge
   would cover a third of the signal */
a.tile b{
  display:block; padding:1px 7px;
  font-family:"IBM Plex Mono",monospace; font-size:10.5px; font-weight:600;
  color:var(--ink-2); background:var(--surface-2); border-top:1px solid var(--line-soft);
}
a.tile:hover,a.tile:focus-visible{border-color:var(--accent)}
a.tile:hover b,a.tile:focus-visible b{color:var(--accent)}

/* ---------- coverage bars, doubling as the table's filter ---------- */
/* Each bar shows how the 39 sequences divide along one dimension, and every
   segment is a filter toggle. The bars stay proportioned to the whole dataset
   rather than to the current selection — they are the map, not the result. */
.filters{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0;
  background:var(--surface); border:1px solid var(--line); border-radius:1px;
  box-shadow:var(--shadow); margin-bottom:14px;
}
.cov-cell{padding:11px 16px 12px; min-width:0}
.cov-cell:nth-child(odd){border-right:1px solid var(--line-soft)}
.cov-cell:nth-child(n+3){border-top:1px solid var(--line-soft)}
.cov-lab{
  font-family:"Bai Jamjuree",sans-serif; font-size:9.5px; letter-spacing:.17em;
  text-transform:uppercase; color:var(--ink-3); font-weight:600; margin-bottom:6px;
}
.bar{display:flex; height:24px; border:1px solid var(--line); border-radius:1px; overflow:hidden}
.seg{
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  min-width:0; padding:0; border:0; border-right:1px solid var(--surface);
  font-family:"IBM Plex Mono",monospace; font-size:10.5px; white-space:nowrap;
  cursor:pointer; color:var(--ink);
}
.seg:last-child{border-right:0}
/* one hue, eight strengths — mixing against the surface keeps the ramp correct
   in both themes without a second palette */
.t1{background:color-mix(in srgb,var(--accent) 100%,var(--surface))}
.t2{background:color-mix(in srgb,var(--accent) 86%,var(--surface))}
.t3{background:color-mix(in srgb,var(--accent) 70%,var(--surface))}
.t4{background:color-mix(in srgb,var(--accent) 56%,var(--surface))}
.t5{background:color-mix(in srgb,var(--accent) 43%,var(--surface))}
.t6{background:color-mix(in srgb,var(--accent) 32%,var(--surface))}
.t7{background:color-mix(in srgb,var(--accent) 22%,var(--surface))}
.t8{background:color-mix(in srgb,var(--accent) 14%,var(--surface))}
/* only the widest segments carry a label, and those are the strong tints */
.seg.t1,.seg.t2,.seg.t3{color:var(--on-accent)}
.seg:hover:not(.empty),.seg.peer{box-shadow:inset 0 0 0 2px var(--ink-2)}
.seg.off{opacity:.42}
/* a segment with nothing left under the other filters is a dead end */
.seg.empty{opacity:.14; cursor:default}
.seg.on{box-shadow:inset 0 0 0 2px var(--ink)}
.covkey{display:flex; flex-wrap:wrap; gap:2px 13px; margin-top:7px}
.covkey button{
  display:flex; align-items:center; gap:5px; padding:1px 0; border:0; background:none;
  font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--ink-3); cursor:pointer;
}
.covkey button i{width:9px; height:9px; border-radius:1px; flex:0 0 auto; display:block}
.covkey button:hover:not(.empty),.covkey button.peer{color:var(--accent)}
.covkey button.on{color:var(--ink); font-weight:600}
.covkey button.empty{opacity:.38; cursor:default}
/* last cell of the grid: text search, reset, and the live count */
.cov-tools{display:flex; flex-wrap:wrap; align-items:center; gap:8px; align-content:center}
.cov-tools input[type="search"],.cov-tools button.reset{
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink);
  background:var(--surface); border:1px solid var(--line); border-radius:1px; padding:5px 8px;
}
.cov-tools input[type="search"]{flex:1 1 200px; min-width:0}
.cov-tools input[type="search"]::placeholder{color:var(--ink-3)}
.cov-tools button.reset{cursor:pointer; color:var(--ink-2)}
.cov-tools input[type="search"]:hover,.cov-tools button.reset:hover{border-color:var(--accent-line)}
.cov-tools .count{
  font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--ink-3);
  font-variant-numeric:tabular-nums; white-space:nowrap; margin-left:auto;
}
.cov-tools .count b{color:var(--ink); font-weight:600}
tr.nomatch td{
  font-family:"Bai Jamjuree",sans-serif; font-size:13px; color:var(--ink-3);
  text-align:center; padding:22px 12px; white-space:normal;
}
@media (max-width:900px){
  .filters{grid-template-columns:1fr}
  .cov-cell:nth-child(odd){border-right:0}
  .cov-cell + .cov-cell{border-top:1px solid var(--line-soft)}
}
/* ---------- scenario-table row preview ---------- */
/* Every row of the scenario table is a link target: the number cell holds the
   real anchor, and the row carries the same href for the click handler, so the
   table still works with scripting off. */
tbody tr[data-href]{cursor:pointer}
tbody tr[data-href]:hover{background:var(--accent-soft)}
.rowtip{
  position:fixed; left:0; top:0; z-index:60; width:420px; max-width:calc(100vw - 28px);
  background:var(--surface); border:1px solid var(--line); border-radius:1px;
  box-shadow:0 2px 6px rgba(23,23,30,.18), 0 18px 44px -22px rgba(23,23,30,.65);
  overflow:hidden; opacity:0; visibility:hidden;
  /* never let the preview intercept the click it is advertising */
  pointer-events:none;
}
.rowtip[data-open]{opacity:1; visibility:visible}
/* the cards are all 1920x1080, so declaring the ratio gives the preview its
   final height before the image loads — the placement maths needs it */
.rowtip img{
  display:block; width:100%; aspect-ratio:16/9; background:#f5f5f5;
  border-bottom:1px solid var(--line-soft);
}
.rowtip img:not([src]){display:none}
.rowtip-body{padding:11px 14px 12px}
.rowtip-no{
  display:block; font-family:"IBM Plex Mono",monospace; font-size:10px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3); margin-bottom:3px;
}
.rowtip-desc{display:block; font-size:12.5px; line-height:1.5; color:var(--ink)}
.rowtip-go{
  display:block; margin-top:9px; padding-top:8px; border-top:1px solid var(--line-soft);
  font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--accent);
}
@media (prefers-reduced-motion:no-preference){
  .rowtip{transition:opacity .12s ease-out}
}
/* on a touch device there is no hover to preview with, and the tap navigates */
@media (hover:none){ .rowtip{display:none} }

/* ---------- footer ---------- */
footer{
  margin-top:48px; padding-top:18px; border-top:1px solid var(--line);
  font-size:11.5px; color:var(--ink-3); display:flex; flex-wrap:wrap; gap:6px 20px;
  font-family:"IBM Plex Mono",monospace;
}

@media (max-width:640px){
  .mast{flex-direction:column; gap:16px}
  .plate{font-size:48px}
  .mast h1{font-size:23px}
  dl > div{grid-template-columns:1fr; gap:1px}
  .wrap{padding:0 16px 60px}
}
@media print{
  body{background:#fff}
  .panel,figure.card,.tblwrap{box-shadow:none; break-inside:avoid}
}
