:root {
  color-scheme: dark;
  --bg: #161616;
  --panel: #1e1e1e;
  --fg: #ececec;
  --muted: #9b9b9b;
  --line: #343434;
  --control: #262626;
  --control-hover: #303030;
  --switch-off: #4a4a4a;
  --focus: #6aa8ff;
  --error: #ff6b61;
  --checker-a: #232323;
  --checker-b: #2b2b2b;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --bg: #f3f3f3;
    --panel: #ffffff;
    --fg: #1b1b1b;
    --muted: #666666;
    --line: #d6d6d6;
    --control: #ffffff;
    --control-hover: #ececec;
    --switch-off: #b8b8b8;
    --focus: #1a66d9;
    --error: #c42b1c;
    --checker-a: #e6e6e6;
    --checker-b: #f5f5f5;
  }
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

/* The panel on the left, the stage filling the rest of the window. */
body {
  margin: 0;
  height: 100dvh;
  display: grid;
  grid-template-columns: 272px minmax(0, 1fr);
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.4 system-ui, sans-serif;
}

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Panel */

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  background: var(--panel);
  border-right: 1px solid var(--line);
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 16px;
}

h1 { margin: 0; font-size: 15px; font-weight: 600; }

#controls { min-width: 0; margin: 0; padding: 0; border: 0; }

/* A section of related controls, optionally switched on from its heading. */
.group, .group-body { display: grid; gap: 12px; }
.group { padding: 14px 16px 16px; border-top: 1px solid var(--line); }

.group h2 {
  margin: 0;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.group-head { display: flex; align-items: center; gap: 8px; }
.group-head h2 { margin-right: auto; }
.group-head label { cursor: pointer; }

/* One control: its label and value on a line, with the slider or presets
   below, so a changing value never moves anything. */
.field {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px 8px;
}
.field > :is(input[type="range"], .presets) { grid-column: 1 / -1; }
.field > select { width: 8em; }

output {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.panel-foot {
  position: sticky;
  bottom: 0;
  margin-top: auto;
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  background: var(--panel);
  border-top: 1px solid var(--line);
}

#status { margin: 0; color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
#status:empty { display: none; }
#status.error { color: var(--error); }

/* Controls */

input[type="range"] { width: 100%; margin: 0; accent-color: var(--focus); }

button, select {
  font: inherit;
  color: inherit;
  background: var(--control);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 5px 10px;
  cursor: pointer;
}

select { padding: 4px 6px; }

:is(button, select):hover:not(:disabled) { background: var(--control-hover); }

button.primary { background: var(--fg); color: var(--bg); border-color: var(--fg); }
button.primary:hover:not(:disabled) { background: var(--fg); opacity: 0.9; }

button.link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--focus);
  text-decoration: underline;
}

:is(button, input, select):disabled,
#controls:disabled :is(label, output) { opacity: 0.45; cursor: default; }

.presets { display: flex; gap: 4px; }
.presets button { flex: 1; padding: 4px; line-height: 0; }
.presets svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
:is(.presets button, .segmented button, #mirror)[aria-pressed="true"] { color: var(--focus); border-color: var(--focus); }

#mirror { padding: 2px 8px; font-size: 13px; }

/* Buttons joined into one control that picks one of them. */
.segmented { display: flex; }
.segmented button { padding: 2px 10px; font-size: 13px; }
.segmented button:not(:first-child) { margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.segmented button:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.segmented button[aria-pressed="true"] { position: relative; } /* its border over its neighbour's */

/* An on/off switch. The knob is a gradient, which every browser draws on a
   checkbox without native styling. */
.switch {
  appearance: none;
  flex: none;
  width: 30px;
  height: 18px;
  margin: 0;
  border-radius: 9px;
  background: radial-gradient(circle at 9px 50%, #fff 6px, transparent 6.5px) var(--switch-off);
  cursor: pointer;
}
.switch:checked { background: radial-gradient(circle at 21px 50%, #fff 6px, transparent 6.5px) var(--focus); }

/* Stage: source and output side by side, or stacked when that fits better. */

#stage {
  min-width: 0;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  padding: 16px;
}

#stage.stacked { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
#stage.empty { display: flex; }
#stage.empty .pane, #stage:not(.empty) #empty { display: none; }

#empty {
  margin: auto;
  max-width: 480px;
  padding: 48px 32px;
  border: 2px dashed var(--line);
  border-radius: 12px;
  text-align: center;
  font-size: 16px;
}

#empty .hint { color: var(--muted); font-size: 13px; }

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

.pane figcaption {
  padding-bottom: 6px;
  color: var(--muted);
  font-size: 12px;
  text-align: center; /* over the image, which is centred in its pane */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.frame { position: relative; flex: 1; min-height: 0; }

/* Sized by app.js; absolute so the canvases never push the layout around. */
.frame canvas {
  position: absolute;
  inset: 0;
  margin: auto;
  background: repeating-conic-gradient(var(--checker-a) 0 25%, var(--checker-b) 0 50%) 0 0 / 16px 16px;
}

canvas.pixelated { image-rendering: pixelated; }

#source { cursor: crosshair; touch-action: none; }

#drop-overlay {
  position: fixed;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 0.55);
  color: #fff;
  font-size: 20px;
  pointer-events: none;
}

/* Narrow screens: the stage stays at the top while the panel scrolls under it. */

@media (max-width: 720px) {
  body { display: flex; flex-direction: column; height: auto; }
  .panel { overflow: visible; border-right: 0; }
  .panel-foot { position: static; }
  #stage {
    order: -1;
    position: sticky;
    top: 0;
    z-index: 1;
    height: 55dvh;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }
}
