/* Boeing OPT StandAlone v4.27 — colours and geometry.
 *
 * The native window is 576x768 with a 48 px title strip (perf.cfg
 * display/screen window-size + margin-top), so the application area the
 * perf.cfg percentages address is 576x720 below that line.  Every box here is
 * in those pixels: perfc.py converted the percentages, app.js places them.
 *
 * Colours are perf.cfg display/color(1), the palette the native UI is drawn
 * from, cross-checked against Xvfb screenshots of the running program.
 */

* { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bkg:      #000;          /* bkg-main        */
  --btn:      #5a5a5a;       /* bkg-active/available (90,90,90) */
  --set:      #00ff00;       /* fg-selected     */
  --setbkg:   #006600;       /* bkg-selected    */
  --blue:     #0091ff;       /* fg-group/fg-disabled (0,145,255) */
  --txt:      #c8c8c8;       /* text-active     */
  --outline:  #b6b6b6;       /* fg-editoutline  */
  --dim:      #6a6a6a;       /* a disabled entry's own value, dimmed */
  --advisory: #ffb400;       /* fg-advisory     */
  /* installed-app insets: notched phones and the iPadOS status bar eat into
     the window a standalone launch gets, and fit() keeps the stage inside */
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
}

html, body {
  height: 100%;
  background: var(--bkg);
  overflow: hidden;
  font-family: Arial, Helvetica, sans-serif;
  -webkit-text-size-adjust: 100%;
}

#stage {
  position: absolute;
  left: 0; top: 0;
  width: 576px;
  height: 768px;
  background: var(--bkg);
  color: var(--txt);
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  line-height: 1;
  /* the native face is a 1-bit one, so its strokes are a single pixel: the
     default macOS smoothing thickens Arial's to two and the whole UI reads
     a weight heavier than the program's */
  -webkit-font-smoothing: antialiased;
  transform-origin: 0 0;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}
#stage > * { position: absolute; }

#titlebar {
  left: 0; top: 0; width: 576px; height: 48px;
  /* the strip is 48 px but OPT draws its wording 3 px above the middle of
     it: line-height 42 puts the row where the native window has it */
  line-height: 42px;
  text-align: center;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  color: #fff;
  pointer-events: none;
}

/* ---- the shared frame -------------------------------------------------
 * perf.cfg declares the five group boxes and the sixteen side buttons once
 * in its `general` block and every page reuses them, so they are drawn under
 * (and stay visible around) whatever page the application area shows. */
#frame, #land, #page { left: 0; top: 48px; width: 576px; height: 720px; }
#frame { z-index: 1; }
/* the landing layer covers the whole frame, so it must not swallow the side
   keys underneath it: only the controls on it take the pointer */
#land  { z-index: 2; pointer-events: none; }
#land .dd:not(.dis), #land .ed:not(.dis) { pointer-events: auto; }
/* a page covers the landing controls but not the frame keys: the program
   draws the sixteen side keys over whatever window is up, so the page itself
   stays transparent and the landing side steps aside */
#page  { z-index: 3; display: none; }
#stage.pgopen #land { display: none; }
#page.show { display: block; }
/* a page covers the whole application area, so it must not swallow the side
   keys underneath it: only the controls on it take the pointer */
#page { pointer-events: none; }
#page .pgbox, #page .pgradio, #page .pgcheck, #page .pgeff { pointer-events: auto; }
#page.show .pgfill { pointer-events: auto; }

.grp {
  position: absolute;
  border: 1px solid var(--blue);
}
/* the caption a group box carries over its top border.  OPT starts the
   wording 7 px right of the box's own left edge -- 1 px border, this 2 px,
   and the 3 px the plate pads itself with -- and lifts the plate so the line
   runs through the last row of the letters */
.grp > .gl {
  position: absolute;
  left: 2px; top: -8px;
  height: 16px; line-height: 16px;
  padding: 0 3px;
  background: var(--bkg);
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: nowrap;
}

/* side buttons: available ones are a flat grey plate inset 3 px, disabled
   ones a black plate with the blue outline and blue text that
   bkg-disabled / fg-disabled ask for, invisible ones are not drawn at all */
.sb {
  position: absolute;
  display: flex;
  align-items: center;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 16px; font-family: 'OPT16', Arial, Helvetica, sans-serif;
  color: var(--txt);
  text-align: left;
  line-height: 20px;
  cursor: pointer;
  overflow: visible;
}
.sb > .f {
  position: absolute;
  left: 3px; right: 3px; top: 3px; bottom: 3px;
  background: var(--btn);
}
/* the wording sits 3 px inside the plate, which is itself inset 3 px, so the
   text starts 6 px from the key's own box: the stand-off an Xvfb capture of
   the running program measures on EXIT (x 6) and on MEL (7 px short of the
   plate's far edge) */
.sb > .t {
  position: relative;
  padding: 0 7px 0 6px;
  width: 100%;
  /* every key the native frame draws is set in OPT16's bold cut -- same
     bitmaps as the regular cut, wider advances (measured on all eleven
     landing keys, EXIT 38 px bold against 33 px regular) */
  font-weight: 700;
}
.sb.r { justify-content: flex-end; }
.sb.r > .t { text-align: right; padding: 0 10px 0 6px; }
.sb.dis > .f { left: 1px; right: 1px; top: 1px; bottom: 1px; background: none; border: 1px solid var(--blue); }
.sb.dis { color: var(--blue); }
/* the key of the window you are on keeps bkg-selected under white text */
.sb.on > .f { background: var(--setbkg); }
.sb.on { color: #fff; }
/* perf.cfg's invisible keys and the empty 13..16 slots: built, never drawn
   until a page claims the slot */
.sb.invis { display: none; }
.sb:not(.dis):hover > .f { box-shadow: inset 0 0 0 3px #fff; }
.sb:active:not(.dis) > .f { box-shadow: inset 0 0 0 3px #fff; }

/* ---- landing page controls -------------------------------------------- */
/* perf.cfg gives every control a box; a droplist paints its plate 3 px inside
   it and a right-pointing triangle at the far end, an entry field paints a
   [b6b6b6] outline 1 px inside and its value in the large entry face. */
.dd {
  position: absolute;
  cursor: pointer;
}
.dd > .f {
  position: absolute;
  left: 3px; right: 3px; top: 3px; bottom: 3px;
  background: var(--btn);
}
.dd > .t {
  position: absolute;
  left: 4px; right: 16px; top: 3px; bottom: 3px;
  display: flex;
  align-items: center;
  /* an unset droplist shows its own title in the same grey an idle control
     uses; a set one shows the chosen entry in the selected green.  The face is
     OPT15's bold cut: Wine's tahomabd strike holds the same bitmaps as
     tahoma's, so the stroke still reads thin, but it carries the bold
     advances and the native caption is set in those.  Measured on all eight
     landing captions -- ARPT SEARCH spans 101 px bold against 92 px regular,
     CONDITION 88 against 81, THRUST RTG 93 against 90. */
  color: var(--txt);
  font-weight: 700;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: nowrap;
  overflow: hidden;
}
.dd.set > .t { color: var(--set); }
/* a condition answered with a contaminant depth carries the number on a
   second line: both lines are flush with the same left edge and the number
   sits 17 px of glyph pitch under the name, which is what the box prints
   when the two are read off the native window and stacked again here */
.dd > .t.two { display: block; }
.dd > .t.two > .d1 { position: absolute; left: 0; top: 3.5px; }
.dd > .t.two > .d2 { position: absolute; left: 0; top: 21.5px; }
.dd > .a {
  position: absolute;
  right: 3px; top: 50%;
  margin-top: -7.5px;
  width: 9.5px; height: 15px;
  background: #000;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
/* nothing to choose from yet: OPT takes the plate away and leaves the blue
   outline it draws a control that is not live in */
.dd.dis { pointer-events: none; }
.dd.dis > .f { left: 1px; right: 1px; top: 1px; bottom: 1px; background: none; border: 1px solid var(--blue); }
.dd.dis > .t { color: var(--blue); }
/* nothing to choose from yet: OPT draws the box in the blue it uses for a
   control that is not live, wording and triangle hollow in the same blue */
.dd.dis > .a { background: var(--blue); }
.dd.dis > .a::after {
  content: '';
  position: absolute;
  left: 2px; right: 1.5px; top: 2.5px; bottom: 2.5px;
  background: var(--bkg);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* mnemonic a control carries next to its box (perf.cfg alt-label) */
.al {
  position: absolute;
  display: flex;
  align-items: center;
  height: 43.2px;
  /* the mnemonic is drawn in the same 11 px cap height the controls are */
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  color: #fff;
  white-space: nowrap;
  pointer-events: none;
}
.al.l { justify-content: flex-end; }
.al.r { justify-content: flex-start; }

.ed {
  position: absolute;
  background: var(--bkg);
  border: 1px solid var(--outline);
  color: #fff;
  font: inherit;
  /* OPT's entry face is the same thin stroke the rest of the window uses,
     four points larger than the captions */
  font-size: 20px; font-family: Arial, Helvetica, sans-serif;
  padding: 0 6px;
  outline: none;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
  user-select: text;
  -webkit-user-select: text;
}
.ed > input, .ed > span { color: #fff; }
.ed:focus { border: 2px solid #fff; }
.ed.dis { border-color: var(--blue); color: var(--blue); }
/* The assumed temperature is the one box perf.cfg gives a `defaultstring`, and
   the take-off window draws it as a blue hollow outline holding that word in a
   dimmed face -- not the blue a disabled control's wording is drawn in, and
   not the white a live entry's value is.  It is also the only disabled entry
   drawn this way: the landing page's VREF ADD is disabled too and keeps its
   ordinary outline and a white value.  The face belongs to the disabled state
   alone: a take-off weight in the box wakes the entry and turns it white. */
#page .ed.dis[data-pg$=":assumedtemp"] { color: var(--dim); }
#page .ed.dis[data-pg$=":assumedtemp"] > input,
#page .ed.dis[data-pg$=":assumedtemp"] > span { color: var(--dim); }

/* the static text under an entry field repeats the value in the other unit */
.st {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  color: #fff;
  white-space: nowrap;
  pointer-events: none;
}

.flag {
  position: absolute;
  background: var(--bkg);
  border: 1px solid var(--blue);
  color: var(--blue);
  font-size: 9px; font-family: 'OPT9', Arial, Helvetica, sans-serif;
  letter-spacing: 1px;
  overflow: hidden;
  white-space: nowrap;
  pointer-events: none;
}

/* the dispatch half of the output drops three of the entry controls; the H5
   hides them by class so an inline display (the entry rows are flex) survives */
#land .off { display: none !important; }

/* group(4) is the aircraft line OPT prints in the middle of the frame */
.acft {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px; font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  color: #fff;
  pointer-events: none;
}

/* ---- outputland result grid -------------------------------------------
 * perf.cfg's outputland page is 25 positioned static texts; every one of them
 * is a row of the result block OPT writes after a calculation. */
.ol {
  position: absolute;
  display: flex;
  align-items: flex-end;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  line-height: 9px;
  padding-bottom: 1px;
  color: #fff;
  white-space: pre-wrap;
  overflow: visible;
}
.ol.j0 { justify-content: flex-start; }
.ol.j1 { justify-content: center; }
.ol.j2 { justify-content: flex-end; }
/* a caption OPT breaks over two lines stacks them from the top of its box, and
   the second line runs past the box the file declares before the control cuts
   it: measured, line one's ink sits 17.6 px below the box top and five rows of
   line two show below the box bottom */
.ol.ml { align-items: flex-start; line-height: 19px; padding-top: 3.5px;
         white-space: pre; overflow: hidden; min-height: 29.6px; }
/* OPT hangs a short cell's ink half a pixel above the cell floor, but leaves the
   floor alone once the cell outgrows its text and hangs the ink from a fixed
   inset off the top instead -- the crossover falls between the 18 px cells the
   landing block is cut in and the 21.6 px cells of the take-off panel.  A flex
   item's baseline sits (ascent - descent)/2 below the middle of its line box, so
   bottom-aligned the line box has to stand a height the strike faces' fixed
   ascent and descent fractions solve; that is the line height app.js's olLine()
   returns per cell. */

/* ---- droplist popup ---------------------------------------------------
 * OPT opens the option list over the field and stays modal on it: the last
 * entry is always EXIT and nothing else dismisses the list. */
#menu { position: absolute; left: 0; top: 48px; width: 576px; height: 720px; display: none; z-index: 6; }
#menu.show { display: block; }
#menu .ml {
  position: absolute;
  background: var(--btn);
  border: 1px solid #000;
}
#menu .mi {
  height: 26px;
  line-height: 26px;
  padding: 0 10px;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  color: var(--txt);
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}
#menu .mi:hover, #menu .mi.sel { color: var(--set); }

/* ---- non-normal configuration dialog ----------------------------------
 * OPT draws this one inside its own window rather than as a window of its own,
 * so it overlays the application area and leaves the two side keys it rewrites
 * (PREVIOUS / NEXT) live.  Geometry measured off a 1024x768 root capture of the
 * native program: frame x 92..484 y 48..696, option plates x 153..422 on a
 * 36 px pitch starting at y 87, a 14x21 diamond at plate left + 8, and the two
 * buttons at the foot.  The frame is positioned from the overlay's corner, so
 * every number inside it is the measured pixel less the 1 px border. */
#nncdlg {
  position: absolute;
  left: 90px; top: 48px; right: 92px; bottom: 0;
  background: var(--bkg);
  display: none;
  z-index: 8;
}
#nncdlg.show { display: block; }
#nncdlg .nnf {
  position: absolute;
  left: 2px; top: 0; width: 393px; height: 649px;
  background: var(--bkg);
  border: 1px solid var(--blue);
}
#nncdlg .nnt {
  position: absolute;
  left: 0; right: 0; top: 14px; height: 23px;
  line-height: 23px;
  text-align: center;
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: pre;
}
#nncdlg .nnr {
  position: absolute;
  left: 60px; width: 270px; height: 30px;
  background: var(--btn);
  color: var(--txt);
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  display: flex;
  align-items: center;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}
#nncdlg .nnr > i {
  position: relative;
  width: 14px; height: 21px;
  margin: 0 7px 0 8px;
  background: #000;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  flex: none;
}
#nncdlg .nnr.on > i::after {
  content: '';
  position: absolute;
  left: 2px; right: 2px; top: 4px; bottom: 4px;
  background: var(--set);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
#nncdlg .nnb {
  position: absolute;
  padding: 0;
  font-family: inherit;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  cursor: pointer;
}
#nncdlg .nnb.ok {
  left: 98px; top: 601px; width: 90px; height: 41px;
  background: var(--bkg);
  border: 1px solid var(--blue);
  color: var(--blue);
}
#nncdlg .nnb.no {
  left: 204px; top: 603px; width: 86px; height: 37px;
  background: var(--btn);
  border: 0;
  color: var(--txt);
}
/* the dialog has the side keys to itself while it is up */
#frame.nnc .sb { display: none !important; }
#frame.nnc #btn-info, #frame.nnc #btn-addapt { display: flex !important; }

/* ---- contaminant-depth prompt -----------------------------------------
 * Three of the seven conditions -- standing water, slush and dry snow -- are
 * asked for a depth the moment they are picked, and the box is part of the
 * pick: it stands over the window and the condition is not settled until it
 * is answered.  Native
 * frame 393x289 at (92,192), the two unit plates 103x30 at x 176 and 297, the
 * entry 114x27 centred under them and the two plates 37 px tall at the foot. */
#dptdlg {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 768px;
  display: none;
  z-index: 9;
}
#dptdlg.show { display: block; }
#dptdlg .dpf {
  position: absolute;
  left: 92px; top: 192px; width: 393px; height: 289px;
  background: var(--bkg);
  border: 1px solid var(--blue);
}
#dptdlg .dpt, #dptdlg .dpm, #dptdlg .dpx {
  position: absolute;
  left: 5px;
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: pre;
}
#dptdlg .dpt { top: 18px; }
#dptdlg .dpm { top: 170px; }
#dptdlg .dpx { top: 198px; }
#dptdlg .dpr {
  position: absolute;
  top: 52px; width: 103px; height: 30px;
  background: var(--btn);
  display: flex;
  align-items: center;
  cursor: pointer;
}
#dptdlg .dpr.mm { left: 83px; }
#dptdlg .dpr.in { left: 204px; }
#dptdlg .dpr > i {
  position: relative;
  width: 14px; height: 21px;
  margin: 0 7px 0 8px;
  background: #000;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  flex: none;
}
#dptdlg .dpr.on > i::after {
  content: '';
  position: absolute;
  left: 2px; right: 2px; top: 4px; bottom: 4px;
  background: var(--set);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
#dptdlg .dpi {
  position: absolute;
  left: 138px; top: 107px; width: 114px; height: 27px;
  background: var(--bkg);
  border: 1px solid var(--outline);
  color: #fff;
  font-family: inherit; font-size: 15px;
  text-align: center;
  outline: none;
  padding: 0 3px;
}
#dptdlg .dpk {
  position: absolute;
  top: 242px; height: 37px;
  padding: 0;
  border: 0;
  background: var(--btn);
  color: var(--txt);
  font-family: inherit; font-size: 15px;
  cursor: pointer;
}
#dptdlg .dpk.ok {
  left: 98px; width: 82px;
  background: var(--bkg);
  border: 1px solid var(--blue);
  color: var(--blue);
}
#dptdlg .dpk.no { left: 204px; width: 86px; }
/* the depth an out-of-range answer raises: a plate of the program's own over
   the dialog, three lines of white on it and a single CK.  It covers the
   dialog completely -- nothing of the box shows through -- and CK gives the
   box back with the entry still holding what was typed into it. */
#dptdlg .dmm {
  position: absolute;
  left: 92px; top: 84px; width: 393px; height: 577px;
  background: var(--bkg);
  border: 1px solid var(--blue);
}
#dptdlg .dml {
  position: absolute;
  left: 21.5px;
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: pre;
}
#dptdlg .dmk {
  position: absolute;
  left: 152px; top: 528px; width: 86px; height: 37px;
  padding: 0;
  border: 0;
  background: var(--btn);
  color: var(--txt);
  font-family: inherit; font-size: 15px;
  cursor: pointer;
}

/* ---- message board ----------------------------------------------------
 * The plate OPT raises when a calculation has something to say: the same
 * 393x577 frame at (92,84) the out-of-range depth prompt uses, one message
 * per paragraph on an 18 px line pitch with a blank line between, and a
 * single CK at the foot.  It stands over the whole window, so the answer it
 * was raised with shows the moment CK takes it down. */
#msgdlg {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 768px;
  display: none;
  z-index: 9;
  /* the board is raised over a window the module has already blanked: a
     capture of the native window with one up is black from the title strip
     down, so this layer carries the background and not only the plate */
  background: var(--bkg);
}
#msgdlg.show { display: block; }
#msgdlg .mp {
  position: absolute;
  left: 92px; top: 84px; width: 393px; height: 577px;
  background: var(--bkg);
  border: 1px solid var(--blue);
}
#msgdlg .ml {
  position: absolute;
  left: 21.5px;
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  white-space: pre;
}
#msgdlg .mk {
  position: absolute;
  left: 152px; top: 528px; width: 86px; height: 37px;
  padding: 0;
  border: 0;
  background: var(--btn);
  color: var(--txt);
  font-family: inherit; font-size: 15px;
  cursor: pointer;
}

/* ---- on-screen keypad -------------------------------------------------
 * display/vkybd(1) `keys` is the whole keyboard as one flat string, six rows
 * of eight; the blank cells keep their width and the active keys (SYMB,
 * SHIFT) are drawn with the blue outline the native UI gives them. */
#kybd { position: absolute; left: 0; top: 0; width: 576px; height: 768px; display: none; z-index: 7; }
#kybd.show { display: block; }
/* the layer is as big as the window, not as big as its keys, so it must not
   blanket the side keys the keyboard is raised over */
#kybd { pointer-events: none; }
#kybd .kk { pointer-events: auto; }
#kybd .kedge {
  position: absolute;
  left: 0; top: 488px; width: 576px; height: 280px;
  border-top: 1px solid var(--blue);
  border-left: 1px solid var(--blue);
}
#kybd .kk {
  position: absolute;
  background: var(--btn);
  border: 0;
  color: var(--txt);
  font: inherit;
  font-size: 19px; font-family: Arial, Helvetica, sans-serif;
  line-height: 17px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
}
#kybd .kk.w2 { background: var(--bkg); border: 1px solid var(--blue); color: var(--blue); }

/* ---- ARPT SEARCH ------------------------------------------------------
 * perf.cfg has no entry for this page, so the boxes below are measured off
 * the running program: a list window that runs to the right edge of the
 * stage, four 39 px result plates on a 90.67 px pitch inside it, and the
 * search field and its CANCEL key sitting on the keyboard's top rule.  The
 * page takes the left side keys (rereserving the N FOUND caption one of them
 * leaves) and raises the same #kybd the SHOW KYBD key does. */
#srch {
  position: absolute; left: 0; top: 0; width: 576px; height: 768px;
  display: none; z-index: 7; pointer-events: none;
}
#srch.show { display: block; }
#srch > * { position: absolute; pointer-events: auto; }
/* the page owns the application area: nothing of the landing sheet or of a
   perf.cfg page is left under it */
#stage.srch #land { display: none; }
#stage.srch #page { visibility: hidden; }
/* the left column stays live: the frame's keys are what the page drives */
#srch .sback { left: 100px; top: 0; width: 476px; height: 768px; }
#srch .slist {
  left: 108px; top: 70px; width: 468px; height: 332px;
  border: 1px solid var(--blue);
  border-right: 0;
  overflow: hidden;
}
#srch .srow {
  position: absolute;
  width: 456px; height: 39px;
  background: var(--btn);
  color: var(--txt);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  line-height: 15px;
  cursor: pointer;
}
#srch .srow > div { max-width: 448px; overflow: hidden; white-space: nowrap; }
#srch .snone {
  position: absolute;
  left: 0; top: 0; width: 466px; height: 330px;
  display: flex; align-items: center; justify-content: center;
  color: var(--txt);
  pointer-events: none;
}
#srch .sfind { left: 1px; top: 220px; width: 96px; color: #fff; }
#srch .sbox {
  left: 103px; top: 454px; width: 367px; height: 26px;
  border: 1px solid #fff;
  background: var(--bkg);
  color: var(--txt);
  font: inherit; font-size: 16px; font-family: 'OPT16', Arial, Helvetica, sans-serif;
  padding: 0 4px;
  outline: none;
}
#srch .scancel {
  left: 475px; top: 444px; width: 97px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0;
  font: inherit; font-size: 16px; font-family: 'OPT16', Arial, Helvetica, sans-serif; color: var(--txt);
  cursor: pointer;
}
#srch .scancel::before {
  content: ''; position: absolute; left: 3px; right: 3px; top: 3px; bottom: 3px;
  background: var(--btn);
}
#srch .scancel:hover::before { box-shadow: inset 0 0 0 3px #fff; }
#srch .scancel > span { position: relative; }
/* the search page has the four left keys the frame's own sit on */
#frame.srch .sb { display: none !important; }
#frame.srch #btn-info, #frame.srch #btn-addapt,
#frame.srch #btn-kybd, #frame.srch #btn-wb { display: flex !important; }
/* ADD AIRPORT is the other window that takes the frame over: it keeps the key
   that opened it, the keyboard, and the four keys that finish or undo the
   form, and drops the frame's own bread and butter keys */
#frame.ada .sb { display: none !important; }
#frame.ada #btn-addapt, #frame.ada #btn-kybd,
#frame.ada #btn-calc, #frame.ada #btn-shdsp,
#frame.ada #btn-15, #frame.ada #btn-16 { display: flex !important; }
/* ARPT INFO keeps the key that opened it and the five the page offers; the
   intersection list is a sixth, and only the window that has one draws it */
#frame.api .sb { display: none !important; }
#frame.api #btn-info, #frame.api #btn-calc, #frame.api #btn-shdsp,
#frame.api #btn-mel, #frame.api #btn-cdl, #frame.api #btn-13 { display: flex !important; }
#frame.apito #btn-14 { display: flex !important; }

/* ---- comment window (RWY COMMENT / ARPT COMMENT) ----------------------
 * The native program blacks the whole window out for this one -- the title
 * strip, the side keys and the page behind all go -- and leaves a 1 px blue
 * box 392x576 at (92,84) holding the wording, the comment wrapped to the
 * 346 px column inside it, and the OK / PRINT plates 37 px tall at its foot.
 * The comment is one run of text: the records carry line breaks of their own
 * and OPT joins them and lets the box do the wrapping. */
#cmtdlg {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 768px;
  background: var(--bkg);
  display: none;
  z-index: 9;
}
#cmtdlg.show { display: block; }
#cmtdlg .cmf {
  position: absolute;
  left: 92px; top: 84px; width: 393px; height: 577px;
  border: 1px solid var(--blue);
}
#cmtdlg .cmt, #cmtdlg .cmb {
  position: absolute;
  left: 22px; width: 346px;
  color: #fff; font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif; line-height: 18px;
}
#cmtdlg .cmt { top: 35px; }
#cmtdlg .cmb { top: 71px; }
#cmtdlg .cmk {
  position: absolute;
  top: 528px; height: 37px;
  border: 0; padding: 0;
  background: var(--btn);
  color: var(--txt);
  font-family: inherit; font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif;
  cursor: pointer;
}
#cmtdlg .cmk.ok { left: 100px; width: 85px; }
#cmtdlg .cmk.pr { left: 204px; width: 85px; }

/* ---- SEND OUTPUT ------------------------------------------------------
 * The window that asks where a finished report goes.  Measured off the
 * running module on a 576x768 client capture: the plate takes the rect the
 * other dialogs use (92..484 by 48..696) over a black field that blacks out
 * every control behind it, the five option bars are 270x30 on a 36 px pitch
 * from y 87, each bar carrying its 20x20 black box 5 px in and its wording
 * 29 px in, and the keys at the foot are 86x37 at y 652.  COMPLETE is the
 * one drawn in the focused state's blue outline, which stands 2 px proud of
 * the grey bar CANCEL wears on all four sides. */
#snddlg {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 768px;
  background: var(--bkg);
  display: none;
  z-index: 10;
}
#snddlg.show { display: block; }
#snddlg .sdm {
  position: absolute;
  left: 92px; top: 48px; width: 393px; height: 649px;
  background: var(--bkg);
  border: 1px solid var(--blue);
}
#snddlg .sdt {
  position: absolute;
  left: 120px; top: 18px; height: 16px;
  color: #fff;
  font-size: 16px; font-family: 'OPT16', Arial, Helvetica, sans-serif;
  line-height: 16px;
  white-space: pre;
}
#snddlg .sdr {
  position: absolute;
  left: 60px; width: 270px; height: 30px;
  background: var(--btn);
  display: flex;
  align-items: center;
  white-space: nowrap;
  cursor: pointer;
}
#snddlg .sdr > i {
  position: relative;
  width: 20px; height: 20px;
  margin: 0 3px 0 5px;
  background: #000;
  flex: none;
}
/* the tick the program draws in the box: its own 1-bit check, the short arm
   running down from (2,11) into the vertex and the long one from there up to
   (18,2.5), both on a 3 px stroke */
#snddlg .sdr.on > i::after {
  content: '';
  position: absolute;
  left: 0; top: 0; width: 20px; height: 20px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpolyline points='2,11 7.5,18.8 18,2.6' fill='none' stroke='%2300ff00' stroke-width='3'/%3E%3C/svg%3E") no-repeat;
}
#snddlg .sdr > span {
  position: relative;
  left: 1px; top: 1px;
  color: var(--txt);
  font-size: 16px; font-family: 'OPT16', Arial, Helvetica, sans-serif;
  white-space: pre;
}
/* the bar the cursor is on takes a white rule three deep, drawn outside it so
   the bar keeps its size and its grey */
#snddlg .sdr.foc { box-shadow: 0 0 0 3px #fff; }
#snddlg .sdk {
  position: absolute;
  padding: 4px 2px 0 0;
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit; font-size: 16px;
  font-family: 'OPT16', Arial, Helvetica, sans-serif;
  cursor: pointer;
}
/* both states of the key are drawn about the same centre, so the outline sits
   2 px outside the bar on every side rather than moving the wording */
#snddlg .sdk.ok {
  left: 98px; top: 601px; width: 90px; height: 41px;
  background: var(--bkg);
  border: 1px solid var(--blue);
  color: var(--blue);
}
#snddlg .sdk.ok.off {
  left: 100px; top: 603px; width: 86px; height: 37px;
  background: var(--btn);
  border: 0;
  color: var(--txt);
}
#snddlg .sdk.no {
  left: 204px; top: 603px; width: 86px; height: 37px;
  background: var(--btn);
  color: var(--txt);
}

/* ---- BUG CARD ---------------------------------------------------------
 * The card the module draws for the flight deck.  Measured off the running
 * module on a 576x768 client capture: the plate is 393x577 at (92,84), its
 * box drawn in one rule three deep rather than as a closed rectangle -- four
 * posts, a top rail, and the floor of the centre box, with no bottom rail at
 * all.  The two N1 values and the three V speeds sit over 1 px rules, and the
 * card's own lettering is the module's bitmap face at the sizes the capture
 * gives, which is why every run carries its own size rather than sharing one
 * rule per class. */
#bugc {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 768px;
  background: var(--bkg);
  display: none;
  z-index: 11;
}
#bugc.show { display: block; }
#bugc .bcp {
  position: absolute;
  left: 92px; top: 84px; width: 393px; height: 577px;
  border: 1px solid var(--blue);
}
#bugc .bcl { position: absolute; background: #fff; }
#bugc .bct {
  position: absolute;
  color: #fff;
  font-family: 'OPT12', Arial, Helvetica, sans-serif;
  white-space: pre;
  line-height: 0;
}
#bugc .bck {
  position: absolute;
  left: 245px; top: 613px; width: 86px; height: 37px;
  padding: 0; border: 0;
  background: var(--btn);
  color: var(--txt);
  font-family: 'OPT16', Arial, Helvetica, sans-serif;
  font-size: 16px;
  cursor: pointer;
}

/* ---- pages built from perf.cfg ---------------------------------------- */
#page > * { position: absolute; }
#page .pggrp { border: 1px solid var(--blue); }
/* the frame's first box carries the aeroplane ident over its top border, the
   same way the landing page's does */
#page .pggrp > .gl {
  position: absolute;
  left: 2px; top: -8px;
  height: 16px; line-height: 16px;
  padding: 0 3px;
  background: var(--bkg);
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
}
/* the frame boxes are painted under the controls they hold */
#page .pggrp { z-index: 0; }
#page .dd:not(.dis) { pointer-events: auto; }
#page .ed:not(.dis) { pointer-events: auto; }
#page .pggrp > .t {
  position: absolute;
  left: 2px; top: -8px;
  height: 16px; line-height: 16px;
  padding: 0 3px;
  background: var(--bkg);
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
}
#page .pgtx { color: #fff; font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif; white-space: nowrap; }
/* the take-off answer sits in a box of its own over the form's frame boxes:
   the face key swaps the whole panel and nothing of the form is touched */
#page #topanel {
  position: absolute;
  left: 0; top: 0; width: 576px; height: 720px;
  z-index: 1;
  pointer-events: none;
}
/* the giant grey word the take-off answer is printed over: OPT names the face
   on screen with it -- FULL or ATM -- and draws it in the disabled plate
   colour, behind every line of the panel.  Its cap height, not its box, is
   what the native window fixes: 96 px from y 583, so the em is 134 and the
   strip of group(5) the word hangs in runs down to its baseline at 679 */
#page .towm {
  position: absolute;
  left: 92.2px; width: 389.3px;
  top: 517.5px;
  font-size: 134px; font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  line-height: 1;
  text-align: center;
  color: var(--btn);
  pointer-events: none;
}
/* where in its box perf.cfg's `just` puts a static text: 0 left, 1 centre,
   2 right.  Left is the default the boxes are built with */
#page .pgtx.j1 { text-align: center; }
#page .pgtx.j2 { text-align: right; }
#page .pglbl {
  position: absolute;
  right: 100%; margin-right: 7px;
  top: 0; height: 100%;
  display: flex; align-items: center;
  color: #fff; font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif; white-space: nowrap;
}
#page .pgbox {
  background: var(--btn);
  color: var(--txt);
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  line-height: 20px;
  padding: 0 8px;
  white-space: nowrap;
}
#page .pgbox > .pglbl { z-index: 1; }
#page .pgbox.sel { color: var(--set); }
#page .pgbox.dis { color: var(--blue); }
#page .pgbox.but { cursor: pointer; }
#page .pgfill {
  background: var(--bkg);
  border: 1px solid var(--outline);
  color: #fff;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  line-height: 20px;
  padding: 0 6px;
}
#page .pgradio {
  display: flex; align-items: center;
  color: var(--txt); font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  cursor: pointer;
}
#page .pgcheck {
  display: flex; align-items: center;
  color: #fff; font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  cursor: pointer;
}
/* a radio plate is the frame key's plate: bkg-active, 3 px inside the box
   perf.cfg gives it */
#page .pgradio > .f {
  position: absolute;
  left: 3px; right: 3px; top: 3px; bottom: 3px;
  background: var(--btn);
}
/* the mark is a 10x13 rhombus 10 px into the plate, 9 px clear of the label;
   bkg-main when it is off, fg-selected when it is on */
#page .pgradio > i {
  position: relative;
  width: 10px; height: 13px;
  margin: 0 9px 0 10px;
  flex: none;
  background: var(--bkg);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
#page .pgradio > span { position: relative; white-space: nowrap; }
#page .pgradio.on > i { background: var(--set); }
#page .pgcheck i {
  width: 12px; height: 12px;
  margin-right: 8px;
  border: 1px solid var(--outline);
  background: var(--bkg);
  flex: none;
}
#page .pgcheck.on i { background: var(--blue); border-color: var(--blue); }
#page .pgeff { border: 1px solid var(--btn); overflow: auto; }
#page .pgeff div { padding: 2px 7px; font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif; color: var(--txt); cursor: pointer; }
#page .pgeff div:hover, #page .pgeff div.sel { background: var(--btn); color: var(--set); }
#page .pgnote { color: var(--advisory); font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif; line-height: 18px; }
#page .ol.adv { color: var(--advisory); }
#page .pgflag {
  background: var(--bkg);
  border: 1px solid var(--btn);
  color: var(--blue);
  font-size: 9px; font-family: 'OPT9', Arial, Helvetica, sans-serif;
  line-height: 8px;
  letter-spacing: 1px;
  overflow: hidden;
  white-space: nowrap;
}

/* ---- modal ------------------------------------------------------------ */
#modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.75);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 60;
}
#modal.show { display: flex; }
.mbox {
  width: min(780px, 94vw);
  max-height: 84%;
  background: var(--bkg);
  border: 1px solid var(--blue);
  display: flex;
  flex-direction: column;
}
.mtitle {
  background: var(--btn);
  color: #fff;
  font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif;
  letter-spacing: .5px;
  padding: 4px 4px 4px 9px;
  display: flex;
  align-items: center;
}
.mtitle span { flex: 1; }
.mtitle button {
  width: 24px; height: 18px;
  background: var(--btn);
  border: 1px solid #fff;
  color: #fff;
  font: inherit;
  font-size: 12px; font-family: 'OPT12', Arial, Helvetica, sans-serif;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}
.mbody {
  overflow: auto;
  padding: 8px 10px 12px;
  font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif;
  line-height: 19px;
  color: #fff;
}
.mbody h4 { font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif; margin: 9px 0 2px; color: var(--set); }
.mbody h4:first-child { margin-top: 0; }
.mbody .row { display: flex; gap: 10px; }
.mbody .row .k { width: 200px; }
.mbody .row .v { flex: 1; }
.mbody .mitem { display: flex; gap: 10px; padding: 2px 6px; cursor: pointer; }
.mbody .mitem:hover { background: var(--btn); }
.mbody .mitem.sel { background: #143014; }
.mbody .mitem .t { flex: 1; }
.mbody .mitem .p { color: var(--set); white-space: nowrap; }
.mbody input {
  background: var(--bkg);
  border: 1px solid var(--outline);
  color: #fff;
  font: inherit;
  font-size: 15px; font-family: 'OPT15', Arial, Helvetica, sans-serif;
  padding: 2px 6px;
}
.mbody .mbtn {
  background: var(--btn);
  border: 0;
  color: #000;
  font: inherit;
  font-size: 13px; font-family: 'OPT13', Arial, Helvetica, sans-serif;
  padding: 7px 16px;
  margin-top: 12px;
  cursor: pointer;
}
.mbody .note { color: var(--advisory); }

/* ---- the native face --------------------------------------------------
 * perf.cfg asks for font-face='Arial', but the shipped program carries no font
 * file of its own: the face comes from the OS, and the captures came from a
 * Wine prefix whose fontconfig resolves Arial (and MS Sans Serif) to Wine's
 * own tahoma.ttf.  Text then goes out through GDI, which snaps the requested
 * integer pixel height straight onto the font's embedded 1-bit EBDT strikes.
 * Tahoma carries strikes at ppem 8,9,10,11,12,13,15,16, so the UI's sizes --
 * 11pt (14.67px -> strike 15), 12pt (16px -> strike 16), 10pt (13.33 -> 13),
 * 9pt (12 -> 12) -- are all bitmap, not outline: one source pixel per bit.
 *
 * The OPTn faces below are those strikes rebuilt as outlines: every ink run of
 * every strike row became a one-pixel-tall rectangle, unitsPerEm is ppem*128,
 * and the advances are the strike's own.  One strike pixel is therefore
 * exactly one device pixel, but only at the face's own integer px size, so
 * every rule that uses one has to sit at that size.  Use `text-rendering`
 * defaults; do not scale, letter-space or synthesize these faces.
 *
 * The sizes with no strike (perf.cfg 14pt/16pt -> ~19/21px, the 134px workbook
 * headline, the 19px keypad caps) stay with the outline fallback above. */
@font-face { font-family: 'OPT9'; font-style: normal; font-weight: 400;
             font-display: block;
             src: url(fonts/opt-9.woff2) format('woff2'); }
@font-face { font-family: 'OPT9'; font-style: normal; font-weight: 700;
             font-display: block;
             src: url(fonts/opt-9-bold.woff2) format('woff2'); }
@font-face { font-family: 'OPT12'; font-style: normal; font-weight: 400;
             font-display: block;
             src: url(fonts/opt-12.woff2) format('woff2'); }
@font-face { font-family: 'OPT12'; font-style: normal; font-weight: 700;
             font-display: block;
             src: url(fonts/opt-12-bold.woff2) format('woff2'); }
@font-face { font-family: 'OPT13'; font-style: normal; font-weight: 400;
             font-display: block;
             src: url(fonts/opt-13.woff2) format('woff2'); }
@font-face { font-family: 'OPT13'; font-style: normal; font-weight: 700;
             font-display: block;
             src: url(fonts/opt-13-bold.woff2) format('woff2'); }
@font-face { font-family: 'OPT15'; font-style: normal; font-weight: 400;
             font-display: block;
             src: url(fonts/opt-15.woff2) format('woff2'); }
@font-face { font-family: 'OPT15'; font-style: normal; font-weight: 700;
             font-display: block;
             src: url(fonts/opt-15-bold.woff2) format('woff2'); }
@font-face { font-family: 'OPT16'; font-style: normal; font-weight: 400;
             font-display: block;
             src: url(fonts/opt-16.woff2) format('woff2'); }
@font-face { font-family: 'OPT16'; font-style: normal; font-weight: 700;
             font-display: block;
             src: url(fonts/opt-16-bold.woff2) format('woff2'); }
