/* MESA — shared shell.
 *
 * The palette is not chosen, it is inherited: these are the tool's own class colours,
 * lifted from mesa_dental/render.py, so the home page and the thing it launches are
 * plainly the same instrument. Enamel is what a finished arch looks like inside the
 * labeller, so enamel is what a finished arch looks like here too.
 */
:root {
  --ground:  #101017;
  --surface: #191921;
  --line:    #2b2b36;
  --line-lit:#454556;
  --enamel:  #f0ebdc;   /* ENAMEL_RGB  — done */
  --gingiva: #c78786;   /* GINGIVA_RGB — the accent, used once */
  --bracket: #29a8e0;   /* BRACKET_RGB — interactive */
  --slate:   #43474d;   /* ARTIFACT_RGB — waiting, inert */
  --dim:     #8b8b99;
  --text:    #e9e9ee;
  color-scheme: dark;
}

/* 16px, not 15. Every control that says `font: inherit` -- which is most of the rail --
   takes its size from here, and the whole instrument panel was reported as too small to
   read comfortably. The rail widened to 340px in the same change so the tooth chart
   could grow with it. */
html, body { margin: 0; background: var(--ground); color: var(--text);
             font: 16px/1.6 "IBM Plex Sans", -apple-system, system-ui, sans-serif; }
a { color: inherit; }
.mono { font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace; }

/* --- boot ------------------------------------------------------------------
   gate.js cannot run until the Firebase SDK has come down from gstatic, and until it
   runs there is nothing standing in front of the page. For that half second the
   labeler showed its tools to somebody who had not signed in yet, and then replaced
   them with the sign-in box. A gated page is therefore hidden from first paint and
   revealed only once the sign-in state is known, so the first thing anybody sees is
   either the sign-in box or the app -- never one and then the other.

   `visibility`, not `display`: the layout still happens underneath, so the canvas is
   already its final size when the labeler is revealed and three.js never sees a
   zero-height viewport.

   The class is opted into per page rather than applied to every page, because
   tutorial.html runs no script at all and a page that nothing ever reveals would stay
   blank for good. Forgetting the class on a new page costs the old flash; applying it
   by default would cost a dead page. */
html.gated body { visibility: hidden; }
html.gated.ready body { visibility: visible; }

/* Something has to be on screen while that resolves or the wait reads as a broken tab.
   The mark alone, on the same ground the gate uses, so arriving at the gate is only the
   words appearing. It breathes because this session proved that a still screen and a
   wedged screen look identical. */
html.gated:not(.ready)::before {
  content: ""; position: fixed; inset: 0; z-index: 20; background: var(--ground);
}
html.gated:not(.ready)::after {
  content: ""; position: fixed; inset: 0; z-index: 21;
  background: url("./sio-mark.svg") no-repeat center / 44px;
  animation: boot 1.4s ease-in-out infinite;
}
@keyframes boot { 0%, 100% { opacity: .30 } 50% { opacity: .85 } }
@media (prefers-reduced-motion: reduce) {
  html.gated:not(.ready)::after { animation: none; opacity: .6 }
}

/* --- gate, injected by gate.js so four pages cannot drift apart --- */
#gate { position: fixed; inset: 0; z-index: 10; background: var(--ground);
        display: grid; place-items: center; }
#gate[hidden] { display: none; }
#gatebox { text-align: center; max-width: 340px; padding: 0 20px; }
#gatebox .mk { width: 44px; height: 44px; color: var(--dim); margin-bottom: 18px; }
#gatebox h1 { font: 600 30px/1 "Jost", sans-serif; letter-spacing: .12em;
              margin: 0 0 10px; color: var(--enamel); }
#gatebox p { color: var(--dim); margin: 0 0 20px; }
#signin { font: 500 15px/1 "IBM Plex Sans", sans-serif; padding: 11px 20px;
          border-radius: 7px; cursor: pointer; background: var(--enamel);
          color: var(--ground); border: 0; }
#signin:hover { background: #fff; }
#gateerr { color: var(--gingiva); margin-top: 16px; min-height: 1.5em; font-size: 14px; }

/* --- brand lockup ---------------------------------------------------------
   SIO Group is the company and MESA is the instrument. The bar used to carry the
   company's mark AND its wordmark, and that lockup was also the only link on the
   page -- so the one control that goes to MESA's home page was labelled "SIO
   Group". A link has to name where it goes.

   So the mark stays, as quiet company identity, and the word beside it is the
   product: mark plus product name is an ordinary lockup, and now the label and
   the destination agree. sio-wordmark.svg is still in the tree and still used on
   the home page, where naming the company is the point. */
.brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none;
         color: #b9b9c6; }
.brand:hover { color: var(--text); }
/* The two marks ship as <img>, an isolated document CSS colour cannot reach, so the ink is
   baked into the files and hover brightens the image instead of recolouring it. */
.brand:hover .mk, .brand:hover .wm { filter: brightness(1.22); }
.brand .mk { width: 26px; height: 26px; flex: none; }
.brand .wm { height: 15px; width: auto; }
/* The company, named once, where naming it is the whole purpose of the element rather
   than a label on a button that goes somewhere else. */
.foot { margin-top: 56px; padding-top: 20px; border-top: 1px solid var(--line); }
.foot .wm { height: 13px; width: auto; opacity: .45; }

/* Jost, as the masthead sets it, so the bar and the home page name the tool alike. */
.brand .name { font: 600 15px/1 "Jost", "IBM Plex Sans", sans-serif;
               letter-spacing: .12em; }

.masthead { font: 600 62px/0.98 "Jost", "IBM Plex Sans", sans-serif;
            letter-spacing: .10em; margin: 0 0 6px; color: var(--enamel); }
.tagline { color: var(--dim); font-size: 13.5px; letter-spacing: .02em;
           margin: 0 0 40px; }
@media (max-width: 560px) { .masthead { font-size: 44px; } }

/* --- page chrome --- */
.page { max-width: 640px; margin: 0 auto; padding: 30px 24px 80px; }
.bar { display: flex; align-items: center; gap: 14px; margin-bottom: 52px; }
.wordmark { font: 600 13px/1 "Jost", sans-serif; letter-spacing: .30em;
            color: var(--enamel); text-decoration: none; }
.bar .spacer { flex: 1; }
[data-who] { color: var(--dim); font-size: 13px; }
[data-signout] { font: inherit; font-size: 13px; color: var(--dim); background: none;
                 border: 0; cursor: pointer; text-decoration: underline; padding: 0 0 0 10px; }

/* --- the signature: the campaign itself, one mark per arch --- */
.count { font: 500 34px/1 "IBM Plex Mono", monospace; letter-spacing: -.02em;
         font-variant-numeric: tabular-nums; margin: 0; }
.count em { font-style: normal; color: var(--dim); }
.count-sub { color: var(--dim); font-size: 14px; margin: 8px 0 22px; }
.marks { display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 8px; }
.mark { width: 9px; height: 16px; border-radius: 2px; background: var(--slate);
        opacity: .5; }
.mark.lower { height: 11px; align-self: flex-end; }   /* the two jaws, not decoration */
/* One shade per state, so the campaign reads as a picture rather than a fraction.
   Amber is started, blue ready for review, green approved; --slate is untouched. Green
   is last on purpose: it is the one everybody reads as "done", and done here means the
   doctor has signed it off, not that an assistant has stopped typing. */
.mark.in_progress { background: #d8a93a; opacity: 1; }
.mark.ready { background: var(--bracket); opacity: 1; }
.mark.approved { background: #6fb26f; opacity: 1; }
.marks-key { color: var(--dim); font-size: 12.5px; display: flex; gap: 8px 18px;
             align-items: center; flex-wrap: wrap; margin-bottom: 46px; }
.marks-key span { display: inline-flex; align-items: center; gap: 6px; }
.mark.key { animation: none; }
@media (prefers-reduced-motion: no-preference) {
  .mark { animation: rise .45s cubic-bezier(.2,.7,.3,1) backwards; }
  @keyframes rise { from { transform: translateY(4px); opacity: 0 } }
}

/* --- destinations --- */
.dests { display: flex; flex-direction: column; }
.dest { display: flex; align-items: baseline; gap: 16px; padding: 17px 4px 17px 16px;
        border-top: 1px solid var(--line); text-decoration: none; position: relative; }
.dest:last-child { border-bottom: 1px solid var(--line); }
.dest::before { content: ""; position: absolute; left: 0; top: -1px; bottom: -1px;
                width: 2px; background: transparent; }
.dest:hover::before, .dest:focus-visible::before { background: var(--bracket); }
.dest:hover { background: var(--surface); }
.dest b { font-weight: 500; font-size: 16px; }
.dest span { color: var(--dim); font-size: 14px; }
.dest .meta { margin-left: auto; color: var(--dim); font-size: 12.5px;
              font-family: "IBM Plex Mono", monospace; white-space: nowrap; }
.dest:focus-visible { outline: none; background: var(--surface); }

/* --- ordinary content: upload + tutorial --- */
h1.title { font-size: 22px; font-weight: 600; margin: 0 0 6px; }
.lede { color: var(--dim); margin: 0 0 30px; }
/* A heading, not a label. This was 12 px dim-grey uppercase mono with .18em tracking --
   the treatment for a field caption -- so the sections read as quieter than the body text
   they introduce and the page had no scannable structure at all. */
h2 { font: 600 18px/1.3 "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
     color: var(--enamel); margin: 40px 0 12px; }
p { margin: 0 0 14px; }
kbd { font: 12.5px/1 "IBM Plex Mono", monospace; background: #23232e; color: var(--text);
      border: 1px solid var(--line-lit); border-radius: 4px; padding: 2px 6px; }
.note { border-left: 2px solid var(--gingiva); padding-left: 14px; color: var(--dim);
        margin: 18px 0; }
table { border-collapse: collapse; width: 100%; margin: 6px 0 18px; }
th, td { text-align: left; padding: 8px 12px 8px 0; border-bottom: 1px solid var(--line);
         vertical-align: top; font-size: 14px; }
th { color: var(--dim); font-weight: 500; font-size: 12.5px; }
td.k { white-space: nowrap; width: 1%; }
.chip { display: inline-block; font: 500 11px/17px "IBM Plex Mono", monospace;
        padding: 0 6px; border-radius: 3px; border: 1px solid var(--line-lit);
        color: var(--dim); }
.chip.has  { background: var(--enamel); color: var(--ground); border-color: var(--enamel); }
.chip.gone { background: #262631; color: var(--dim); text-decoration: line-through; }
.chip.dup  { background: #b8514f; color: #fff; border-color: #b8514f; }
/* The two tag states the chart has no cell for, so the tutorial's legend of what is drawn
   ON the arch can show the actual colours rather than describe them. Values match
   label.html's .tag.unnumbered and .tag.flag. */
.chip.open { background: #d8a93a; color: #14141a; border-color: #d8a93a; }
.chip.flag { background: #6a5acd; color: #fff; border-color: #6a5acd; }

/* --- upload --- */
.drop { border: 1px dashed var(--line-lit); border-radius: 10px; padding: 34px 20px;
        text-align: center; background: var(--surface); }
.drop.over { border-color: var(--bracket); background: #17222b; }
.pick { font: 500 15px/1 "IBM Plex Sans", sans-serif; padding: 11px 20px; cursor: pointer;
        border-radius: 7px; background: var(--enamel); color: var(--ground);
        border: 0; display: inline-block; }
.pick:hover { background: #fff; }
.formats { color: var(--dim); font-size: 13px; margin-top: 14px; }
.queue { list-style: none; padding: 0; margin: 24px 0 0; }
.queue li { display: flex; align-items: center; gap: 12px; padding: 10px 2px;
            border-bottom: 1px solid var(--line); font-size: 14px; }
.queue .name { font-family: "IBM Plex Mono", monospace; font-size: 13px;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.queue .state { margin-left: auto; color: var(--dim); font-size: 12.5px;
                font-family: "IBM Plex Mono", monospace; white-space: nowrap; }
.queue .state.bad { color: var(--gingiva); }
.queue .state.ok  { color: var(--enamel); }
.track { height: 2px; background: var(--line); border-radius: 2px; overflow: hidden;
         width: 84px; }
.track i { display: block; height: 100%; background: var(--bracket); width: 0; }
