/* Hatchery — everything specific to this tool.
   The shell, the components and the tokens are the house set; only what the
   pattern composer needs is here. */

/* The artwork sits on the viewport's ground with a hairline, never a shadow —
   it is a piece of paper on a table, not a floating card. */
.viewport {
  display: grid;
  place-items: center;
}

/* The shell sizes a viewport canvas to fill; this one is a fixed-ratio sheet
   sized in script, so it opts out. */
.viewport #stage {
  display: block;
  width: auto;
  height: auto;
  border-radius: var(--md-sys-shape-corner-medium);
  box-shadow: var(--app-hairline);
  touch-action: none;   /* the canvas owns dragging, not the browser's scroller */
}

.viewport-hint { max-width: min(52ch, calc(100% - 24px - 200px)); }

/* ---------- pickers ----------
   Both draw themselves from the same geometry and painters the artwork uses,
   so choosing from them is choosing the thing itself rather than a symbol
   standing in for it. */

.picker {
  display: grid;
  gap: 6px;
}

.picker--shapes { grid-template-columns: repeat(4, 1fr); }
.picker--textures { grid-template-columns: repeat(3, 1fr); }

.picker-cell {
  position: relative;
  display: grid;
  place-items: center;
  gap: 4px;
  padding: 8px 4px;
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
  overflow: hidden;
}

.picker-cell svg {
  width: 26px;
  height: 26px;
  fill: currentColor;
}

.picker-cell[aria-pressed="true"] {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

.picker-cell--wide { padding: 6px 6px 4px; }

.picker-cell canvas {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-surface-container-lowest);
}

.picker-caption {
  font: var(--md-sys-typescale-label-small);
  color: inherit;
}

/* ---------- shape list ---------- */

.shape-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.shape-thumb {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-high);
}

.shape-thumb svg {
  width: 18px;
  height: 18px;
  fill: var(--md-sys-color-on-surface-variant);
}

.md-list-item[aria-selected="true"] .shape-thumb {
  background: var(--md-sys-color-surface);
}

.md-list-item[aria-selected="true"] .shape-thumb svg {
  fill: var(--md-sys-color-on-secondary-container);
}

/* An inked thumbnail is a small print of the shape - its own ink, on the
   document's paper - so the interface colours have to keep out of it, selection
   included, or picking a pink shape would repaint it in the accent colour. The
   hairline stops a pale paper dissolving into the panel behind it. */
.shape-thumb--inked {
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant);
}

.shape-thumb--inked svg,
.md-list-item[aria-selected="true"] .shape-thumb--inked svg {
  fill: currentColor;
}

.shape-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* One line each. An uploaded file arrives with whatever name it had, and
   "design minis icon copy" wrapped to three lines and took the row with it. */
.shape-text .headline,
.shape-text .supporting {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The row's buttons stay out of the way until the row is worth acting on. */
.shape-row .md-icon-button { opacity: 0; flex: 0 0 auto; }
.shape-row:hover .md-icon-button,
.shape-row:focus-within .md-icon-button,
.shape-row[aria-selected="true"] .md-icon-button { opacity: 1; }

@media (hover: none) {
  .shape-row .md-icon-button { opacity: 1; }
}

/* The swatch grid is this tool's own, so its touch sizing lives here. The
   general targets are in the house sheets, where every tool gets them. */
@media (pointer: coarse) {
  .picker-cell { min-height: 44px; }
}

/* ---------- inspector extras ---------- */

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hint-text {
  margin: 0;
  font: var(--md-sys-typescale-body-small);
  color: var(--md-sys-color-on-surface-variant);
}

/* Sits above the groups rather than inside one, because what it says is true
   of all of them. Tinted so it reads as a state the panel is in, not as a note
   about the first control under it. */
.multi-note {
  margin: 4px 4px 10px;
  padding: 10px 12px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant);
}

/* The picture, its name and what to do with it. Sized so a wide photo and a
   tall one take the same room, which keeps the panel from jumping when one is
   swapped for the other. */
.image-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.image-thumb {
  flex: 0 0 auto;
  width: 72px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-high);
}

.image-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.swatches {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
}

/* Each swatch is the palette itself: the paper with a bar of its ink. */
.swatch {
  position: relative;
  aspect-ratio: 1;
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--sw-paper);
  box-shadow: var(--app-hairline);
  cursor: pointer;
  overflow: hidden;
}

.swatch::after {
  content: "";
  position: absolute;
  inset: 32% 18%;
  border-radius: 2px;
  background: var(--sw-ink);
}

.swatch[aria-pressed="true"] {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* ---------- export dialog ---------- */

.dialog-note {
  margin: 0 0 4px;
  font: var(--md-sys-typescale-body-small);
  color: var(--md-sys-color-on-surface-variant);
}

.export-size {
  margin: 0;
  font: var(--md-sys-typescale-body-medium);
  color: var(--md-sys-color-on-surface-variant);
  font-variant-numeric: tabular-nums;
}

#dlg-export .content {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ---------- credit badge ----------
   DOM over the canvas, never inside it, so exports never contain it. */

.viewport-credit {
  --credit-scale: 1.6;
  position: absolute; top: 12px; right: 12px; z-index: 5;
  display: block; padding: 0; line-height: 0;
  border-radius: calc(9px * var(--credit-scale)); overflow: hidden;
  background: color-mix(in srgb, var(--md-sys-color-surface-container-high) 82%, transparent);
  backdrop-filter: blur(12px);
  box-shadow: var(--app-hairline);
  transition: background-color var(--md-sys-motion-duration-short) var(--md-sys-motion-standard);
}
.viewport-credit:hover { background: var(--md-sys-color-surface-container-high); }
.viewport-credit svg {
  display: block;
  width: calc(100px * var(--credit-scale));
  height: calc(32px * var(--credit-scale));
}
.viewport-credit .credit-label { fill: var(--md-sys-color-on-surface-variant); }
.viewport-credit .credit-name,
.viewport-credit .credit-mark { fill: var(--md-sys-color-on-surface); }

@media (max-width: 1180px) { .viewport-credit { --credit-scale: 1.35; } }
@media (max-width: 960px)  { .viewport-credit { --credit-scale: 1.15; } }

/* Stacked under 960px the shell puts the canvas after the panels — order: 1
   sorts it behind the default 0. On a tool whose whole point is the picture,
   the picture goes first. */
@media (max-width: 960px) {
  .viewport { order: -1; }
}

/* An uploaded outline arrives at whatever aspect it was drawn at, so its cell
   gives it room rather than the square a primitive needs. */
.picker-cell--custom svg,
.shape-thumb svg[viewBox]:not([viewBox^="-0.62"]) {
  width: 100%;
  height: 100%;
  max-width: 26px;
  max-height: 26px;
  object-fit: contain;
}

/* The upload cell is an action among choices, so it is outlined rather than
   filled - it adds to the row instead of competing for selection. */
.picker-cell--upload {
  background: none;
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant);
}

.picker-cell--upload svg { fill: var(--md-sys-color-on-surface-variant); }

.picker-cell--upload:hover {
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline);
}

/* The paper's "no texture" cell. Outlined and empty rather than carrying a
   swatch of its own: every other cell shows the pattern it will paint, and the
   honest picture of no pattern is nothing. */
.picker-cell--none {
  background: none;
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant);
}

.picker-cell--none:hover { box-shadow: inset 0 0 0 1px var(--md-sys-color-outline); }

.picker-cell--none[aria-pressed="true"] {
  background: var(--md-sys-color-secondary-container);
  box-shadow: none;
}

/* The paper's row in the layer list. It is not a shape and cannot be hidden,
   duplicated or deleted, so it carries no buttons and sits under everything -
   which is also where it is in the picture. */
.shape-row--paper .shape-thumb {
  border-radius: var(--md-sys-shape-corner-extra-small);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant);
}

/* Nothing behind the artwork by default — the canvas paints its own ground.
   With transparency on, the chequerboard shows through, and because it lives
   on the element rather than in the canvas it cannot reach an export.

   Mid grey rather than the usual near-white, and the same grey in both themes.
   Ink here is as often bone white as it is black, and a pale chequer loses the
   white artwork completely — which reads as the feature being broken. */
.viewport #stage[data-transparent="true"] {
  --chequer-a: #8d8d8d;
  --chequer-b: #7c7c7c;
  background-color: var(--chequer-a);
  background-image:
    linear-gradient(45deg, var(--chequer-b) 25%, transparent 25%),
    linear-gradient(-45deg, var(--chequer-b) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--chequer-b) 75%),
    linear-gradient(-45deg, transparent 75%, var(--chequer-b) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}

/* ---------- colour ---------- */

.color-field {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The native swatch, stripped back to just the colour it holds. */
.color-field input[type="color"] {
  flex: 0 0 auto;
  width: 40px;
  height: 34px;
  padding: 0;
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  background: none;
  box-shadow: var(--app-hairline);
  cursor: pointer;
}

.color-field input[type="color"]::-webkit-color-swatch-wrapper { padding: 3px; }
.color-field input[type="color"]::-webkit-color-swatch {
  border: none;
  border-radius: 5px;
}
.color-field input[type="color"]::-moz-color-swatch {
  border: none;
  border-radius: 5px;
}

/* Hex beside it, because a brand colour arrives as six characters, not as a
   point somewhere in a picker. */
.color-field .hex {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  padding: 0 10px;
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-body-medium);
  font-family: var(--md-sys-typescale-plain-font);
  font-variant-numeric: tabular-nums;
  text-transform: lowercase;
}

.color-field .hex:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: -2px;
}

/* Sits under the two colour fields it acts on, so the swap reads as something
   done to them rather than a setting of its own. */
.swap-colours {
  width: 100%;
  justify-content: center;
}

/* Cells past the current page are hidden one by one rather than by a rule, so
   the page size is a number in one place instead of a selector to keep in step
   with it. The swatches stay painted either way. */
.picker--textures .picker-cell[hidden] { display: none; }

.show-more {
  align-self: flex-start;
  margin: 2px 0 0 -8px;
}

/* ---------- align ---------- */

.align-row {
  display: flex;
  align-items: center;
  gap: 2px;
}

/* The two axes are one row, split by a hairline: six buttons read as six
   choices, where two rows of three read as a grid with meaning it does not
   have. */
.align-sep {
  width: 1px;
  height: 20px;
  margin: 0 6px;
  background: var(--md-sys-color-outline-variant);
}
