/* ============================================================
   CODEBLOOM STUDIO — STYLES
   Aligned with Animation Station design system
   ============================================================ */

/* Tokens, reset, buttons, header chrome, the class-code widget, and the
   layout-column shells (.sidebar/.left-panel/.right-panel) now come from
   the shared stylesheet (apps-shared-files/shared.css). Only Art Studio's
   workspace and editor-specific styling live in this file. */

/* --- Selection chrome token (Art Studio-specific) --- */
/* Dedicated UI colour for the node editor's spine, anchors, and handles. Kept
   SEPARATE from --primary on purpose: --primary (#4e4eff) doubles as a colour
   kids paint with, so node chrome drawn in it vanishes the moment a stroke is
   blue. This azure — the hue Figma, Webflow, and the OS accent all converge on
   — reads as system chrome rather than content and is the most colour-blind-safe
   hue. Mirrors SiteStack's --ui-select. (Canvas chrome is drawn on a 2D context,
   so app.js reads this value via getComputedStyle; this is its source of truth.) */
:root {
  --ui-select: #0a84ff;
}

/* App-specific: the four-column workspace has a floor below which the fixed
   side columns would crush the canvas; below it we scroll horizontally rather
   than collapse. 1280px clears a maximized 14" laptop (~1512 CSS px) with room
   to spare. (The shared body uses overflow:hidden; the editor needs scroll.) */
body {
  min-width: 1280px;
  overflow-x: auto;
  overflow-y: hidden;
}

/* App-specific header bit not in the shared chrome: the current drawing name. */
.header__drawing-name {
  font-size: var(--fs-sm);
  opacity: 0.4;
  flex-shrink: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
  margin-left: var(--small);
}

/* --- Workspace (4-column grid matching Animation Station) --- */

.workspace {
  display: grid;
  grid-template-columns: 80px 120px 1fr 290px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 0 var(--large) var(--large) 0;
}

/* --- Column 2: Tools Panel (options-panel style) --- */

.tools-panel {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.tools-panel__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--small) var(--medium) 0;
  display: flex;
  flex-direction: column;
  gap: var(--small);
}

.tools-panel__label {
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--black);
  padding-top: var(--small);
}

.tools-panel__footer {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--small) var(--medium) var(--medium);
  flex-shrink: 0;
}

.tools-panel__footer-row {
  display: flex;
  gap: 4px;
}

.tools-panel__group {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}

.tools-panel__separator {
  height: 1px;
  background: rgba(78, 78, 255, 0.15);
  margin: 2px 0;
  flex-shrink: 0;
}

/* Tool buttons (shared between panel and footer) */

.toolbox__btn {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--primary);
  border-radius: var(--radius-md);
  background: transparent;
  cursor: pointer;
  color: var(--black);
  transition: all 0.15s;
  flex-shrink: 0;
  padding: 0;
}

.toolbox__btn:hover:not(.toolbox__btn--active):not(:disabled) {
  background: var(--bg);
  border-color: var(--primary);
}

.toolbox__btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.toolbox__btn--active {
  background: var(--primary);
  color: var(--white);
  border-color: var(--primary);
}

.toolbox__btn svg {
  width: 26px;
  height: 26px;
}

.toolbox__preview {
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.toolbox__btn--active .toolbox__preview {
  filter: invert(1);
}

/* --- Canvas Area --- */

.canvas-area {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  min-height: 0;
  min-width: 0;
  position: relative;
  padding: 0 var(--medium);
}

/* Canvas action bar — everyday object verbs above the stage (Scratch-style):
   persistent, horizontal, greyed when N/A so positions stay stable. */
.canvas-toolbar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--medium);
  flex-shrink: 0;
  padding: var(--small) 0;
  /* background: var(--bg); */
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  /* border: 2px solid var(--border); */
  /* border-bottom: none; */
  position: absolute;
  z-index: 10;
  width: calc(100% - var(--medium) * 2);
}

/* Group wrapper: clusters related buttons; separation comes from the larger
   inter-group gap on .canvas-toolbar (no border). */
.canvas-toolbar__group {
  display: flex;
  align-items: center;
  gap: var(--small);
}

/* Reuse the shared .btn (primary) — only add the icon+label layout and a
   disabled state here; the button itself is NOT restyled from scratch. */
.canvas-toolbar .btn {
  display: inline-flex;
  align-items: center;
  gap: var(--small);

  &.btn--primary {
    background: var(--primary);
    border: 2px solid var(--primary);
    color: var(--white);
  }
}

.canvas-toolbar .btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.canvas-toolbar .btn:disabled {
  opacity: 0.35;
  pointer-events: none;
  /* color: var(--white);
  background: transparent;
  border: 2px solid transparent; */
}

/* Grows to fill the space below the action bar and centers the stage in it. */
.canvas-stage-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  min-width: 0;
  border: 2px solid var(--border);
  /* border-top: unset; */
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* Workspace chrome — must match WORKSPACE_CHROME in renderCanvasBounds() so the
     wrapper and the canvas paint beyond the pasteboard read as one backdrop. */
  /* background: var(--bg); */
}

.canvas-stage {
  /* border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden; */
  display: flex;
  align-items: center;
  justify-content: center;
  /* padding: var(--medium); */
  /* background: var(--white); */
  max-width: 100%;
  max-height: 100%;
}

.canvas__wrapper {
  /* border-radius: var(--radius-md); */
  overflow: hidden;
  line-height: 0;
  height: 100%;
  /* background: yellow; */
}

/* Brush/eraser size ring (Photoshop/Figma style): a pointer-following circle
   sized to the true tool diameter × zoom. Lives over the Fabric canvas; a CSS
   cursor can't do this (caps ~128px and blurs). The dark stroke + white
   box-shadow keep it legible on any colour. updateSizeRing() positions it. */
.tool-ring {
  position: absolute;
  top: 0;
  left: 0;
  border: 1.5px solid rgba(0, 0, 0, 0.55);
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.7);
  transform: translate(-50%, -50%);
  pointer-events: none;
  display: none;
  z-index: 10;
}

.tool-ring--visible {
  display: block;
}

/* --- Zoom Controls --- */

.zoom-controls {
  position: absolute;
  bottom: var(--medium);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--small);
  background: var(--white);
  border: 2px solid var(--primary);
  border-radius: var(--radius-md);
  padding: var(--small);
}

.zoom-controls__btn {
  width: 30px;
  /* height: 28px; */
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  font-family: var(--font);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--black);
  transition: all 0.15s;
}

.zoom-controls__btn:hover {
  background: var(--bg);
}

.zoom-controls__btn--text {
  font-size: var(--fs-sm);
  width: auto;
  padding: 0 var(--small);
  text-transform: uppercase;
  font-weight: 700;
}

.zoom-controls__level {
  font-size: var(--fs-sm);
  font-weight: 700;
  min-width: 42px;
  text-align: center;
  padding: 0 2px;
}

/* --- Inspector (Right Sidebar — card-based sections) --- */

.inspector {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  overflow: hidden;
  padding: 0;
}

/* Folder tabs + scrolling card frame — mirrors SiteStack's inspector exactly.
   The tab row stays put; the card scrolls. The active tab dips 2px to connect
   into the card (the open-folder look). */
.inspector__tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

.inspector__tab {
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: var(--small) var(--medium);
  border: 2px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--bg);
  color: var(--primary);
  cursor: pointer;
}

.inspector__tab:hover:not(.inspector__tab--active) {
  background: var(--white);
}

.inspector__tab--active {
  background: var(--white);
  color: var(--black);
  margin-bottom: -2px;
  position: relative;
  z-index: 1;
  cursor: default;
}

.inspector__scroll {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 2px solid var(--border);
  border-radius: 0 var(--radius-lg) var(--radius-lg) var(--radius-lg);
  overflow: hidden;
}

.inspector__scroll-inner {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--medium);
  padding: var(--medium);
}

.inspector__body {
  display: flex;
  flex-direction: column;
  gap: var(--medium);
}

.inspector__body--hidden {
  display: none;
}

/* Overlay scrollbar — a thin custom thumb drawn over the content's right edge
   (native bar hidden), matching SiteStack exactly. Driven by
   attachOverlayScrollbar() in app.js; the thumb lives in the position:relative
   .inspector__scroll layer, which clips it to the rounded card. */
.osb-hide-native {
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* legacy Edge */
}

.osb-hide-native::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none; /* Chrome / Safari / Edge */
}

.osb-thumb {
  position: absolute;
  width: 4px;
  right: 3px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--primary) 35%, transparent);
  cursor: grab;
  pointer-events: auto;
  z-index: 50;
  transition: background 0.15s;
}

.osb-thumb:hover,
.osb-thumb:active {
  background: color-mix(in srgb, var(--primary) 60%, transparent);
}

.osb-thumb:active {
  cursor: grabbing;
}

.inspector__section {
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  flex-shrink: 0;
}

.inspector__section--hidden {
  display: none;
}

.inspector__section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--small) var(--medium);
  background: var(--primary);
  border: none;
  cursor: pointer;
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--white);
  transition: background 0.15s;
}

.inspector__section-header:hover {
  background: #3a3aee;
}

.inspector__section-chevron {
  width: 16px;
  height: 16px;
  transition: transform 0.2s;
  flex-shrink: 0;
  opacity: 0.7;
}

.inspector__section--collapsed .inspector__section-chevron {
  transform: rotate(-90deg);
}

.inspector__section--collapsed .inspector__section-body {
  display: none;
}

.inspector__section-body {
  padding: var(--medium);
}

/* Actions section — accent-colored */

.inspector__section--actions {
  border-color: var(--accent);
}

.inspector__section--actions .inspector__section-header {
  background: var(--accent);
}

.inspector__section--actions .inspector__section-header:hover {
  background: #e63565;
}

/* Inspector color row */

.inspector__color-row {
  display: flex;
  align-items: center;
  gap: var(--small);
  margin-bottom: var(--small);
  background: var(--bg);
  padding: var(--small) var(--medium);
  border-radius: var(--small);
}

/* Inline variant: the group card supplies the background/padding, so the row
   sits flush and lays its label + controls on a single line. Used by Fill /
   Stroke to reclaim the vertical space the stacked label used to cost. */
.inspector__color-row--inline {
  background: none;
  padding: 0;
  margin-bottom: 0;
}

/* Re-introduce the gap only when a control actually follows (e.g. Stroke's
   width slider); a hidden field contributes nothing. */
.inspector__color-row--inline
  + .inspector__field:not(.inspector__field--hidden) {
  margin-top: var(--small);
}

/* Let the hex field absorb the leftover width instead of a fixed 70px, so the
   label + wells + buttons always fit the panel on one row. */
.inspector__color-row--inline .inspector__hex-input {
  flex: 1;
  width: auto;
  min-width: 0;
}

.inspector__color-well {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 2px solid #ccc;
  border-radius: var(--radius-sm);
  cursor: pointer;
  background: none;
  flex-shrink: 0;
  transition: border-color 0.15s;
  position: relative;
}

.inspector__color-well:hover {
  border-color: var(--primary);
}

.inspector__color-preview {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: calc(var(--radius-sm) - 2px);
  position: relative;
}

.inspector__color-preview--none {
  background: var(--white) !important;
}

.inspector__color-preview--mixed {
  background: conic-gradient(
    #ff457a 0deg,
    #ffd700 90deg,
    #4e4eff 180deg,
    #00c897 270deg,
    #ff457a 360deg
  ) !important;
}

.inspector__color-preview--none::after {
  content: "";
  position: absolute;
  left: 15%;
  top: 50%;
  width: 70%;
  height: 2px;
  background: var(--accent);
  transform: rotate(-45deg);
  transform-origin: center;
}

.inspector__hex-input {
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
  width: 70px;
  padding: 4px var(--small);
  border: 2px solid rgba(78, 78, 255, 0.2);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--black);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  outline: none;
}

.inspector__hex-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(78, 78, 255, 0.15);
}

.inspector__no-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: #999;
  margin-left: auto;
  flex-shrink: 0;
  transition: all 0.15s;
}

.inspector__no-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.inspector__no-btn--active {
  color: var(--accent);
  border-color: var(--accent);
  background: #fff0f4;
}

.inspector__no-btn svg {
  width: 16px;
  height: 16px;
}

/* Bitmap-disabled states */

.inspector__color-row--disabled,
.swap-color__inline--disabled {
  opacity: 0.25;
  pointer-events: none;
}

/* Color picker popover */

.color-picker {
  display: none;
  position: fixed;
  z-index: 150;
  background: var(--white);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--medium);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  /* Definite width: the SV square is width:100% with no intrinsic size, so the
     popover needs its own width to size the square consistently. */
  width: 240px;
  max-height: calc(100vh - 16px);
  overflow-y: auto;
}

.color-picker--open {
  display: block;
}

.color-picker__opacity {
  display: flex;
  align-items: center;
  gap: var(--small);
  padding: var(--small) 0 0;
}

.color-picker__opacity .inspector__range {
  flex: 1;
}

/* Custom SV-square + hue-slider picker (makeCustomPicker). CSS-responsive: the
   square fills the popover width and stays square, thumbs are placed by %, and
   drag input is read off the live rect — so no fixed size or resize call. */
.cpick {
  display: flex;
  flex-direction: column;
  gap: var(--medium);
}

.cpick__area {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  cursor: crosshair;
  touch-action: none;
}

.cpick__hue {
  position: relative;
  width: 100%;
  height: 14px;
  border-radius: 999px;
  cursor: pointer;
  touch-action: none;
  background: linear-gradient(
    to right,
    #f00 0%,
    #ff0 17%,
    #0f0 33%,
    #0ff 50%,
    #00f 67%,
    #f0f 83%,
    #f00 100%
  );
}

.cpick__area-thumb,
.cpick__hue-thumb {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--white);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.cpick__hue-thumb {
  top: 50%;
}

/* Gradient controls inside the picker popover */
.color-picker__fill-type {
  margin-bottom: var(--small);
}

/* Start/end colour controls: a small swatch + editable hex field for each stop
   (start on the left, end on the right) with a swap button between them. There's
   no gradient preview here — the direction buttons above already preview the
   gradient — so the swatch just shows the stop colour and doubles as its select
   button; the selected one gets a ring so it's clear which you're editing. */
.color-picker__bar {
  display: flex;
  align-items: center;
  gap: var(--small);
  margin-top: var(--medium);
  margin-bottom: var(--medium);
}

.color-picker__bar-hex {
  flex: 1;
  width: auto;
  min-width: 0;
}

/* Mirror the inspector colour well/preview: the stop button carries the frame
   (grey by default, primary when selected — matching the well's active outline),
   and the dot is just the colour fill nested inside with the well's inner radius. */
.color-picker__bar-stop {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 2px solid #ccc;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  transition: border-color 0.15s;
}

.color-picker__bar-stop:hover,
.color-picker__bar-stop--active {
  border-color: var(--primary);
}

.color-picker__bar-dot {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: calc(var(--radius-sm) - 2px);
}

.color-picker__bar-swap {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  padding: 4px;
  border: 0px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--black);
  cursor: pointer;
  transition: all 0.15s;
}

.color-picker__bar-swap:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.color-picker__bar-swap svg {
  display: block;
  width: 100%;
  height: 100%;
}

.color-picker__direction {
  margin-top: var(--medium);
}

.color-picker__direction .inspector__label {
  display: block;
  margin-bottom: 4px;
}

.color-picker__direction .inspector__dash-btn {
  border: 2px solid #cbcbcb;
}

.color-picker__direction .inspector__dash-btn--active {
  border: 2px solid var(--primary);
}

/* Eyedropper button */

.inspector__eyedropper-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: #999;
  flex-shrink: 0;
  transition: all 0.15s;
  padding: 0;
}

.inspector__eyedropper-btn:hover {
  color: var(--primary);
  border-color: var(--primary);
}

.inspector__eyedropper-btn--active {
  color: var(--white);
  background: var(--primary);
  border-color: var(--primary);
}

.inspector__eyedropper-btn svg {
  width: 14px;
  height: 14px;
}

/* Inspector coordinate row */

.inspector__coord-row {
  display: block;
  align-items: center;
  gap: var(--small);
  margin-bottom: var(--small);
}

.inspector__coord-row:last-child {
  margin-bottom: 0;
}

.inspector__coord-label {
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  width: 46px;
  flex-shrink: 0;
  text-align: left;
}

.inspector__coord-input {
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
  width: 0;
  flex: 1;
  min-width: 60px;
  padding: 4px var(--small);
  border: 2px solid rgba(78, 78, 255, 0.2);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--black);
  text-align: center;
  outline: none;
  -moz-appearance: textfield;
}

.inspector__coord-input::-webkit-inner-spin-button,
.inspector__coord-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.inspector__coord-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(78, 78, 255, 0.15);
}

/* Inspector inner controls */

.inspector__field {
  margin-bottom: var(--medium);
}

.inspector__field:last-child {
  margin-bottom: 0;
}

.inspector__label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 4px;
}

.inspector__label--fixed {
  width: 36px;
  flex-shrink: 0;
  margin-bottom: 0;
}

.inspector__control {
  display: flex;
  align-items: center;
  gap: var(--small);
}

/* Inline fields: lay every labelled control in a section body on one row,
   matching the Appearance inline groups. Applied to the Shape options panel via
   a single body modifier (rather than tagging each row). The rows are
   .inspector__group cards (so they get the light-blue card from that class);
   this only adds the inline layout. The 72px label column fits the longest
   shape label ("Roundness"/"Thickness") and keeps the sliders aligned. */
/* These panels run a wider 72px label column (fits "Roundness"/"Wave size");
   the Appearance inline groups keep the default 56px. --label-col is the single
   source for both the label width and the no-label slider indent below. */
.inspector__section-body--inline-fields {
  --label-col: 72px;
}

.inspector__section-body--inline-fields .inspector__group {
  display: flex;
  align-items: center;
  gap: var(--small);
}

.inspector__section-body--inline-fields .inspector__label {
  width: var(--label-col);
  flex-shrink: 0;
  margin-bottom: 0;
  white-space: nowrap;
}

.inspector__section-body--inline-fields .inspector__control,
.inspector__section-body--inline-fields .inspector__dash-btns {
  flex: 1;
  min-width: 0;
}

/* A multi-row card inside the inline-fields layout: keep the card block-stacked
   (rather than the default one-row flex) so its rows sit on separate lines.
   Used by the Brush Shape grid and the Texture + Spread pair. */
.inspector__section-body--inline-fields .inspector__group--stacked {
  display: block;
}

/* The stacked card's own top label returns to a normal block label above its
   content (the inline rule had turned every label into a fixed inline column).
   Direct child only, so a nested inline row's label keeps its inline column. */
.inspector__section-body--inline-fields
  .inspector__group--stacked
  > .inspector__label {
  width: auto;
  margin-bottom: var(--small);
  white-space: normal;
}

/* An inline label+control row nested inside a stacked card (e.g. Texture's
   on/off toggle); its label still picks up the 72px inline column above. */
.inspector__inline-row {
  display: flex;
  align-items: center;
  gap: var(--small);
}

/* A no-label control (Stroke's Width, Texture's Spread) reserves the label
   column on its left so the slider starts under the controls of the rows above,
   respecting the row flow. --label-col falls back to the Appearance width (56px)
   where the inline-fields panels don't raise it to 72px. */
.inspector__indented-control {
  padding-left: calc(var(--label-col, 56px) + var(--small));
}

/* Gap above a no-label control that follows the inline row (Spread under
   Texture), mirroring Stroke's width slider. */
.inspector__inline-row + .inspector__field {
  margin-top: var(--small);
}

.inspector__range {
  flex: 1;
  /* Native range inputs have an intrinsic min-width that blocks flex shrink,
     pushing the value label out of the card — let it shrink to make room. */
  min-width: 0;
  padding: var(--small) 0;
  accent-color: var(--primary);
}

.inspector__value {
  font-size: var(--fs-sm);
  min-width: 32px;
  text-align: center;
  flex-shrink: 0;
}

/* Property group — a light-blue card that visually clusters related controls
   inside a busy panel (e.g. Fill / Stroke / Corners within Appearance). Mirrors
   SiteStack's .prop wrapper, in Art Studio's namespace; reuses --bg so it reads
   as the same ecosystem grouping device. The existing .inspector__field
   :last-child rule already zeroes trailing space inside the card. */
.inspector__group {
  background: var(--bg);
  padding: var(--small) var(--medium);
  border-radius: var(--radius-sm);
  margin-bottom: var(--small);
}

.inspector__group:last-child {
  margin-bottom: 0;
}

/* Inline group: label + its single control sit on one row, the card itself
   being the flex container (e.g. Opacity / Shadow / Flip). Declared BEFORE the
   --hidden rule so .inspector__group--hidden's display:none still wins when
   both classes are present. */
.inspector__group--inline {
  display: flex;
  align-items: center;
  gap: var(--medium);
}

.inspector__group--inline > .inspector__control,
.inspector__group--inline > .inspector__toggles,
.inspector__group--inline > .inspector__dash-btns {
  flex: 1;
  min-width: 0;
}

/* Inline Shadow toggles trade some horizontal padding for the room the label
   now takes, so None/Normal/Glow still fit the panel width on one line. */

.inspector__group-label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--black);
  margin-bottom: var(--small);
}

/* Inline label: sits on the same row as its controls (e.g. Fill / Stroke /
   Opacity / Shadow / Flip). One fixed width across all of them keeps the
   controls in a single aligned column; sized to fit the longest ("OPACITY"). */
.inspector__group-label--inline {
  width: 56px;
  flex-shrink: 0;
  margin-bottom: 0;
}

/* Inspector actions grid */

.inspector__actions {
  display: flex;
  flex-direction: column;
  gap: var(--medium);
}

/* A row of action buttons inside an .inspector__group card. The card supplies
   the light-blue background/padding; the row only lays the buttons out in a
   grid. Multiple rows can stack within one card (e.g. Order + Align). */
.inspector__action-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--small);
}

.inspector__action-row + .inspector__action-row {
  margin-top: var(--small);
}

.inspector__action-row--trio {
  grid-template-columns: 1fr 1fr 1fr;
}

.inspector__action-row--single {
  grid-template-columns: 1fr;
}

/* Contextual hiding: drop a row (or a whole group card) when nothing in it
   applies, rather than showing a strip of greyed-out buttons. */
.inspector__action-row--hidden,
.inspector__group--hidden,
.inspector__field--hidden {
  display: none;
}

.inspector__action-btn {
  display: flex;
  align-items: center;
  gap: var(--small);
  /* padding: 6px var(--small); */
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--black);
  transition: all 0.15s;
}

.inspector__action-btn:hover:not(:disabled) {
  color: var(--primary);
}

.inspector__action-btn:disabled {
  opacity: 0.25;
  cursor: default;
}

.inspector__action-btn--active {
  /* background: var(--primary); */
  color: var(--primary);
  /* border-color: var(--primary); */
}

/* Delete — destructive action. Red at rest (warns without a confirm dialog),
   deeper red on hover. Uses --accent, the suite's established danger colour. */
.inspector__action-btn--danger {
  color: var(--accent);
}

.inspector__action-btn--danger:hover:not(:disabled) {
  color: #e63565;
}

.inspector__action-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Text controls */

.propbar__select {
  font-family: var(--font);
  font-size: var(--fs-sm);
  padding: 2px var(--small);
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--black);
  width: 100%;
  cursor: pointer;
}

.propbar__number {
  font-family: var(--font);
  font-size: var(--fs-sm);
  width: 50px;
  padding: 2px var(--small);
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  text-align: center;
}

.propbar__togglebtn {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  font-family: var(--font);
  font-size: var(--fs-md);
  color: var(--black);
  transition: all 0.15s;
}

.propbar__togglebtn:hover {
  background: var(--bg);
  border-color: var(--primary);
}

.propbar__togglebtn--active {
  background: var(--primary);
  color: var(--white);
  border-color: var(--primary);
}

/* --- Modal --- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 15, 0.4);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 200;
}

.modal-overlay.visible {
  display: flex;
}

.modal {
  background: var(--bg);
  border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
  max-width: 400px;
  width: 90%;
  box-shadow: 0 8px 30px rgba(10, 10, 15, 0.15);
}

.modal--wide {
  max-width: 720px;
}

.modal__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--medium);
}

.modal__title {
  font-size: var(--fs-lg);
  font-weight: 700;
  margin-bottom: var(--medium);
}

.modal__header .modal__title {
  margin-bottom: 0;
}

.modal__close {
  font-size: var(--fs-xl);
  background: none;
  border: none;
  cursor: pointer;
  color: var(--black);
  padding: 0 var(--small);
  line-height: 1;
}

.modal__close:hover {
  color: var(--accent);
}

.modal__text {
  font-size: var(--fs-md);
  margin-bottom: var(--medium);
  line-height: 1.5;
  opacity: 0.6;
}

.modal__field {
  margin-bottom: var(--medium);
}

.modal__label {
  display: block;
  font-size: var(--fs-sm);
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: var(--small);
}

.modal__input {
  font-family: var(--font);
  font-size: var(--fs-md);
  width: 100%;
  padding: var(--small) var(--medium);
  border: 2px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
}

.modal__input:focus {
  box-shadow: 0 0 0 3px rgba(78, 78, 255, 0.15);
}

.modal__error {
  font-size: var(--fs-sm);
  color: var(--accent);
  margin-bottom: var(--small);
}

.modal__buttons {
  display: flex;
  gap: var(--medium);
  justify-content: center;
  margin-top: var(--medium);
}

/* --- Swap Color --- */

.swap-color__inline {
  display: flex;
  align-items: center;
  gap: 4px;
  background: var(--bg);
  padding: var(--small) var(--medium);
  border-radius: var(--small);
}

.swap-color__arrow {
  font-size: var(--fs-md);
  color: var(--primary);
}

.swap-color__go {
  padding: 4px 8px;
}

/* --- Picker Grid (shared by Stickers, Paint, Shapes modals) --- */

.sticker-picker__bar {
  display: flex;
  flex-direction: column;
  gap: var(--medium);
  /* padding: var(--small) var(--small) 0; */
}

.sticker-picker__search {
  width: 100%;
  padding: var(--medium) var(--medium);
  font-size: var(--fs-md);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--white);
  color: var(--black);
  font-family: var(--font);
}

.sticker-picker__search:focus {
  outline: none;
  border-color: var(--primary);
}

.sticker-picker__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--small);
}

.sticker-picker__tab {
  padding: var(--small) var(--medium);
  font-size: var(--fs-sm);
  border: 2px solid rgba(78, 78, 255, 0.3);
  border-radius: var(--radius-lg);
  background: var(--white);
  color: var(--black);
  cursor: pointer;
  transition:
    border-color 0.15s,
    background 0.15s;
}

.sticker-picker__tab:hover {
  border-color: var(--primary);
}

.sticker-picker__tab--active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--white);
}

.sticker-picker__empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--black);
  font-size: var(--fs-md);
  padding: var(--large);
}

.peep-builder {
  display: flex;
  gap: var(--medium);
  padding: var(--small);
  height: 60vh;
}

.peep-builder__preview {
  flex: 0 0 40%;
  display: flex;
  flex-direction: column;
  gap: var(--small);
}

.peep-builder__stage {
  flex: 1;
  min-height: 160px;
  background: var(--white);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.peep-builder__stage svg {
  height: 100%;
  width: auto;
  max-width: 100%;
}

/* Primary action, pinned above the preview so it reads as the outcome. */
.peep-builder__add {
  width: 100%;
}

.peep-builder__panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--small);
}

.peep-builder__subtabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--small);
}

/* Randomize lives at the end of the tab row, pushed to the right. */
.peep-builder__randomize {
  margin-left: auto;
}

.peep-builder__pane {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--medium);
}

.peep-thumbs {
  padding: var(--small);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(78px, 1fr));
  gap: var(--medium);
}

/* Poses are full figures — give them a larger cell than head-only thumbs. */
.peep-thumbs--body {
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}

.peep-thumbs--body .peep-thumb img {
  height: 104px;
}

.peep-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--white);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition:
    border-color 0.15s,
    transform 0.1s;
}

.peep-thumb:hover {
  border-color: var(--primary);
  transform: scale(1.05);
}

.peep-thumb--active {
  border-color: var(--primary);
}

.peep-thumb img {
  width: 100%;
  height: 64px;
  object-fit: contain;
  pointer-events: none;
}

.peep-thumb__label {
  font-size: var(--fs-sm);
  color: var(--black);
  text-align: center;
  line-height: 1.1;
}

/* Global Colors strip (left column, under the action buttons). Colour is a
   whole-character choice — thumbnails are colour-agnostic line art — so it
   lives here rather than per part tab. A hairline sets it off from the buttons
   once it has content. */
.peep-builder__colors {
  display: flex;
  flex-direction: column;
  gap: var(--small);
}

.peep-builder__colors:not(:empty) {
  padding-top: var(--small);
  border-top: 1px solid rgba(78, 78, 255, 0.15);
}

.peep-builder__label {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--black);
}

.peep-colors {
  display: flex;
  flex-wrap: wrap;
  gap: var(--medium);
}

/* One region: a swatch of its current colour with a caption. Opens the
   picker popover (which carries the region's presets). */
.peep-color-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.peep-color-chip__dot {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid var(--border);
  background: var(--chip-color, var(--white));
  transition: transform 0.1s;
}

.peep-color-chip:hover .peep-color-chip__dot {
  transform: scale(1.12);
}

.peep-color-chip--active .peep-color-chip__dot {
  border-color: var(--black);
  box-shadow:
    0 0 0 2px var(--white),
    0 0 0 4px var(--primary);
}

.peep-color-chip__label {
  font-size: var(--fs-sm);
  color: var(--black);
}

/* Peep-builder color popover — a makeCustomPicker instance plus the region's
   preset swatches. Sits above the modal (overlay is z-index 200); mirrors the
   inspector picker's chrome. */
.peep-cpick {
  display: none;
  flex-direction: column;
  gap: var(--small);
  position: fixed;
  z-index: 250;
  width: 200px;
  background: var(--white);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--medium);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.peep-cpick--open {
  display: flex;
}

.peep-cpick__hex {
  width: 100%;
  text-align: center;
}

/* Curated presets inside the popover — quick one-tap colours. */
.peep-cpick__presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}

.peep-cpick__preset {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--border);
  padding: 0;
  cursor: pointer;
  transition: transform 0.1s;
}

.peep-cpick__preset:hover {
  transform: scale(1.12);
}

.peep-cpick__preset--active {
  border-color: var(--black);
  box-shadow:
    0 0 0 2px var(--white),
    0 0 0 3px var(--primary);
}

.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: var(--medium);
  height: 60vh;
  overflow-y: auto;
  align-content: start;
  border-radius: var(--radius-md);
  padding: var(--small);
  margin-top: var(--medium);
  /* background: var(--bg); */
}

.picker-grid__item {
  aspect-ratio: 1;
  background: var(--white);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--small);
  gap: 4px;
  transition:
    border-color 0.15s,
    transform 0.1s;
}

.picker-grid__item:hover {
  border-color: var(--primary);
  transform: scale(1.05);
}

.picker-grid__item img,
.picker-grid__item svg {
  width: 100%;
  height: 100%;
  object-fit: contain;
  flex: 1;
  min-height: 0;
}

.picker-grid__item canvas {
  width: 72px;
  height: 72px;
  flex: 1;
  min-height: 0;
}

.picker-grid__label {
  font-size: var(--fs-sm);
  color: var(--black);
  text-align: center;
  flex-shrink: 0;
}

/* --- Brush dash-style button row --- */

/* Segmented on/off toggle — mirrors SiteStack's .prop__toggles (single outer
   border, dividers between, active half filled). For mutually-exclusive states
   like the Shadow None|Normal|Glow control. */
.inspector__toggles {
  display: flex;
  gap: 0;
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  overflow: hidden;
  width: 100%;
}

.inspector__toggle {
  flex: 1;
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 4px 6px;
  border: none;
  border-right: 1px solid var(--primary);
  background: var(--white);
  color: var(--black);
  cursor: pointer;
  transition: all 0.15s;
}

.inspector__toggle:last-child {
  border-right: none;
}

.inspector__toggle:hover:not(.inspector__toggle--active) {
  background: var(--border);
  color: var(--white);
}

.inspector__toggle--active {
  background: var(--primary);
  color: var(--white);
}

.inspector__dash-btns {
  display: flex;
  gap: 4px;
}

/* The pattern picker carries more choices than the other dash-button rows, so
   let it wrap onto multiple lines — each icon keeps a comfortable size (5 per
   row) instead of shrinking to squeeze all of them onto one line. */
.inspector__dash-btns--wrap {
  flex-wrap: wrap;
}

.inspector__dash-btns--wrap .inspector__dash-btn {
  flex: 0 0 calc(20% - 4px);
}

.inspector__dash-btn {
  flex: 1;
  height: 26px;
  border: 2px solid rgba(78, 78, 255, 0.3);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--black);
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px 3px;
  overflow: hidden;
}

.inspector__dash-btn svg {
  display: block;
  width: 100%;
  height: 100%;
}

.inspector__dash-btn:not(.inspector__dash-btn--active):hover {
  border-color: var(--primary);
  /* background: var(--bg); */
}

.inspector__dash-btn--active {
  background: var(--primary);
  color: var(--white);
  border-color: var(--primary);
}

/* Text-label toggle buttons (e.g. bubble Shape/Tail) rather than icon glyphs. */
.inspector__dash-btn--text {
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 700;
}

/* Swatch buttons whose face is a live mini-gradient (background set by JS) —
   used by the gradient direction picker. Padding is dropped so the gradient
   reaches the border. The selected one shows a primary border (the same active
   outline as the colour-preview well) rather than a solid fill, which would
   hide its preview — .inspector__dash-btn--active already supplies that border,
   and the inline gradient overrides its background fill. */
.inspector__dash-btn--swatch {
  padding: 0;
  height: 30px;
}

.inspector__brush-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 4px;
}

/* --- Scrollbar styling --- */

.inspector::-webkit-scrollbar,
.tools-panel__body::-webkit-scrollbar,
.picker-grid::-webkit-scrollbar,
.peep-builder__pane::-webkit-scrollbar {
  width: 4px;
}

.inspector::-webkit-scrollbar-thumb,
.tools-panel__body::-webkit-scrollbar-thumb,
.picker-grid::-webkit-scrollbar-thumb,
.peep-builder__pane::-webkit-scrollbar-thumb {
  background: var(--primary);
  border-radius: 2px;
}

/* --- Toast (app-local; consumed by showToast() and the shared share modal) --- */

.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(100px);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 10px 20px;
  border-radius: var(--radius-md);
  background: var(--black);
  color: var(--white);
  z-index: 2000;
  transition: transform 0.3s ease;
  pointer-events: none;
}

.toast--visible {
  transform: translateX(-50%) translateY(0);
}
