/* InstantPalette - image color picker (layer 5, this page only)
   Load order: tokens.css -> base.css -> site.css -> tools.css -> image-color-picker.css

   Only what is genuinely specific to this tool lives here: the drop zone, the canvas stage with its pins,
   crosshair and loupe, the sample-image row, the picked-color readout and the pick history strip.
   Buttons, inputs, segmented controls, swatch tiles, code blocks and result grids come from tools.css. */

/* ================= Drop zone (no image yet) ================= */
.ipx-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  min-height: 280px; padding: 28px 20px;
  border: 1.5px dashed var(--line-2); border-radius: var(--r-lg);
  background: var(--ground);
  text-align: center;
}
.ipx-drop .ipx-ico { width: 34px; height: 34px; color: var(--ink-2); }
.ipx-drop-h { margin: 0; font: 600 17px/1.3 var(--f-sans); }
.ipx-drop-p { margin: 0; max-width: 44ch; font: 400 14px/1.6 var(--f-sans); color: var(--ink-2); }
.ipx-drop-p kbd { margin: 0 1px; }
/* A two-key shortcut never breaks across lines */
.ipx-nw { white-space: nowrap; }
/* Dragging a file over the page: solid ink edge, never a colour cue alone - the copy changes too */
.ipx-drop.is-over { border: 1.5px solid var(--ink-1); background: var(--hover); }

/* ================= Sample images ================= */
.ipx-samples { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; }
.ipx-samples .field-l { width: 100%; text-align: center; }
.ipx-sample {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 5px 12px 5px 5px;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--raised); color: var(--ink-1);
  font: 500 14px/1 var(--f-sans);
}
@media (hover: hover) and (pointer: fine) { .ipx-sample:hover { border-color: var(--ink-1); } }
.ipx-sample .strip { width: 46px; height: 34px; border-radius: var(--r-sm); flex: none; }

/* ================= Canvas stage ================= */
/* The frame is sized in JS. It is normally the exact box the image occupies, but it never drops below
   --ipx-frame-min: a panorama or a 1x1 icon would otherwise leave a sliver of a canvas with the pins
   spilling out of it. When the picture is shorter or narrower than the frame, JS letterboxes it inside the
   canvas and places pins and the crosshair through the same mapping, so a pin still sits on its own pixel. */
.ipx-stage { display: flex; justify-content: center; }
.ipx-frame { --ipx-frame-min: 150px; position: relative; line-height: 0; max-width: 100%; }
@media (hover: none), (pointer: coarse) { .ipx-frame { --ipx-frame-min: 176px; } }
.ipx-canvas {
  display: block; width: 100%; height: 100%;
  border-radius: var(--r); background: var(--sunken);
  /* Vertical swipes still scroll the page; taps and sideways drags are ours */
  touch-action: pan-y;
  cursor: crosshair;
}
/* An upscaled tiny source (a favicon, a 1x1 test file) stays crisp instead of turning into a blur */
.ipx-frame.is-px .ipx-canvas { image-rendering: pixelated; }
.ipx-canvas:focus-visible { outline: 2px solid var(--ink-1); outline-offset: 3px; }

/* Crosshair: two rings so it stays visible on any pixel underneath */
.ipx-cross {
  position: absolute; left: 0; top: 0; width: 22px; height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  border: 2px solid #FFF;
  box-shadow: 0 0 0 2px #000, inset 0 0 0 1px #000;
  pointer-events: none;
}
.ipx-cross[hidden] { display: none; }

/* Pins: one per palette colour, draggable, focusable, arrow-key movable */
/* The overlay covers the canvas, so it must not swallow the picks: only the pins themselves take pointers */
.ipx-pins { position: absolute; inset: 0; pointer-events: none; }
.ipx-pin {
  --ink: #000; --anti: #FFF;
  position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px; padding: 0;
  border: 0; border-radius: 50%;
  background: var(--pc, var(--sunken)); color: var(--ink);
  box-shadow: 0 0 0 2px var(--anti), 0 0 0 3.5px var(--ink);
  font: 500 13px/30px var(--f-mono); text-align: center;
  cursor: grab; touch-action: none; pointer-events: auto;
}
/* 44px hit area without a 44px dot */
.ipx-pin::before { content: ""; position: absolute; inset: -7px; border-radius: 50%; }
.ipx-pin:active { cursor: grabbing; }
.ipx-pin.is-drag { box-shadow: 0 0 0 2px var(--anti), 0 0 0 5px var(--ink); }
.ipx-pin:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; box-shadow: 0 0 0 2px var(--anti), 0 0 0 3.5px var(--ink), 0 0 0 8px var(--anti); }
/* Two pins sampled from nearby pixels sit on top of each other. The one being used comes to the front, so
   its ring, its number and its focus outline are never drawn over by a neighbour. */
.ipx-pin.is-drag, .ipx-pin:focus-visible { z-index: 2; }
@media (hover: hover) and (pointer: fine) { .ipx-pin:hover { z-index: 1; } }

/* Loupe: magnified pixels plus the codes, parked in a stage corner so it never runs off screen */
.ipx-loupe {
  position: absolute; top: 8px; right: 8px; width: 128px;
  padding: 8px; border-radius: var(--r);
  background: var(--raised); color: var(--ink-1);
  box-shadow: var(--shadow-pop);
  pointer-events: none; line-height: normal;
}
.ipx-loupe.is-left { right: auto; left: 8px; }
.ipx-loupe[hidden] { display: none; }
.ipx-loupe canvas {
  display: block; width: 112px; height: 112px;
  border-radius: var(--r-sm); background: var(--sunken);
  image-rendering: pixelated;
}
.ipx-loupe .lp-hex { display: block; margin-top: 6px; font: 500 13px/1.2 var(--f-mono); }
.ipx-loupe .lp-name { display: block; margin-top: 2px; font: 500 12px/1.35 var(--f-sans); color: var(--ink-2); }
.ipx-loupe .lp-more { display: none; margin-top: 4px; font: 500 12px/1.5 var(--f-mono); color: var(--ink-2); }
.ipx-loupe .lp-more span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 620px) {
  /* Sized to the content so the longest line - always the oklch() one - fits whole. A truncated code is
     useless, and the cap keeps the loupe from covering the picture it is magnifying. */
  .ipx-loupe { width: max-content; min-width: 178px; max-width: 250px; }
  .ipx-loupe .lp-more { display: block; }
}

.ipx-hint { margin: 10px 0 0; font: 400 12px/1.9 var(--f-sans); color: var(--ink-2); text-align: center; }
.ipx-hint span { display: block; }
.ipx-hint kbd { margin: 0 2px; }

/* ================= Picked colour readout ================= */
.ipx-read {
  display: grid; grid-template-columns: 96px 1fr; gap: 14px;
  padding: 14px; border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised);
}
.ipx-read .ipx-big {
  --ink: #000; --anti: #FFF;
  min-height: 96px; border-radius: var(--r);
  background: var(--sw, var(--sunken));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink-1) 10%, transparent);
  display: flex; align-items: flex-end; padding: 8px;
  font: 500 12px/1.2 var(--f-mono); color: var(--ink);
}
.ipx-read-bd { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.ipx-read-n { margin: 0; font: 600 16px/1.3 var(--f-sans); }
.ipx-read-n .ipx-lvl { font: 500 12px/1 var(--f-sans); color: var(--ink-2); margin-left: 8px; white-space: nowrap; }
/* Wide enough for a full oklch() string: a truncated code is worse than a second row */
.ipx-codes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(298px, 100%), 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
.ipx-code {
  display: flex; align-items: center; gap: 8px; width: 100%;
  min-height: 44px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--ground); color: var(--ink-1); text-align: left;
}
@media (hover: hover) and (pointer: fine) { .ipx-code:not([disabled]):hover { border-color: var(--ink-3); } }
/* Before the first pick there is nothing to copy: the row reads as a placeholder and takes no tab stop */
.ipx-code[disabled] { color: var(--ink-3); background: transparent; }
.ipx-code[disabled] .k, .ipx-code[disabled] .i { color: var(--ink-3); }
.ipx-code .k { font: 400 12px/1 var(--f-sans); color: var(--ink-2); width: 42px; flex: none; }
/* A code is the whole point of the row: it wraps rather than truncating, at any width */
.ipx-code .v { font: 500 13px/1.35 var(--f-mono); min-width: 0; overflow-wrap: anywhere; }
.ipx-code .i { width: 16px; height: 16px; margin-left: auto; color: var(--ink-2); flex: none; }

/* Pick history: the wrapper carries the spacing, the list inside it only the layout */
.ipx-hist, .ipx-hist-list { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ipx-hist { margin-top: 12px; }
.ipx-hist-h { margin: 0; font: 400 12px/14px var(--f-sans); color: var(--ink-2); }
.ipx-chip {
  --ink: #000; --anti: #FFF;
  width: 44px; height: 34px; padding: 0;
  border: 0; border-radius: var(--r-sm);
  background: var(--sw, var(--sunken));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink-1) 14%, transparent);
}
@media (hover: none), (pointer: coarse) { .ipx-chip { width: 44px; height: 44px; } }
.ipx-chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; box-shadow: 0 0 0 2px var(--anti); }
@media (hover: hover) and (pointer: fine) { .ipx-chip:hover { box-shadow: inset 0 0 0 2px var(--ink); } }

/* ================= Palette controls and results ================= */
.ipx-ctl { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; }
.ipx-ctl .field { flex: 0 1 auto; }
/* Five options do not fit one row on a phone. tools.css lets a .tseg scroll sideways, which hides options
   behind an edge with no affordance, so this one wraps instead. */
#ipx-variant { flex-wrap: wrap; overflow: visible; }
/* Count stepper: two buttons and a reading, never an <input type=number> spinner */
.ipx-step {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px; border-radius: var(--r-sm); background: var(--sunken);
}
.ipx-step button { width: 40px; height: 40px; display: grid; place-items: center; border-radius: var(--r-xs); color: var(--ink-1); }
@media (hover: hover) and (pointer: fine) { .ipx-step button:hover:not([disabled]) { background: var(--raised); } }
.ipx-step button[disabled] { color: var(--ink-3); }
.ipx-step .n { min-width: 34px; text-align: center; font: 500 15px/1 var(--f-mono); font-variant-numeric: tabular-nums; }
@media (hover: none), (pointer: coarse) { .ipx-step button { width: 44px; height: 44px; } }

.ipx-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
/* In a panel header the row sits beside the heading, so it takes no top margin */
.tpanel-hd .ipx-actions { margin-top: 0; }
/* Why the Colors reading stopped below what was asked for */
.ipx-short { margin: 10px 0 0; font: 400 12px/1.5 var(--f-sans); color: var(--ink-2); }
.ipx-status { margin: 10px 0 0; font: 400 13px/1.6 var(--f-sans); color: var(--ink-2); }
.ipx-empty {
  margin: 0; padding: 18px; border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  font: 400 14px/1.6 var(--f-sans); color: var(--ink-2); text-align: center;
}

/* The swatch tile carries a prominence reading under the code */
.swtile .share { font: 500 12px/1.2 var(--f-mono); opacity: .82; }

/* ================= Small screens ================= */
@media (max-width: 560px) {
  .ipx-drop { min-height: 232px; padding: 22px 16px; }
  .ipx-read { grid-template-columns: 72px 1fr; gap: 12px; padding: 12px; }
  /* A swatch as tall as three stacked code rows reads as a stripe, not a color: keep it square */
  .ipx-read .ipx-big { min-height: 72px; height: 72px; align-self: start; }
  .ipx-read-n .ipx-lvl { display: block; margin: 4px 0 0; }
  .ipx-loupe { width: 104px; padding: 6px; }
  .ipx-loupe canvas { width: 92px; height: 92px; }
  /* Heading on one line, the buttons on the next, instead of a two-word column beside them.
     Remove image becomes an icon button so the primary action keeps the rest of the row. */
  .tpanel-hd { flex-wrap: wrap; }
  .tpanel-hd .ipx-actions { width: 100%; flex-wrap: nowrap; }
  .tpanel-hd .ipx-actions > .tprimary { flex: 1 1 auto; }
  #ipx-clear { width: 44px; padding: 0; flex: none; justify-content: center; }
  #ipx-clear .ipx-lbl { display: none; }
  /* The code label sits above its value so a long oklch() string gets the full width */
  .ipx-code { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 8px; }
  .ipx-code .k { grid-area: 1 / 1; width: auto; }
  .ipx-code .v { grid-area: 2 / 1; }
  .ipx-code .i { grid-area: 1 / 2 / 3 / 3; margin-left: 0; }
}

/* Reduced motion: nothing here animates, but keep the drag affordance calm */
@media (prefers-reduced-motion: reduce) {
  .ipx-pin, .ipx-drop { transition: none; }
}
