/* Page management forms and the visual tile editor (BUILD_PLAN.md Phase 5). */

/* Chat name style preview (settings.html) — a dark card matching an
   actual chat bubble's own background, so a styled name previews the way
   it'll really look in a room rather than against the page's own
   (possibly light-themed) background. */
.chat-name-preview {
  background: var(--tilt-bg);
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
  padding: 0.6rem 0.75rem;
  font-weight: 600;
  font-size: 1rem;
}

.manage-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.manage-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--tilt-border);
  border-radius: var(--tilt-radius);
  background: var(--tilt-surface);
}

.manage-row .manage-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.manage-row select {
  padding: 0.25rem;
  border-radius: calc(var(--tilt-radius) / 2);
  border: 1px solid var(--tilt-border);
}

/* :not([hidden]), not a plain element selector — border-editor-page.js
   toggles individual labels (e.g. #border-color-label) via el.hidden, and
   a bare `form label { display: block }` (specificity 0-0-2) would beat
   the UA stylesheet's `[hidden] { display: none }` (0-0-1) and leave the
   label visible anyway. Same bug class as .gradient-editor above —
   :not([hidden]) sidesteps the specificity fight instead of trying to
   out-rank it. */
form label:not([hidden]) {
  display: block;
  margin-top: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
}

form input,
form select,
form textarea {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
  background: var(--tilt-bg);
  color: var(--tilt-text);
  margin-top: 0.25rem;
}

form button {
  margin-top: 1rem;
}

.grid-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: 0.75rem 0.5rem;
}

.grid-fields label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-top: 0;
  font-size: 0.75rem;
  font-weight: 600;
}

/* input[type=color] is excluded from components.css's universal input
   baseline (it has its own native rendering that baseline would break),
   so left unstyled it renders as a tiny, inconsistently-sized native
   swatch that doesn't match the rest of the form. Squaring it off here
   with appearance:none and controlling the swatch pseudo-elements gives a
   clean, evenly-sized box in every browser instead. */
.grid-fields input[type="color"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2.5rem;
  padding: 0;
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
  background: none;
  cursor: pointer;
}

.grid-fields input[type="color"]::-webkit-color-swatch-wrapper {
  padding: 0;
  border-radius: calc(var(--tilt-radius) / 2);
}

.grid-fields input[type="color"]::-webkit-color-swatch {
  border: none;
  border-radius: calc(var(--tilt-radius) / 2);
}

.grid-fields input[type="color"]::-moz-color-swatch {
  border: none;
  border-radius: calc(var(--tilt-radius) / 2);
}

.bg-image-preview {
  width: 100%;
  max-width: 20rem;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 1px solid var(--tilt-border);
  border-radius: var(--tilt-radius);
  margin: 0.5rem 0;
  display: block;
}

.shape-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4rem, 1fr));
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.shape-picker button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
  padding: 0.5rem;
  color: var(--tilt-text-muted);
  font-size: 0.7rem;
  text-transform: none;
  letter-spacing: normal;
}

.shape-picker button[aria-pressed="true"] {
  border-color: var(--tilt-accent);
  color: var(--tilt-accent);
  background: rgba(255, 45, 149, 0.1);
}

.shape-picker button .shape-swatch {
  width: 2.5rem;
  height: 2.5rem;
  background: var(--tilt-accent);
}

/* Shared gradient editor (js/theme/gradient-editor.js) — used by both
   theme.html's background gradient and border-editor.html's border
   gradient. `:not([hidden])` on the display rules, not plain class
   selectors: both this container and .gradient-angle-field get toggled
   via the `hidden` attribute (js/ui/theme-page.js, gradient-editor.js
   itself for the angle field on linear/radial switch), and a plain class
   selector's `display: flex` beats the UA stylesheet's `[hidden] {
   display: none }` on specificity alone — same bug class already hit
   twice elsewhere this session (the sticky-note tile background, the
   More-dropdown/overflow clash). `:not([hidden])` sidesteps the
   specificity fight entirely: the flex rule simply doesn't match a
   hidden element, so there's nothing to out-rank. */
.gradient-editor:not([hidden]) {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.5rem 0;
  padding: 0.75rem;
  border: 1px solid var(--tilt-border);
  border-radius: var(--tilt-radius);
}

.gradient-angle-field:not([hidden]) {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.gradient-stops-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.gradient-stop-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.gradient-stop-row input[type="color"] {
  flex-shrink: 0;
}

.gradient-stop-row input[type="range"] {
  flex: 1;
}

.gradient-stop-row button {
  flex-shrink: 0;
  padding: 0.25rem 0.5rem;
}

.image-preview-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.image-preview-list img {
  width: 4rem;
  height: 4rem;
  object-fit: cover;
  border-radius: calc(var(--tilt-radius) / 2);
}

/* Photos tile only (image-upload-multi) — each card carries its own
   global-discovery controls, so it needs real width/column layout rather
   than the bare thumbnail chip the plain single-Image tile above uses. */
.photo-editor-card {
  width: 12rem;
  margin: 0;
  padding: 0.6rem;
  background: var(--tilt-bg);
  border: 1px solid var(--tilt-border);
  border-radius: var(--tilt-radius);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.photo-editor-card img {
  width: 100%;
  height: 8rem;
  object-fit: cover;
  border-radius: calc(var(--tilt-radius) / 2);
}

/* js/ui/photo-share-control.js's returned wrapper — same internal
   spacing as .photo-editor-card's own flex column above, since this now
   sits between the image and each caller's own delete/remove button
   (js/ui/editor-page.js's Photos tile, js/ui/photos-page.js's library). */
.photo-share-control {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.photo-editor-status {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--tilt-text-muted);
}

.photo-editor-caption {
  font-size: 0.8rem;
  color: var(--tilt-text-muted);
  overflow-wrap: anywhere;
}

.photo-editor-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

/* Every button directly in a card (not just .photo-editor-actions' own —
   js/ui/photos-page.js's Delete button is a card-level sibling, appended
   after buildPhotoShareControl's returned div, not inside it) needs this
   same compact sizing. Without it, Delete kept the site's default button
   padding/font-size and overflowed the card's fixed 12rem width. */
.photo-editor-card > button,
.photo-editor-actions button {
  font-size: 0.7rem;
  padding: 0.3rem 0.5rem;
  width: 100%;
}

/* Visual tile editor -------------------------------------------------- */

.editor-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem 0;
}

.editor-toolbar h1 {
  font-family: var(--tilt-font-display);
  font-size: 1.25rem;
}

.editor-toolbar form {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.editor-toolbar select {
  padding: 0.5rem;
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
}

.editor-toolbar button {
  margin-top: 0;
}

.editor-instructions {
  padding: 0 1.5rem;
  color: var(--tilt-text-muted);
  font-size: 0.875rem;
  max-width: 60rem;
}

.editor-layout {
  display: grid;
  grid-template-columns: 1fr 20rem;
  gap: 1.5rem;
  align-items: start;
  padding: 1rem 1.5rem 2rem;
}

/* The editor canvas is deliberately NOT a CSS Grid container. It was
   originally `display: grid`, and its height (via grid-auto-rows) was
   determined by whichever tiles happened to be in normal flow at that
   moment — so a tile pulled out of flow to be dragged/resized could hit
   an invisible ceiling set by other tiles, since it no longer contributed
   to that calculation. Every tile here is always plain pixel-positioned
   (see js/ui/editor-page.js), and the canvas's own height is set
   explicitly in JS from the actual tile layout, not derived from
   whichever children currently happen to be in flow. profile.html's real,
   non-interactive rendering is unaffected — it still uses CSS Grid.  */

.editor-canvas {
  max-width: none;
  margin: 0;
  padding: 1rem;
  background:
    repeating-linear-gradient(to right, var(--tilt-border) 0 1px, transparent 1px calc(100% / 12)),
    var(--tilt-bg);
  background-size: calc(100% + 1px) 100%;
  border: 1px dashed var(--tilt-border);
  border-radius: var(--tilt-radius);
  position: relative;
  /* visible, not hidden: tiles near the edge have drag/resize handles that
     sit partly outside their own box (see .tile-drag-handle below), and
     those would otherwise get clipped by the canvas edge. */
  overflow: visible;
}

.editor-canvas .tile {
  cursor: pointer;
  user-select: none;
  margin: 0;
  /* profile.css sets overflow:auto for real tile content scrolling, but
     that would clip the drag/resize handles below, which sit partly
     outside the tile's own box on purpose so they don't cover content. */
  overflow: visible;
}

.editor-canvas .tile.is-selected {
  outline: 2px solid var(--tilt-accent);
  outline-offset: 2px;
}

.editor-canvas .tile.is-dragging {
  opacity: 0.9;
  z-index: 10;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.drag-ghost {
  position: absolute;
  border: 2px dashed var(--tilt-accent);
  border-radius: var(--tilt-radius);
  background: color-mix(in srgb, var(--tilt-accent) 12%, transparent);
  pointer-events: none;
  z-index: 5;
}

.tile-drag-handle,
.tile-resize-handle {
  position: absolute;
  width: 1.75rem;
  height: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--tilt-surface);
  border: 1px solid var(--tilt-border);
  border-radius: calc(var(--tilt-radius) / 2);
  font-size: 1rem;
  line-height: 1;
  padding: 0;
  touch-action: none;
}

.tile-drag-handle {
  top: -0.5rem;
  left: -0.5rem;
  cursor: grab;
}

.tile-drag-handle:active {
  cursor: grabbing;
}

.tile-resize-handle {
  bottom: -0.5rem;
  right: -0.5rem;
  cursor: nwse-resize;
}

.tile-editor-body {
  overflow: auto;
  max-height: 100%;
}

.tile-empty-canvas {
  color: var(--tilt-text-muted);
  font-style: italic;
  padding: 2rem;
  text-align: center;
}

.tile-inspector {
  position: sticky;
  top: 1rem;
  background: var(--tilt-surface);
  border: 1px solid var(--tilt-border);
  border-radius: var(--tilt-radius);
  padding: 1rem;
}

.tile-inspector h2 {
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.inspector-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

@media (max-width: 60rem) {
  .editor-layout {
    grid-template-columns: 1fr;
  }

  .tile-inspector {
    position: static;
  }
}
