.tool-main {
  padding-block: 40px 64px;
}

.tool-head {
  margin-bottom: 28px;
}

.tool-kicker {
  margin: 0 0 8px;
  color: var(--accent);
}

.tool-head h1 {
  margin: 0;
  color: var(--ink);
  font-size: 32px;
  line-height: 1.25;
}

.tool-description {
  max-width: 60ch;
  margin: 8px 0 0;
  color: var(--muted);
}

/* ---- panels: one shape for every section of the tool ---- */

.panel {
  padding: 20px;
  border: 1px solid var(--line);
  margin-bottom: 16px;
}

.panel-title {
  margin: 0 0 16px;
  color: var(--accent);
  font-size: inherit;
  font-weight: 400;
}

/* ---- controls: label, input, readout, aligned across every panel ---- */

/* 16ch clears the longest label - "start lightness" is 15 characters, and the
   face is monospace, so the column cannot be eyeballed */
.control {
  display: grid;
  grid-template-columns: 9ch minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.control:last-child {
  margin-bottom: 0;
}

.control label {
  color: var(--muted);
}


input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 20px;
  /* the UA default is 2px, which puts every slider out of line with the hex box */
  margin: 0;
  background: transparent;
  cursor: pointer;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 1px;
  background: var(--line);
}

input[type="range"]::-moz-range-track {
  height: 1px;
  background: var(--line);
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 11px;
  height: 18px;
  margin-top: -9px;
  background: var(--thumb, var(--accent));
  border: 1px solid var(--ink);
}

input[type="range"]::-moz-range-thumb {
  width: 11px;
  height: 18px;
  border-radius: 0;
  background: var(--thumb, var(--accent));
  border: 1px solid var(--ink);
}

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

/* the base colour is one thing set three ways, so hue, light and colorful
   share a thumb. Theirs is the neutral and every other slider takes the
   accent, which keeps one loud colour on the page rather than two. */
#base-h,
#base-j,
#base-m { --thumb: var(--faint); }

input[type="text"],
select,
textarea {
  padding: 5px 8px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
}

input[type="text"]:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: -1px;
}

input[type="text"].is-invalid {
  border-color: var(--warm);
}

/* ---- base color ---- */

/* a full-width bar rather than a chip beside the sliders, so every control
   column in the tool starts at the same place */
.base-chip {
  width: 22px;
  height: 22px;
  border: 1px solid var(--line);
}

.field {
  display: grid;
  grid-template-columns: 9ch minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.field label {
  color: var(--muted);
}

/* ---- mode toggle ---- */

.modes {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin-bottom: 16px;
}

.mode {
  padding: 8px 20px;
  color: var(--muted);
  background: var(--paper);
  border: 1px solid var(--line);
  cursor: pointer;
}

.mode + .mode {
  border-left-width: 0;
}

.mode:hover {
  color: var(--ink);
}

.mode.is-active {
  color: var(--paper);
  background: var(--accent);
  border-color: var(--accent);
}

.choices {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.choice {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--ink);
  cursor: pointer;
}

/* ---- palette ---- */

/* The theme's paper measures about 4 units of green off neutral and its border
   colour about 6, where 1 unit is a just-noticeable difference. A tinted
   hairline touching a sample biases it far more than a distant background
   does, so the swatches carry no border and no gap: nothing tinted touches
   them. The strip sits on a neutral field instead, mid grey by default, which
   is the surround colour appraisal standards specify. */
.surround {
  padding: 22px;
  margin-bottom: 16px;
  background: #777777;
}

.swatches {
  display: flex;
}

.swatch {
  flex: 1;
  min-width: 0;
  height: 84px;
}

.toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  cursor: pointer;
}

/* ---- codes ---- */

.output-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.output-bar-second {
  margin-top: 18px;
}

.output-label {
  color: var(--muted);
}

.formats {
  display: flex;
}

.format {
  padding: 4px 12px;
  color: var(--muted);
  background: var(--paper);
  border: 1px solid var(--line);
  cursor: pointer;
}

.format + .format {
  border-left-width: 0;
}

.format:hover:not(:disabled) {
  color: var(--ink);
}

/* ANSI indices only mean anything once the palette has been snapped to the
   256-colour table, so the tab is inert until ANSI mode is on */
.format:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.format.is-active {
  color: var(--paper);
  background: var(--accent);
  border-color: var(--accent);
}

.copy {
  padding: 4px 12px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  cursor: pointer;
}

.copy:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.codes {
  display: block;
  width: 100%;
  resize: vertical;
  line-height: 1.5;
}

.copy-status {
  display: block;
  margin-top: 10px;
  color: var(--faint);
  min-height: 1.5em;
}

@media (max-width: 620px) {
  /* The label takes its own row rather than shrinking below its own text, which
     leaves the whole width for the control. The second column here used to hold
     the readouts; they are gone, and reserving space for them was costing every
     slider about a fifth of its length. */
  .control {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }

  .field {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 8px;
  }

  .control label,
  .field label {
    grid-column: 1 / -1;
  }

  /* a thumb sized for a fingertip rather than a cursor */
  input[type="range"] {
    height: 34px;
  }

  input[type="range"]::-webkit-slider-thumb {
    width: 22px;
    height: 22px;
  }

  input[type="range"]::-moz-range-thumb {
    width: 22px;
    height: 22px;
  }

  /* the mode tabs wrap on a phone, and a button at the start of the second
     row has no neighbour to borrow a left wall from. Same remedy as the
     format tabs below: every button keeps its own border, and a gap stands
     in for the shared edge. */
  .modes {
    gap: 6px;
  }

  .mode {
    flex: 1 1 auto;
  }

  .mode + .mode {
    border-left-width: 1px;
  }

  /* six format tabs do not fit across a phone, so they wrap instead of
     overflowing. Wrapping puts a button at the start of a row, so each one
     carries its own left border again and a gap replaces the shared edge. */
  .output-bar {
    flex-wrap: wrap;
  }

  .formats {
    flex-wrap: wrap;
    gap: 6px;
    width: 100%;
  }

  .format,
  .surround-pick {
    flex: 1 1 auto;
  }

  .format + .format {
    border-left-width: 1px;
  }

  .copy {
    width: 100%;
  }

  .swatch {
    height: 64px;
  }
}

/* A sixteen-color scheme cannot be judged from a swatch strip: whether keywords
   fight variables only shows up in a real token stream, on the background the
   scheme actually uses. */
.preview {
  margin: 0;
  padding: 14px 0;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.75;
  overflow-x: auto;
  white-space: pre;
  tab-size: 2;
}

.preview .row {
  display: block;
  padding: 0 16px;
}

.preview .ln {
  display: inline-block;
  width: 2.5em;
  margin-right: 1em;
  text-align: right;
  user-select: none;
}

.preview .dep {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}


/* the picker and the mode controls are one panel, so the panels nested inside
   it carry no frame of their own */
.panel .panel {
  padding: 0;
  border: 0;
  margin-bottom: 0;
}

/* the ANSI switch rides at the right-hand end of the mode row */
#ansi-toggle-row {
  margin-left: auto;
  padding-left: 16px;
}

/* rows have to be the same height whatever control they hold, or the spacing
   reads differently from one mode to the next */
.control select {
  height: 24px;
  padding: 0 4px;
}

/* A long single column of controls is harder to scan than two short ones, so a
   panel carrying more than six splits: six down the left, the rest to the
   right. Column flow over six rows puts them in that order rather than
   alternating sides the way row flow would.
   The picker rows sit in this panel while the mode rows sit in a tab panel
   inside it, so the tab panel gives up its own box and lets its rows join the
   same grid. Hidden panels keep display:none and hidden rows take no cell, so
   the count and the layout agree. The gap replaces the per-row margins, or the
   two would add up. */
.panel-controls.is-split {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(7, auto);
  grid-auto-columns: minmax(0, 1fr);
  align-content: start;
  gap: 10px 28px;
}

.panel-controls.is-split [role="tabpanel"]:not([hidden]) {
  display: contents;
}

.panel-controls.is-split .field,
.panel-controls.is-split .control {
  margin-bottom: 0;
}

/* Two columns of controls on a phone leaves each slider about 140px, which is
   most of why they were hard to drag. The split stays a grid so the tab panel
   can still fold its rows in, but it runs down a single column.
   This has to sit after the rule that establishes the split: the two have the
   same specificity, so order is what decides it. */
@media (max-width: 620px) {
  .panel-controls.is-split {
    grid-auto-flow: row;
    grid-template-rows: none;
    grid-template-columns: minmax(0, 1fr);
  }
}
