/*!
 * Hytale Skin Viewer - nogard.dev
 * Copyright (c) 2026 Nogard. All rights reserved.
 *
 * Served to your browser so the tool can run. That is not a licence to copy, host,
 * rebrand, resell or redistribute this code, in whole or in part.
 * Licensing enquiries: https://nogard.dev/contact
 */
/* Hytale Skin Viewer - Tool-specific styles only */
/* Shared styles come from converter.css; the results card follows the Skin Stealer */

/* ---- Actions row: Look up / Download / Copy / Clear ----
   A GRID, not .converter-buttons-container. That container is flex, and four buttons each
   carrying .converter-button's min-width:162px wrap 3+1 on a mid-width screen, which is
   the ragged wrap the playbook warns about. This is the Glyph Generator's .glyph-actions
   logic verbatim: 2 columns, promoted to 4 at 720px, with the min-width override that the
   grid requires or the columns cannot shrink. */
.hsv-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  max-width: 560px;          /* (560 - 12) / 2 = 274 per button */
  margin: 24px auto 0;
}

.hsv-actions .converter-button,
.hsv-actions .converter-button-secondary {
  min-width: 0;
}

/* Four in a row only once they genuinely fit. Measured intrinsic widths (icon + gap +
   label + 48px padding): Copy Outfit JSON 209px, Download PNG 191px, Look up 137px,
   Clear 115px. Four 209s plus three 12px gaps is 872px of content. At a 950px viewport
   that leaves only 6px of slack on the widest label, so the switch waits for 1000px,
   where the column is wide enough for 227px buttons and 18px of breathing room.
   The Glyph Generator's 720px works there because its labels are shorter; copying the
   number rather than the reasoning is what clipped the text. */
@media (min-width: 1000px) {
  .hsv-actions {
    grid-template-columns: repeat(4, 1fr);
    max-width: 960px;
  }
}

.hsv-actions .converter-button span,
.hsv-actions .converter-button-secondary span {
  white-space: nowrap;
}

/* ---- Result layout ----
   The picture is the product, so it gets the only card with any weight and the character
   is the largest thing on the page. Controls sit beside it as labelled rows, NOT as nested
   sub-cards: two pill rows do not need three levels of box. The wardrobe is reference data
   and gets no chrome, only type and column rules. Palette and radii are the site's. */
.hsv-result {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-top: 30px;
}

/* ---- hero: everything about the picture ---- */
.hsv-hero {
  padding: 24px 28px 22px;
  background: #fff;
  border: 2px solid #e9ecef;
  border-radius: 24px;
}

.hsv-id {
  display: flex;
  /* Stacked and centred, not side by side: the UUID is a 36-character monospace chip, so on a
     narrow hero it wrapped to its own line anyway, and next to a short name it left an odd gap.
     align-items centres BOTH children and keeps the chip hugging its text rather than stretching
     to the column width, which is why it is not text-align. Centred at every width, so there is
     no breakpoint where the header jumps alignment. */
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding-bottom: 16px;
  margin-bottom: 20px;
  border-bottom: 1px solid #eef0f2;
}

/* style.css scopes only h2 to article, so h3-h6 pick up margin:20px 0 10px globally */
.hsv-name {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  color: #2c3e50;
  text-transform: none;
  letter-spacing: 0;
  word-break: break-word;
}

/* the uuid IS the copy control, so it does not need a separate button beside it */
.hsv-uuid {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 9px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: #6b7280;
  font-family: Consolas, 'Roboto Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Liberation Mono', 'Courier New', monospace;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.hsv-uuid svg { width: 13px; height: 13px; opacity: 0.55; flex-shrink: 0; }
.hsv-uuid:hover { color: #374151; background: #f3f4f6; border-color: #e5e7eb; }
.hsv-uuid:hover svg { opacity: 1; }
.hsv-uuid:active { transform: scale(0.98); }
.hsv-uuid:focus-visible { outline: 2px solid #3984a7; outline-offset: 2px; }
/* Same success colour and tinted pill as the Skin Downloader and the donate page's wallet rows,
   so "it copied" reads the same way everywhere on the site. The border keeps the chip from
   shifting by a pixel as the background appears. */
.hsv-uuid.copied { color: #16a34a; background: rgba(34, 197, 94, 0.15); border-color: transparent; }
.hsv-uuid.copied svg { opacity: 1; }
.hsv-uuid.copied:hover { color: #16a34a; background: rgba(34, 197, 94, 0.15); border-color: transparent; }

.hsv-hero-body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}

/* ---- the figure ---- */
.hsv-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

/* No plate behind the character: the render is the product, and a tinted rectangle around
   it just competed with it. The checkerboard lives on the canvas, so transparency still
   reads without one. */
.hsv-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 260px;
  height: 380px;
}

/* A canvas, not an img, so a background composites behind the character and the whole
   thing exports as one picture. It also sidesteps style.css's (0,1,3) rule that forces
   width:100%, margin-top:10px and a 24px radius onto every img in an article. */
.hsv-result .hsv-stage canvas {
  width: auto;
  max-width: 100%;
  max-height: 340px;
  height: auto;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
}

/* the checkerboard reads as "transparent", so what you see is what the PNG will be */
.hsv-stage-alpha canvas {
  background-image:
    linear-gradient(45deg, #eceef0 25%, transparent 25%, transparent 75%, #eceef0 75%),
    linear-gradient(45deg, #eceef0 25%, transparent 25%, transparent 75%, #eceef0 75%);
  background-size: 14px 14px;
  background-position: 0 0, 7px 7px;
  background-color: #fff;
}

/* ---- controls: labelled rows, no boxes ---- */
.hsv-tools {
  display: flex;
  flex-direction: column;
  gap: 15px;
  min-width: 0;
}

/* One tinted card per functionality, matching the Chibi Skin Maker's .options-group.
   NO BORDER: styles/tool-cards.css strips it with `.controls-section .tool-panel
   .tool-card { border: none }`, so a nested card separates by fill alone. Verified against
   its computed style: rgba(0,0,0,.04), 0px border, radius 18, padding 20. */
.hsv-field {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 20px;
  background: rgba(0, 0, 0, 0.04);
  border-radius: 18px;
}

/* .options-group-label, shared with .tool-card h3 across the site */
.hsv-label {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: #333;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  text-align: center;
}

.hsv-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
}

.hsv-pill {
  padding: 8px 16px;
  background: #fff;
  border: 2px solid #d1d5db;
  border-radius: 50px;
  color: #374151;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
}

.hsv-pill:hover { border-color: #3984a7; }
.hsv-pill:active { transform: scale(0.98); }
.hsv-pill:focus-visible { outline: 2px solid #3984a7; outline-offset: 2px; }
.hsv-pill[aria-pressed="true"] { background: #3984a7; border-color: #3984a7; color: #fff; }

/* consequence over configuration: the output size is stated, never asked for */
.hsv-out {
  margin: 0;
  font-size: 13px;
  color: #6b7280;
  text-align: center;
}

/* min-height, not filler text: the line reserves its space so the first message cannot
   shove the buttons upward, while shipping empty. */
.hsv-status {
  min-height: 20px;
  margin-top: 10px;
  font-size: 13px;
  color: #6b7280;
  text-align: center;
}
.hsv-status.is-error { color: #b91c1c; font-weight: 600; }

.hsv-alert {
  margin: 0;
  padding: 18px 22px;
  background: #fef2f2;
  border: 2px solid #fecaca;
  border-radius: 24px;
  color: #b91c1c;
  font-size: 15px;
  font-weight: 600;
  text-align: center;
}

/* Centred, with Reset absolutely positioned, so the label sits dead centre whether or not
   the group has a button. This is the Chibi Skin Maker's .vp-group-head verbatim. */
.hsv-field-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 28px;
}

.hsv-field-head .hsv-reset {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

.hsv-reset {
  padding: 3px 12px;
  background: none;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  color: #888;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.hsv-reset:hover { color: #555; border-color: #999; }
.hsv-reset:active { transform: translateY(-50%) scale(0.98); }
.hsv-reset:focus-visible { outline: 2px solid #3984a7; outline-offset: 2px; }

/* ---- background swatches ----
   Circles, with the colour picker AS the seventh swatch and the image tile as the eighth,
   exactly as the Chibi Skin Maker and Mojavatar do it. Values lifted from
   minecraft-chibi-skin-maker.css and unscoped from #viewer-section. */
.bg-presets {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 8px;
  justify-items: center;
}

.bg-preset,
.bg-custom {
  width: 100%;
  aspect-ratio: 1;
  max-width: 40px;
  min-width: 0;
  height: auto;
  padding: 0;
  border: 2px solid #d1d5db;
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.bg-preset:hover,
.bg-custom:hover { border-color: #3984a7; }
.bg-preset:active,
.bg-custom:active { transform: scale(0.96); }
.bg-preset:focus-visible,
.bg-custom:focus-visible,
.bg-custom:has(:focus-visible) { outline: 2px solid #3984a7; outline-offset: 2px; }
.bg-preset.active,
.bg-custom.active { border-color: #3984a7; box-shadow: 0 0 0 2px rgba(57, 132, 167, 0.3); }

.bg-custom {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  color: #6b7280;
  background-size: cover;
  background-position: center;
}

.bg-custom:hover { color: #3984a7; }
.bg-custom svg { width: 17px; height: 17px; pointer-events: none; }
/* the image swatch wears the chosen picture, so its icon steps aside once one is set */
.bg-image-tile.has-image svg { display: none; }

/* the real inputs cover the whole swatch, invisible, so the native picker opens on tap */
.bg-custom input[type="color"],
.bg-image-tile input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: none;
  opacity: 0;
  cursor: pointer;
}

/* Native checkbox, centred, matching .input-group.checkbox-group: the whole row is the
   hit target and the box is 18px, not 16px. */
.hsv-check {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 0;
  color: #666;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: opacity 0.2s ease;
}

.hsv-check input {
  width: 18px;
  height: 18px;
  accent-color: #3984a7;
  cursor: pointer;
}

/* a vignette needs a background to darken, so it dims while transparent is on */
.hsv-check.is-disabled { opacity: 0.4; cursor: not-allowed; }
.hsv-check.is-disabled input { cursor: not-allowed; }

/* ---- sheet: the wardrobe as reference data ---- */
.hsv-sheet {
  padding: 22px 28px 24px;
  background: #f8f9fa;
  border: 2px solid #e9ecef;
  border-radius: 24px;
}

.hsv-sheet-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 18px;
}

.hsv-sheet-head h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.hsv-sheet-meta { font-size: 13px; color: #6b7280; }

/* Outfit table. CSS columns, not a grid: groups hold 2 to 7 slots each, so a grid leaves
   a hole under the short one beside a tall one. Columns balance automatically.
   TWO columns, not three: at three the value column was only ~206px and three of the
   twenty values wrapped onto a second line ("Top Wasteland Marauder" plus its colour chip
   needs ~222px). Two gives ~363px and nothing wraps. */
.hsv-outfit { columns: 2; column-gap: 44px; }

.hsv-group {
  break-inside: avoid;
  page-break-inside: avoid;
  margin-bottom: 18px;
}

.hsv-group:last-child { margin-bottom: 0; }

.hsv-group-title {
  margin: 0 0 7px;
  padding-bottom: 6px;
  border-bottom: 1px solid #e5e7eb;
  font-size: 11px;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* A FIXED label column, not auto. With auto, every group sized its own label column from
   its own longest word, so values started at four different offsets (39, 40, 48, 69px) and
   nothing lined up down the sheet. 68px clears the longest label ("Underwear", 60px). */
.hsv-slots {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  gap: 7px 12px;
  margin: 0;
  align-items: baseline;
}

.hsv-slot-label { font-size: 12px; color: #6b7280; white-space: nowrap; }

.hsv-slot-value {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: baseline;
  margin: 0;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: #2c3e50;
}

.hsv-slot-empty { color: #6b7280; font-weight: 400; }

.hsv-chip {
  padding: 1px 7px;
  background: #e9ecef;
  border-radius: 50px;
  font-size: 11px;
  font-weight: 600;
  color: #6b7280;
}

/* converter.css ships no :disabled rule and transitions `all`, so without the hover
   re-assertion a disabled button still darkens on hover and reads as clickable */
.converter-button:disabled,
.converter-button-secondary:disabled { opacity: 0.5; cursor: not-allowed; }
.converter-button:disabled:hover { background-color: #3984a7; border-color: #d1d5db; }
.converter-button-secondary:disabled:hover { background-color: #85898f; border-color: #d1d5db; }

/* Responsive: shrink before stacking */
@media (max-width: 900px) {
  .hsv-hero-body { grid-template-columns: 1fr; gap: 24px; justify-items: center; }
  .hsv-tools { width: 100%; }
  .hsv-outfit { columns: 1; }
}

@media (max-width: 760px) {
  .bg-presets { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 620px) {
  .hsv-hero { padding: 20px 18px 18px; }
  .hsv-sheet { padding: 18px 18px 20px; }
  .hsv-field { padding: 16px; }
  .hsv-stage { width: 100%; height: 320px; }
  .hsv-result .hsv-stage canvas { max-height: 290px; }
  .hsv-outfit { columns: 1; }
}

/* Below the width where two buttons fit side by side, stack them one per row. The Glyph
   Generator does the same at this breakpoint; without it the pair squeezes under the
   162px label width and the text clips. */
@media (max-width: 460px) {
  .hsv-actions { grid-template-columns: 1fr; }
}

@media (max-width: 420px) {
  .hsv-name { font-size: 20px; }
  .hsv-pill { padding: 7px 13px; font-size: 13px; }
}
