/* ECHOES technical specification.
 *
 * A working document, not a brochure. It is read on a laptop in a production
 * office and printed in a venue, so the type is quiet, the status of every
 * requirement is legible at a glance, and the one decorative gesture - the
 * spectrum rule under the masthead - is the show's own prism, used once.
 *
 * Status colour is semantic and is never the accent. Verified is calm, missing
 * is loud, and nothing that is merely unverified is allowed to look settled. */

:root {
  /* White, not off-white. The tables are the content and they read cleaner
   * on white - and the rider prints and exports from these same pages, where
   * a tinted ground becomes a tinted page. */
  --paper:      #ffffff;
  --raised:     #ffffff;
  --sunken:     #f3f4f6;
  --ink:        #17181b;
  --ink-soft:   #4a4d54;
  --ink-faint:  #80848c;
  --rule:       #e1e3e7;
  --rule-soft:  #eceef1;

  --verified:      #1f6f4a;
  --verified-bg:   #e4f0e9;
  --unclear:       #8a5a09;
  --unclear-bg:    #f8eddb;
  --missing:       #a32b1e;
  --missing-bg:    #fae5e1;
  --contradictory: #8a2170;
  --contradictory-bg: #f7e3f2;

  --critical:    #a32b1e;
  --operational: #8a5a09;
  --minor:       #6a6d75;

  --sans: ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --measure: 68ch;
  --sidebar: 16.5rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:     #131417;
    --raised:    #1b1d21;
    --sunken:    #0e0f11;
    --ink:       #eceef2;
    --ink-soft:  #b0b4bd;
    --ink-faint: #767b85;
    --rule:      #2c2f35;
    --rule-soft: #24262b;

    --verified:      #6ed3a2;
    --verified-bg:   #14291f;
    --unclear:       #e2b25c;
    --unclear-bg:    #2c2314;
    --missing:       #f08b7c;
    --missing-bg:    #2e1714;
    --contradictory: #e79ad4;
    --contradictory-bg: #2c1527;

    --critical:    #f08b7c;
    --operational: #e2b25c;
    --minor:       #9aa0aa;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.58 var(--sans);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration-color: var(--ink-faint); text-underline-offset: 2px; }
a:hover { text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 2px; }

/* ---------------------------------------------------------------- shell

   The navigation runs across the top rather than down the side. A sidebar
   wide enough not to wrap "DiGiCo Quantum 338 Session File" took 22rem off
   every page, and these pages are tables - they want the width. */

.shell { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; flex-direction: column; gap: 0;
  padding: 0 1.6rem .7rem;
  background: var(--raised); border-bottom: 1px solid var(--rule);
}

/* The masthead sits centred over the menu, with the version pill parked
   at the right without pulling the name off centre - it is absolute, so
   it takes no part in the centring. The menu button stays on the left
   edge on a phone, where the pill and the name share the row instead. */
/* The logo band. Black edge to edge - the mark is white artwork and
   disappears on the paper ground - but only here: the menu below it and
   the page under that stay light. The negative margins cancel the bar's
   own side padding so the black reaches both edges. */
.masthead-row {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: .5rem 1rem;
  margin: 0 -1.6rem; padding: .9rem 1.6rem 1.15rem;
  background: #000;
}

.brand { display: block; text-decoration: none; text-align: center; }
/* The artwork carries a wide margin of its own, so the box has to be set
   well above the size the mark should read at. */
.brand .logo {
  display: block; margin: 0 auto;
  width: auto; height: 5.4rem; max-width: 100%;
}
.brand span {
  display: block; margin-top: .3rem;
  font: 600 .72rem/1.4 var(--sans); letter-spacing: .18em;
  text-transform: uppercase; color: #cfd2d8;
}
/* The actions sit on the black band, parked at the right. Absolute, so
   the logo stays centred on the band rather than being shoved left by
   whatever sits beside it - and the menu below centres under the logo. */
.masthead-row .navtail {
  position: absolute; right: 1.6rem; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: .6rem;
}
.masthead-row .pill {
  border-color: #4a4d54; color: #cfd2d8; background: transparent;
}

/* The prism: white light through the edge of the masthead. Once, and small. */
.spectrum {
  height: 2px;
  background: linear-gradient(90deg, #d9534f, #e8a33d, #e3d04a, #4fa86a, #3f7fd0, #7a5bc4);
}

.sitenav { margin-left: 0; padding-top: .85rem; }

.nav {
  display: flex; align-items: stretch; justify-content: center;
  flex-wrap: wrap; gap: .1rem .35rem;
}
.nav a {
  display: flex; align-items: baseline; gap: .45rem; white-space: nowrap;
  padding: .5rem .7rem; border-radius: 5px; text-decoration: none;
  font-size: .95rem; color: var(--ink-soft);
}
.nav a:hover { background: var(--sunken); color: var(--ink); }
/* No weight here. This selector outranks the top-level rule below, so the
   600 it used to carry made the page you are ON lighter than every other
   item in the bar - the one inconsistency nobody could unsee. Weight is
   decided in one place, further down. */
.nav a[aria-current="page"] { background: var(--sunken); color: var(--ink); }
.nav > h3 { display: none; }          /* section labels are implicit up here */

.nav .n {
  display: flex; align-items: baseline; gap: .3rem;
  font: 600 .7rem/1 var(--mono); color: var(--ink-faint); flex: none;
}
.nav .n .issues { color: var(--missing); font-weight: 700; white-space: nowrap; }
.nav .n .total { font-style: normal; color: var(--ink-faint); font-weight: 400; }

/* A group is a dropdown: its summary sits in the bar, its sections fall
   beneath it rather than pushing the bar wider. */
.nav details.drop { position: relative; }
.nav details.drop > summary {
  display: flex; align-items: baseline; gap: .4rem; white-space: nowrap;
  padding: .5rem .7rem; border-radius: 5px; cursor: pointer; list-style: none;
  font: 400 .95rem/1.5 var(--sans); color: var(--ink-soft);
}
.nav details.drop > summary::-webkit-details-marker { display: none; }
.nav details.drop > summary::after {
  content: "\25BE"; font-size: .62rem; color: var(--ink-faint);
}
.nav details.drop > summary:hover { background: var(--sunken); color: var(--ink); }
.nav details.drop[open] > summary { background: var(--sunken); color: var(--ink); }

.nav details.drop > .panel {
  position: absolute; top: calc(100% + .35rem); left: 0; z-index: 40;
  display: flex; flex-direction: column; gap: .05rem;
  min-width: max-content; padding: .35rem;
  border: 1px solid var(--rule); border-radius: 6px;
  background: var(--raised); box-shadow: 0 6px 22px rgba(0, 0, 0, .13);
}
.nav details.drop:last-child > .panel { left: auto; right: 0; }
.nav details.drop > .panel a { justify-content: space-between; gap: 1.4rem; }

.main {
  width: 100%; max-width: 96rem; margin: 0 auto;
  padding: 2rem 2.4rem 6rem;
}

/* --------------------------------------------------------------- header */

.masthead { border-bottom: 1px solid var(--rule); padding-bottom: 1.1rem; margin-bottom: 2rem; }
.masthead h1 { font-size: 1.6rem; line-height: 1.2; margin: 0 0 .5rem; text-wrap: balance; }
.meta {
  display: flex; flex-wrap: wrap; gap: .3rem 1.4rem;
  font: .78rem/1.5 var(--mono); color: var(--ink-soft);
}
.meta b { color: var(--ink); font-weight: 600; }

.pill {
  display: inline-block; padding: .08rem .45rem; border-radius: 3px;
  font: 600 .7rem/1.6 var(--mono); letter-spacing: .04em;
  border: 1px solid currentColor;
}
.pill.draft     { color: var(--unclear); }
.pill.published { color: var(--verified); }

/* ---------------------------------------------------------------- cards */

.grid { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }

.card {
  background: var(--raised); border: 1px solid var(--rule); border-radius: 6px;
  padding: .85rem .95rem; text-decoration: none; display: block;
}
.card:hover { border-color: var(--ink-faint); }
.card h3 { margin: 0 0 .5rem; font-size: .93rem; }
.card .bar { display: flex; height: 5px; border-radius: 3px; overflow: hidden; background: var(--sunken); margin-bottom: .45rem; }
.card .bar i { display: block; }
.card .tally { font: .72rem/1.5 var(--mono); color: var(--ink-soft); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: .8rem; margin-bottom: 2rem; }
.stat { background: var(--raised); border: 1px solid var(--rule); border-radius: 6px; padding: .7rem .85rem; }
.stat b { display: block; font: 700 1.5rem/1.1 var(--mono); font-variant-numeric: tabular-nums; }
.stat span { font-size: .75rem; color: var(--ink-soft); }
.stat.warn b { color: var(--missing); }

/* --------------------------------------------------------- requirements */

.req {
  border: 1px solid var(--rule); border-left-width: 3px; border-radius: 5px;
  background: var(--raised); padding: .85rem 1rem; margin-bottom: .7rem;
}
.req.s-VERIFIED      { border-left-color: var(--verified); }
.req.s-UNCLEAR       { border-left-color: var(--unclear); }
.req.s-MISSING       { border-left-color: var(--missing); }
.req.s-CONTRADICTORY { border-left-color: var(--contradictory); }

.req-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; margin-bottom: .4rem; }
.rid { font: 700 .8rem/1 var(--mono); letter-spacing: .02em; }
.tag {
  font: 600 .67rem/1.7 var(--mono); letter-spacing: .05em;
  padding: 0 .4rem; border-radius: 3px;
}
.tag.VERIFIED      { color: var(--verified);      background: var(--verified-bg); }
.tag.UNCLEAR       { color: var(--unclear);       background: var(--unclear-bg); }
.tag.MISSING       { color: var(--missing);       background: var(--missing-bg); }
.tag.CONTRADICTORY { color: var(--contradictory); background: var(--contradictory-bg); }
.tag.prio { color: var(--ink-soft); background: var(--sunken); }
.qty { margin-left: auto; font: 600 .8rem/1 var(--mono); font-variant-numeric: tabular-nums; }

.req p { margin: 0 0 .5rem; max-width: var(--measure); }
.question {
  margin: .55rem 0 .3rem; padding: .5rem .7rem; border-radius: 4px;
  background: var(--sunken); font-size: .87rem; max-width: var(--measure);
}
/* Scoped to .question, not to .req: the requirements moved into a table and
 * the label ran straight into its own sentence. */
.question b { display: block; font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: .2rem; }
.note, .req .note { font-size: .84rem; color: var(--ink-soft); max-width: var(--measure); margin: .35rem 0; }

.cites { list-style: none; margin: .5rem 0 0; padding: 0; display: flex;
  flex-direction: column; gap: .3rem; }
.cites li { font-size: .82rem; color: var(--ink-soft); padding-left: .85rem; position: relative; }
.cites li::before { content: "↳"; position: absolute; left: 0; color: var(--ink-faint); }
.cites .q { font-style: italic; color: var(--ink); }
.cites .where { font-family: var(--mono); font-size: .76rem; }
.cites .absent { color: var(--missing); }
/* An override by the production, shown as an override. The document it
 * supersedes stays listed directly beneath it, still quoted. */
.cites li.stated { color: var(--ink); }
.cites li.stated::before { content: "★"; color: var(--unclear); }
.cites li.stated b { color: var(--unclear); }

/* The outstanding list: one row per unanswered item, scannable by status and
 * clickable through to the full requirement. Severity is carried by a left
 * edge rather than a badge, so a column of them reads as a shape. */
.items { display: flex; flex-direction: column; gap: .35rem; margin-bottom: 2rem; }
.items .group {
  font: 600 .7rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); margin: 1.2rem 0 .3rem;
}
.items .group:first-child { margin-top: 0; }
.item {
  display: grid; grid-template-columns: 6.2rem 11rem minmax(0, 1fr);
  gap: .1rem .8rem; align-items: baseline; text-decoration: none;
  padding: .55rem .8rem; border: 1px solid var(--rule); border-left-width: 3px;
  border-radius: 4px; background: var(--raised);
}
.item:hover { border-color: var(--ink-faint); background: var(--sunken); }
.item.s-VERIFIED      { border-left-color: var(--verified); }
.item.s-UNCLEAR       { border-left-color: var(--unclear); }
.item.s-MISSING       { border-left-color: var(--missing); }
.item.s-CONTRADICTORY { border-left-color: var(--contradictory); }
.item .rid { font: 700 .76rem/1.5 var(--mono); }
.item .where { font: .72rem/1.5 var(--mono); color: var(--ink-faint); }
.item .what { font-size: .87rem; }
.item .ask {
  grid-column: 3; font-size: .8rem; color: var(--ink-soft);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
a.stat { text-decoration: none; display: block; }
a.stat:hover { border-color: var(--ink-faint); }

@media (max-width: 52rem) {
  .item { grid-template-columns: 1fr; }
  .item .ask { grid-column: 1; }
}

/* A fact that is easy to miss because it is stated once and applies widely.
 * Loud on purpose, and repeated on every requirement it governs. */
.highlight {
  margin: .55rem 0 .4rem; padding: .5rem .7rem .5rem .85rem;
  border-left: 3px solid var(--ink); border-radius: 0 4px 4px 0;
  background: var(--sunken); max-width: var(--measure);
  font-size: .87rem; font-weight: 600;
}

/* Citations are there to be followed. An affordance you have to hover to find
 * is one most readers never use, so the link is a button and it is visible. */
a.open {
  /* Block-level, not inline: beside a long quotation an inline button lands on
   * the same line and sits on top of the words it is meant to support. */
  display: flex; width: fit-content; max-width: 100%;
  align-items: baseline; gap: .45rem; margin-top: .4rem;
  padding: .3rem .6rem; border: 1px solid var(--rule); border-radius: 4px;
  background: var(--paper); text-decoration: none;
  font: 600 .78rem/1.3 var(--sans); color: var(--ink);
}
a.open::before { content: "⤢"; color: var(--ink-faint); }
a.open:hover { border-color: var(--ink); background: var(--sunken); }
a.open .what { font: 400 .74rem/1.3 var(--mono); color: var(--ink-soft); }
.cites a.open { margin-left: -.85rem; }
.file a.open { margin-top: .5rem; }
.open-inline {
  margin-top: .5rem; font: 600 .75rem/1 var(--sans); color: var(--ink-soft);
}
.card:hover .open-inline { color: var(--ink); }

/* ----------------------------------------------------------------- gaps */

.con { border: 1px solid var(--rule); border-radius: 5px; background: var(--raised);
  padding: .9rem 1rem; margin-bottom: .8rem; border-top: 3px solid var(--minor); }
.con.CRITICAL    { border-top-color: var(--critical); }
.con.OPERATIONAL { border-top-color: var(--operational); }
.con h3 { margin: 0 0 .45rem; font-size: .95rem; display: flex; gap: .55rem; align-items: baseline; }
.con .sev { font: 700 .68rem/1.7 var(--mono); letter-spacing: .06em; }
.con.CRITICAL .sev    { color: var(--critical); }
.con.OPERATIONAL .sev { color: var(--operational); }
.con.MINOR .sev       { color: var(--minor); }
.con dl { display: grid; grid-template-columns: max-content minmax(0,1fr); gap: .25rem .8rem;
  margin: .6rem 0 0; font-size: .85rem; }
.con dt { font: 600 .7rem/1.7 var(--mono); color: var(--ink-faint); }
.con dd { margin: 0; }

/* -------------------------------------------------------------- sources */

.tree { list-style: none; padding: 0; margin: 0; }
.tree .folder { font: 600 .8rem/2 var(--mono); color: var(--ink-faint);
  letter-spacing: .03em; margin-top: 1rem; }
.file { border: 1px solid var(--rule); border-radius: 5px; background: var(--raised);
  padding: .7rem .9rem; margin-bottom: .5rem; }
.file h4 { margin: 0 0 .35rem; font-size: .9rem; font-family: var(--mono); }
.file .facts { display: flex; flex-wrap: wrap; gap: .2rem 1.1rem;
  font: .74rem/1.6 var(--mono); color: var(--ink-soft); }
.file .derived { margin-top: .45rem; font-size: .8rem; color: var(--ink-soft); }
.file .derived a { font-family: var(--mono); font-size: .76rem; }
.file.binary { border-style: dashed; }
.file .warn { color: var(--missing); font-size: .82rem; margin-top: .4rem; max-width: var(--measure); }

/* --------------------------------------------------------------- viewer */

.viewer { border: 1px solid var(--rule); border-radius: 6px; overflow: hidden;
  background: var(--sunken); }
.viewer-bar { display: flex; align-items: center; gap: .4rem; padding: .45rem .6rem;
  border-bottom: 1px solid var(--rule); background: var(--raised); }
.viewer-bar button {
  font: 600 .78rem/1 var(--sans); padding: .38rem .6rem; border-radius: 4px;
  border: 1px solid var(--rule); background: var(--paper); color: var(--ink); cursor: pointer;
}
.viewer-bar button:hover { border-color: var(--ink-faint); }
.viewer-bar .zoom { margin-left: auto; font: .75rem/1 var(--mono); color: var(--ink-soft); }
.stage { position: relative; overflow: auto; height: 74vh; background: #fff; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .stage { background: #e9e9e6; } }
/* .canvas carries the scrollable (scaled) size; .layer holds tiles at the
 * pyramid level's own pixel coordinates and is scaled into it. Transform does
 * not affect layout, so without the two elements the scrollbars would describe
 * the wrong size. */
.canvas { position: relative; }
.layer { position: absolute; inset: 0 auto auto 0; transform-origin: 0 0; }
.layer img { position: absolute; display: block; image-rendering: auto; }

/* ---------------------------------------------------------------- misc */

table { border-collapse: collapse; width: 100%; font-size: .85rem; }
th, td { text-align: left; padding: .4rem .6rem; border-bottom: 1px solid var(--rule-soft); }
th { font: 600 .7rem/1.8 var(--mono); letter-spacing: .06em; color: var(--ink-faint);
  text-transform: uppercase; }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.scroll-x { overflow-x: auto; }

h2 { font-size: 1.12rem; margin: 2.2rem 0 .8rem; padding-bottom: .3rem;
  border-bottom: 1px solid var(--rule-soft); }
h2:first-of-type { margin-top: 0; }
.lede { color: var(--ink-soft); max-width: var(--measure); margin: -.3rem 0 1.5rem; }

.banner { border: 1px solid var(--missing); background: var(--missing-bg); color: var(--missing);
  border-radius: 5px; padding: .7rem .9rem; font-size: .87rem; margin-bottom: 1.5rem; }
.banner b { display: block; margin-bottom: .2rem; }

.actions { display: flex; gap: .5rem; margin: 1.2rem 0 0; }
.actions button, .actions a.btn {
  font: 600 .8rem/1 var(--sans); padding: .5rem .8rem; border-radius: 4px;
  border: 1px solid var(--rule); background: var(--raised); color: var(--ink);
  cursor: pointer; text-decoration: none;
}
.actions button:hover, .actions a.btn:hover { border-color: var(--ink-faint); }

footer { margin-top: 4rem; padding-top: 1rem; border-top: 1px solid var(--rule);
  font-size: .78rem; color: var(--ink-faint); max-width: var(--measure); }

/* ---------------------------------------------------------------- mobile

   The bar becomes a drawer. Stacked, the reader scrolls past every section
   to reach the content on every page. */

.scrim { display: none; }
.menu { display: none; }

@media (max-width: 68rem) {
  .topbar { padding: 0 .9rem .6rem; gap: 0; }
  .masthead-row { margin: 0 -.9rem; padding: .85rem .9rem; }
  .masthead-row .pill { right: .9rem; }
  .brand .logo { height: 3.4rem; margin: 0; }
  .brand span { font-size: .6rem; letter-spacing: .12em; margin-top: .2rem; }
  /* Logo left, hamburger right, one line. The brand was taking its full
     content width - a 142px mark plus forty characters of subtitle - and
     pushing the button onto a line of its own. It shrinks now, and the
     subtitle wraps inside it rather than shoving the menu down. */
  .masthead-row { justify-content: space-between; align-items: center; }
  .brand {
    order: 1; text-align: left; flex: 1 1 0; min-width: 0;
  }
  .brand .logo { margin: 0; }
  .brand span { white-space: normal; }
  .menu { order: 2; flex: 0 0 auto; margin-left: .8rem; align-self: center; }

  .menu {
    display: flex; align-items: center; gap: .5rem; margin-left: auto;
    font: 600 .85rem/1 var(--sans); color: var(--ink);
    padding: .5rem .7rem; border: 1px solid var(--rule); border-radius: 5px;
    background: var(--paper); cursor: pointer;
  }
  .menu .bars, .menu .bars::before, .menu .bars::after {
    display: block; width: 15px; height: 2px; background: currentColor;
    border-radius: 2px; content: "";
  }
  .menu .bars { position: relative; }
  .menu .bars::before { position: absolute; top: -5px; }
  .menu .bars::after  { position: absolute; top: 5px; }

  .sitenav {
    margin-left: 0;
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 40;
    width: min(23rem, 88vw); height: 100dvh; overflow-y: auto;
    margin-left: 0; padding: 1.2rem 1rem 4rem;
    background: var(--raised); border-right: 1px solid var(--rule);
    transform: translateX(-100%); transition: transform .18s ease-out;
  }
  body.nav-open .sitenav { transform: none; }
  body.nav-open { overflow: hidden; }

  /* The drawer lives inside the sticky top bar, and a positioned element with
     a z-index makes a stacking context: the drawer's z-index is ranked among
     the bar's children, never against the scrim outside it. So the bar itself
     has to clear the scrim, or the scrim paints over the open drawer. */
  body.nav-open .topbar { z-index: 45; }

  body.nav-open .scrim {
    display: block; position: fixed; inset: 0; z-index: 35;
    background: rgba(0, 0, 0, .42);
  }

  /* Down here a group is a list that opens in place, not a floating panel. */
  .nav { flex-direction: column; align-items: stretch; gap: .1rem; }
  .nav details.drop > .panel {
    position: static; border: 0; box-shadow: none; background: none;
    padding: .1rem 0 .3rem .9rem; min-width: 0;
  }
  .nav details.drop > summary::after { margin-left: auto; }
  .nav a, .nav details.drop > summary { white-space: normal; }

  .main { padding: 1.4rem 1.05rem 4rem; }
  .masthead h1 { font-size: 1.32rem; }
  .stats { grid-template-columns: repeat(auto-fit, minmax(6.4rem, 1fr)); gap: .5rem; }
  .stat { padding: .55rem .6rem; }
  .stat b { font-size: 1.25rem; }
  .grid { grid-template-columns: 1fr; }
  .req { padding: .75rem .8rem; }
  .qty { margin-left: 0; width: 100%; }
  a.open { width: 100%; }
  .con dl { grid-template-columns: 1fr; gap: .1rem; }
  .stage { height: 62vh; }
  .viewer-bar { flex-wrap: wrap; }
  .viewer-bar .zoom { width: 100%; margin-left: 0; order: 3; }
  .item { grid-template-columns: 1fr; }
  .item .ask { grid-column: 1; }
  table.requirements .c-item, table.requirements .c-type { width: auto; }
  table.channels, table.checklist { font-size: .78rem; }
  h2 { font-size: 1.02rem; margin-top: 1.8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .sitenav { transition: none; }
}

@media print {
  .sitenav, .actions, .viewer-bar, .topbar, .scrim, .spectrum { display: none !important; }
  .shell { display: block; }
  .main { padding: 0; max-width: none; }
  body { background: #fff; color: #000; font-size: 10.5pt; }
  .req, .con, .file, .card { break-inside: avoid; border-color: #bbb; background: #fff; }
  .stage { height: auto; overflow: visible; }
  a { text-decoration: none; }
  .req .question { background: #f2f2f2; }
}

/* ------------------------------------------------- transcribed documents */

.tablebar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem;
  margin: 0 0 .7rem;
}
.tablebar input[type="search"] {
  flex: 1 1 16rem; min-width: 0;
  padding: .45rem .65rem; border: 1px solid var(--rule); border-radius: 5px;
  background: var(--raised); color: var(--ink); font: 400 .87rem/1.3 var(--sans);
}
.tablebar label {
  display: flex; align-items: center; gap: .4rem;
  font-size: .82rem; color: var(--ink-soft); white-space: nowrap;
}
.tablebar .count { font: .75rem/1 var(--mono); color: var(--ink-faint); }

table.channels { font: .82rem/1.45 var(--sans); }
table.channels thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--raised); border-bottom: 1px solid var(--rule);
}
table.channels td { vertical-align: top; }
table.channels .c-ch, table.channels .c-input {
  font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.channels .c-ch { font-weight: 700; }
table.channels .c-mic, table.channels .c-di { font-family: var(--mono); font-size: .78rem; }
table.channels .nil { color: var(--ink-faint); }
table.channels tr.blank td { color: var(--ink-faint); background: var(--sunken); }
table.channels tr:target { outline: 2px solid var(--ink); outline-offset: -2px; }

/* A conflict is shown on the channel it affects, not in a separate report. */
table.channels tr.critical > td { background: var(--missing-bg); }
table.channels tr.warning  > td { background: var(--unclear-bg); }
table.channels tr.minor    > td { background: var(--sunken); }
.flag { font: 700 .68rem/1.6 var(--mono); white-space: nowrap; }
tr.critical .flag { color: var(--missing); }
tr.warning  .flag { color: var(--unclear); }
tr.minor    .flag { color: var(--ink-soft); }

tr.alert-row td {
  font-size: .82rem; padding: .45rem .6rem .6rem 1.6rem;
  border-bottom: 1px solid var(--rule);
}
tr.alert-row.critical td { background: var(--missing-bg); color: var(--missing); }
tr.alert-row.warning  td { background: var(--unclear-bg); color: var(--unclear); }
tr.alert-row.minor    td { background: var(--sunken); color: var(--ink-soft); }
tr.alert-row a { font-family: var(--mono); font-weight: 700; }

ol.aux { font-size: .87rem; padding-left: 1.4rem; max-width: none; }
ol.aux li { font-family: var(--mono); font-size: .8rem; margin: .12rem 0; }

/* A reproduced document is a list of equipment, not an essay. The 68ch
 * reading measure that suits prose just wrapped every line at half the width
 * of the box it sits in and left the rest empty. These run full width. */
ul.doc { padding-left: 1.15rem; max-width: none; }
ul.doc li { margin: .25rem 0; font-size: .88rem; break-inside: avoid; }
ul.doc ul { padding-left: 1.1rem; margin: .2rem 0; }
p.docline {
  max-width: none; margin: .7rem 0 .3rem;
  font-size: .88rem; font-weight: 600;
}
.document > .lede, .document .banner { max-width: none; }

@media (max-width: 62rem) {
  table.channels { font-size: .78rem; }
  .tablebar label { width: 100%; }
}

/* ------------------------------------------------------ source documents */

.docs-head { margin-top: 2.8rem; }

.document {
  border: 1px solid var(--rule); border-radius: 7px; background: var(--raised);
  padding: 1.1rem 1.2rem 1.3rem; margin: 1rem 0 1.4rem;
}
.document > h2 { margin-top: 0; border-bottom: 0; padding-bottom: 0; }
.document > .lede { margin: .1rem 0 .7rem; }
.document h3 { font-size: .9rem; margin: 1.4rem 0 .5rem; }
.document.binary { border-style: dashed; }

.provenance {
  display: flex; flex-wrap: wrap; align-items: center; gap: .45rem 1rem;
  padding-bottom: .85rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--rule-soft);
}
.provenance .where { font: .74rem/1.5 var(--mono); color: var(--ink-faint); }
.provenance a.open { margin: 0 0 0 auto; }

.banner.soft {
  border-color: var(--rule); background: var(--sunken); color: var(--ink-soft);
}
.banner.soft b { color: var(--ink); }

.xrefs { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
.xref {
  display: block; padding: .6rem .8rem; border: 1px solid var(--rule);
  border-radius: 5px; background: var(--raised); text-decoration: none;
}
.xref:hover { border-color: var(--ink-faint); }
.xref b { display: block; font-size: .87rem; }
.xref span { font-size: .78rem; color: var(--ink-soft); }

.con.done { opacity: .72; }
.con.done .tag { margin-left: auto; }

@media (max-width: 62rem) {
  .document { padding: .85rem .8rem 1rem; }
  .provenance a.open { margin-left: 0; }
}

/* ----------------------------------------------------------------- tabs */

.tabs {
  display: flex; align-items: center; gap: .3rem;
  border-bottom: 1px solid var(--rule); margin: 1.4rem 0 1.6rem;
}
.tabs [role="tab"] {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .55rem .9rem; margin-bottom: -1px; cursor: pointer;
  border: 1px solid transparent; border-bottom: 2px solid transparent;
  border-radius: 5px 5px 0 0; background: none; color: var(--ink-soft);
  font: 600 .88rem/1.2 var(--sans);
}
.tabs [role="tab"]:hover { color: var(--ink); background: var(--sunken); }
.tabs [role="tab"][aria-selected="true"] {
  color: var(--ink); border-bottom-color: var(--ink); background: none;
}
.tabs [role="tab"] .n { gap: .3rem; }
.tabs .printall {
  margin-left: auto; padding: .4rem .7rem; cursor: pointer;
  border: 1px solid var(--rule); border-radius: 4px;
  background: var(--raised); color: var(--ink); font: 600 .78rem/1 var(--sans);
}
.tabs .printall:hover { border-color: var(--ink-faint); }

[id^="panel-requirements"] > .req:first-child { margin-top: 0; }
[id^="panel-content"] > .document:first-of-type { margin-top: 0; }

@media print {
  /* Both panels, always. A rider that dropped its requirements because a tab
   * happened to be closed would be actively dangerous. */
  .tabs { display: none !important; }
  [role="tabpanel"][hidden] { display: block !important; }
  [role="tabpanel"]::before {
    display: block; margin: 1.2rem 0 .5rem; font-weight: 700; font-size: 12pt;
  }
  [id^="panel-requirements"]::before { content: "Requirements"; }
}

@media (max-width: 62rem) {
  .tabs { gap: 0; }
  .tabs [role="tab"] { padding: .5rem .6rem; font-size: .82rem; }
  .tabs .printall { display: none; }
}

ol.aux li.flagged { color: var(--unclear); }
.aux-alert {
  display: block; margin: .15rem 0 .4rem;
  font: 400 .78rem/1.45 var(--sans); color: var(--unclear);
}
.aux-alert.critical { color: var(--missing); }
.aux-alert a { font-family: var(--mono); font-weight: 700; }

.group-head {
  margin: 1.5rem 0 .5rem; padding-bottom: .3rem;
  border-bottom: 1px solid var(--rule-soft);
  font: 700 .74rem/1.4 var(--sans); letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft);
}
.group-head:first-child { margin-top: .2rem; }

ul.doc li.flagged { color: var(--unclear); }
.item-note {
  display: block; margin: .2rem 0 .45rem;
  font: 400 .8rem/1.45 var(--sans); color: var(--unclear);
}
.item-note.critical { color: var(--missing); }
.item-note a { font-family: var(--mono); font-weight: 700; }

/* ----------------------------------------------------------- checklist */

table.checklist { font: .86rem/1.45 var(--sans); margin-bottom: .5rem; }
table.checklist thead th {
  position: sticky; top: 0; z-index: 2; background: var(--raised);
  border-bottom: 1px solid var(--rule);
}
table.checklist td { vertical-align: top; }
/* The box sits on the FIRST LINE of the item, not in the middle of the row:
   a three-line row still has to tick beside its name. Measured rather than
   guessed - at .55rem the box fell 4.8px below the line centre on the
   backline and 2.7px below it on the requirements tables, which have a
   different cell padding and a 17px line box against the backline's 16px.
   Two values because they are two line boxes; both verified at 0.0px. */
table.checklist .c-tick { padding-top: .25rem; }
table.checklist .c-tick input { width: 1.05rem; height: 1.05rem; cursor: pointer; }
table.checklist .c-qty {
  width: 4rem; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 700;
}
/* A quantity the document does not state is shown, but never as though the
 * document said it. */
table.checklist .c-qty .assumed { font-weight: 400; color: var(--ink-faint); }
table.checklist .c-note { color: var(--ink-soft); font-size: .82rem; }
table.checklist .c-note .sub { display: block; }
table.checklist tr.flagged .c-name { color: var(--unclear); }
table.checklist tr:has(input:checked) .c-name {
  color: var(--ink-faint); text-decoration: line-through;
}
.checklist-bar {
  display: flex; align-items: center; gap: .8rem; margin: .2rem 0 .8rem;
  font: .78rem/1 var(--mono); color: var(--ink-faint);
}
/* Lifted into the masthead, under the item counts: one line, and it keeps
   its place when the columns stack on a phone. */
.checklist-bar.inmeta {
  margin: .45rem 0 0; gap: .7rem; flex-wrap: nowrap;
  white-space: nowrap; overflow-x: auto; scrollbar-width: none;
}
.checklist-bar.inmeta::-webkit-scrollbar { display: none; }
.checklist-bar.inmeta button { padding: .28rem .5rem; flex: none; }

/* The sentence that says ticks are private matters - nobody should think
   a ticked page is a submitted response - so on a narrow screen it is
   shortened rather than cut off mid-word by the overflow. */
.tnote-short { display: none; }
@media (max-width: 34rem) {
  .checklist-bar .tnote { display: none; }
  .checklist-bar .tnote-short { display: inline; }
}
.checklist-bar button {
  font: 600 .75rem/1 var(--sans); padding: .35rem .6rem; cursor: pointer;
  border: 1px solid var(--rule); border-radius: 4px;
  background: var(--raised); color: var(--ink);
}

@media print {
  table.checklist .c-tick input { -webkit-appearance: none; appearance: none;
    border: 1px solid #555; border-radius: 2px; }
  .checklist-bar { display: none; }
}

/* --------------------------------------------------- the original, folded */

details.original { margin-top: 1.2rem; border-top: 1px solid var(--rule-soft); }
details.original > summary {
  display: flex; align-items: baseline; gap: .6rem; cursor: pointer;
  padding: .7rem .2rem .2rem; list-style: none;
  font: 600 .88rem/1.4 var(--sans); color: var(--ink);
}
details.original > summary::-webkit-details-marker { display: none; }
details.original > summary::before {
  content: "\203A"; font-size: 1.05rem; line-height: 1; color: var(--ink-faint);
  transition: transform .15s ease-out;
}
details.original[open] > summary::before { transform: rotate(90deg); }
details.original > summary:hover { color: var(--ink); }
details.original > summary:hover .hint { color: var(--ink-soft); }
details.original .hint {
  margin-left: auto; font: 400 .76rem/1.4 var(--mono); color: var(--ink-faint);
}
details.original[open] .hint { visibility: hidden; }
details.original .viewer { margin-top: .6rem; }

@media print {
  /* A printed rider carries the drawings. */
  details.original { display: block; }
  details.original > summary { list-style: none; }
  details.original:not([open]) > *:not(summary) { display: revert !important; }
}
@media (prefers-reduced-motion: reduce) {
  details.original > summary::before { transition: none; }
}

/* Navigation groups: five headings a supplier recognises, opening onto the
 * sections underneath them. */
/* Left over from the sidebar, and more specific than the rule that sets the
 * top bar's casing - so the group headings stayed title case and darker
 * while every other top-level item was uppercase and soft. They match now. */
/* Nothing in the menu is bold until it is the page you are on. */
/* Longhands, not a `font:` shorthand. This selector carries three classes
   and outranks every weight rule in the file, so a shorthand here silently
   reset the weight and left exactly the dropdown groups - and only those -
   looking lighter than the plain links beside them. Weight is set once,
   further down; nothing in this rule is allowed to touch it. */
.nav details.drop.section > summary {
  font-family: var(--sans); font-size: .82rem; line-height: 1.5;
  letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-soft);
}
.nav details.drop.section > summary::after { margin-left: .3rem; order: 3; }
.nav details.drop.section > summary .n { order: 2; margin-left: auto; }
.nav details.drop.section > .panel a { font-size: .9rem; }
.nav details.drop.section { margin-bottom: .15rem; }

.group-title {
  display: flex; align-items: baseline; gap: .6rem;
  margin: 1.8rem 0 .6rem; font-size: .95rem;
}
.group-title .n {
  display: flex; gap: .35rem; font: 600 .72rem/1 var(--mono);
  color: var(--ink-faint);
}
.group-title .n .issues { color: var(--missing); font-weight: 700; }
.group-title .n .total { font-style: normal; font-weight: 400; }
.group-title + .grid { margin-bottom: .4rem; }

/* ------------------------------------------------------- a file to take */

.filecard {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.2rem;
  padding: 1rem 1.1rem; margin: .8rem 0 1rem;
  border: 1px solid var(--rule); border-radius: 6px; background: var(--sunken);
}
.filecard .filename {
  flex: 1 1 18rem; min-width: 0; font: 700 .95rem/1.4 var(--mono);
  word-break: break-word;
}
.filecard .filemeta {
  flex: 1 1 100%; order: 3; display: flex; flex-wrap: wrap; gap: .2rem 1.1rem;
  font: .74rem/1.5 var(--mono); color: var(--ink-faint);
}
a.download {
  order: 2; padding: .6rem 1rem; border-radius: 5px; text-decoration: none;
  border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
  font: 600 .85rem/1 var(--sans); white-space: nowrap;
}
a.download:hover { opacity: .88; }
a.download::before { content: "↓ "; }

.dochead {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem 1rem;
  margin-bottom: .2rem;
}
.dochead h2 { margin: 0; border-bottom: 0; padding-bottom: 0; flex: 1 1 auto; }
.dochead a.open { margin-top: 0; flex: none; }

/* ------------------------------------------------- requirements as items */

table.requirements td { padding: .5rem .6rem; vertical-align: top; }
table.requirements .c-tick { padding-top: .38rem; }
table.requirements .c-item { width: 11rem; }
table.requirements .c-type { width: 17rem; font-size: .84rem; }
table.requirements .c-desc { font-size: .85rem; color: var(--ink-soft); }
table.requirements .iname {
  display: block; font: 600 .89rem/1.35 var(--sans); color: var(--ink);
}
table.requirements .rid {
  font: 600 .68rem/1.6 var(--mono); color: var(--ink-faint); text-decoration: none;
}
table.requirements .rid:hover { color: var(--ink); }
table.requirements .rq {
  display: block; margin-top: .2rem;
  font: 700 .76rem/1.4 var(--mono); font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
table.requirements .src {
  display: inline-block; margin-left: .4rem;
  font: .72rem/1.5 var(--mono); color: var(--ink-faint);
}
table.requirements .src::before { content: "⤢ "; }
table.requirements .src:hover { color: var(--ink); }
/* No status stripe on the row. It was a 3px inset shadow on the first
   cell, which in the card layout lands beside the checkbox as a stray
   coloured bar - and on any layout it was saying a second time what the
   alert row underneath already says in words. A verified row needs no
   mark at all; an open one has its own line. */
table.requirements tr:target { outline: 2px solid var(--ink); outline-offset: -2px; }
table.requirements tr:has(input:checked) .iname {
  color: var(--ink-faint); text-decoration: line-through;
}

@media (max-width: 62rem) {
  table.requirements .c-item,
  table.requirements .c-type { width: auto; }
}

details.srcbox { margin-top: .4rem; }
/* The citation is evidence, wanted occasionally. As a visible block under
 * every row it was a paragraph of provenance between every two items. */
details.srcbox > summary {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.15rem; height: 1.15rem; cursor: pointer; list-style: none;
  border: 1px solid var(--rule); border-radius: 50%;
  font: 700 .7rem/1 var(--sans); font-style: italic;
  color: var(--ink-faint); background: var(--raised);
}
details.srcbox > summary::-webkit-details-marker { display: none; }
details.srcbox > summary:hover { color: var(--ink); border-color: var(--ink-faint); }
details.srcbox[open] > summary { color: var(--ink); border-color: var(--ink); }
/* Visible to screen readers, not on screen. */
.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
details.srcbox .cites { margin-top: .35rem; }
details.srcbox .cites li { font-size: .78rem; }
/* The rider does not carry the evidence boxes. A printed page cannot be
   clicked, so an unfolded citation is just the same statement again in
   smaller type under every row - and the whole document is cited on the
   site, where the reader can actually open the source. */
@media print { details.srcbox { display: none !important; } }

table.requirements .borrowed-note {
  display: block; margin-top: .15rem;
  font: .68rem/1.4 var(--mono); color: var(--ink-faint);
}
/* No tint on a borrowed row. The little line under the name already says
   where it is owned, and a grey band reads as "disabled" to everyone who
   has not read the legend - which is everyone. */
table.requirements tr.borrowed td { background: none; }

table.checklist .c-name { width: 12rem; font-weight: 600; }
table.checklist .c-spec { font-size: .84rem; }
i.alt {
  font-style: italic; color: var(--ink-faint); font-weight: 400;
  padding: 0 .1rem;
}

i.unspec { font-style: italic; color: var(--ink-faint); }

/* ------------------------------------------------------ clipped notes */

button.more {
  display: inline; padding: 0; margin-left: .2rem; cursor: pointer;
  border: 0; background: none; color: var(--ink);
  font: 600 inherit/inherit var(--sans); font-size: .95em;
  text-decoration: underline; text-underline-offset: 2px;
}
button.more:hover { color: var(--missing); }

dialog.notemodal {
  position: relative;
  max-width: 44rem; width: calc(100% - 2.5rem);
  padding: 1.4rem 1.5rem 1.1rem; border: 1px solid var(--rule);
  border-radius: 8px; background: var(--raised); color: var(--ink);
}
dialog.notemodal::backdrop { background: rgba(0, 0, 0, .45); }
dialog.notemodal .notebody { font-size: .93rem; line-height: 1.6; }
dialog.notemodal form { margin-top: 1.1rem; text-align: right; }
dialog.notemodal button {
  font: 600 .82rem/1 var(--sans); padding: .5rem .9rem; cursor: pointer;
  border: 1px solid var(--rule); border-radius: 5px;
  background: var(--paper); color: var(--ink);
}
@media print { dialog.notemodal { display: none; } }

/* Drawing tabs: seven A3 sheets, one at a time. */
.tabs.drawings { flex-wrap: wrap; margin: .6rem 0 1.4rem; }
.tabs.drawings [role="tab"] { font-size: .83rem; padding: .5rem .75rem; }
[id^="panel-dwg-"] .document { margin-top: 0; }
[id^="panel-dwg-"] details.original { border-top: 0; margin-top: .4rem; }
[id^="panel-dwg-"] details.original > summary { display: none; }

table.review { font-size: .85rem; }
table.review .c-rid { width: 6.5rem; font: 700 .76rem/1.5 var(--mono); }
table.review .c-rid a { text-decoration: none; }
table.review .c-sec { width: 12rem; font-size: .8rem; color: var(--ink-soft); }
table.review .c-what { width: 20rem; font-weight: 600; }
table.review .c-stat { width: 8rem; }
table.review .c-ask { color: var(--ink-soft); }
table.review tr.s-CRITICAL    td:first-child { box-shadow: inset 3px 0 var(--critical); }
table.review tr.s-OPERATIONAL td:first-child { box-shadow: inset 3px 0 var(--operational); }
table.review tr.s-MINOR       td:first-child { box-shadow: inset 3px 0 var(--minor); }
table.review tr.s-CONTRADICTORY td:first-child { box-shadow: inset 3px 0 var(--contradictory); }
table.review tr.s-MISSING     td:first-child { box-shadow: inset 3px 0 var(--missing); }
table.review tr.s-UNCLEAR     td:first-child { box-shadow: inset 3px 0 var(--unclear); }
.tag.CRITICAL    { color: var(--critical);    background: var(--missing-bg); }
.tag.OPERATIONAL { color: var(--operational); background: var(--unclear-bg); }
.tag.MINOR       { color: var(--minor);       background: var(--sunken); }

/* ------------------------------------------------------- review filters */

.chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 .9rem; }
.chip {
  display: inline-flex; align-items: baseline; gap: .45rem; cursor: pointer;
  padding: .4rem .7rem; border: 1px solid var(--rule); border-radius: 999px;
  background: var(--raised); color: var(--ink-soft);
  font: 600 .8rem/1 var(--sans);
}
.chip span {
  font: 700 .72rem/1 var(--mono); font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
.chip:hover { border-color: var(--ink-faint); color: var(--ink); }
.chip[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.chip[aria-pressed="true"] span { color: var(--paper); opacity: .75; }
.chip.s-CRITICAL, .chip.s-MISSING           { color: var(--missing); }
.chip.s-CONTRADICTORY                        { color: var(--contradictory); }
.chip.s-UNCLEAR, .chip.s-OPERATIONAL         { color: var(--unclear); }

/* The notes column is a margin, not a column. Capped so a single long note
 * cannot squeeze the item and type it belongs to. */
/* Fixed, so every group table has the same columns. Sized to content, each
 * group would size itself and the four tables would step in and out down the
 * page - which reads as four different tables rather than one list. */
table.checklist { width: 100%; table-layout: fixed; }
/* The tick column holds a 17px box. It is sized to that and nothing more -
 * on a fixed layout every rem it takes comes off the type column, which is
 * the one carrying the make and model. */
table.checklist .c-tick,
table.requirements .c-tick {
  width: 1.8rem; padding-left: .5rem; padding-right: .25rem;
}
table.checklist .c-name { width: 19%; }
table.checklist .c-spec { width: auto; }      /* the rest */
table.checklist .c-qty  { width: 5%; }
table.checklist .c-note { width: 12%; overflow-wrap: anywhere; }
table.checklist td, table.checklist th { overflow-wrap: break-word; }

/* Left, everywhere. A fixed layout plus tabular numerals had some columns
 * reading as though they were centred. */
table.checklist th, table.checklist td { text-align: left; vertical-align: top; }
table.checklist .c-qty, table.checklist .c-tick { text-align: left; }

/* Category boxes: how much is open, where. */
.stat { display: block; text-decoration: none; }
.stat b { display: block; font: 700 1.6rem/1.1 var(--mono); font-variant-numeric: tabular-nums; }
.stat span { display: block; font: 600 .84rem/1.3 var(--sans); margin-top: .1rem; }
.stat .of { display: block; font: .72rem/1.4 var(--mono); font-style: normal; color: var(--ink-faint); margin-top: .2rem; }
.stat.warn b { color: var(--missing); }
.stat:hover { border-color: var(--ink-faint); }
.stats { grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); }

/* Reference is a utility menu, not a section. It sits apart, on the right. */
.nav details.drop.reference { margin-left: auto; }

/* ------------------------------------------------------- contact page */

/* Two cards, side by side. There are two people on this page and the pair
   is the information: management on the left, technical on the right. The
   grid declaration was here without its `display`, so they stacked. */
.contacts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;
  align-items: stretch; max-width: 46rem;
}
@media (max-width: 40rem) { .contacts { grid-template-columns: 1fr; } }
.contact {
  position: relative; overflow: hidden;
  border: 1px solid var(--rule); border-radius: 8px; background: var(--raised);
  padding: 1.3rem 1.4rem 1.2rem;
}
.contact::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, #d9534f, #e8a33d, #e3d04a, #4fa86a, #3f7fd0, #7a5bc4);
}
.contact .crole {
  font: 600 .66rem/1.6 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint);
}
.contact .cname {
  font: 700 1.3rem/1.25 var(--sans); margin: .3rem 0 .7rem;
  letter-spacing: -.01em;
}
.contact .clines { display: flex; flex-direction: column; gap: .3rem; }
.contact .clines a {
  display: inline-flex; align-items: center; gap: .5rem;
  font: .88rem/1.5 var(--mono); color: var(--ink); text-decoration: none;
  width: fit-content;
}
.contact .clines a:hover { text-decoration: underline; text-underline-offset: 3px; }
.contact .clines a::before {
  display: inline-block; width: 1.1rem; text-align: center;
  color: var(--ink-faint); font-family: var(--sans);
}
.contact .clines a[href^="mailto:"]::before { content: "\2709"; }
.contact .clines a[href^="tel:"]::before { content: "\260E"; }

/* ------------------------------------------------------------- colour

   One hue per category, taken from the prism the show is named after, so
   the colour says which part of the rig you are looking at rather than
   decorating the page. Everything else stays quiet: status keeps its own
   semantic colours and never borrows these. */

.g-0 { --accent: #2f6fb8; --accent-soft: #e3edf9; }  /* Sound       blue   */
.g-1 { --accent: #c4701c; --accent-soft: #fbead9; }  /* Stage       orange */
.g-2 { --accent: #bf3d86; --accent-soft: #fae4f0; }  /* Lights      pink   */
.g-3 { --accent: #c1392f; --accent-soft: #fbe6e4; }  /* LED Screens red    */
.g-4 { --accent: #2b8355; --accent-soft: #e2f1e9; }  /* Backline    green  */
.g-5 { --accent: #6b55b5; --accent-soft: #ebe7f7; }  /* Production  purple */
.g-6 { --accent: #2a7d80; --accent-soft: #e0f0f0; }  /* Contact     teal   */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .g-0 { --accent: #7fb3ec; --accent-soft: #16222f; }
  :root:not([data-theme="light"]) .g-1 { --accent: #e5a35c; --accent-soft: #2e2214; }
  :root:not([data-theme="light"]) .g-2 { --accent: #ef8fc4; --accent-soft: #2e1827; }
  :root:not([data-theme="light"]) .g-3 { --accent: #f08b7c; --accent-soft: #2e1714; }
  :root:not([data-theme="light"]) .g-4 { --accent: #6ed3a2; --accent-soft: #14291f; }
  :root:not([data-theme="light"]) .g-5 { --accent: #b3a2f0; --accent-soft: #201c33; }
  :root:not([data-theme="light"]) .g-6 { --accent: #6cc9cc; --accent-soft: #10272a; }
}

/* The page wears its category. */
body[class*="g-"] .masthead { border-bottom: 2px solid var(--accent); }
body[class*="g-"] .masthead h1 { color: var(--accent); }
body[class*="g-"] h2 { border-bottom-color: var(--accent); }
/* Underlined tabs take the accent as their TEXT colour. The drawing tabs
   are filled pills that take it as their BACKGROUND, so this rule has to
   stay off them - it outranks theirs (an extra element in the selector)
   and was painting the label the same pink as the pill under it. */
body[class*="g-"] .tabs:not(.drawings) [role="tab"][aria-selected="true"] {
  color: var(--accent); border-bottom-color: var(--accent);
}
body[class*="g-"] .group-head { border-bottom-color: var(--accent); color: var(--accent); }

/* Menu: categories in caps, the sections under them as written. */
.nav > a, .nav details.drop > summary {
  text-transform: uppercase; letter-spacing: .07em; font-size: .82rem;
  font-weight: 700;
}
.nav details.drop > .panel a { text-transform: none; letter-spacing: 0; }

/* Selected and hover both carry the category's colour. */
.nav > a.top:hover, .nav details.drop > summary:hover {
  background: var(--accent-soft); color: var(--accent);
}
.nav details.drop[open] > summary,
.nav > a.top[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent);
}
.nav details.drop > .panel { border-top: 2px solid var(--accent); }
.nav details.drop > .panel a:hover { background: var(--accent-soft); color: var(--accent); }
.nav details.drop > .panel a[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent); font-weight: 600;
}
.nav a[href="index.html"]:hover,
.nav a[href="index.html"][aria-current="page"] {
  background: var(--sunken); color: var(--ink);
}

/* Dashboard boxes, one per category. */
.stat[class*="g-"] { border-top: 3px solid var(--accent); }
.stat[class*="g-"] span { color: var(--accent); }
.stat[class*="g-"]:hover { background: var(--accent-soft); border-color: var(--accent); }

/* Rows respond to the pointer, so a long table can be read across. */
table.checklist tbody tr:hover > td { background: var(--sunken); }
table.channels tbody tr:hover > td { background: var(--sunken); }
.item:hover, .xref:hover, .card:hover { border-color: var(--ink-faint); }

/* The top-level areas carry weight - they are the site's spine and have to
   read at a glance. The sections inside a panel stay light, so the open
   page is still the heaviest thing on screen. */
/* Weight, decided once. Top-level areas are bold, the sections inside a
   panel are not, and the page you are on is bold wherever it sits. Every
   selector here carries a class and an element more than any rule above,
   so nothing earlier in the file can quietly win. */
.nav > a, .nav > details.drop > summary { font-weight: 700; }
.nav > details.drop > .panel > a { font-weight: 400; }
.nav > details.drop > .panel > a[aria-current="page"] { font-weight: 700; }

/* ------------------------------------------------------- download rider */

/* Orange: the one filled button on the bar, and the only thing here that
   takes something away with you. #c4701c is the Stage hue - the palette
   already has it, so the bar gains no new colour. */
.navtail .download-rider {
  text-transform: uppercase; letter-spacing: .07em; text-decoration: none;
  color: #ffffff; background: #c4701c; border-color: #c4701c;
}
.navtail .download-rider::before { content: "↓ "; }
.navtail .download-rider:hover {
  background: #d9832b; border-color: #d9832b; color: #ffffff;
}

.footlinks { margin: 0 0 .8rem; font-size: .82rem; }

/* The printed rider. Screen never sees these. */
.ridercover, .riderchapter { display: none; }
@media print {
  .ridercover { display: block; page-break-after: always; text-align: left;
    padding-top: 22vh; }
  .ridercover h1 { font-size: 40pt; letter-spacing: .22em; margin: 0; }
  .ridercover .rsub { font-size: 15pt; margin: .6rem 0 0; }
  .ridercover .rmeta { font: 10pt/1.7 var(--mono); margin: 2.2rem 0 0; }
  .ridercover .rnote { font-size: 9pt; margin-top: 40vh; max-width: 34em;
    color: #444; }
  .riderchapter { display: block; page-break-before: always; }
  .riderchapter .actions, .riderchapter .tabs { display: none !important; }
}

.riderdraw { display: none; }
@media print {
  .riderdraw {
    display: block; width: 100%; height: auto; margin: .6rem 0 0;
    page-break-inside: avoid; border: 1px solid #ccc;
  }
}

/* Separators between the top-level menu items. */
.nav > .sep {
  color: var(--rule); font-weight: 400; user-select: none;
  padding: 0 .1rem; align-self: center;
}
@media (max-width: 68rem) { .nav > .sep { display: none; } }

/* A note on a phone.
   Five columns across 390px gives the note column about forty pixels, and
   the one cell that says what is wrong comes out a word per line. Below the
   breakpoint the prose is replaced by a button that opens the same text in
   the note dialog. */
.more.compact { display: none; }

@media (max-width: 68rem) {
  .c-note .longform, .c-ask .longform { display: none; }
  .c-note .more.compact, .c-ask .more.compact {
    display: inline-block; white-space: nowrap;
    font: 600 .7rem/1 var(--sans); letter-spacing: .06em;
    text-transform: uppercase; text-decoration: none;
    padding: .34rem .5rem; border: 1px solid currentColor;
    border-radius: 4px; background: none; cursor: pointer;
  }
  .c-ask .more.compact { color: var(--missing); }
  .c-note .more.compact { color: var(--ink-soft); }
}

.notemodal .x {
  position: absolute; top: .45rem; right: .55rem;
  font: 400 1.35rem/1 var(--sans); color: var(--ink-faint);
  border: 0; background: none; cursor: pointer; padding: .1rem .3rem;
}
.notemodal .x:hover { color: var(--ink); }

/* Printing is a tool, not a heading: an icon at the right margin, out of
   the way of the first thing the reader came for. */
.actions:has(.printicon) { justify-content: flex-end; margin-top: 0; }
.actions .printicon {
  font-size: 1.05rem; line-height: 1; padding: .4rem .55rem;
  color: var(--ink-soft);
}
.actions .printicon:hover { color: var(--ink); }

/* One line for a section whose rows all carry the same provenance. */
.provenance {
  margin: 0 0 .9rem; padding: .6rem .8rem; border-radius: 5px;
  background: var(--verified-bg); color: var(--verified);
  font-size: .82rem; line-height: 1.55; max-width: var(--measure);
}
.provenance b { font-weight: 700; }

/* Quantity in a requirements table.
   It inherits the backline's 5% column, which is right for a bare number
   and wrong for "3 minimum" - at that width every cell broke across two
   lines. Wide enough for the number and its unit together, and told not
   to wrap, so the count reads as one value rather than two. */
table.requirements .c-qty {
  width: 11rem; white-space: nowrap; padding-right: 1rem;
  font-family: var(--sans); font-weight: 400;
}
table.requirements .c-qty b {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 700;
}
table.requirements .c-qty .unit {
  margin-left: .4rem; color: var(--ink-soft); font-size: .82rem;
  white-space: nowrap;
}
table.requirements .c-qty .unspec { font-size: .82rem; }

/* Five columns, not four: the type column gives up the room. */
table.requirements:has(.c-qty) .c-type { width: 11rem; }

@media (max-width: 68rem) {
  table.requirements .c-qty { width: auto; }
}

/* Every chapter starts on its own page in the rider.
   Two sections sharing a sheet reads as one section with a heading in the
   middle of it, which is exactly the thing a supplier skims past. */
@media print {
  .riderchapter { break-before: page; page-break-before: always; }
  .riderchapter:first-of-type {
    break-before: auto; page-break-before: avoid;
  }
  .riderchapter > .masthead h1 { break-after: avoid; page-break-after: avoid; }
}

/* The drawing tab strip: the navigation for its page, so it stays put.
   `--topbar-h` is measured in tabs.js - the bar's height changes with the
   viewport and a hard-coded offset would either overlap it or leave a gap. */
.tabs.drawings {
  position: sticky; top: var(--topbar-h, 0px); z-index: 20;
  flex-wrap: wrap; gap: .25rem;
  margin: 0 0 1.4rem; padding: .5rem .55rem;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--raised);
  box-shadow: 0 1px 0 var(--rule-soft), 0 6px 18px -14px rgba(0, 0, 0, .5);
}
.tabs.drawings [role="tab"] {
  font: 600 .8rem/1.2 var(--sans); padding: .45rem .7rem;
  margin-bottom: 0; border: 1px solid transparent; border-radius: 999px;
  color: var(--ink-soft); background: var(--sunken);
}
.tabs.drawings [role="tab"]:hover {
  color: var(--accent, var(--ink));
  border-color: var(--accent, var(--rule));
  background: var(--accent-soft, var(--sunken));
}
/* Body-scoped to match the rule above rather than merely beat it: two
   selectors of equal weight, one excluding what the other claims. */
body .tabs.drawings [role="tab"][aria-selected="true"] {
  color: #ffffff; background: var(--accent, var(--ink));
  border-color: var(--accent, var(--ink));
}
body[class*="g-"] .tabs.drawings { border-top: 2px solid var(--accent); }

/* The masthead with nothing but a version on it should not reserve the
   room a title needed. */
.masthead.bare { padding-bottom: .7rem; margin-bottom: 1.4rem; }

@media print { .tabs.drawings { position: static; box-shadow: none; } }

/* One shape, two buttons. Each had its own font size, padding and border
   before, so they stood a couple of pixels apart in height - close enough
   to look like a mistake rather than a distinction. */
/* One shape for all three. Download was 38.1px against 34.0px for the
   other two, because the V0001 badge inside it has padding of its own and
   pushed the line box open. A shared min-height settles it whatever any
   of them happens to contain. */
.navtail a.fixissues, .navtail .download-rider, .navtail .share-rider {
  display: inline-flex; align-items: center; gap: .4rem;
  font: 700 .8rem/1 var(--sans); white-space: nowrap;
  padding: 0 .9rem; margin: 0; min-height: 2.35rem;
  border: 1px solid transparent; border-radius: 5px;
}
/* On black the page's --missing goes muddy; this red is mixed for it. */
.navtail a.fixissues {
  text-transform: uppercase; letter-spacing: .07em; text-decoration: none;
  border-color: #b8564a; color: #ff9d90;
}
.navtail a.fixissues:hover,
.navtail a.fixissues[aria-current="page"] {
  background: #3a1a16; border-color: #ff9d90; color: #ffb7ac;
}
.navtail a.fixissues .n { font-size: .72rem; }
.navtail a.fixissues .n .issues { color: inherit; }

@media (max-width: 68rem) {
  /* No room beside a logo on a phone: the actions take their own row
     under it, still on the black. */
  .masthead-row .navtail {
    position: static; transform: none; order: 4;
    width: 100%; justify-content: center; flex-wrap: wrap;
    margin-top: .75rem;
  }
  /* What a reader does with this site comes first - take it away, pass it
     on. Fix issues is ours, so on a phone it drops to its own line under
     them rather than leading. */
  .navtail details.dl { order: 1; }
  .navtail details.sh { order: 2; }
  .navtail a.fixissues {
    order: 3; flex-basis: 100%; justify-content: center; margin-top: .1rem;
  }
}

/* The open count, beside the page title.
   It replaced a banner that said the same sentence on eleven pages and
   pushed the content of every one of them down a line and a half. */
.masthead h1 .fixhere {
  display: inline-flex; align-items: baseline; gap: .35rem;
  margin-left: .8rem; vertical-align: middle;
  padding: .3rem .6rem; border-radius: 999px;
  border: 1px solid var(--missing); color: var(--missing);
  background: var(--missing-bg); text-decoration: none;
  font: 600 .72rem/1.2 var(--sans); letter-spacing: .04em;
  text-transform: uppercase; white-space: nowrap;
}
.masthead h1 .fixhere b { font: 700 .82rem/1 var(--mono); }
.masthead h1 .fixhere:hover { border-color: var(--ink); color: var(--ink); }
@media print { .masthead h1 .fixhere { display: none; } }

/* A drawing page shows the drawing, not a picture of a drawing in a box.
   The framed, rounded viewer made sense when the scan was folded away as
   supporting evidence; on the pages that exist FOR the sheet it put a
   border and two rounded corners between the reader and the thing they
   opened. Here it runs the full width of the column, and the sheet sits
   centred in it when it does not fill that width. */
.original.open { margin-top: .2rem; }
.original.open .viewer {
  border: 0; border-radius: 0; background: transparent;
  margin-left: -2.4rem; margin-right: -2.4rem;
}
.original.open .viewer-bar {
  padding-left: 2.4rem; padding-right: 2.4rem;
  border-bottom: 1px solid var(--rule-soft); background: transparent;
}
.original.open .stage { background: #fff; }
/* Auto margins centre the sheet while it is narrower than the stage and
   collapse to nothing once it is wider, so panning still reaches both
   edges at any zoom. */
.original.open .canvas { margin: 0 auto; }
.original.open + .note,
.original.open ~ .note { margin-top: .5rem; }

@media (max-width: 68rem) {
  .original.open .viewer { margin-left: -1.05rem; margin-right: -1.05rem; }
  .original.open .viewer-bar { padding-left: 1.05rem; padding-right: 1.05rem; }
}
@media print {
  .original.open .viewer { margin: 0; }
  .original.open .viewer-bar { display: none; }
}

/* Phone: the number dials, the mark beside it opens WhatsApp. Two actions,
   because a crew abroad reaches for one and a venue landline the other. */
.contact .phoneline { display: inline-flex; align-items: center; gap: .45rem; }
.contact .clines a.wa {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.55rem; height: 1.55rem; border-radius: 50%;
  background: #25d366; color: #ffffff; text-decoration: none;
  flex: none;
}
.contact .clines a.wa::before { content: none; }
.contact .clines a.wa:hover { background: #1da851; }

/* ------------------------------------------------------------ the gate

   The one page that is not a working document. Black, because the mark is
   white and because the rest of the site is deliberately paper - arriving
   somewhere and then leaving it should feel like two different places. */

body.home {
  margin: 0; min-height: 100dvh; background: #000; color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.gate {
  width: 100%; max-width: 54rem; padding: 3rem 1.6rem 4rem;
  text-align: center;
}
.gatelogo { display: block; margin: 0 auto; width: auto; height: 6.5rem; max-width: 86%; }

.typed {
  margin: 2.2rem 0 0; min-height: 2.6rem;
  font: 700 clamp(1.15rem, 4.2vw, 2rem)/1.25 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: #fff;
}
.caret {
  display: inline-block; width: .6ch; margin-left: .12em;
  border-bottom: .12em solid #c4701c; vertical-align: baseline;
  animation: blink 1.05s steps(1, end) infinite;
}
.typed-done .caret { animation: none; opacity: 0; }
@keyframes blink { 50% { opacity: 0; } }

.gatesub {
  margin: 1.5rem 0 0; color: #9aa0aa;
  font: .8rem/1.7 var(--sans); letter-spacing: .14em; text-transform: uppercase;
}
.gatesub span { color: #6f757f; }

/* The menu arrives after the line finishes, not with it. */
.gatemenu {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem;
  margin-top: 2.6rem;
  opacity: 0; transform: translateY(.5rem);
  transition: opacity .5s ease-out .1s, transform .5s ease-out .1s;
  pointer-events: none;
}
.typed-done .gatemenu { opacity: 1; transform: none; pointer-events: auto; }
.gatemenu a {
  padding: .6rem 1rem; border-radius: 999px; text-decoration: none;
  border: 1px solid #33363c; background: #131417; color: #d6d9de;
  font: 700 .78rem/1 var(--sans); letter-spacing: .08em;
  text-transform: uppercase; white-space: nowrap;
}
.gatemenu a:hover { border-color: var(--accent, #fff); color: #fff; }
.gatemenu a.g-0 { --accent: #5b9bdd; }
.gatemenu a.g-1 { --accent: #e09548; }
.gatemenu a.g-2 { --accent: #e56faf; }
.gatemenu a.g-3 { --accent: #e0655a; }
.gatemenu a.g-4 { --accent: #4fae79; }
.gatemenu a.g-5 { --accent: #9584da; }
.gatemenu a.g-6 { --accent: #47a8ab; }

/* No JavaScript: the line is already written, so the menu must be usable. */
.gate:not(.typed-done) .gatemenu { opacity: 1; transform: none; pointer-events: auto; }
.typed:has(.typedtext:empty) ~ .gatemenu { opacity: 0; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .gatemenu { transition: none; }
}

/* --------------------------------------------------------- the gallery

   Photographs, in the order the day happens. The grid is masonry-ish by
   row rather than true masonry: equal-height rows read as a contact sheet,
   which is what a technician is scanning, and a true masonry column order
   reads top-to-bottom when the sequence here is left-to-right. */

.galjump { margin: 1rem 0 .4rem; }
.galjump a {
  padding: .45rem .8rem; border-radius: 999px; text-decoration: none;
  border: 1px solid var(--rule); background: var(--raised);
  font: 600 .78rem/1 var(--sans); color: var(--ink-soft);
}
.galjump a:hover { border-color: var(--accent, var(--ink)); color: var(--accent, var(--ink)); }

.galsec { margin-top: 2.6rem; }
.galsec h2 { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .3rem; }
.galsec h2 .count {
  font: 700 .72rem/1 var(--mono); color: var(--paper);
  background: var(--accent, var(--ink)); padding: .3rem .5rem; border-radius: 999px;
}

.shots {
  display: grid; gap: .7rem; margin-top: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.shot { margin: 0; }
.shot a { display: block; text-decoration: none; }
.shot img, .shot video {
  display: block; width: 100%; height: 12rem; object-fit: cover;
  border-radius: 6px; background: var(--sunken);
  border: 1px solid var(--rule);
}
.shot a:hover img { border-color: var(--accent, var(--ink)); }
.shot.video { grid-column: span 2; }
.shot.video video { height: auto; object-fit: contain; }
.shot figcaption {
  margin-top: .35rem; font: .7rem/1.4 var(--mono); color: var(--ink-faint);
  overflow-wrap: anywhere;
}

/* The lightbox. A contact sheet is for finding the frame; this is for
   reading it, so the chrome is minimal and the arrows are always there. */
.lightbox {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center; flex-direction: column;
  gap: .8rem; padding: 3rem 4rem; background: rgba(0, 0, 0, .93);
}
.lightbox[hidden] { display: none; }
.lightbox img {
  max-width: 100%; max-height: calc(100dvh - 8rem);
  object-fit: contain; border-radius: 4px;
}
.lbmeta {
  margin: 0; font: .76rem/1.5 var(--mono); color: #9aa0aa;
  letter-spacing: .04em;
}
.lightbox button {
  position: absolute; border: 1px solid #3a3d44; background: rgba(0, 0, 0, .5);
  color: #fff; cursor: pointer; border-radius: 50%;
  width: 2.6rem; height: 2.6rem; font: 400 1.5rem/1 var(--sans);
}
.lightbox button:hover { border-color: #fff; background: rgba(255, 255, 255, .12); }
.lbclose { top: 1rem; right: 1rem; font-size: 1.25rem; }
.lbprev { left: 1rem; top: 50%; transform: translateY(-50%); }
.lbnext { right: 1rem; top: 50%; transform: translateY(-50%); }

.g-7 { --accent: #7a6a4f; --accent-soft: #f1ede4; }   /* Gallery  sand */

@media (max-width: 68rem) {
  .shots { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); }
  .shot img { height: 8rem; }
  .shot.video { grid-column: 1 / -1; }
  .lightbox { padding: 3.5rem 1rem; }
}
@media print { .galjump, .lightbox { display: none !important; } }

/* The release number, on the one button that hands a file over. */
.navtail .download-rider .rel {
  font: 700 .7rem/1 var(--mono); letter-spacing: .06em;
  padding: .18rem .35rem; border-radius: 3px;
  background: rgba(0, 0, 0, .22); color: #ffe6cd;
}

/* The rider's running foot. `position: fixed` is how a printed page gets
   one in Chrome: the element repeats on every sheet. Screen never sees it,
   and the page box leaves room so it never lands on the content. */
/* The running foot is NOT done here. `position: fixed` in paged media put
   it at y=76pt - near the top of the sheet, straight through the content -
   on fifteen of thirty-two pages. Chrome offers no @page margin boxes
   either, so make_rider.py stamps each page after the fact, where the
   coordinates are known and nothing can collide with them. */
.riderstamp { display: none !important; }

/* A retired channel. Present, numbered, and plainly not to be patched. */
table.channels tr.retired > td { background: var(--sunken); }
table.channels .nouse {
  font-style: italic; color: var(--ink-faint); font-size: .92em;
}

/* ===================================================== the printed rider

   A4, not a browser window. Everything below exists because something that
   works on a 1400px page does not survive 186mm of paper: tables sized for
   a wide viewport, text parked behind a button, a value explained only by a
   tooltip nobody can hover on paper. Nothing may be lost on the way to the
   page - what the screen hides behind an affordance, print spells out. */

/* Room for the running foot at the bottom, and enough at the top that a
   table continuing onto a second sheet does not start under the header the
   browser prints there. */
@page { size: A4 portrait; margin: 18mm 12mm 18mm; }

@media print {
  html, body { width: auto; }
  body { font-size: 9.5pt; line-height: 1.45; }

  /* Let the ink through: status colours and category rules carry meaning. */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  /* A horizontal scroller has no meaning on paper, and it clips. */
  .scroll-x { overflow: visible !important; }

  /* Tables: release the pixel widths chosen for a wide viewport and let
     the content set the columns against the width actually available. */
  table.checklist, table.channels, table.requirements {
    table-layout: auto !important; width: 100% !important;
    font-size: 8.5pt; border-collapse: collapse;
  }
  table.checklist th, table.checklist td,
  table.channels th, table.channels td {
    width: auto !important; padding: 3pt 4pt !important;
    overflow-wrap: break-word; vertical-align: top;
  }
  table.requirements .c-item { width: 18% !important; }
  table.requirements .c-type { width: 18% !important; }
  table.requirements .c-qty  { width: 12% !important; }
  table.checklist .c-name { width: 20% !important; }
  table.checklist .c-note { width: 22% !important; }
  table.checklist .c-tick, table.requirements .c-tick { width: 14pt !important; }

  /* A row split across a page break is two half-rows nobody can read. */
  tr, .shot, .contact, .filecard { break-inside: avoid; }
  thead { display: table-header-group; }   /* repeat headers on every sheet */

  /* The checklist is the point of a printed rider: keep the boxes, drop
     the browser-only furniture around them. */
  .checklist-bar, .tablebar, .chips, .galjump { display: none !important; }
  table.checklist .c-tick input, table.requirements .c-tick input {
    -webkit-appearance: none; appearance: none;
    width: 9pt; height: 9pt; border: .75pt solid #333; border-radius: 1pt;
    display: inline-block;
  }

  /* Anything parked behind an affordance is spelled out. A note clipped at
     ninety characters with a "read more" button becomes the whole note; a
     quantity explained by a tooltip says what the tooltip said. */
  .clipped { display: none !important; }
  button.more {
    display: inline !important; border: 0 !important; padding: 0 !important;
    background: none !important; color: inherit !important;
    font: inherit !important; text-decoration: none !important;
    font-size: 0 !important;
  }
  button.more::after {
    content: attr(data-full);
    font-size: 8.5pt; font-family: var(--sans); color: var(--ink-soft);
  }
  .longform { display: inline !important; }
  .more.compact { display: none !important; }
  table.checklist .c-qty .assumed::after {
    content: " (not stated in the document; taken as 1)";
    font-family: var(--sans); font-size: 7.5pt; font-weight: 400;
  }
  .nouse { font-style: italic; }

  /* Drawings: one per page at most, never taller than the sheet. */
  .riderdraw { max-height: 245mm; object-fit: contain; }

  /* Headings keep their content with them. */
  h1, h2, h3, h4 { break-after: avoid; }
  .masthead { break-after: avoid; }
  .group-head { break-after: avoid; }

  /* Links print as text; a bare URL in the middle of a rider is noise. */
  a[href]::after { content: none !important; }
}

/* ==================================================== tables on a phone

   A seven-column table in 390px is not a table. Squeezed, the columns break
   words down the middle - "Q T Y" stacked one letter per line, "Electri c
   guitar" - and the cells that matter get three characters of width.

   Below 48rem each row becomes a card and each cell a labelled line. Every
   cell keeps its content and gains the column name it lost with the header,
   so nothing is hidden behind a swipe and nothing is dropped. The checkbox
   and the row's own id stay on one line at the top, where a reader working
   down a list needs them. */

/* `screen and`, not a bare width query: an A4 page inside its margins is
   about 41rem wide, so a plain max-width query turns every printed table
   into cards and takes the rider from 32 pages to 51. Paper has the width
   of a desktop table and none of the reasons to stack it. */
@media screen and (max-width: 48rem) {
  .scroll-x { overflow: visible; }

  table.checklist, table.channels, table.requirements,
  table.checklist tbody, table.channels tbody, table.requirements tbody {
    display: block; width: 100%; table-layout: auto;
  }
  table.checklist thead, table.channels thead, table.requirements thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;      /* read by screen readers */
  }

  table.checklist tbody tr, table.channels tbody tr,
  table.requirements tbody tr {
    display: block; position: relative;
    margin: 0 0 .6rem; padding: .6rem .7rem .5rem 2.1rem;
    border: 1px solid var(--rule); border-radius: 7px;
    background: var(--raised);
  }
  /* A block with the label in a left gutter, NOT a flex row. Flex makes
     every child of the cell its own item, so a type carrying alternatives
     - "Martin HD-28 <i>or</i> Martin OM-42 <i>or</i> ..." - came out as
     four narrow columns with the words broken down the middle. As a block
     the content is ordinary inline flow again and wraps like prose. */
  table.checklist tbody tr > td, table.channels tbody tr > td,
  table.requirements tbody tr > td {
    display: block; position: relative;
    width: auto !important; border: 0;
    padding: .16rem 0 .16rem 5.9rem;
    overflow-wrap: anywhere;
  }
  td[data-label]::before {
    content: attr(data-label);
    position: absolute; left: 0; top: .28rem; width: 5.4rem;
    font: 700 .62rem/1.5 var(--sans); letter-spacing: .08em;
    text-transform: uppercase; color: var(--ink-faint);
  }
  /* An empty cell is noise once every cell is its own line. */
  table.channels tbody td:has(.nil) { display: none; }
  table.checklist tbody td:empty, table.channels tbody td:empty,
  table.requirements tbody td:empty { display: none; }

  /* Tick and id ride at the top of the card, not as lines of their own. */
  table.checklist .c-tick, table.requirements .c-tick {
    position: absolute; left: .6rem; top: .65rem; padding: 0;
  }
  .c-tick::before { content: none; }
  table.checklist .c-tick, table.requirements .c-tick { padding-left: 0; }
  table.channels .c-ch { font-weight: 700; }

  /* The alert row belongs to the card above it, so it reads as part of it. */
  /* An alert row has no label, so it gets no label gutter. The override
     needs the full selector: `tr.alert-row > td` alone loses to
     `table.checklist tbody tr > td` on specificity and the text started
     94px in, a third of the way across a phone. */
  tr.alert-row { margin-top: -.6rem !important; border-radius: 0 0 7px 7px; }
  table.checklist tbody tr.alert-row > td,
  table.requirements tbody tr.alert-row > td,
  table.channels tbody tr.alert-row > td {
    padding: .5rem .7rem;
  }
  tr.alert-row td::before { content: none; }
  tr.alert-row td:empty { display: none; }

  /* Wide fixed widths set for a desktop grid have nothing to do here. */
  table.requirements .c-item, table.requirements .c-type,
  table.requirements .c-qty, table.checklist .c-name,
  table.checklist .c-note, table.checklist .c-qty { width: auto !important; }
  .c-desc, .c-spec { font-size: .85rem; }
}

/* ============================================ the download menu

   The whole rider, or only the areas somebody needs. A lighting company
   does not want fifty backline lines to find the fixture schedule. */

.navtail details.dl { position: relative; }
.navtail details.dl > summary { list-style: none; cursor: pointer; }
.navtail details.dl > summary::-webkit-details-marker { display: none; }
.navtail details.dl > summary::after {
  content: "\25BE"; font-size: .6rem; margin-left: .15rem; opacity: .85;
}

.dlpanel {
  position: absolute; top: calc(100% + .45rem); right: 0; z-index: 50;
  width: 17rem; padding: .85rem .95rem 1rem; text-align: left;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--raised); color: var(--ink);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .22);
}
.dlhead {
  margin: 0 0 .6rem; font: 400 .78rem/1.5 var(--sans); color: var(--ink-soft);
}
.dlpanel label {
  display: flex; align-items: baseline; gap: .5rem; cursor: pointer;
  padding: .3rem 0; font: 400 .85rem/1.4 var(--sans); color: var(--ink);
}
.dlpanel label input { flex: none; margin: 0; }
.dlall { font-weight: 600 !important; }
.dlparts {
  max-height: 0; overflow: hidden; opacity: .45;
  padding-left: 1.3rem; transition: max-height .18s ease-out, opacity .18s;
}
.dlparts.on { max-height: 22rem; opacity: 1; }
.dlnote {
  margin: .5rem 0 .7rem; font: 400 .72rem/1.45 var(--sans);
  color: var(--ink-faint);
}
.dlgo {
  width: 100%; padding: .55rem .8rem; cursor: pointer;
  border: 1px solid #c4701c; border-radius: 5px;
  background: #c4701c; color: #fff;
  font: 700 .8rem/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
}
.dlgo:hover { background: #d9832b; border-color: #d9832b; }
.dlgo:disabled { opacity: .5; cursor: not-allowed; }

@media (max-width: 68rem) {
  .dlpanel { right: auto; left: 50%; transform: translateX(-50%); }
}
@media print { details.dl { display: none !important; } }

/* Share sits beside Download and is the quieter of the two: taking the
   rider away is the common act, passing it on the occasional one. */
.navtail details.sh { position: relative; }
.navtail .share-rider {
  cursor: pointer; list-style: none;
  text-transform: uppercase; letter-spacing: .07em;
  border-color: #4a4d54; color: #d6d9de;
}
.navtail .share-rider::-webkit-details-marker { display: none; }
.navtail .share-rider::before { content: "\2197"; font-size: .9em; }
.navtail .share-rider::after {
  content: "\25BE"; font-size: .6rem; opacity: .8;
}
.navtail .share-rider:hover { border-color: #d6d9de; color: #fff; }

.shpanel { width: 18rem; }
.shgo { display: flex; flex-wrap: wrap; gap: .4rem; }
.shgo button {
  flex: 1 1 auto; padding: .5rem .6rem; cursor: pointer;
  border: 1px solid var(--rule); border-radius: 5px;
  background: var(--raised); color: var(--ink);
  font: 600 .78rem/1 var(--sans); white-space: nowrap;
}
.shgo button:hover { border-color: var(--ink); }
@media print { details.sh { display: none !important; } }

/* The share control on a page. It knows what page it is on, so it offers
   this area and the whole rider - no box to tick saying where you are. */
.actions details.ps { position: relative; margin-right: auto; }
.actions details.ps > summary {
  list-style: none; cursor: pointer;
  font-size: 1rem; line-height: 1; padding: .4rem .6rem;
  border: 1px solid var(--rule); border-radius: 4px;
  background: var(--raised); color: var(--ink-soft);
}
.actions details.ps > summary::-webkit-details-marker { display: none; }
.actions details.ps > summary:hover { color: var(--ink); border-color: var(--ink-faint); }

.pspanel {
  position: absolute; top: calc(100% + .4rem); left: 0; z-index: 45;
  width: 15.5rem; padding: .7rem; text-align: left;
  display: flex; flex-direction: column; gap: .35rem;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--raised);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .2);
}
.pspanel > [data-share] {
  padding: .45rem .6rem; cursor: pointer; text-align: left;
  border: 1px solid var(--rule); border-radius: 5px;
  background: var(--paper); color: var(--ink);
  font: 600 .8rem/1.3 var(--sans);
}
.pspanel > [data-share].on {
  border-color: var(--accent, var(--ink)); color: var(--accent, var(--ink));
  background: var(--accent-soft, var(--sunken));
}
.pspanel .shgo { margin-top: .25rem; }
@media print { details.ps { display: none !important; } }

/* Alternatives, one per line. "A or B or C" run together reads as a single
   specification; a supplier scanning for what to bring has to parse the
   sentence. Down a column it is a list of things to pick from. */
.alt-first, .alt-more { display: block; }
.alt-more { margin-top: .1rem; }

/* The two actions on the way in. They arrive with the section links, after
   the line finishes typing - offering a download before the page has said
   what the document is would be putting the file before the point. */
.gateacts {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem;
  margin-top: 1.6rem;
  opacity: 0; transform: translateY(.5rem);
  transition: opacity .5s ease-out .25s, transform .5s ease-out .25s;
  pointer-events: none;
}
.typed-done .gateacts { opacity: 1; transform: none; pointer-events: auto; }
.gate:not(.typed-done) .gateacts { opacity: 1; transform: none; pointer-events: auto; }
.typed:has(.typedtext:empty) ~ .gateacts { opacity: 0; pointer-events: none; }

.gatedl, .gateshare > summary {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  min-height: 2.6rem; padding: 0 1.1rem; list-style: none;
  border-radius: 6px; text-decoration: none;
  font: 700 .82rem/1 var(--sans); letter-spacing: .07em;
  text-transform: uppercase;
}
.gatedl {
  background: #c4701c; border: 1px solid #c4701c; color: #fff;
}
.gatedl:hover { background: #d9832b; border-color: #d9832b; }
.gatedl.busy { opacity: .6; pointer-events: none; }
.gatedl .rel {
  font: 700 .7rem/1 var(--mono); letter-spacing: .06em;
  padding: .18rem .35rem; border-radius: 3px;
  background: rgba(0, 0, 0, .25); color: #ffe6cd;
}
.gateshare { position: relative; }
.gateshare > summary {
  border: 1px solid #4a4d54; background: transparent; color: #d6d9de;
}
.gateshare > summary::-webkit-details-marker { display: none; }
.gateshare > summary:hover { border-color: #d6d9de; color: #fff; }
.gateshare .pspanel { left: 50%; transform: translateX(-50%); }
