/* EMS Web IETM — Southeast Military Equipment
 *
 * Design system taken from the SEME Service Bay board: charcoal chrome with a
 * maroon rule, Barlow for anything structural (uppercase, wide tracking),
 * Assistant for reading, Cascadia Mono for part numbers and NSNs.
 *
 * Two concerns are layered here:
 *   1. application chrome — topbar, library, admin, viewer shell;
 *   2. the class vocabulary the original 2361C stylesheets emit, which we do
 *      not control: cb-div, step-div, alert/caution/warning, uoc, and friends.
 *      Those selectors must match the stylesheet output exactly.
 *
 * The branding stops at the chrome. Inside a work package the typography stays
 * plain and high-contrast, because that content is a maintenance procedure
 * being read off a laptop in a bay, not a dashboard.
 */

@font-face {
  font-family: Assistant; font-style: normal; font-weight: 200 800;
  font-display: swap; src: url(/static/fonts/assistant.woff2) format('woff2');
}
@font-face {
  font-family: Barlow; font-style: normal; font-weight: 600;
  font-display: swap; src: url(/static/fonts/barlow-600.woff2) format('woff2');
}
@font-face {
  font-family: Barlow; font-style: normal; font-weight: 700;
  font-display: swap; src: url(/static/fonts/barlow-700.woff2) format('woff2');
}

:root {
  --bg: #f4f4f4;
  --maroon: #8b1a1a;
  --maroon-dim: rgba(139, 26, 26, .28);
  --maroon-faint: rgba(139, 26, 26, .10);
  --amber: #8a6100;
  --green: #2e7d4f;
  --red: #c62828;
  --ink: #1c1c1c;
  --ink-dim: #6f6f6f;
  --charcoal: #1c1c1c;
  --slate: #323841;
  --tan: #c2b7ac;
  --line: #e0e0e0;
  --panel: #ffffff;

  --accent: var(--maroon);
  --accent-ink: #ffffff;
  --radius: 3px;

  --sans: Assistant, "Segoe UI", system-ui, sans-serif;
  --head: Barlow, "Arial Narrow", Impact, sans-serif;
  --mono: "Cascadia Mono", Consolas, "SF Mono", ui-monospace, monospace;
}

/* Night shift in a bay is a real case, so dark stays supported — but on
   brand. Maroon at #8b1a1a fails contrast on charcoal, so the accent is
   lifted for dark only. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #131518;
    --ink: #e9e7e4;
    --ink-dim: #9aa0a6;
    --line: #2f343a;
    --panel: #1b1e22;
    --maroon: #cf4444;
    --maroon-dim: rgba(207, 68, 68, .32);
    --maroon-faint: rgba(207, 68, 68, .12);
    --accent: var(--maroon);
    --green: #56b880;
    --amber: #d9a441;
    --red: #ff6b61;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 14px/1.55 var(--sans);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { font-family: var(--head); font-weight: 700; letter-spacing: .01em; }

/* ============================================================ chrome */

.topbar {
  display: flex; align-items: center; gap: 1.2rem;
  padding: 0 1rem; height: 52px;
  background: var(--charcoal);
  border-bottom: 3px solid var(--maroon);
  text-transform: uppercase; letter-spacing: .12em; font-size: 11px;
  white-space: nowrap;
  position: sticky; top: 0; z-index: 40;
}
.topbar a { color: rgba(255, 255, 255, .78); }
.topbar a:hover { color: #fff; text-decoration: none; }

.brand { display: flex; align-items: center; gap: .7rem; flex: none; }
.brand img { height: 28px; width: auto; display: block; }
.brand .product {
  font-family: var(--head); font-weight: 700; font-size: 11px;
  letter-spacing: .2em; color: #fff;
  border-left: 1px solid rgba(255, 255, 255, .25); padding-left: .7rem;
}

.topbar-right {
  margin-left: auto; display: flex; align-items: center; gap: 1.1rem;
  font-family: var(--head); font-weight: 600; font-size: 11px; letter-spacing: .12em;
}
.topbar-right a { padding: .2rem 0; border-bottom: 1px solid transparent; }
.topbar-right a:hover { border-bottom-color: var(--maroon); }
.who { color: rgba(255, 255, 255, .6); }
.inline { display: inline; margin: 0; }
.topbar .linkbtn {
  background: transparent; color: rgba(255, 255, 255, .78);
  border: 1px solid rgba(255, 255, 255, .3); border-radius: var(--radius);
  padding: .2rem .55rem; cursor: pointer;
  font: inherit; text-transform: uppercase; letter-spacing: .1em;
  transition: all .15s;
}
.topbar .linkbtn:hover {
  color: #fff; background: var(--maroon); border-color: var(--maroon);
  text-decoration: none;
}

.linkbtn {
  background: none; border: 0; color: var(--accent); cursor: pointer;
  font: inherit; text-decoration: underline; padding: 0;
}

.page { max-width: 1120px; margin: 0 auto; padding: 1.6rem 1rem 4rem; }

h1 { font-size: 1.35rem; margin: 0 0 1rem; text-transform: uppercase; letter-spacing: .06em; }
h2 {
  font-size: 1rem; margin: 1.7rem 0 .6rem; text-transform: uppercase;
  letter-spacing: .1em; font-weight: 600; color: var(--ink-dim);
}

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.1rem;
}
.muted { color: var(--ink-dim); }
.small { font-size: .85rem; }
.mono { font-family: var(--mono); }

table.grid { width: 100%; border-collapse: collapse; background: var(--panel); }
table.grid th, table.grid td {
  border: 1px solid var(--line); padding: .42rem .6rem; text-align: left; vertical-align: top;
}
table.grid th {
  background: var(--maroon-faint);
  font-family: var(--head); font-weight: 600; font-size: .74rem;
  text-transform: uppercase; letter-spacing: .09em; color: var(--ink);
}

.btn {
  display: inline-block; background: var(--maroon); color: #fff;
  border: 1px solid var(--maroon); border-radius: var(--radius);
  padding: .42rem .9rem; cursor: pointer;
  font-family: var(--head); font-weight: 600; font-size: .78rem;
  text-transform: uppercase; letter-spacing: .1em;
  /* Stated, not inherited: a <button> takes line-height:normal from the UA
     stylesheet while an <a> inherits the body's 1.55, so without this the
     same .btn is 5px shorter on a button and the two never line up when a
     link and a single-button form sit side by side. */
  line-height: 1.55;
  transition: filter .15s;
}
.btn:hover { filter: brightness(1.15); text-decoration: none; }

/* A row of actions mixing links with single-button forms. Flex so the
   spacing is deliberate rather than whatever whitespace the source happens
   to collapse to, and so the form wrapper cannot shift its button. */
.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.btn-row form { margin: 0; }
.btn.secondary { background: transparent; color: var(--accent); border-color: var(--line); }
.btn.secondary:hover { border-color: var(--maroon); filter: none; }
.btn.danger { background: var(--red); border-color: var(--red); }

input, select, textarea {
  font: inherit; color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius); padding: .42rem .55rem;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--maroon-dim); outline-offset: -1px; border-color: var(--maroon);
}
label {
  display: block; margin: .55rem 0 .15rem;
  font-family: var(--head); font-weight: 600; font-size: .72rem;
  text-transform: uppercase; letter-spacing: .09em; color: var(--ink-dim);
}

.pill {
  display: inline-block; font-family: var(--head); font-weight: 600;
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  padding: .1rem .45rem; border: 1px solid var(--line);
  border-radius: 999px; color: var(--ink-dim);
}
.pill.a { border-color: var(--green); color: var(--green); }
.pill.b, .pill.c, .pill.d, .pill.e, .pill.f { border-color: var(--amber); color: var(--amber); }
.pill.export { border-color: var(--red); color: var(--red); }

.banner {
  border-left: 3px solid var(--amber);
  background: color-mix(in srgb, var(--amber) 9%, transparent);
  padding: .6rem .8rem; font-size: .88rem; margin-bottom: 1rem;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.banner.err {
  border-color: var(--red);
  background: color-mix(in srgb, var(--red) 9%, transparent);
}

/* ============================================================== login */

.login-wrap { max-width: 380px; margin: 8vh auto; }
.login-wrap .card { padding: 1.5rem; border-top: 3px solid var(--maroon); }
.login-wrap input { width: 100%; }
.login-wrap .btn { width: 100%; margin-top: 1.1rem; }

/* External sign-in. A quiet "or" rule between the password form and the
   provider buttons, then full-width buttons matching the primary one. */
.oidc-sep {
  display: flex; align-items: center; gap: .6rem;
  margin: 1.1rem 0 .3rem; color: var(--ink-dim); font-size: .74rem;
  text-transform: uppercase; letter-spacing: .1em;
}
.oidc-sep::before, .oidc-sep::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}
.oidc-buttons { display: flex; flex-direction: column; gap: .5rem; }
.oidc-btn { width: 100%; text-align: center; text-decoration: none; }

/* ============================================================ portal */
.portal { max-width: 880px; margin: 3rem auto 0; }
.portal h1 { margin-bottom: .2rem; }
.portal-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.1rem; margin-top: 1.8rem;
}
.portal-tile {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--panel); border: 1px solid var(--line);
  border-top: 3px solid var(--maroon); border-radius: var(--radius);
  padding: 1.4rem 1.5rem; transition: border-color .12s, transform .12s;
}
.portal-tile:hover { border-color: var(--maroon); transform: translateY(-2px); }
.portal-tile h2 { margin: 0 0 .5rem; font-size: 1.15rem; }
.portal-tile p { margin: 0; color: var(--ink-dim); font-size: .9rem; line-height: 1.5; }
/* Shown but not linked: the reader can see what the product is and how to get
   it, rather than a tile that silently is not there. */
.portal-tile-locked { border-top-color: var(--line); cursor: default; }
.portal-tile-locked:hover { border-color: var(--line); transform: none; }
.portal-tile .portal-go {
  margin-top: 1rem; font-family: var(--head); font-weight: 600; font-size: .78rem;
  text-transform: uppercase; letter-spacing: .08em; color: var(--maroon);
}

/* ============================================================ library */

.manual-list { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
.manual-card {
  display: block; background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--maroon);
  border-radius: var(--radius); padding: .95rem; color: inherit;
  transition: border-color .15s, transform .1s;
}
.manual-card:hover { border-color: var(--maroon); text-decoration: none; }
.manual-card h3 {
  margin: 0 0 .35rem; font-size: .98rem;
  text-transform: uppercase; letter-spacing: .04em;
}
.manual-card .meta {
  font-size: .78rem; color: var(--ink-dim);
  display: flex; gap: .6rem; flex-wrap: wrap;
}

/* ======================================================= viewer shell */

body.viewer { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
.viewer-main { flex: 1; display: flex; min-height: 0; }

.nav-pane {
  width: 330px; flex: 0 0 330px; overflow-y: auto; background: var(--panel);
  border-right: 1px solid var(--maroon-dim); padding: .65rem;
}
.nav-pane .manual-title {
  font-family: var(--head); font-weight: 700; font-size: .92rem;
  text-transform: uppercase; letter-spacing: .05em; margin: .2rem .2rem .15rem;
}
.nav-pane .manual-sub {
  font-size: .74rem; color: var(--ink-dim); margin: 0 .2rem .8rem;
  letter-spacing: .04em;
}
.model-tag {
  display: inline-block; padding: 0 .3rem; border-radius: 2px;
  background: var(--maroon-faint); color: var(--maroon); font-weight: 600;
}

/* Navigation tree.
 *
 * The publisher's own hierarchy, nested as deeply as they made it (six levels
 * in the P-19R), so every rule here has to work at any depth rather than
 * assuming the old section-then-list pair. Indentation comes from nesting the
 * lists, not from a per-depth class. */
.nav-list { list-style: none; margin: 0; padding: 0; }
.nav-list .nav-list { padding-left: .85rem; }
.nav-tree + .nav-tree { margin-top: .5rem; border-top: 1px solid var(--line); padding-top: .4rem; }

.nav-twisty {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font-family: var(--head); font-weight: 600; font-size: .78rem;
  letter-spacing: .04em; color: var(--ink);
  padding: .3rem .3rem; border-radius: var(--radius);
  display: flex; align-items: center; gap: .4rem;
}
/* Only the top level is shouted; deeper folders are ordinary titles, or a
   six-level tree becomes a wall of capitals. */
.nav-tree > .nav-list > .nav-branch > .nav-twisty {
  text-transform: uppercase; letter-spacing: .1em; font-size: .76rem;
}
.nav-twisty:hover { background: var(--maroon-faint); }
.nav-twisty .caret {
  font-size: .7rem; opacity: .55; width: .8em; flex: 0 0 auto;
  transition: transform .12s ease;
}
.nav-branch[aria-expanded="true"] > .nav-twisty > .caret { transform: rotate(90deg); }
.nav-twisty .nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-twisty .count {
  margin-left: auto; font-size: .7rem; color: var(--ink-dim);
  font-weight: 600; font-family: var(--mono); letter-spacing: 0; flex: 0 0 auto;
}

.nav-leaf { display: flex; align-items: flex-start; gap: .15rem; }
.nav-leaf > a {
  flex: 1; display: block; padding: .24rem .35rem; font-size: .83rem; color: var(--ink);
  border-radius: var(--radius); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-leaf > a:hover { background: var(--maroon-faint); text-decoration: none; }
.nav-leaf > a.active { background: var(--maroon); color: #fff; }
.nav-leaf > a .wpid {
  font-family: var(--mono); font-size: .73rem; opacity: .6; margin-right: .35rem;
}
/* A leaf with sub-items owns a nested list, so it cannot stay a flex row. */
.nav-leaf:has(> .nav-subitems) { display: block; }
.nav-leaf:has(> .nav-subitems) > a { display: inline-block; width: calc(100% - 1.4rem); }

/* The expander for tables and figures inside one work package. Deliberately
   quieter than a folder twisty: it opens content within a page, not a branch
   of the manual. */
.sub-twisty {
  background: none; border: 0; cursor: pointer; color: var(--maroon);
  font-size: .68rem; padding: .24rem .2rem; border-radius: var(--radius);
  flex: 0 0 auto; transition: transform .12s ease;
}
.sub-twisty:hover { background: var(--maroon-faint); }
.sub-twisty[aria-expanded="true"] { transform: rotate(90deg); }

.nav-subitems { list-style: none; margin: 0 0 .2rem; padding: 0 0 0 1.5rem; }
.nav-subitems a {
  display: block; padding: .18rem .35rem; font-size: .78rem; color: var(--ink-dim);
  border-radius: var(--radius); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-subitems a:hover { background: var(--maroon-faint); color: var(--ink); text-decoration: none; }
.nav-subitems a.active { background: var(--maroon); color: #fff; }
.subitem-type {
  font-family: var(--mono); font-size: .66rem; text-transform: uppercase;
  opacity: .6; margin-right: .35rem;
}
.subitem-note {
  padding: .18rem .35rem; font-size: .76rem; color: var(--ink-dim); font-style: italic;
}

/* The content column is the pane plus the chrome that must outlive it: a
   fragment load replaces the pane's markup entirely, so anything persistent
   is a sibling of it, not a child. */
.content-col { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.content-bar {
  flex: 0 0 auto; display: flex; align-items: center; gap: .5rem;
  padding: .5rem 1.5rem; border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.content-bar .btn { padding: .25rem .7rem; font-size: .75rem; }

.content-pane { flex: 1; overflow-y: auto; padding: 1.2rem 1.5rem 5rem; min-width: 0; position: relative; }
.wp-head { border-bottom: 2px solid var(--maroon); padding-bottom: .55rem; margin-bottom: 1.1rem; }
.wp-head h1 { font-size: 1.1rem; margin: 0; letter-spacing: .04em; }
.wp-head .wp-meta {
  font-size: .74rem; color: var(--ink-dim); font-family: var(--mono);
  margin-top: .2rem;
}

.loading { color: var(--ink-dim); font-size: .85rem; padding: 2rem 0; }

/* Per-account attribution mark. Deliberately faint: it is for tracing a leak,
   not for obstructing the technician reading the page. */
.wm-mark {
  position: fixed; right: .5rem; bottom: .35rem; z-index: 5;
  font: 10px/1 var(--mono); color: var(--ink-dim); opacity: .35;
  pointer-events: none; user-select: none;
}

/* ==================================================== search + marks */

.manual-search { margin: 0 .2rem .5rem; }
.manual-search input { width: 100%; font-size: .84rem; }
ul.results { list-style: none; padding: 0; margin: 0; }
ul.results > li { border-bottom: 1px solid var(--line); padding: .65rem 0; }
ul.results > li:last-child { border-bottom: 0; }
ul.results a { font-weight: 600; }
.result-meta { font-size: .75rem; color: var(--ink-dim); margin: .12rem 0 .22rem; }
.result-snip { font-size: .86rem; }
.result-snip mark { background: color-mix(in srgb, var(--amber) 34%, transparent); color: inherit; }

.wp-tools { display: flex; gap: .9rem; margin-top: .4rem; font-size: .8rem; }
.wp-tools .mark-toggle.is-marked { font-weight: 700; }
.wp-tools .mark-toggle.is-marked::before { content: "\2605 "; }
.mark-editor { margin-top: .6rem; max-width: 34rem; }
.mark-editor textarea { width: 100%; font-size: .86rem; }
.mark-editor-controls { display: flex; align-items: center; gap: .5rem; margin-top: .4rem; }
.mark-note {
  margin-top: .3rem; padding: .45rem .6rem; font-size: .86rem;
  background: var(--maroon-faint); border-left: 3px solid var(--maroon);
  border-radius: 0 var(--radius) var(--radius) 0; white-space: pre-wrap;
}

/* ======================================================= parts + RPSTL */

.parts-toolbar { display: inline-flex; align-items: center; gap: .8rem; margin-left: .6rem; font-size: .8rem; }
.parts-selected { color: var(--ink-dim); }
.parts-status { color: var(--maroon); font-weight: 600; }
.picklist-count:not(:empty)::before { content: "("; }
.picklist-count:not(:empty)::after { content: ")"; }

.rpstl .rpstl-group > button { font-size: .82rem; }
.rpstl .rpstl-sub { margin: .2rem 0 .55rem; }
.rpstl .rpstl-sub-title {
  font-family: var(--head); font-weight: 600; font-size: .72rem;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-dim); margin: .4rem 0 .1rem;
}
.rpstl ul { list-style: none; margin: 0; padding-left: .9rem; }
.rpstl .rpstl-group[aria-expanded="false"] > ul { display: none; }
.rpstl li a { display: block; padding: .2rem .3rem; font-size: .84rem; border-radius: var(--radius); }
.rpstl li a:hover { background: var(--maroon-faint); text-decoration: none; }
.nav-pane a.rpstl-entry { font-weight: 700; }

/* ============================================== fault-isolation wizard */

.diag-entry .btn { margin-top: .35rem; }
.diag-history { margin: .4rem 0 .8rem; font-size: .84rem; }
.diag-history summary { cursor: pointer; color: var(--ink-dim); }
.diag-history ol { margin: .3rem 0 0; padding-left: 1.4rem; }
.diag-answer {
  margin-top: 1.3rem; padding: 1rem; border: 1px solid var(--line);
  border-left: 3px solid var(--maroon);
  border-radius: 0 var(--radius) var(--radius) 0; background: var(--panel);
}
.diag-prompt {
  margin: 0 0 .7rem; font-family: var(--head); font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; font-size: .82rem;
}
.diag-choices { display: flex; gap: .5rem; flex-wrap: wrap; }
.diag-choices .btn { min-width: 6.5rem; }
.diag-controls { display: flex; gap: .5rem; margin: 1rem 0 .5rem; }

ul.fault-list { list-style: none; padding: 0; margin: 0 0 1rem; }
ul.fault-list > li {
  display: flex; align-items: baseline; gap: .7rem;
  padding: .5rem .65rem; border: 1px solid var(--line);
  border-left-width: 3px; border-radius: 0 var(--radius) var(--radius) 0;
  margin-bottom: .35rem; background: var(--panel);
}
.fault-state {
  font-family: var(--head); font-weight: 700; text-transform: uppercase;
  font-size: .66rem; letter-spacing: .09em; min-width: 4.6rem;
}
.fault-bad { border-left-color: var(--red); }
.fault-bad .fault-state { color: var(--red); }
.fault-possible { border-left-color: var(--amber); }
.fault-possible .fault-state { color: var(--amber); }
.fault-ok { border-left-color: var(--green); opacity: .8; }
.fault-ok .fault-state { color: var(--green); }
.fault-text { flex: 1; }
ol.diag-trace { font-size: .88rem; }
ol.diag-trace ul { margin: .15rem 0 .3rem; }

/* ============================================ 2361C stylesheet output
   Deliberately plainer than the chrome: this is the maintenance procedure,
   and legibility beats branding inside it. */

.wp-body { max-width: 62rem; }
.wp-body img { max-width: 100%; height: auto; }
.wp-body table { border-collapse: collapse; margin: .7rem 0; max-width: 100%; }
.wp-body th, .wp-body td { border: 1px solid var(--line); padding: .32rem .5rem; vertical-align: top; }
.wp-body th {
  background: var(--maroon-faint);
  font-family: var(--head); font-weight: 600; font-size: .76rem;
  text-transform: uppercase; letter-spacing: .06em;
}
/* Wide parts tables and diagrams scroll in their own box rather than making
   the page scroll sideways. */
.wp-body .table-scroll, .wp-body .general-table-div { overflow-x: auto; }

.wp-body h2 {
  font-size: .95rem; color: var(--ink); border-bottom: 1px solid var(--line);
  padding-bottom: .2rem;
}
.wp-body .wp-title-div {
  font-family: var(--head); font-size: 1.05rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
}
.wp-body .wp_maintlvl {
  font-family: var(--head); font-size: .72rem; color: var(--ink-dim);
  text-transform: uppercase; letter-spacing: .1em;
}

.wp-body .step-div { margin: .5rem 0; }
.wp-body .step_number { font-weight: 700; margin-right: .4rem; font-variant-numeric: tabular-nums; }
.wp-body .step_para { display: inline; }

/* Warnings, cautions and notes keep their conventional colours: these are
   safety markings, not brand surface. */
.wp-body .alert-container { margin: .8rem 0; }
.wp-body .alert {
  border: 1px solid var(--line); border-left-width: 4px;
  border-radius: 0 var(--radius) var(--radius) 0; background: var(--panel);
}
.wp-body .alert-title {
  font-family: var(--head); font-weight: 700; font-size: .78rem;
  letter-spacing: .1em; text-transform: uppercase;
  padding: .4rem .65rem; display: flex; align-items: center; gap: .45rem;
}
.wp-body .alert-body { padding: .1rem .65rem .6rem; }
.wp-body .alert.warning { border-left-color: var(--red); }
.wp-body .alert-title.warning { color: var(--red); }
.wp-body .alert.caution { border-left-color: var(--amber); }
.wp-body .alert-title.caution { color: var(--amber); }
.wp-body .alert.note { border-left-color: var(--slate); }
.wp-body .alert-title.note { color: var(--slate); }
.wp-body .alert-icon { width: 20px; height: 20px; }
.wp-body .icon-set-div { display: flex; gap: .3rem; flex-wrap: wrap; margin: .2rem 0; }
.wp-body .icon-set-div img { width: 42px; height: auto; }

/* Collapsible blocks. The stylesheets mark the collapsed state with
   class="closed" on the <li>. */
.wp-body ul.toggle-control { list-style: none; padding-left: 0; }
.wp-body ul.toggle-control > li {
  border: 1px solid var(--line); border-radius: var(--radius);
  margin: .35rem 0; background: var(--panel);
}
.wp-body .toggle-toggler {
  display: block; padding: .45rem .65rem; font-family: var(--head);
  font-weight: 600; font-size: .84rem; cursor: pointer;
  text-transform: uppercase; letter-spacing: .05em;
}
.wp-body .toggle-toggler::before { content: "\25be"; margin-right: .4rem; opacity: .6; }
.wp-body li.closed .toggle-toggler::before { content: "\25b8"; }
.wp-body ul.toggle-control > li > div { padding: 0 .65rem .55rem; }
.wp-body li.closed > div { display: none; }

.wp-body .figure-div { margin: .9rem 0; }
.wp-body .figure_title-span {
  display: block; font-size: .8rem; color: var(--ink-dim); margin-top: .25rem;
}
/* Figures are full-resolution scans; without the cap a wide one forces the
   whole content pane to scroll sideways. */
.wp-body .diagram {
  border: 1px solid var(--line); background: #fff; cursor: zoom-in;
  max-width: 100%; height: auto;
}

/* Figures render expanded; the toggle only collapses a large diagram, so it
   stays quiet until wanted, and never prints. */
.wp-body .figure-toggle { font-size: .74rem; letter-spacing: .04em; }
.wp-body .figure-hidden { display: none; }
@media print {
  .figure-toggle { display: none; }
}

/* Links into software that only existed on the technician's own PC - the
   vendor's diagnostic and courseware programs. Marked rather than removed so
   the reader can see the manual pointed somewhere, and that the destination is
   not something this viewer withheld. Dotted, not coloured: it must not read
   as a link that is merely failing. */
.wp-body .external-unavailable {
  border-bottom: 1px dotted var(--ink-dim); color: var(--ink-dim); cursor: help;
}

/* Applicability. `filtered` is how the stylesheets mark content the selected
   model excludes. */
.wp-body .filtered { display: none; }
.wp-body .hide { display: none; }
.wp-body .uoc-tag { font-size: .7rem; color: var(--ink-dim); font-family: var(--mono); }

/* Change bars: cb-div/cb-span carry change markings in the source. */
.wp-body .cb-div.changed, .wp-body .cb-span.changed {
  border-left: 2px solid var(--amber); padding-left: .35rem;
}

.wp-body .nsn-span, .wp-body .partno-span, .wp-body .cageno-span {
  font-family: var(--mono); font-size: .86em;
}
.wp-body .link-prompt-span a { text-decoration: underline dotted; }

.wp-body input[type="button"] {
  font-family: var(--head); font-weight: 600; font-size: .74rem;
  text-transform: uppercase; letter-spacing: .08em;
  padding: .28rem .65rem; cursor: pointer;
  background: transparent; color: var(--accent);
  border: 1px solid var(--line); border-radius: var(--radius); margin-right: .35rem;
}
.wp-body input[type="button"]:hover { border-color: var(--maroon); }
.wp-body input[type="checkbox"] { cursor: pointer; accent-color: var(--maroon); }
.wp-body table.sortable th a { color: inherit; text-decoration: underline dotted; }

/* ====================================================== asset viewers */

/* `svh`, not `dvh`, and the distinction matters more than it looks.
   `dvh` is the *dynamic* viewport height: it recalculates continuously as the
   phone's address bar slides in and out. Ruffle re-renders its canvas on every
   container resize, so a dynamic unit turns ordinary scrolling into a repaint
   loop - which presented as the schematic strobing on a handset. `svh` is the
   small viewport height and is constant, which is what a fixed app layout
   wants. `100vh` stays first as the fallback for browsers without either. */
.viewer-frame {
  display: flex; flex-direction: column;
  height: 100vh; height: 100svh;
  overflow: hidden;
}
.viewer-toolbar {
  display: flex; align-items: center; gap: .6rem; padding: .4rem .7rem;
  background: var(--charcoal); color: #fff;
  border-bottom: 3px solid var(--maroon);
  font-family: var(--head); font-weight: 600; font-size: .76rem;
  text-transform: uppercase; letter-spacing: .09em;
}
.viewer-toolbar .muted { color: rgba(255, 255, 255, .55); }
.viewer-toolbar .spacer { margin-left: auto; }
.viewer-toolbar .btn.secondary { color: #fff; border-color: rgba(255, 255, 255, .35); }
.viewer-toolbar .btn.secondary:hover { background: var(--maroon); border-color: var(--maroon); }
.viewer-frame .stage {
  flex: 1; overflow: auto; display: flex; align-items: center; justify-content: center;
  background: var(--slate); padding: 1rem;
}
.viewer-frame .stage img { max-width: 100%; max-height: 100%; background: #fff; }
.viewer-frame .stage img.zoomed { max-width: none; max-height: none; cursor: grab; }
/* The player is sized by this box, so it has to have a real height rather than
   inheriting one from a centred flex line. `min-height: 0` lets it shrink
   inside the flex column instead of overflowing it. */
#ruffle-stage { width: 100%; height: 100%; flex: 1 1 auto; min-height: 0; }

@media (max-width: 820px) {
  /* Stretch rather than centre: centring leaves the player at its intrinsic
     size, which on a phone is a sliver. Also give it a floor, so a short
     viewport still yields something usable to pan around. */
  .viewer-frame .stage { padding: .35rem; align-items: stretch; justify-content: stretch; }
  /* Stable unit here too - a dynamic floor resizes the player on every scroll. */
  #ruffle-stage { min-height: 55svh; }
  .viewer-toolbar { font-size: .68rem; gap: .4rem; padding: .35rem .5rem; }
}
.ruffle-missing {
  color: #e9e7e4; background: #262b31; border: 1px solid #3a4048;
  border-radius: var(--radius); padding: 1.2rem; max-width: 48rem;
  font-size: .9rem; line-height: 1.55;
}
.ruffle-missing code {
  background: #15181c; padding: .1rem .3rem; border-radius: 2px; font-family: var(--mono);
}
.ruffle-missing .btn { margin-top: .2rem; }

/* Says why the stage just went blank during an automatic restart. Overlaid
   rather than in flow so the stage does not resize under the player. */
.stage-notice {
  position: fixed; left: 50%; bottom: 1.2rem; transform: translateX(-50%); z-index: 6;
  background: var(--charcoal); color: #fff; border: 1px solid var(--maroon);
  border-radius: var(--radius); padding: .45rem .9rem;
  font-size: .78rem; letter-spacing: .04em;
}

/* ============================================================== admin upload */

.upload-start {
  display: grid; gap: 1rem; margin-bottom: 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
}
.upload-start .card { display: flex; flex-direction: column; }
.upload-start .card p:last-of-type { margin-top: auto; }

.upload-pickers {
  display: grid; gap: 1rem; margin-top: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.upload-pickers input[type="file"] { width: 100%; font-size: .82rem; }

.upload-progress { margin-top: 1rem; }
.upload-bar {
  height: .5rem; background: var(--line); border-radius: 999px; overflow: hidden;
}
.upload-bar span {
  display: block; height: 100%; width: 0;
  background: var(--maroon); transition: width .2s linear;
}
.upload-progress p { margin: .4rem 0 0; }

tr.row-blocked { opacity: .62; }
tr.row-blocked td { background: color-mix(in srgb, var(--red) 5%, transparent); }

#job-log {
  max-height: 20rem; overflow: auto; margin: .5rem 0 0;
  background: var(--slate); color: #e9e7e4;
  padding: .6rem .8rem; border-radius: var(--radius); white-space: pre-wrap;
}

/* The contents button belongs to the narrow layout only; beside the tree on a
   desktop it would just be noise. */
.nav-toggle { display: none; }
.nav-toggle-icon { font-size: 1rem; line-height: 1; }

@media (max-width: 820px) {
  .nav-toggle { display: inline-flex; align-items: center; gap: .4rem; }

  /* The pane overlays the page rather than sitting beside it, so it starts
     closed. It used to start open with no way to dismiss it - the button that
     the stylesheet and the script both referred to was never in the markup -
     which on a phone meant the navigation permanently covered the content. */
  .nav-pane {
    position: absolute; z-index: 30; height: 100%;
    box-shadow: 0 0 24px rgba(0, 0, 0, .3);
    display: none;
  }
  body.viewer.nav-open .nav-pane { display: block; }
  .brand .product { display: none; }

  /* Tapping the page behind the open pane closes it, which is what everything
     else with a slide-over panel does. */
  body.viewer.nav-open .wp-pane::before {
    content: ""; position: absolute; inset: 0; z-index: 25;
    background: rgba(0, 0, 0, .35);
  }
}
