/* =====================================================================
   colregs -- a night-watch instrument.

   Two modes, and they are not light-and-dark.  Dark is the normal mode,
   because this is used after sunset.  NIGHT is red-on-black, because
   dark adaptation takes twenty minutes to build and a second to lose,
   and it is worth more than a pretty screen.

   In night mode every lamp goes red.  That is deliberate, not a bug:
   the lamp letters W R G Y carry the pattern, exactly as they do in the
   terminal version, so a signal stays unambiguous with no colour at all.
   ===================================================================== */

:root {
  --ground:  #07090b;
  --panel:   #10151a;
  --panel-2: #161c23;
  --line:    #232b34;
  --text:    #e6eaef;
  --dim:     #8995a3;
  --accent:  #6fb3d9;
  --sea:     #1b2730;
  --deck:    #ffd27f;      /* working lights: warm, and nothing like a nav light */

  --lamp-w: #f2f4f7;
  --lamp-r: #ff4438;
  --lamp-g: #2fd45f;
  --lamp-y: #ffd60a;
  --hull:   #2a3139;
  --mast:   #39424c;

  --tap: 56px;
  --radius: 10px;
}

:root[data-mode="night"] {
  --ground:  #060101;
  --panel:   #0e0303;
  --panel-2: #140505;
  --line:    #3a0f0c;
  --text:    #cf2a20;
  --dim:     #8a1d16;
  --accent:  #e23a2c;
  --sea:     #1a0605;
  --deck:    #e23a2c;

  /* every lamp red; the letter is what disambiguates */
  --lamp-w: #e23a2c;
  --lamp-r: #e23a2c;
  --lamp-g: #e23a2c;
  --lamp-y: #e23a2c;
  --hull:   #2a0b08;
  --mast:   #3a100c;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--ground);
  color: var(--text);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
  padding-bottom: env(safe-area-inset-bottom);
  overflow-x: hidden;
}

.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

/* ---------- top bar ---------- */
.bar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 8px;
  padding: calc(env(safe-area-inset-top) + 10px) 14px 10px;
  background: var(--ground);
  border-bottom: 1px solid var(--line);
}
.bar h1 {
  flex: 1; margin: 0;
  font-size: 17px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase;
}
.bar button {
  min-width: 46px; min-height: 40px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em;
  cursor: pointer;
}
.bar .back { font-size: 24px; line-height: 1; padding-bottom: 4px; }
:root[data-mode="night"] .bar .mode { border-color: var(--accent); }

main { padding: 16px 14px 8px; max-width: 760px; margin: 0 auto; }

.lede { color: var(--dim); margin: 0 0 18px; max-width: 58ch; }
.note { color: var(--dim); font-size: 13px; margin-top: 22px; }

/* ---------- home tiles ---------- */
.tiles { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 560px) { .tiles { grid-template-columns: 1fr 1fr; } }

.tile {
  display: flex; flex-direction: column; gap: 4px;
  min-height: 84px; padding: 16px;
  text-align: left; cursor: pointer;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  font: inherit;
}
.tile:active { background: var(--panel-2); }
.t-name { font-size: 18px; font-weight: 600; }
.t-sub  { font-size: 13px; color: var(--dim); }

/* ---------- the drawing ---------- */
.stage {
  background: #000; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 8px; margin-bottom: 12px; overflow: hidden;
}
:root[data-mode="night"] .stage { background: #000; }
.stage svg { display: block; width: 100%; height: auto; }
.stage-sound { padding: 18px 12px; }

.aspect { margin: 0 0 14px; color: var(--text); font-size: 15px; }

/* ---------- bearing slider ---------- */
.bearing { margin-bottom: 14px; }
.bearing label { display: block; font-size: 13px; color: var(--dim); margin-bottom: 6px; }
.bearing output {
  display: inline-block; margin-left: 10px;
  font-family: ui-monospace, Menlo, monospace; font-size: 15px;
  color: var(--accent);
}
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: calc(100% - 68px); height: 36px; background: transparent; vertical-align: middle;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; background: var(--line); border-radius: 2px;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 30px; height: 30px; margin-top: -13px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--ground);
}
input[type="range"]::-moz-range-track { height: 4px; background: var(--line); }
input[type="range"]::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--ground);
}

/* ---------- lamp letter keys ---------- */
/*  The heading over the light bar: this is her, not another plan view,
    and the two pictures sit one above the other.  */
.barhead { font-size: 13px; font-weight: 700; letter-spacing: 0.14em;
           text-transform: uppercase; color: var(--dim); margin: 0 0 8px; }
.legend { font-size: 13px; color: var(--dim); line-height: 2; margin: 4px 0 16px; }
.k {
  display: inline-block; min-width: 22px; padding: 1px 5px; margin-right: 2px;
  text-align: center; border-radius: 4px;
  font-family: ui-monospace, Menlo, monospace; font-weight: 700;
  background: #000; border: 1px solid var(--line);
}
.k-w { color: var(--lamp-w); } .k-r { color: var(--lamp-r); }
.k-g { color: var(--lamp-g); } .k-y { color: var(--lamp-y); }

/* ---------- buttons ---------- */
.actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 20px; }
.btn {
  flex: 1 1 auto; min-height: var(--tap); min-width: 140px; padding: 0 18px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; font-weight: 600; cursor: pointer;
}
.btn:active { background: var(--panel-2); }
.btn-play { border-color: var(--accent); color: var(--accent); }

/* ---------- multiple choice ---------- */
.opts { display: grid; gap: 10px; margin: 6px 0 16px; }
.opt {
  display: flex; gap: 12px; align-items: flex-start;
  min-height: var(--tap); padding: 14px 16px; text-align: left;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; cursor: pointer;
}
.opt:active { background: var(--panel-2); }
.opt .ltr {
  flex: 0 0 auto; font-family: ui-monospace, Menlo, monospace;
  font-weight: 700; color: var(--dim);
}
.opt[data-state="right"] { border-color: var(--lamp-g); }
.opt[data-state="right"] .ltr { color: var(--lamp-g); }
.opt[data-state="wrong"]  { border-color: var(--lamp-r); opacity: 0.75; }
.opt[data-state="wrong"] .ltr { color: var(--lamp-r); }
.opt[disabled] { cursor: default; }

/* In NIGHT mode every colour token collapses to red, so a green border
   and a red border are the same border.  The tick and cross carry the
   verdict instead -- the same discipline as the W/R/G/Y lamp letters.
   This also repairs the encounter rows, which had the identical fault. */
.opt[data-state="right"] .ltr::after { content: " \2713"; }
.opt[data-state="wrong"] .ltr::after { content: " \2717"; }

/* ---------- the drill ---------- */
.ask { margin: 10px 0 0; }
.ask-q {
  margin: 0 0 10px; font-weight: 600; color: var(--text);
}
/* The sixth row is the way out, not a candidate, so it should not read as
   one of the five you are choosing between. */
.opt.tell { background: transparent; color: var(--dim); font-style: italic; }
.opt.tell:active { background: var(--panel); }

.verdict {
  margin: 0 0 16px; font-weight: 600; color: var(--dim);
}
.verdict[data-state="right"] { color: var(--lamp-g); }
.verdict[data-state="right"]::before { content: "\2713\00a0"; }
.verdict[data-state="wrong"] { color: var(--lamp-r); }
.verdict[data-state="wrong"]::before { content: "\2717\00a0"; }

.deckrow { display: flex; margin: 0 0 10px; }
.deckbtn {
  flex: 1; min-height: 44px; background: var(--panel); color: var(--dim);
  border: 1px solid var(--line); border-radius: var(--radius);
  font: 600 13px/1 ui-monospace, Menlo, monospace; letter-spacing: 0.06em;
  cursor: pointer;
}
.deckbtn[aria-pressed="true"] { background: var(--panel-2); color: var(--deck); border-color: var(--deck); }
.decknote {
  margin: 0 0 12px; padding: 10px 12px; font-size: 13px; line-height: 1.45;
  color: var(--dim); background: var(--panel-2);
  border-left: 3px solid var(--deck); border-radius: var(--radius);
}
.decknote strong { color: var(--text); }

/* ---------- flashing lamps ----------
   Annex I's minimum is 120 flashes per minute, so 500 ms per cycle.  A
   short on-period rather than a 50% blink, because that is what a flashing
   navigation light looks like.  steps() so it snaps rather than fades - a
   lamp is on or it is off.

   Under prefers-reduced-motion the animation stops and the lamp sits lit;
   the " fl" after the letter is what then says it flashes, which is the
   same reason the letters carry the colour. */
@keyframes lamp-flash {
  0%, 36%   { opacity: 1; }
  40%, 100% { opacity: 0.10; }
}
.lamp-flash { animation: lamp-flash 0.5s steps(1, end) infinite; }

/* The submarine's identification beacon, 32 CFR 707.7: "one flash per second
   for three seconds followed by a three second off-period".  A six-second
   cycle - three flashes at one a second, then dark for three.  The RHYTHM is
   the recognition, so it is rendered as specified rather than as a generic
   blink. */
@keyframes lamp-group3 {
  0%,    6%  { opacity: 1; }
  7%,   16%  { opacity: 0.10; }
  17%,  23%  { opacity: 1; }
  24%,  33%  { opacity: 0.10; }
  34%,  40%  { opacity: 1; }
  41%, 100%  { opacity: 0.10; }
}
.lamp-group3 { animation: lamp-group3 6s steps(1, end) infinite; }

@media (prefers-reduced-motion: reduce) {
  .lamp-flash, .lamp-group3 { animation: none; opacity: 1; }
}

/* ---------- the reveal ---------- */
.answer {
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px;
}
.answer h2, .answer h3 { margin: 0 0 8px; font-size: 18px; }
.answer p { margin: 0; color: var(--dim); }
.answer strong { color: var(--text); }

.situation { margin: 0 0 10px; }

/* ---------- reference lists ---------- */
.ref { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 8px; }
.ref summary {
  cursor: pointer; min-height: 44px; display: flex; align-items: center;
  color: var(--accent); font-weight: 600;
}
.row {
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.row:last-child { border-bottom: 0; }
.row b { display: block; font-weight: 600; }
.row span { color: var(--dim); font-size: 14px; }
.row .pat {
  font-family: ui-monospace, Menlo, monospace; letter-spacing: 0.12em;
  color: var(--accent);
}

/* ---------- rules ---------- */
.ridx { display: grid; gap: 8px; margin-bottom: 8px; }
.ridx button {
  display: flex; gap: 12px; align-items: center;
  min-height: 52px; padding: 10px 14px; text-align: left;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; cursor: pointer;
}
.ridx .done { color: var(--lamp-g); font-family: ui-monospace, Menlo, monospace; }
.ridx .todo { color: var(--dim); font-family: ui-monospace, Menlo, monospace; }

/*  THE PANEL IS THE CONTAINER, NOT EACH PARAGRAPH. The lesson body used
    to be one pre; it is now a box of paragraphs, so the border, padding
    and background belong to the box and its children carry none.       */
.prose {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 13.5px; line-height: 1.6; color: var(--text);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px; margin: 0 0 16px;
}
/*  NOTHING ELSE STYLES A pre IN HERE. There was a `.lesson pre, .check
    pre` pair setting pre-wrap, left over from when a lesson body WAS one
    pre. It still matched -- the only pre left in a lesson is .lp-pre --
    and out-specified it, so a held paragraph went on wrapping and drew a
    second panel inside the first. The question box showed both.        */

/*  the shell's 72-column breaks are dropped and the browser wraps: see
    renderProse() in colregs.js for which paragraphs keep theirs        */
.prose > :first-child { margin-top: 0; }
.prose > :last-child  { margin-bottom: 0; }
.lp      { margin: 0 0 12px; }
.lp-item { margin: 0 0 6px; padding-left: 2.2em; text-indent: -2.2em; }
.lp-item + .lp { margin-top: 12px; }

/*  A HELD PARAGRAPH KEEPS THE SHELL'S LAYOUT EXACTLY. C4's anatomy of a
    report is 67 columns and the box is about 44, so it has to scroll --
    on its own, never pushing the page sideways. It is given its own
    inset panel because, flush with the reflowed prose around it, a
    clipped table looks like text that went missing rather than a table
    you can push. The inset says: this one is wider than the screen.   */
.lp-pre {
  white-space: pre; overflow-x: auto; -webkit-overflow-scrolling: touch;
  margin: 0 0 12px; font: inherit; color: inherit;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 6px; padding: 10px 12px;
}
.check { border-top: 1px solid var(--line); padding-top: 14px; }

/* ---------- footer ---------- */
.foot {
  max-width: 760px; margin: 28px auto 0; padding: 16px 14px 28px;
  border-top: 1px solid var(--line);
  color: var(--dim); font-size: 12.5px; line-height: 1.6;
}
.foot p { margin: 0 0 10px; }
.foot strong { color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------- the contacts figures -----------------------------------
   The relative-motion plot and the compass rose, drawn by
   contacts-figs.js. The colours live HERE and not in the drawing code,
   which is the point: setMode() redraws every view that is showing,
   because the rest of the app bakes the palette in with cssvar() at
   draw time, and a figure drawn before the toggle keeps the old one.
   Drawn that way these came out blue and green on the night palette.
   Styled from the custom properties, they follow the toggle with no
   redraw and nothing to add to setMode()'s list.                     */
.ct-fig { width: 100%; height: auto; max-width: 440px; display: block;
          margin: 10px auto; background: var(--panel-2);
          border: 1px solid var(--line); border-radius: var(--radius); }
.ct-fig text { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
               font-size: 13px; }

/* the range control: the figure only answers C1's question if you can
   change down the scale, so the buttons are part of the figure */
.ct-wrap   { margin: 10px auto; max-width: 440px; }
.ct-rng    { display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
             justify-content: center; margin-bottom: 6px; }
.ct-rng-lab { color: var(--dim); font-family: ui-monospace, Menlo, monospace;
              font-size: 11px; letter-spacing: 0.08em; }
.ct-rng button {
  font-family: ui-monospace, Menlo, monospace; font-size: 12px;
  min-width: 38px; min-height: 34px; padding: 4px 6px;
  color: var(--dim); background: var(--panel);
  border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.ct-rng button[data-on] { color: var(--accent); border-color: var(--accent); }

.ct-ring     { fill: none; stroke: var(--line); stroke-width: 1; }
.ct-edge     { fill: none; stroke: var(--dim); stroke-width: 1.5; }
.ct-track    { stroke: var(--accent); stroke-width: 1.5; opacity: 0.55;
               stroke-dasharray: 1 4; }
.ct-cpa-line { stroke: var(--dim); stroke-width: 1; stroke-dasharray: 4 4; }
.ct-cpa      { fill: none; stroke: var(--accent); stroke-width: 2; }
.ct-own      { fill: var(--accent); }
.ct-own-lab  { fill: var(--accent); }
.ct-mark     { fill: var(--text); }
.ct-num      { fill: var(--text); }
.ct-lab      { fill: var(--dim); }

/* the sidelights, and on the night palette both are the same red by
   design -- the WORD in the label is what disambiguates, which is the
   whole reason relative bearings are spoken as Red and Green */
.ct-spoke { stroke-width: 1.5; opacity: 0.55; }
.ct-port  { stroke: var(--lamp-r); fill: var(--lamp-r); }
.ct-stbd  { stroke: var(--lamp-g); fill: var(--lamp-g); }

/* ---------- the contacts exercises ---------------------------------
   The tracking table and the Ekelund leg pair are genuine tables, so
   they are tables: the shell draws them with %-23s because a terminal
   has no other way, and that is not a reason for a browser to.      */
.ct-tab { width: 100%; border-collapse: collapse; margin: 0 0 16px;
          font-family: ui-monospace, Menlo, monospace; font-size: 13.5px;
          background: var(--panel); border: 1px solid var(--line);
          border-radius: var(--radius); overflow: hidden; }
.ct-tab th { text-align: left; font-weight: 600; color: var(--dim);
             font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
             padding: 10px 12px 6px; border-bottom: 1px solid var(--line); }
.ct-tab td { padding: 7px 12px; color: var(--text);
             font-variant-numeric: tabular-nums; }
.ct-tab td.num, .ct-tab th:last-child { text-align: right; }
.ct-tab tr + tr td { border-top: 1px solid var(--line); }

.exq { margin: 0 0 18px; }
.exq h3 { color: var(--accent); font-size: 14px; margin: 0 0 8px; }
/*  scroll-margin, because the header is sticky: scrollIntoView() put
    the score line underneath it and the first thing you saw after
    answering was the range buttons.  */
.exmark { border-top: 1px solid var(--line); margin-top: 22px; padding-top: 16px;
          scroll-margin-top: 76px; }
.exmark h3 { color: var(--accent); font-size: 15px; margin: 0 0 12px; }

/*  the index's second group: a name and a line about it */
.ridx .sub { display: block; color: var(--dim); font-size: 12px; margin-top: 2px; }

/*  "another" reads as what it is -- a control, not a word */
button.linkish { background: none; border: 0; padding: 0; cursor: pointer;
                 color: var(--accent); font: inherit; text-decoration: underline; }

/*  the card is one block and keeps its own margins: it is a card, and a
    card whose columns have been reflowed is a list */
.card-pre { background: none; border: 0; padding: 0; margin: 0; }
