/* The tooth.monster treatment. The tokens and the bevel recipes are copied from
   the site's css/style.css, so see that file's README for why they are built this
   way. Copied rather than linked so a change there cannot break this tool. */

:root {
  --color-white:      #FFFFFF;
  --color-paper:      #FAF6EC;
  --color-cream:      #EADBC2;
  --color-navy:       #00427F;
  --color-slate:      #93AECB;
  --color-brick:      #802E28;
  --color-sienna:     #80553E;
  --color-midnight:   #201B2A;

  --cell: 16px;

  --bevel: 2px;
  --bevel-light: var(--color-white);
  --bevel-face:  var(--color-cream);
  --bevel-shade: var(--color-sienna);
  --bevel-dark:  var(--color-midnight);

  --raised:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-light),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-dark);
  --pressed:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-dark),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-light);
  --sunken:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-shade),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-light);
  --drop: 4px 4px 0 0 rgb(32 27 42 / 0.45);

  --pad: 8px;
  --knobs-w: calc(var(--cell) * 22);
  --tab-w: calc(var(--cell) * 1.75);

  --font-ui: "Roboto", Tahoma, Verdana, Geneva, "DejaVu Sans", sans-serif;
  --font-chrome: "Silkscreen", "Press Start 2P", system-ui;
  --font-chrome-size: 12px;
}

@font-face {
  font-family: "Silkscreen";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/silkscreen-regular-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Silkscreen";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/silkscreen-bold-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Press Start 2P";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/press-start-2p-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Roboto";
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/roboto-latin.woff2") format("woff2");
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  height: 100%;
  background-color: var(--color-cream);
  /* The site's own background, the still underneath so the page is never bare
     while the GIF loads. */
  background-image: url("img/toothbackground-motion.gif"), url("img/toothbackground.svg");
  background-size: calc(72 * var(--cell)) calc(36 * var(--cell));
  background-attachment: fixed;
}

@media (prefers-reduced-motion: reduce) {
  html { background-image: url("img/toothbackground.svg"); }
}

body {
  height: 100dvh;
  margin: 0;
  padding: var(--cell);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  font: 15px/1.5 var(--font-ui);
  color: var(--color-midnight);
}

button, select, input { font: inherit; color: inherit; }

.press-start { font-family: "Press Start 2P", system-ui; font-weight: 400; }

/* The file inputs are hidden inside their labels, so the label takes the focus
   ring. Width and height 0 rather than display:none, which would drop them out of
   the tab order. */
label:has(> input[type="file"]) { position: relative; cursor: pointer; }
label > input[type="file"] { position: absolute; width: 0; height: 0; opacity: 0; }
label:has(> input[type="file"]:focus-visible) {
  outline: 3px solid var(--color-navy);
  outline-offset: -3px;
}

/* ---- boxes -------------------------------------------------------------- */

.box {
  position: relative;
  background: var(--fill, var(--color-paper));
  color: var(--ink, var(--color-midnight));
  outline: 1px solid var(--color-midnight);
  box-shadow:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-light),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-dark),
    inset calc(2 * var(--bevel)) calc(2 * var(--bevel)) 0 0 var(--bevel-face),
    inset calc(-2 * var(--bevel)) calc(-2 * var(--bevel)) 0 0 var(--bevel-shade),
    var(--drop);
}

.titlebar {
  --fill: var(--color-navy);
  --ink: var(--color-paper);
  display: flex;
  align-items: center;
  gap: var(--pad);
  min-height: calc(var(--cell) * 3);
  padding: 0 calc(var(--bevel) * 2 + var(--pad));
}

.titlebar h1 {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: 15px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.titlebar-logo {
  display: block;
  flex: none;
  width: calc(var(--cell) * 1.5);
  height: calc(var(--cell) * 1.5);
  margin-left: calc(var(--pad) / 2);
  color: var(--color-paper);
}
.titlebar-logo a { display: block; width: 100%; height: 100%; color: inherit; }
.titlebar-logo svg { display: block; width: 100%; height: 100%; }

.titlebar-buttons { display: flex; flex: none; gap: var(--bevel); }

.titlebar-btn {
  display: grid;
  place-items: center;
  width: calc(var(--cell) * 1.5);
  height: calc(var(--cell) * 1.5);
  background: var(--color-cream);
  box-shadow: var(--raised);
}
.titlebar-btn img { display: block; width: 60%; height: 60%; object-fit: contain; }

/* ---- the menu strip ----------------------------------------------------- */

nav.menu {
  display: flex;
  align-items: stretch;
  min-height: calc(var(--cell) * 2.25);
  margin-top: 1px;
  background: var(--color-cream);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised);
}

.menu-gap { flex: 1; }

.menu-item {
  display: flex;
  align-items: center;
  padding: 0 calc(var(--pad) * 1.25);
  border: 0;
  background: none;
  color: inherit;
  font-family: var(--font-chrome);
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.menu-item:hover {
  background: var(--color-paper);
  box-shadow: var(--raised);
}

.menu-item:focus-visible {
  background: var(--color-paper);
  outline: 3px solid var(--color-navy);
  outline-offset: -3px;
}

.menu-item[aria-pressed="true"],
.menu-item:active {
  background: var(--color-paper);
  box-shadow: var(--pressed);
}

/* ---- layout ------------------------------------------------------------- */

main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--knobs-w);
  gap: var(--cell);
  min-height: 0;
  margin-top: var(--cell);
}

.stage-column {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* ---- caption strip ------------------------------------------------------ */

.caption {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--pad);
  min-height: calc(var(--cell) * 2);
  margin: 0;
  padding: 0 calc(var(--pad) / 2) 0 var(--pad);
  background: var(--color-navy);
  color: var(--color-paper);
  outline: 1px solid var(--color-midnight);
  box-shadow:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-light),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-dark),
    inset calc(2 * var(--bevel)) calc(2 * var(--bevel)) 0 0 var(--bevel-face),
    inset calc(-2 * var(--bevel)) calc(-2 * var(--bevel)) 0 0 var(--bevel-shade);
  font-family: var(--font-chrome);
  font-size: var(--font-chrome-size);
  font-weight: 400;
  line-height: 1;
}

.caption > span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.caption > i {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(var(--cell) * 1.25);
  height: calc(var(--cell) * 1.25);
  background: var(--color-cream);
  box-shadow: var(--raised);
}
.caption > i > img { display: block; width: 60%; height: 60%; object-fit: contain; }

/* ---- the preview -------------------------------------------------------- */

.stage {
  --checker-a: #e6e1d6;
  --checker-b: #f3efe5;
  flex: 1;
  display: grid;
  min-height: 0;
  margin-top: 1px;
  overflow: auto;
  overscroll-behavior: contain;
  /* A picture with cells left empty shows this, so it reads as transparent
     rather than as a colour in the mosaic. */
  background: conic-gradient(var(--checker-a) 25%, var(--checker-b) 0 50%,
                             var(--checker-a) 0 75%, var(--checker-b) 0) 0 0 / 20px 20px;
  box-shadow: var(--drop);
}

/* ⚠️ The bevel has to be an overlay. An inset shadow paints under children, and
   the preview fills the box edge to edge, so it would never be seen. This is the
   .gallery-hero problem on the site. Sticky, because the box itself scrolls in
   the 16px view and an absolute overlay would scroll away with the picture. */
.stage::after {
  content: "";
  position: sticky;
  grid-area: 1 / 1;
  top: 0;
  left: 0;
  z-index: 2;
  place-self: start;
  width: 100%;
  height: 100%;
  min-height: 100%;
  pointer-events: none;
  box-shadow:
    inset var(--bevel) var(--bevel) 0 0 var(--bevel-shade),
    inset calc(-1 * var(--bevel)) calc(-1 * var(--bevel)) 0 0 var(--bevel-light),
    inset calc(2 * var(--bevel)) calc(2 * var(--bevel)) 0 0 var(--bevel-dark),
    inset calc(-2 * var(--bevel)) calc(-2 * var(--bevel)) 0 0 var(--bevel-face);
}

.stage > img {
  grid-area: 1 / 1;
  display: block;
  margin: auto;
}

.stage.fit > img {
  width: 100%;
  height: 100%;
  min-height: 0;
  padding: calc(var(--bevel) * 2);
  object-fit: contain;
}

/* Sized in JS to match the export, so never let the grid shrink it. */
.stage.full > img { max-width: none; }


.empty {
  grid-area: 1 / 1;
  align-self: center;
  justify-self: center;
  max-width: calc(var(--cell) * 24);
  margin: var(--cell);
  padding: calc(var(--pad) * 2);
  background: var(--color-paper);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised), var(--drop);
  text-align: center;
}
.empty h3 { margin: 0 0 var(--pad); font-size: 1.1rem; }
.empty p { margin: 0 0 calc(var(--pad) * 1.5); font-size: 0.85rem; }

.stage.dragging { outline: 3px dashed var(--color-navy); outline-offset: -8px; }

.busy {
  position: sticky;
  grid-area: 1 / 1;
  top: var(--pad);
  left: var(--pad);
  z-index: 3;
  place-self: start;
  margin: var(--pad);
  padding: 0 var(--pad);
  background: var(--color-cream);
  box-shadow: var(--raised), 2px 2px 0 0 rgb(32 27 42 / 0.45);
  font-family: var(--font-chrome);
  font-size: var(--font-chrome-size);
  line-height: calc(var(--cell) * 1.5);
  pointer-events: none;
}

.status,
.error {
  flex: none;
  min-height: calc(var(--cell) * 2);
  margin: calc(var(--cell) / 2 + 3px) 0 0;
  padding: calc(var(--pad) / 2) var(--pad);
  font-size: 0.8rem;
  outline: 1px solid var(--color-midnight);
}

.status {
  background: var(--color-cream);
  box-shadow: var(--sunken);
  font-variant-numeric: tabular-nums;
}

.error {
  background: var(--color-brick);
  color: var(--color-paper);
  white-space: pre-wrap;
}

/* ---- the knobs ---------------------------------------------------------- */

.knobs {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* One tab per section, in a row. Eight names do not fit across the panel in the
   chrome font, so only the open tab shows its name and the rest shrink to icons. */
.toolbar {
  display: flex;
  flex: none;
  gap: 1px;
  padding: var(--bevel);
  background: var(--color-cream);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised);
}

.tool-tab {
  display: flex;
  flex: 0 0 var(--tab-w);
  align-items: center;
  justify-content: center;
  gap: calc(var(--pad) / 1.5);
  min-width: 0;
  height: calc(var(--cell) * 2);
  padding: 0;
  border: 0;
  background: var(--color-cream);
  box-shadow: var(--raised);
  cursor: pointer;
}

.tool-tab img { display: block; flex: none; width: 14px; height: 14px; object-fit: contain; }

.tool-tab span {
  display: none;
  overflow: hidden;
  font-family: var(--font-chrome);
  font-size: var(--font-chrome-size);
  line-height: 1;
  white-space: nowrap;
}

.tool-tab:hover { background: var(--color-paper); }

.tool-tab:focus-visible {
  outline: 3px solid var(--color-navy);
  outline-offset: -3px;
}

/* Navy, like every other title on the page, with the black symbol flipped to read
   on it. Hover keeps it navy, or the name would turn paper on paper. */
.tool-tab[aria-selected="true"],
.tool-tab[aria-selected="true"]:hover {
  flex: 1 1 0;
  justify-content: flex-start;
  /* The same inset a closed tab gives its 14px icon, so it stays put on opening. */
  padding-left: calc((var(--tab-w) - 14px) / 2);
  background: var(--color-navy);
  color: var(--color-paper);
  box-shadow: var(--pressed);
}
.tool-tab[aria-selected="true"] span { display: block; }
.tool-tab[aria-selected="true"] img { filter: invert(1); }
.tool-tab[aria-selected="true"]:focus-visible { outline-color: var(--color-paper); }

.tool-panel {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  margin-top: 1px;
  /* Clips the scroller to the bevel, which the panel's own shadow draws. */
  padding: calc(var(--bevel) * 2);
  overflow: hidden;
}

.tool-panels { display: flex; flex: 1; flex-direction: column; min-height: 0; }

.panel-foot {
  display: flex;
  flex: none;
  justify-content: flex-end;
  padding: calc(var(--pad) / 2) var(--pad);
  border-top: 1px solid var(--bevel-shade);
}

.knob-body {
  display: grid;
  flex: 1;
  align-content: start;
  gap: calc(var(--pad) * 1.75);
  min-height: 0;
  padding: var(--pad);
  overflow-y: auto;
  overscroll-behavior-y: contain;
}

.knob-body:focus-visible { outline: 2px solid var(--color-navy); outline-offset: -2px; }

.save-dock {
  flex: none;
  margin-top: calc(var(--cell) / 2 + 3px);
  padding: calc(var(--pad) / 2) var(--pad);
  background: var(--color-cream);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised);
}

.knob {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 var(--pad);
}

.knob-label,
.slot-label { font-size: 0.8rem; font-weight: 500; line-height: 1.3; }

/* Reads label, description, then the control. Set here rather than in the markup
   because the description is only added to the rows that have one. */
.knob small { order: 1; }
.knob .ctl,
.knob .modes { order: 2; margin-top: calc(var(--pad) / 2); }

.knob small,
.hint {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.3;
  opacity: 0.75;
}

.hint.warn { color: var(--color-brick); opacity: 1; }

.ctl {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--pad);
}

input[type="number"],
input[type="text"],
select {
  min-width: 0;
  padding: calc(var(--pad) / 3) calc(var(--pad) / 2);
  border: 0;
  border-radius: 0;
  outline: 1px solid var(--color-midnight);
  background: var(--color-paper);
  box-shadow: var(--sunken);
  font-size: 0.85rem;
}

input[type="number"] { flex: none; width: calc(var(--cell) * 3.75); text-align: right; }
select { width: 100%; }

input[type="number"]:focus-visible,
input[type="text"]:focus-visible,
select:focus-visible { outline: 2px solid var(--color-navy); }

/* A sunken track and a raised thumb, like everything else here. The two engines
   need separate selectors, and one invalid selector drops a whole rule, so they
   cannot share.

   ⚠️ The track's edge is a shadow ring, not an outline. The thumb is the track's
   child, and an outline paints after children, so it drew across the thumb. */
input[type="range"] {
  flex: 1;
  min-width: 0;
  height: var(--cell);
  margin: 0;
  background: none;
  cursor: pointer;
  appearance: none;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 8px;
  background: var(--color-paper);
  box-shadow:
    0 0 0 1px var(--color-midnight),
    inset 1px 1px 0 0 var(--bevel-shade),
    inset -1px -1px 0 0 var(--bevel-light);
}
input[type="range"]::-moz-range-track {
  height: 8px;
  background: var(--color-paper);
  box-shadow:
    0 0 0 1px var(--color-midnight),
    inset 1px 1px 0 0 var(--bevel-shade),
    inset -1px -1px 0 0 var(--bevel-light);
}

input[type="range"]::-webkit-slider-thumb {
  width: 10px;
  height: 16px;
  margin-top: -4px;
  background: var(--color-cream);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised);
  appearance: none;
}
input[type="range"]::-moz-range-thumb {
  width: 10px;
  height: 16px;
  border: 0;
  border-radius: 0;
  background: var(--color-cream);
  outline: 1px solid var(--color-midnight);
  box-shadow: var(--raised);
}

input[type="range"]:focus-visible { outline: 2px solid var(--color-navy); outline-offset: 2px; }

input[type="checkbox"] {
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: var(--color-navy);
}

.knob.toggle label { display: flex; align-items: center; gap: calc(var(--pad) / 1.5); }

.modes { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: calc(var(--pad) / 4) var(--pad); }
.modes label { display: flex; align-items: center; gap: calc(var(--pad) / 2); font-size: 0.8rem; }

/* ---- chips -------------------------------------------------------------- */

.chip {
  display: inline-block;
  padding: 0 calc(var(--pad) / 1.5);
  border: 0;
  background: var(--color-cream);
  box-shadow: var(--raised);
  font-size: 0.75rem;
  line-height: 1.6;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.chip:hover:not(:disabled),
.chip:focus-visible { background: var(--color-paper); }
.chip:focus-visible { outline: 2px solid var(--color-navy); outline-offset: 1px; }
.chip:active:not(:disabled) { box-shadow: var(--pressed); }
.chip:disabled { cursor: default; opacity: 0.55; }

/* Only visible once the knob has moved, but it keeps its space, so a row does not
   reflow under the pointer in the middle of a drag. */
.knob .reset { visibility: hidden; font-size: 0.65rem; }
.knob.changed .reset { visibility: visible; }

.save-button {
  width: 100%;
  margin-bottom: calc(var(--pad) / 2);
  padding-block: calc(var(--pad) / 3);
  outline: 1px solid var(--color-midnight);
}

/* ---- swatches and symbols ----------------------------------------------- */

.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  margin-top: calc(var(--pad) / 2);
  padding: var(--bevel);
  background: var(--color-cream);
  box-shadow: var(--raised);
}

.swatch {
  position: relative;
  width: calc(var(--cell) * 1.5);
  height: calc(var(--cell) * 1.5);
  padding: 0;
  border: 0;
  box-shadow: var(--raised);
  cursor: pointer;
}

.swatch:focus-visible { outline: 2px solid var(--color-navy); outline-offset: 1px; z-index: 1; }

.swatch[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top right, transparent 44%, var(--color-paper) 44% 48%,
                    var(--color-brick) 48% 52%, var(--color-paper) 52% 56%, transparent 56%);
  box-shadow: var(--pressed);
}

.preset-slot { display: grid; gap: calc(var(--pad) * 2.5); }
.preset-slot > .chip { justify-self: start; }

.preset-section { display: grid; gap: calc(var(--pad) / 1.5); }
.preset-section .pool-actions { margin: 0; }

.preset-list { display: grid; gap: calc(var(--pad) / 2); }
.preset-row { display: flex; align-items: stretch; gap: calc(var(--pad) / 2); }
.preset-row > .chip:last-child { flex: none; width: var(--cell); padding: 0; }

.preset-pick {
  display: block;
  flex: 1;
  min-width: 0;
  padding: calc(var(--pad) / 2) var(--pad);
  outline: 1px solid var(--color-midnight);
  line-height: 1.3;
  text-align: left;
  white-space: normal;
}
.preset-pick b { display: block; font-size: 0.8rem; font-weight: 500; overflow-wrap: anywhere; }
.preset-pick[aria-pressed="true"] { background: var(--color-paper); box-shadow: var(--pressed); }

.preset-save { display: flex; gap: calc(var(--pad) / 2); }
.preset-save input { flex: 1; }

.slot-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--pad); }
.pool-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; opacity: 0.75; }

.symbol-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(calc(var(--cell) * 3.75), 1fr));
  gap: calc(var(--pad) / 2);
  margin-top: calc(var(--pad) / 2);
}

.sym-tile { position: relative; min-width: 0; }

/* In the pool it stands up, out of it it is pressed in and fades, so the state
   reads across the whole grid at a glance. */
.sym-toggle {
  display: grid;
  place-items: center;
  width: 100%;
  height: calc(var(--cell) * 3);
  padding: 0;
  border: 0;
  background: var(--color-cream);
  box-shadow: var(--raised);
  cursor: pointer;
}

.sym-toggle img { display: block; width: 62%; height: 62%; object-fit: contain; }
.sym-toggle:hover { background: var(--color-paper); }
.sym-toggle:focus-visible { outline: 2px solid var(--color-navy); outline-offset: 1px; }

.sym-toggle[aria-pressed="false"] {
  background: var(--color-paper);
  box-shadow: var(--sunken);
}
.sym-toggle[aria-pressed="false"] img { opacity: 0.2; }

.sym-weight {
  display: grid;
  grid-template-columns: var(--cell) minmax(0, 1fr) var(--cell);
  align-items: center;
  margin-top: 2px;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.sym-step { padding: 0; font-size: 0.75rem; line-height: var(--cell); }

.sym-delete {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--cell);
  height: var(--cell);
  padding: 0;
  border: 0;
  background: var(--color-brick);
  color: var(--color-paper);
  box-shadow: var(--raised);
  font-size: 0.75rem;
  line-height: 1;
  cursor: pointer;
}
.sym-delete:focus-visible { outline: 2px solid var(--color-navy); outline-offset: 1px; }

.pool-actions {
  display: flex;
  gap: calc(var(--pad) / 2);
  margin: var(--pad) 0 calc(var(--pad) / 2);
}

/* ---- responsive --------------------------------------------------------- */

/* Tablet tier: the same two columns as far as they stay usable. */
@media (max-width: 1099px) {
  :root { --knobs-w: calc(var(--cell) * 19); --tab-w: calc(var(--cell) * 1.4); }
}

/* Stacks at the site's own breakpoint. The picture comes first, so a phone sees
   the result of a knob by scrolling rather than behind it. */
@media (max-width: 699px) {
  :root { --cell: 14px; --pad: 10px; }

  html { height: auto; }

  body { height: auto; padding: var(--cell); grid-template-rows: auto auto auto; }

  main { grid-template-columns: minmax(0, 1fr); }

  .stage { flex: none; height: 62dvh; }

  .tool-panel { flex: none; overflow: visible; }
  .tool-panels { flex: none; }
  .knob-body { overflow: visible; }

  nav.menu { flex-wrap: wrap; }
  .menu-gap { display: none; }
  .menu-item { flex: 1 1 auto; justify-content: center; min-height: calc(var(--cell) * 3); }
  input[type="range"] { height: calc(var(--cell) * 2); }
}
