/* Stitchcraft.
 *
 * Light only, and deliberately. A chart is a printed thing: what is on
 * the screen should look like what comes out of the printer, and a dark
 * theme would show you white symbols on black and then hand you the
 * opposite on paper. */

:root {
  --bg: #f4f5f7;
  --panel: #ffffff;
  --line: #d9dce3;
  --text: #1b1e26;
  --muted: #676d7c;
  --accent: #2f7fd6;
  --hover: #eef1f6;
  --scrim: rgba(24, 26, 34, .45);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 20px 28px;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* head ------------------------------------------------------------- */

.top {
  padding: 20px 0 16px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
}
/* The wordmark. Copperplate and Papyrus are system faces rather than
   web fonts, so the stack degrades on its own: whichever the machine has
   is used, and `fantasy` picks up the browser's display face otherwise.
   Copperplate draws small capitals for lowercase, which reads a size
   smaller than it measures -- hence the extra point and wider tracking. */
.top h1 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: Copperplate, Papyrus, fantasy;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: .8px;
}
/* The mark beside the wordmark: four stitches in thread colours over a
   line-coloured ground, the gap showing through as the grid. Same drawing
   as the favicon so the tab and the page match. Decorative only. */
/* min-width: 0 so the tagline wraps inside the viewport instead of the
   block holding its max-content width and pushing off the right edge. */
.brand { flex: 1 1 auto; min-width: 0; }
.mark { display: inline-flex; flex: none; width: 24px; height: 24px; }
.mark svg { width: 100%; height: 100%; display: block; }
.tag { margin: 3px 0 0; max-width: 62ch; font-size: 13px; color: var(--muted); }

/* The credit, top right. It is the one line a visitor might need
   later, so it lives where it is found rather than at the foot. */
.top-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: none;
}
.credit {
  margin: 0;
  max-width: 34ch;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  text-align: right;
}
.credit b { color: var(--text); font-weight: 600; }
.credit a { color: inherit; }
@media (max-width: 700px) {
  .top-actions { flex: 1 1 100%; min-width: 0; flex-direction: row-reverse; justify-content: flex-end; flex-wrap: wrap; }
  .credit { flex: 1 1 200px; min-width: 0; text-align: left; max-width: none; }
}

/* about and help ------------------------------------------------------ */

/* The scrim under the panel. Fades, and is taken out of the tab order
   once it is gone. */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--scrim);
  opacity: 0;
  visibility: hidden;
  transition: opacity .28s ease, visibility .28s;
}
.scrim.open { opacity: 1; visibility: visible; }

/* The page behind the panel holds still. The gutter is reserved either
   way, so taking the scrollbar away does not shift the layout. */
html { scrollbar-gutter: stable; }
body.drawer-open { overflow: hidden; }

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 41;
  width: min(430px, 100%);
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 20px 22px 28px;
  background: var(--panel);
  border-left: 1px solid var(--line);
  box-shadow: -18px 0 40px rgba(0, 0, 0, .25);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform .28s ease, visibility .28s;
}
.drawer.open { transform: none; visibility: visible; }

@media (prefers-reduced-motion: reduce) {
  .scrim, .drawer { transition: none; }
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.drawer-head h2 {
  margin: 0;
  font-family: Copperplate, Papyrus, fantasy;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: .6px;
}
.drawer-close { flex: none; padding: 2px 10px; font-size: 18px; line-height: 1.2; }

.drawer-body { font-size: 14px; color: var(--text); }
.drawer-body p { margin: 0 0 12px; }
.drawer-body b { font-weight: 600; }

.drawer-how { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.drawer-how h3 {
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}

.drawer-contact { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line); }
.drawer-contact h3 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}
.drawer-contact p { margin: 0 0 5px; }
.drawer-contact a { color: var(--accent); text-decoration: none; }
.drawer-contact a:hover { text-decoration: underline; }
.drawer-note { margin-top: 10px !important; font-size: 13px; color: var(--muted); }

/* the download gate -------------------------------------------------- */

.gate {
  width: min(92vw, 380px);
  padding: 22px 22px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 18px 50px rgba(20, 24, 36, .18);
}
.gate::backdrop { background: rgba(27, 30, 38, .45); }
.gate h2 { margin: 0 0 6px; font-size: 16px; }
.gate p { margin: 0 0 14px; font-size: 13px; color: var(--muted); }
.gate p a { color: var(--accent); }
.gate-field { display: block; margin-bottom: 8px; }
.gate-field span { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.gate-field input {
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 15px;
  letter-spacing: .12em;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.gate-field input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.gate-err { min-height: 18px; margin: 0 0 8px !important; color: #c0392b !important; font-size: 12px; }
.gate-actions { display: flex; justify-content: flex-end; gap: 8px; }
.gate.busy button[type=submit] { opacity: .6; pointer-events: none; }

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

.app {
  display: grid;
  grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
}

.panel {
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.group { display: flex; flex-direction: column; gap: 9px; }
.group h2 {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}

/* controls --------------------------------------------------------- */

.btn {
  padding: 7px 10px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
}
.btn:hover { background: var(--hover); }
.btn.wide { width: 100%; }
.btn.on {
  background: var(--text);
  border-color: var(--text);
  color: var(--panel);
}

/* The one thing on the page that has to be found first. */
button.btn.pick {
  display: block;
  width: 100%;
  padding: 13px 14px;
  text-align: left;
  border-style: dashed;
  border-color: var(--accent);
}
button.btn.pick b { display: block; font-size: 14px; }
button.btn.pick span {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#preview {
  display: block;
  width: 100%;
  max-height: 150px;
  object-fit: contain;
  background: var(--hover);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.field { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.field > span { color: var(--muted); flex: none; min-width: 92px; }
.field input[type=range] { flex: 1; min-width: 0; }
.field b { flex: none; min-width: 30px; text-align: right; font-variant-numeric: tabular-nums; }
.field select { flex: 1; padding: 5px 6px; font: inherit; font-size: 13px;
                border: 1px solid var(--line); border-radius: 7px; background: var(--panel); }

.opt { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); }

.modes { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; align-items: center; }
.modes .btn { grid-column: span 2; }
.modes .btn.tex { grid-column: span 3; }
.modes .label { grid-column: 1 / -1; font-size: 12px; color: var(--muted); margin-top: 4px; }
.row.two { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }

.modes .btn { padding: 7px 2px; font-size: 12px; }

.readout { margin: 0; font-size: 12px; color: var(--muted); }
.hint { margin: 0; font-size: 12px; color: var(--muted); }

/* the key ---------------------------------------------------------- */

/* The Show all button sits on the heading line: it is only ever there
   when something is picked out, and a row of its own would make the key
   jump up and down as threads are chosen and dropped. */
.group h2 { display: flex; align-items: center; gap: 8px; }
.btn.tiny {
  margin-left: auto;
  padding: 2px 7px;
  font-size: 10px;
  letter-spacing: .04em;
  text-transform: none;
  border-radius: 6px;
}

.key { display: flex; flex-direction: column; gap: 2px; }
.key-row {
  display: grid;
  grid-template-columns: 26px 14px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 2px 4px;
  font-size: 12px;
  text-align: left;
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}
.key-row:hover { background: var(--hover); }
/* Picked out. The same yellow the chart marks those stitches with, so
   the row and the squares it points at are plainly the same thing. */
.key-row.on { background: #ffe9a3; border-color: #d8b64a; }
.key-row.on .key-count { color: var(--text); }
.key-sym { display: block; width: 26px; height: 26px; border-radius: 4px; }
.key-dot { width: 14px; height: 14px; border: 1px solid var(--line); border-radius: 3px; }
.key-name { font-variant-numeric: tabular-nums; }
.key-count { color: var(--muted); font-variant-numeric: tabular-nums; }

/* the chart -------------------------------------------------------- */

.stage {
  position: relative;
  min-height: 320px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* Zoom and the note about moving, on the chart rather than in a panel
   three sections away from it. */
.chartbar {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}
.chartbar .btn { padding: 4px 9px; font-size: 13px; }
.chartbar .btn.zoom { min-width: 30px; font-size: 15px; line-height: 1; }
.chartbar .btn:disabled { opacity: .4; cursor: default; }
.zoomlabel {
  min-width: 46px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.chartbar-hint {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
}
@media (max-width: 620px) { .chartbar-hint { display: none; } }
body:not(.has-picture) .chartbar { display: none; }

/* The canvas is drawn at its true size and this pane scrolls, so the
   square size means exactly what it says and nothing is ever scaled.
   Touch scrolls it the way the browser wants to; a mouse drags it. */
.scroll {
  overflow: auto;
  max-height: calc(100vh - 190px);
  cursor: grab;
  overscroll-behavior: contain;
}
.scroll.dragging { cursor: grabbing; }
#canvas { display: block; image-rendering: crisp-edges; user-select: none; }

.empty {
  padding: 60px 0;
  text-align: center;
  color: var(--muted);
}
body.has-picture .empty { display: none; }

.stage.working::after {
  content: "Working\2026";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .72);
  color: var(--muted);
  border-radius: 12px;
}
