/* ---------------------------------------------------------------- tokens */

:root {
  /* The palette the app icon and the listing use: deep forest, one green, sand.
     Two blues from the client build this came from survived here longer than
     anything else, in --brand-soft and the primary button's hover. */
  --ink: #16211d;
  --muted: #667771;
  --line: #e5e2da;
  --line-strong: #cbc8bf;
  --bg: #f4f1ea;
  --card: #fff;
  --brand: #1f7a52;
  --brand-strong: #175f40;
  --brand-soft: rgba(63, 176, 122, .12);
  --panel-bg: #0e2a20;
  --panel-ink: #eeece4;
  --panel-line: #22453a;
  --warn: #8a6100;
  --warn-bg: #fff6e0;
  --ok: #1f7a52;
  --danger: #a3231a;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(14, 42, 32, .05), 0 10px 30px rgba(14, 42, 32, .07);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1 { font-size: 16px; margin: 0; letter-spacing: -.01em; }
h2 { font-size: 14px; margin: 0 0 12px; }

/* ------------------------------------------------------------------- bar */

.bar {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  flex: none;
}
.bar__sub { margin: 1px 0 0; color: var(--muted); font-size: 12px; }
.bar__actions { display: flex; gap: 8px; align-items: center; }

/*
 * Its own row under the header, not a cell inside it.
 *
 * Sharing the header's action row meant a long message pushed the
 * toggle and the buttons around, and errors are exactly the messages that are
 * long. On its own line it can say as much as it needs to and nothing moves.
 */
.status {
  flex: none;
  margin: 0;
  padding: 8px 16px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
/* No message, no bar. */
.status:empty { display: none; }
.status--error { color: var(--danger); background: color-mix(in srgb, var(--danger) 7%, var(--card)); }
.status--ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--card)); }

/* `hidden` is a user agent rule, and any author rule that sets `display` beats
   it. `.setup` sets `display: flex`, so the setup banner rendered permanently:
   an empty red bar on every load, because the code that fills its text returns
   early when the theme is already set up. Anything hidden by attribute needs
   this, so it is declared once rather than per component. */
[hidden] {
  display: none !important;
}

/* The landing state, when the app is opened without a product. */
.home {
  max-width: 520px;
  margin: 96px auto;
  text-align: center;
}

.home__title {
  margin: 0 0 12px;
  font-size: 26px;
  letter-spacing: -.02em;
}

.home__body {
  margin: 0 0 28px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
}

/* Shown only when the storefront cannot render what is saved here. */
.setup {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  font-size: 13px;
  color: var(--ink);
  background: color-mix(in srgb, var(--danger) 7%, var(--card));
  border-bottom: 1px solid var(--line);
}

/* The plan bar is information, not a warning, so it is not red. */
.setup--plan {
  background: var(--card);
}

.setup--ok {
  background: color-mix(in srgb, var(--ok) 8%, var(--card));
}

.setup__text {
  margin: 0;
  flex: 1;
}

/* --------------------------------------------------------------- buttons */

.btn {
  font: inherit;
  font-size: 13px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  white-space: nowrap;
  transition: background .12s, border-color .12s;
}
/* Hover is scoped away from disabled buttons. The old rule forced the disabled
   background to white while a primary button keeps white text, so a disabled
   Save turned into an empty white box under the cursor. */
.btn:not(:disabled):hover { background: #f6f6f8; border-color: var(--muted); }
.btn:disabled { opacity: .45; cursor: default; }
.btn--primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn--primary:not(:disabled):hover { background: var(--brand-strong); border-color: var(--brand-strong); }
.btn--danger { color: var(--danger); }
.btn--small { padding: 3px 9px; font-size: 12px; }

:where(button, a, input, select, textarea):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}


/* ---------------------------------------------------------------- fields */

select, input[type="text"], input[type="search"], input[type="number"], textarea {
  font: inherit;
  font-size: 13px;
  padding: 9px 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  width: 100%;
  transition: border-color .12s ease, box-shadow .12s ease;
}

select:hover, input[type="text"]:hover, input[type="search"]:hover,
input[type="number"]:hover, textarea:hover {
  border-color: var(--muted);
}

/* One focus treatment for every control, so the drawer does not flicker
   between a browser default outline and a custom one as you tab through it. */
select:focus, input[type="text"]:focus, input[type="search"]:focus,
input[type="number"]:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

::placeholder { color: var(--muted); opacity: 1; }

textarea { resize: vertical; min-height: 76px; line-height: 1.5; }

/* The native arrow sits differently in every browser, so the control draws its
   own and reserves the room for it. */
select {
  appearance: none;
  padding-right: 30px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%23667771' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 11px;
  cursor: pointer;
}

input[type="checkbox"] {
  appearance: none;
  width: 16px;
  height: 16px;
  flex: none;
  margin: 0;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--card);
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}

input[type="checkbox"]:hover { border-color: var(--muted); }

input[type="checkbox"]:checked {
  background: var(--brand) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10'%3E%3Cpath d='M1 5l3.5 3.5L11 1.5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 10px no-repeat;
  border-color: var(--brand);
}

input[type="checkbox"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--brand-soft);
}

input[type="color"] {
  width: 44px;
  height: 34px;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--card);
  cursor: pointer;
}
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch { border: none; border-radius: 5px; }

.field { margin-bottom: 18px; }
.field > label { display: block; font-weight: 600; font-size: 12px; margin-bottom: 6px; letter-spacing: .01em; }
.field__help { color: var(--muted); font-size: 11.5px; margin: 6px 0 0; line-height: 1.45; }
.field--inline { display: flex; gap: 8px; align-items: center; }
.field--inline > label { margin: 0; font-weight: 400; font-size: 13px; }
.field--inline input:not([type="checkbox"]) { width: auto; }

.choices { display: flex; flex-wrap: wrap; gap: 10px 18px; }
.choices label { display: flex; gap: 7px; align-items: center; font-weight: 400; font-size: 13px; cursor: pointer; }
.choices input:not([type="checkbox"]) { width: auto; }

.banner { padding: 10px 12px; border-radius: 6px; margin-bottom: 16px; font-size: 13px; }
.banner--warn { background: var(--warn-bg); color: var(--warn); }

.badge {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--muted);
}

/* ------------------------------------------------------------- workspace */

.workspace-body { height: 100vh; display: flex; flex-direction: column; overflow: hidden; }

.workspace {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr);
  min-height: 0;
  min-width: 0;
}
.workspace--settings { grid-template-columns: 216px minmax(0, 1fr) 300px; }

/* Dark panel of draggable content types */

.panel {
  background: var(--panel-bg);
  color: var(--panel-ink);
  overflow-y: auto;
  padding: 12px 10px 40px;
  min-width: 0;
}
.panel__group { margin-bottom: 18px; }
.panel__group h3 {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: rgba(242, 242, 244, .5);
  margin: 0 0 6px 6px;
  font-weight: 600;
}
.panel__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  padding: 7px 9px;
  margin-bottom: 2px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: inherit;
  cursor: grab;
  font: inherit;
  font-size: 13px;
  transition: background .12s;
}
.panel__item:hover { background: rgba(255, 255, 255, .09); }
.panel__item:active { cursor: grabbing; }
.panel__item--dragging { opacity: .35; }
.panel__icon { width: 15px; text-align: center; opacity: .7; flex: none; font-size: 13px; }

/* ----------------------------------------------------------------- stage */

.stage-wrap {
  overflow: auto;
  padding: 28px 28px 140px;
  background: var(--bg);
  min-width: 0;
}
.stage {
  /* Explicit, because a stage that shrinks to its content is unusable when the
     content is one empty row. */
  width: 100%;
  margin: 0 auto;
  background: var(--card);
  min-height: 320px;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: max-width .18s ease;

  /* The same custom properties the theme section sets, so spacing on the stage
     matches spacing on the storefront rather than only the colours matching. */
  --uns-blocks-max-width: 1280px;
  --uns-blocks-padding-inline: 25px;
  --uns-blocks-padding-inline-desktop: 20px;
  --uns-blocks-gap: 40px;
}
.stage { max-width: 1440px; }
.stage__hint { text-align: center; color: var(--muted); margin: 18px 0 0; font-size: 13px; }

/* Every node gets a frame, a label, a toolbar and drop zones. */

.node { position: relative; }
.node__frame { position: relative; min-height: 10px; outline-offset: -1px; }
.node:hover > .node__frame { outline: 1px dashed var(--line-strong); }
.node--selected > .node__frame { outline: 2px solid var(--brand); }
.node--selected { z-index: 2; }

.node__label,
.node__tools {
  position: absolute;
  top: 0;
  transform: translateY(-100%);
  background: var(--brand);
  color: #fff;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  transition: opacity .1s;
}
.node__label {
  left: 0;
  font-size: 11px;
  line-height: 1.6;
  padding: 2px 8px;
  border-radius: 5px 5px 0 0;
  white-space: nowrap;
}
.node__tools {
  right: 0;
  display: flex;
  gap: 1px;
  padding: 2px;
  border-radius: 5px 5px 0 0;
}
.node:hover > .node__frame > .node__label,
.node:hover > .node__frame > .node__tools,
.node--selected > .node__frame > .node__label,
.node--selected > .node__frame > .node__tools {
  opacity: 1;
  pointer-events: auto;
}

.node__tool {
  border: none;
  background: none;
  color: #fff;
  font-size: 12px;
  line-height: 1;
  padding: 4px 6px;
  cursor: pointer;
  border-radius: 3px;
}
.node__tool:hover { background: rgba(255, 255, 255, .24); }
.node__tool--grab { cursor: grab; }

.node--hidden > .node__frame { opacity: .38; }
.node--hidden > .node__frame::after {
  content: "hidden";
  position: absolute;
  top: 6px;
  right: 6px;
  font-size: 10px;
  background: var(--ink);
  color: #fff;
  padding: 1px 7px;
  border-radius: 10px;
  z-index: 2;
}

/* A block whose own rules mean it renders nothing still has to be selectable. */
.node__placeholder {
  padding: 22px 18px;
  text-align: center;
  color: var(--warn);
  background: var(--warn-bg);
  border-radius: 4px;
  font-size: 12px;
  margin: 4px;
}
.node__placeholder strong { display: block; color: var(--ink); font-size: 13px; margin-bottom: 3px; }

.node__badges {
  position: absolute;
  bottom: 3px;
  left: 3px;
  display: flex;
  gap: 3px;
  z-index: 2;
  pointer-events: none;
}
.node__badges .badge { background: rgba(255, 255, 255, .94); }

/* Drop zones sit between children and at the ends of every container. */

.dropzone {
  height: 8px;
  margin: 1px 0;
  border-radius: 4px;
  transition: background .1s, height .1s;
}
.dropzone--active { background: var(--brand); height: 16px; }
.dropzone--empty {
  min-height: 78px;
  border: 1px dashed var(--line-strong);
  border-radius: 6px;
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 12px;
  margin: 10px;
  background: repeating-linear-gradient(45deg, transparent, transparent 9px, rgba(0, 0, 0, .015) 9px, rgba(0, 0, 0, .015) 18px);
}
.dropzone--empty.dropzone--active {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand);
}

/* Column resizing */

.node--column { position: relative; }
.resizer {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 13px;
  margin-left: -6px;
  cursor: col-resize;
  z-index: 4;
  display: grid;
  place-items: center;
}
.resizer::before {
  content: "";
  width: 3px;
  height: 40px;
  background: var(--brand);
  border-radius: 2px;
  opacity: 0;
  transition: opacity .1s;
}
.resizer:hover::before, .resizer--active::before { opacity: 1; }
.resizer__readout {
  position: absolute;
  top: 6px;
  background: var(--ink);
  color: #fff;
  font-size: 11px;
  padding: 2px 7px;
  border-radius: 10px;
  white-space: nowrap;
  display: none;
}
.resizer--active .resizer__readout { display: block; }

/* -------------------------------------------------------------- settings */

.settings {
  border-left: 1px solid var(--line);
  background: var(--card);
  overflow-y: auto;
  padding: 0 14px 60px;
  min-width: 0;
}
.settings__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  padding: 12px 0 10px;
  margin-bottom: 14px;
  z-index: 1;
}
.settings__head h2 { margin: 0; font-size: 14px; }
.settings__warn {
  background: var(--warn-bg);
  color: var(--warn);
  padding: 9px 11px;
  border-radius: 6px;
  font-size: 12px;
  margin: 0 0 12px;
}

/* Repeatable children: tiles, buttons, slides */

.tiles { border: 1px solid var(--line); border-radius: 6px; padding: 10px; }
.tiles__row {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.tiles__row:last-of-type { border-bottom: none; }
.tiles__name { flex: 1; min-width: 0; font-size: 13px; }
.tiles__warn { color: var(--warn); font-size: 11px; }

/* ------------------------------------------------- custom element designer */

.designer {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px 16px 80px;
  display: grid;
  grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 820px) { .designer { grid-template-columns: 1fr; } }

.designer > section {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
}
.designer code { background: var(--bg); padding: 1px 4px; border-radius: 3px; font-size: 12px; }
.designer textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }

.stack { list-style: none; margin: 0 0 12px; padding: 0; display: grid; gap: 6px; }

.preview {
  width: 100%;
  height: 220px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
}

.el {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.el--active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
.el__name { flex: 1; min-width: 0; font-size: 13px; }
.el__type { display: block; color: var(--muted); font-size: 11px; }

.fieldrow {
  display: grid;
  grid-template-columns: 1fr 1fr auto auto auto;
  gap: 6px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.fieldrow:last-of-type { border-bottom: none; }
.fieldrow input:not([type="checkbox"]), .fieldrow select { width: 100%; }
.fieldrow__req { display: flex; gap: 7px; align-items: center; font-size: 11px; white-space: nowrap; }
.fieldrow__req input:not([type="checkbox"]) { width: auto; }

/* --------------------------------------------------------- product picker */

.bar__product { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bar__thumb {
  width: 34px;
  height: 34px;
  border-radius: 5px;
  object-fit: cover;
  border: 1px solid var(--line);
  flex: none;
}

.picker {
  width: min(520px, 92vw);
  max-height: 80vh;
  border: none;
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: var(--shadow);
}
.picker::backdrop { background: rgba(0, 0, 0, .35); }
.picker__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.picker__head h2 { margin: 0; }
.picker__note { color: var(--muted); font-size: 12px; margin: 8px 0 0; }
.picker__note--error { color: var(--danger); }

.picker__list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  max-height: 46vh;
  overflow-y: auto;
  display: grid;
  gap: 2px;
}
.picker__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.picker__item:hover { background: var(--bg); border-color: var(--line); }
.picker__item img { width: 34px; height: 34px; border-radius: 5px; object-fit: cover; flex: none; background: var(--bg); }
.picker__item span { min-width: 0; }
.picker__handle { display: block; color: var(--muted); font-size: 11px; }
.picker__badge {
  margin-left: auto;
  flex: none;
  align-self: center;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  color: var(--brand);
  background: var(--brand-soft);
}

/* Image fields, and the picker that fills them */

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

.imagefield__preview {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.imagefield__preview img { max-width: 100%; max-height: 150px; display: block; }
.imagefield__actions { display: flex; gap: 8px; }
.imagefield__actions .btn { flex: 1 1 0; }
/* Says "nothing chosen" without spending a line of text on it. */
.imagefield__preview--empty {
  background-image: linear-gradient(45deg, var(--line) 25%, transparent 25%, transparent 75%, var(--line) 75%),
    linear-gradient(45deg, var(--line) 25%, transparent 25%, transparent 75%, var(--line) 75%);
  background-size: 14px 14px;
  background-position: 0 0, 7px 7px;
  opacity: .5;
}

.imagefield__url { font-size: 11px; }
.imagefield__actions { display: flex; gap: 6px; }

.picker--images { width: min(760px, 92vw); }
.picker__tools { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.picker__tools input[type="search"] { flex: 1 1 auto; }

.imagegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 8px;
  max-height: 58vh;
  overflow-y: auto;
}

.imagegrid__item {
  position: relative;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  cursor: pointer;
  overflow: hidden;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.imagegrid__item:hover, .imagegrid__item:focus-visible { border-color: var(--brand); outline: none; }
.imagegrid__item img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

.imagegrid__size {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: 2px 3px;
  font-size: 9px;
  color: #fff;
  background: rgba(0, 0, 0, .6);
  text-align: center;
}
