/* =====================================================================
   drill -- a study machine with no material in it.

   This tool ships EMPTY. It carries no questions, no procedures and no
   text of anybody's: it reads a content pack the user loads from their
   own device, which is read locally and never leaves it. That is the
   whole design. Material somebody else owns can be studied without ever
   being published, and the published part is only the machine.

   Two modes, as everywhere in this suite. NIGHT is red-on-black because
   the watch you are drilling for is as likely to be at 0300 as 1500.

   One rule the CSS has to enforce as firmly as the code: the answer is
   NOT IN THE PAGE until it is asked for. Not hidden, not collapsed,
   not transparent -- absent. An answer you can select, zoom or reveal
   with a long press is an answer you have read.
   ===================================================================== */
:root {
  --ground:  #07090b;
  --panel:   #10151a;
  --panel-2: #161c23;
  --line:    #232b34;
  --text:    #e6eaef;
  --dim:     #8995a3;
  --accent:  #6fb3d9;

  --ok:      #2fb35f;      /* an item checked and sound */
  --att:     #e8a33d;      /* needs attention: a defect, open */
  --bad:     #ff4438;      /* short of minimum, overdue */
  --none:    #5a6673;      /* not observed, not observable */
  --pass:    #2fb35f;      /* a section passed */
  --part:    #e8a33d;      /* studied, but under the mark */
  --locked:  #5a6673;      /* not open yet */
  --unseen:  #3a4450;      /* not studied -- NOT the same as weak */

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

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

  --ok:      #a82218;
  --att:     #e23a2c;
  --bad:     #ff6b5e;
  --none:    #6b1a14;
  --pass:    #a82218;
  --part:    #e23a2c;
  --locked:  #6b1a14;
  --unseen:  #4a1210;
}

* { 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;
  /* Stops a scroll at the top of the page from chaining to the host and
     dismissing an embedded view.  A watch stander scrolling the log should
     not be able to close the app by accident. */
  overscroll-behavior: none;
}

/* ---------------------------------------------------------------------
   [hidden] FIRST, and with !important.

   `hidden` is only a presentation hint: any `display` rule beats it.
   In an earlier build every step of the camera sight showed its controls
   at once because `.panel { display: grid }` quietly won, and the screen
   was unusable.  This rule has to sit above every component rule in the
   file, which is why it is here and not further down.
   --------------------------------------------------------------------- */
[hidden] { display: none !important; }

.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
.tnum { font-variant-numeric: tabular-nums; }

/* ---- the bar ------------------------------------------------------- */
.bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 8px;
  padding: calc(env(safe-area-inset-top) + 8px) 12px 8px;
  background: var(--ground);
  border-bottom: 1px solid var(--line);
}
.bar h1 {
  flex: 1 1 auto; min-width: 0;
  margin: 0; font-size: 17px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bar button {
  flex: 0 0 auto;
  min-height: 40px; padding: 0 12px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 13px; font-weight: 600; letter-spacing: .04em;
}
.bar .back { font-size: 24px; line-height: 1; padding: 0 14px; }

main { padding: 12px; max-width: 760px; margin: 0 auto; }

.lede { color: var(--dim); margin: 4px 0 16px; }
.note { color: var(--dim); font-size: 13px; }
.warn { color: var(--bad); }

/* ---- panels -------------------------------------------------------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 12px;
}
.panel > h2 {
  margin: 0 0 10px;
  font-size: 12px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--dim);
}

/* ---- the status banner --------------------------------------------- */
.status { display: flex; align-items: flex-start; gap: 10px; }
.status .who { flex: 1 1 auto; min-width: 0; }
.status .nm { font-size: 18px; font-weight: 600; }
.status .wh { color: var(--dim); font-size: 13px; }
.kindtag {
  display: inline-block; margin-top: 4px;
  padding: 2px 7px; border-radius: 5px;
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  border: 1px solid var(--line); color: var(--dim);
}
.kindtag.sub { color: var(--low); border-color: var(--low); }

/* ---- the slot strip ------------------------------------------------ */
.slots { display: flex; align-items: center; gap: 8px; }
.slots .d {
  flex: 1 1 auto; text-align: center;
  font-size: 16px; font-weight: 600;
}
.slots .d small { display: block; color: var(--dim); font-weight: 400; font-size: 12px; }
.slots button {
  flex: 0 0 auto; width: 48px; height: 44px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 20px; line-height: 1;
}

/* ---- forms --------------------------------------------------------- */
.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.fields label { display: block; font-size: 12px; color: var(--dim); margin-bottom: 3px; }
.fields .f { min-width: 0; }
input[type="text"], input[type="number"], input[type="search"], select {
  width: 100%; min-height: 44px; padding: 0 10px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 16px;            /* 16px or iOS zooms the page on focus */
  font-variant-numeric: tabular-nums;
}
input:focus-visible, select:focus-visible, button:focus-visible, .row:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.btn {
  min-height: var(--tap); padding: 0 16px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 15px; font-weight: 600;
}
.btn.wide { width: 100%; }
.btn.go { border-color: var(--accent); color: var(--accent); }
.btn:disabled { opacity: .45; }
.btnrow { display: flex; gap: 8px; flex-wrap: wrap; }
.btnrow .btn { flex: 1 1 auto; }

/* ---- rows ----------------------------------------------------------- */
.row {
  display: block; width: 100%; text-align: left;
  min-height: var(--tap); padding: 10px 12px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 8px;
}
.row b { display: block; font-size: 15px; font-weight: 600; }
.row span { display: block; color: var(--dim); font-size: 13px; }
.row .far { float: right; color: var(--dim); font-size: 13px; font-variant-numeric: tabular-nums; }

/* ---- the terminal view --------------------------------------------- */
details.asterm { margin-top: 10px; }
details.asterm summary {
  cursor: pointer; color: var(--dim); font-size: 13px;
  padding: 6px 0; list-style: none;
}
details.asterm summary::-webkit-details-marker { display: none; }
details.asterm summary::before { content: "\25B8\00a0"; }
details.asterm[open] summary::before { content: "\25BE\00a0"; }
details.asterm pre {
  margin: 6px 0 0; padding: 10px;
  background: #000; color: #d8dee4;
  border: 1px solid var(--line); border-radius: 6px;
  font-family: ui-monospace, Menlo, monospace; font-size: 12px; line-height: 1.35;
  overflow-x: auto;
}
:root[data-mode="night"] details.asterm pre { color: var(--text); }

/* ---- progress ------------------------------------------------------ */
.bararea { height: 4px; background: var(--panel-2); border-radius: 2px; overflow: hidden; }
.bararea i { display: block; height: 100%; background: var(--accent); width: 0; }

.foot { color: var(--dim); font-size: 13px; margin: 20px 0 8px; }
.foot strong { color: var(--text); }

@media (max-width: 420px) {
  .fields { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---- the entry form -------------------------------------------------
   A field is one row: label, the control, and the two decline buttons.
   `-` and `/` are first-class answers, not an escape hatch, so they are
   always present and always the same size as everything else. A form
   that punishes blanks gets invented numbers -- somebody who did not
   read the barometer writes something plausible rather than leave a gap
   that looks like negligence.
   --------------------------------------------------------------------- */
.field { margin-bottom: 14px; }
.field > .lab {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px; margin-bottom: 5px;
}
.field > .lab b { font-weight: 600; color: var(--text); }
.field > .lab .carried {
  margin-left: auto; color: var(--carry); font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.field .ctl { display: flex; gap: 8px; align-items: stretch; }
.field .ctl input { flex: 1 1 auto; min-width: 0; }
.declines { display: flex; gap: 6px; flex: 0 0 auto; }
.dbtn {
  width: 46px; min-height: 44px;
  background: var(--panel-2); color: var(--none);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 17px; font-weight: 700; line-height: 1;
}
.dbtn[aria-pressed="true"] { color: var(--ground); background: var(--none); border-color: var(--none); }
:root[data-mode="night"] .dbtn[aria-pressed="true"] { color: var(--ground); }
.field .why { margin-top: 6px; font-size: 13px; color: var(--att); }
.field .why .btnrow { margin-top: 6px; }

/* the coded menus: the VOS 0-9 codes, as a grid of keys */
.codes { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.code {
  display: flex; align-items: center; gap: 8px;
  min-height: 46px; padding: 0 10px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 14px; text-align: left;
}
.code i {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 5px;
  background: var(--line); color: var(--text);
  display: grid; place-items: center;
  font-style: normal; font-weight: 700; font-size: 12px;
}
.code[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
.code[aria-pressed="true"] i { background: var(--accent); color: var(--ground); }

/* ---- sections, states and lists -------------------------------------- */
.secnav { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.secnav button {
  flex: 1 1 auto; min-height: 44px; padding: 0 10px;
  background: var(--panel-2); color: var(--dim);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 13px; font-weight: 600;
}
.secnav button[aria-current="true"] { color: var(--accent); border-color: var(--accent); }
.secnav button .tick { color: var(--ok); }

.items { margin: 0; padding: 0; list-style: none; }
.items li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.items li:last-child { border-bottom: 0; }
.items .nm { flex: 1 1 auto; min-width: 0; }
.items .nm b { display: block; font-weight: 600; font-size: 15px; }
.items .nm span { display: block; color: var(--dim); font-size: 13px; }
.items .num { font-variant-numeric: tabular-nums; text-align: right; }
.tag {
  flex: 0 0 auto; padding: 2px 7px; border-radius: 5px;
  font-size: 11px; font-weight: 700; letter-spacing: .05em;
  border: 1px solid currentColor;
}
.tag.ok { color: var(--ok); }
.tag.att { color: var(--att); }
.tag.bad { color: var(--bad); }
.tag.none { color: var(--none); }

.statebtns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.statebtns button {
  min-height: 44px; background: var(--panel-2); color: var(--dim);
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 13px; font-weight: 600;
}
.statebtns button[aria-pressed="true"] { border-color: currentColor; }
.statebtns button.o[aria-pressed="true"] { color: var(--ok); }
.statebtns button.a[aria-pressed="true"] { color: var(--att); }
.statebtns button.n[aria-pressed="true"],
.statebtns button.x[aria-pressed="true"] { color: var(--none); }

.logline {
  font-family: ui-monospace, Menlo, monospace; font-size: 12px;
  word-break: break-all; color: var(--dim);
}
.nag { border-color: var(--att); }
.nag h2 { color: var(--att); }

/* ---- the section list ------------------------------------------------ */
.sections { margin: 0; padding: 0; list-style: none; }
.sections li { margin-bottom: 8px; }
.seclink {
  display: block; width: 100%; text-align: left;
  padding: 11px 12px; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
}
.seclink .nm { display: flex; align-items: baseline; gap: 8px; }
.seclink .num {
  flex: 0 0 auto; width: 1.8em; color: var(--dim);
  font-variant-numeric: tabular-nums; font-size: 13px;
}
.seclink b { flex: 1 1 auto; font-weight: 600; font-size: 15px; }
.seclink .sub { display: block; margin-top: 3px; margin-left: calc(1.8em + 8px);
                color: var(--dim); font-size: 13px; }
.seclink[data-state="pass"]   { border-color: var(--pass); }
.seclink[data-state="pass"] b { color: var(--pass); }
.seclink[data-state="part"]   { border-color: var(--part); }
.seclink[data-state="locked"] { opacity: .72; }

.pill {
  flex: 0 0 auto; padding: 2px 7px; border-radius: 5px; font-size: 11px;
  font-weight: 700; letter-spacing: .05em; border: 1px solid currentColor;
}
.pill.pass   { color: var(--pass); }
.pill.part   { color: var(--part); }
.pill.locked { color: var(--locked); }
.pill.unseen { color: var(--unseen); }

/* ---- the reference --------------------------------------------------- */
.ref { font-size: 15px; line-height: 1.6; overflow-wrap: break-word; }
.ref h2.part { font-size: 13px; font-weight: 700; letter-spacing: .08em;
               text-transform: uppercase; color: var(--accent);
               margin: 22px 0 10px; }
.ref h2:not(.part) { font-size: 17px; margin: 20px 0 8px; }
.ref h3 { font-size: 15px; margin: 16px 0 6px; color: var(--text); }
.ref p { margin: 0 0 10px; }
.ref ul, .ref ol { margin: 0 0 12px; padding-left: 22px; }
.ref li { margin-bottom: 6px; }
.ref blockquote {
  margin: 0 0 12px; padding: 10px 12px; background: var(--panel-2);
  border-left: 3px solid var(--accent); border-radius: 0 6px 6px 0;
}
.ref blockquote p:last-child { margin-bottom: 0; }
.ref table { width: 100%; border-collapse: collapse; margin: 0 0 14px; font-size: 14px; }
.ref th, .ref td { text-align: left; vertical-align: top; padding: 7px 8px;
                   border-bottom: 1px solid var(--line); }
.ref th { font-size: 11px; font-weight: 700; letter-spacing: .06em;
          text-transform: uppercase; color: var(--dim); }
.ref tr:last-child td { border-bottom: 0; }
.ref .tablewrap { overflow-x: auto; }
.ref strong { color: var(--text); font-weight: 700; }

/*  A FIGURE IN THE REFERENCE.  Some of what this app teaches is a SHAPE:
    the search patterns are rows of bearings and distances that mean
    nothing until you see the spiral, and Larry's word on them was that
    they "need a visual in any event to properly understand them".  The
    pack draws its own, as inline SVG.

    Nothing here sets a stroke or a fill.  The drawing takes its colour
    from currentColor, so it follows day, night and the red mode without
    being told which one is on -- and a figure that needed its own colours
    would need three sets of them.  */
.ref figure.fig { margin: 4px 0 18px; }
.ref figure.fig svg { display: block; margin: 0 auto; max-width: 100%;
                      height: auto; overflow: visible; }
.ref .fig-cap { color: var(--dim); font-size: 13px; line-height: 1.5;
                max-width: 34rem; margin: 8px auto 0; }

/* ---- drilling -------------------------------------------------------- */
.card { background: var(--panel); border: 1px solid var(--line);
        border-radius: var(--radius); padding: 16px; margin-bottom: 12px; }
.qnum { color: var(--dim); font-size: 12px; letter-spacing: .06em;
        text-transform: uppercase; margin-bottom: 8px; }
.qtext { font-size: 18px; line-height: 1.45; margin: 0 0 4px; }
.qsrc { color: var(--dim); font-size: 12px; margin-top: 10px; }
.qsrc.hand { color: var(--part); }
.atext { font-size: 16px; line-height: 1.5; margin: 14px 0 0;
         padding-top: 14px; border-top: 1px solid var(--line); }

/* the choices in a graded test */
.choices { display: grid; gap: 8px; margin-top: 14px; }
.choice {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  padding: 11px 12px; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px; font-size: 15px;
  line-height: 1.4;
}
.choice i { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 5px;
            background: var(--line); display: grid; place-items: center;
            font-style: normal; font-weight: 700; font-size: 12px; }
.choice[aria-pressed="true"] { border-color: var(--accent); }
.choice[aria-pressed="true"] i { background: var(--accent); color: var(--ground); }
.choice[data-mark="right"] { border-color: var(--pass); color: var(--pass); }
.choice[data-mark="wrong"] { border-color: var(--bad); color: var(--bad); }
.choice:disabled { opacity: 1; }

/* ---- scores ---------------------------------------------------------- */
.score { text-align: center; padding: 8px 0 4px; }
.score .big { font-size: 46px; font-weight: 700; font-variant-numeric: tabular-nums;
              line-height: 1.1; }
.score .big.pass { color: var(--pass); }
.score .big.fail { color: var(--bad); }
.score .of { color: var(--dim); font-size: 14px; }

.bars { margin: 0; padding: 0; list-style: none; }
.bars li { padding: 9px 0; border-bottom: 1px solid var(--line); }
.bars li:last-child { border-bottom: 0; }
.bars .top { display: flex; gap: 8px; align-items: baseline; font-size: 14px; }
.bars .top b { flex: 1 1 auto; font-weight: 600; }
.bars .top span { color: var(--dim); font-variant-numeric: tabular-nums; }
.bars .track { height: 6px; margin-top: 6px; background: var(--panel-2);
               border-radius: 3px; overflow: hidden; }
.bars .track i { display: block; height: 100%; background: var(--part); }
.bars li[data-state="pass"] .track i { background: var(--pass); }
.bars li[data-state="unseen"] .track i { background: var(--unseen); }

/* ---- ordering questions ---------------------------------------------
   The steps you have placed, numbered, then the ones still to place.
   Rows are full width and at least one tap target tall, because the
   only place this gets used in anger is a wet foredeck. Built from the
   same tokens as .choice, so night mode carries it without a second
   rule. */
.seq-picked { list-style: none; margin: 12px 0 0; padding: 0; }
.seq-pool { display: grid; gap: 8px; margin-top: 12px; }
.seq-row {
  display: flex; gap: 10px; align-items: flex-start; width: 100%;
  text-align: left; min-height: var(--tap); padding: 11px 12px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  font: inherit; font-size: 15px; line-height: 1.4; cursor: pointer;
}
.seq-picked .seq-row { margin-bottom: 8px; }
.seq-pool .seq-row:hover { border-color: var(--accent); }
.seq-row .seq-n {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 5px;
  background: var(--line); display: grid; place-items: center;
  font-weight: 700; font-size: 12px; font-variant-numeric: tabular-nums;
}
.seq-row.chosen { border-color: var(--accent); }
.seq-row.chosen .seq-n { background: var(--accent); color: var(--ground); }
.seq-row[data-mark="right"] { border-color: var(--pass); color: var(--pass); }
.seq-row[data-mark="right"] .seq-n { background: var(--pass); color: var(--ground); }
/*  A STEP IN THE WRONG PLACE HAS TO LOOK WRONG.  There was no rule for
    this at all: a placed row carried no mark, so a wrong order rendered
    in the accent colour next to the right order in green, and read as
    green.  The accent rule below it would otherwise win on the chosen
    rows, so these come after .seq-row.chosen deliberately. */
.seq-row[data-mark="wrong"] { border-color: var(--bad); color: var(--bad); }
.seq-row[data-mark="wrong"] .seq-n { background: var(--bad); color: var(--ground); }
.seq-picked.right .seq-row { cursor: default; }
