/* Page runtime: frame, layouts, and the state marker every widget wears (principle 3).
   Colours, fonts and spacing come from the project's theme.css. A theme may also set:
     --app-height   e.g. 100vh: the page fits the window and regions scroll on their own (app-like screens)
     --frame-bg, --frame-border   the header's background and bottom border */
:root {
  --bg: #f6f6f4;
  --surface: #ffffff;
  --text: #1c1c1e;
  --muted: #6b6b72;
  --border: #e2e2de;
  --accent: #3552d6;
  --on-accent: #ffffff;
  --radius: 10px;
  --space: 16px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --page-width: 1120px;
  --sidebar-width: 400px;
  --state-sample: #8d8d93;
  --state-building: #6353d8;
  --state-real: #2f9e57;
  --state-attention: #cf5146;
}

html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

#jv-app { min-height: 100vh; height: var(--app-height, auto); display: flex; flex-direction: column; }

/* The frame */
.jv-frame { display: flex; align-items: center; gap: var(--space); }
.jv-frame[hidden], .jv-frame:empty { display: none; }
/* --frame-width lines the header and footer up with a centred page (fixed centre); unset, they run edge to edge. */
#jv-header, #jv-footer { padding-inline: max(var(--space), calc((100% - var(--frame-width, 100%)) / 2 + var(--space))); }
#jv-header {
  padding-block: 10px;
  background: var(--frame-bg, transparent);
  border-bottom: var(--frame-border, 0);
  position: relative;
  z-index: 20;
}
#jv-footer { padding-block: var(--space); }
.jv-frame > .jv-widget { flex: 0 0 auto; min-width: 0; }
.jv-frame > .jv-widget[data-width="fill"], .jv-frame > .jv-widget:only-of-type { flex: 1 1 0; }

/* The page and its layouts. With a fixed --app-height the page scrolls inside the window, and the
   regions of a sidebar or split layout scroll on their own. */
.jv-page {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  gap: var(--space);
  padding: var(--space);
  box-sizing: border-box;
  width: 100%;
  align-items: stretch;
}
/* Every layout keeps to the same page width (centred, or edge to edge when the theme says 100%), so pages match. */
.jv-page { max-width: var(--page-width); margin-left: auto; margin-right: auto; }
.jv-layout-single, .jv-layout-grid { grid-template-columns: minmax(0, 1fr); align-content: start; }
.jv-layout-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
.jv-layout-sidebar { grid-template-columns: var(--sidebar-width) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }

.jv-region { display: flex; flex-direction: column; gap: var(--space); min-width: 0; min-height: 0; }
.jv-layout-split > .jv-region, .jv-layout-sidebar > .jv-region {
  overflow-y: auto;
  /* Room for state markers and outlines that sit just outside a widget. */
  padding: 12px 8px;
  margin: -12px -8px;
}
.jv-region > .jv-widget[data-width="fill"] { flex: 1 1 0; min-height: 300px; }
.jv-layout-grid .jv-region { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.jv-layout-grid .jv-region > .jv-widget[data-width="wide"] { grid-column: 1 / -1; }

/* Phone layout: the screen is the app. The page scrolls inside the window, a "fill" part takes the height that is
   left (widgets read --jv-fill to stretch), and the frame's header and footer stay where they are. */
body[data-layout="phone"] #jv-app { height: 100dvh; min-height: 0; }
body[data-layout="phone"] #jv-header { flex-wrap: nowrap; padding: 8px 12px; gap: 10px; }
body[data-layout="phone"] #jv-header > .jv-widget[data-width="fill"] { flex: 1 1 0; }
body[data-layout="phone"] #jv-footer { padding: 0; }
.jv-layout-phone { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); padding: 10px; gap: 10px; overflow: hidden; }
.jv-layout-phone > .jv-region { overflow-y: auto; gap: 10px; padding: 6px 4px; margin: -6px -4px; overscroll-behavior: contain; }
.jv-layout-phone > .jv-region > .jv-widget[data-width="fill"] { --jv-fill: 100%; --jv-fill-max: none; flex: 1 1 0; min-height: 260px; }
/* A frame region whose every part has stepped out (e.g. the phone bar on a desktop page) takes no room. */
.jv-frame:not(:has(> .jv-widget:not(.jv-hidden))) { display: none; }

@media (max-width: 760px) {
  #jv-app { height: auto; }
  .jv-page:not(.jv-layout-phone) { grid-template-columns: minmax(0, 1fr) !important; grid-template-rows: none !important; overflow: visible; }
  .jv-layout-split > .jv-region, .jv-layout-sidebar > .jv-region { overflow: visible; padding: 0; margin: 0; }
  .jv-page:not(.jv-layout-phone) > .jv-region > .jv-widget[data-width="fill"] { flex: 0 0 auto; min-height: 0; }
  body[data-layout="phone"] #jv-app { height: 100dvh; }
  #jv-header { flex-wrap: wrap; row-gap: 8px; }
  /* A header widget that fills the width gets its own row; the rest wrap below it. */
  #jv-header > .jv-widget[data-width="fill"]:not(:only-of-type) { flex-basis: 100%; }
}

/* A page that isn't there, or isn't there yet */
.jv-not-found {
  display: grid; place-content: center; justify-items: center; gap: 8px;
  min-height: 55vh; padding: 24px; text-align: center; color: var(--muted);
}
.jv-not-found h1 { margin: 0; font-size: 22px; font-weight: 600; color: var(--text); }
.jv-not-found p { margin: 0; max-width: 34ch; line-height: 1.5; }
.jv-not-found a { color: var(--accent); }
.jv-sketching { display: flex; gap: 7px; margin-bottom: 8px; }
.jv-sketching span {
  width: 10px; height: 10px; border-radius: 50%;
  background: linear-gradient(135deg, #7b5cff, #3aa6ff 60%, #33cfad);
  animation: jv-bob 1.3s ease-in-out infinite;
}
.jv-sketching span:nth-child(2) { animation-delay: 0.15s; }
.jv-sketching span:nth-child(3) { animation-delay: 0.3s; }
@keyframes jv-bob { 40% { transform: translateY(-6px); opacity: 0.6; } }

/* Widgets and their state marker */
.jv-widget { position: relative; border-radius: var(--radius); min-width: 0; }
.jv-widget.jv-hidden { display: none; }
.jv-host { height: 100%; }

.jv-badge {
  position: absolute; top: -10px; right: 14px; z-index: 5;
  display: inline-flex; align-items: center; gap: 6px;
  height: 20px; padding: 0 9px 0 7px; box-sizing: border-box; border-radius: 999px;
  font: 600 11px/1 system-ui, -apple-system, "Segoe UI", sans-serif; letter-spacing: 0.01em; white-space: nowrap;
  color: var(--muted); background: var(--surface);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 10%, transparent), 0 2px 8px color-mix(in srgb, var(--text) 8%, transparent);
  pointer-events: none;
}
.jv-badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--state-sample); }

/* Sample: a quiet dotted outline. */
.jv-widget[data-state="sample"] { outline: 1.5px dashed color-mix(in srgb, var(--state-sample) 60%, transparent); outline-offset: 4px; }

/* Building: an aurora ring travels round the widget while Jarvis works on it. */
@property --jv-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.jv-widget[data-state="building"] { animation: jv-glow 2.6s ease-in-out infinite; }
.jv-widget[data-state="building"]::before {
  content: ""; position: absolute; inset: -4px; z-index: 4; pointer-events: none;
  border-radius: calc(var(--radius) + 4px); padding: 2px;
  background: conic-gradient(from var(--jv-angle), #7b5cff, #3aa6ff, #33cfad, #7b5cff);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: jv-orbit 3s linear infinite;
}
.jv-widget[data-state="building"] > .jv-badge { color: var(--state-building); }
.jv-widget[data-state="building"] > .jv-badge::before {
  background: conic-gradient(#7b5cff, #3aa6ff, #33cfad, #7b5cff);
  animation: jv-spin 1.2s linear infinite;
}
@keyframes jv-orbit { to { --jv-angle: 360deg; } }
@keyframes jv-spin { to { transform: rotate(360deg); } }
@keyframes jv-glow { 50% { box-shadow: 0 0 28px 2px rgb(58 166 255 / 0.16); } }

/* Real: just a small green dot. */
.jv-widget[data-state="real"] > .jv-badge {
  top: -4px; width: 9px; height: 9px; padding: 0; gap: 0; font-size: 0;
  background: var(--state-real); box-shadow: 0 0 0 2px var(--bg);
}
.jv-widget[data-state="real"] > .jv-badge::before { display: none; }

/* On Jarvis's own screens every part is finished, so "works for real" needs no marker there. */
body[data-project="jarvis"] .jv-widget[data-state="real"]:not(.jv-attention) > .jv-badge { display: none; }

/* Needs attention: a decision about this widget waits on the user. */
.jv-attention { outline: 2px solid var(--state-attention) !important; outline-offset: 4px; }
.jv-attention > .jv-badge {
  top: -10px; width: auto; height: 20px; padding: 0 9px 0 7px; gap: 6px; font-size: 11px;
  color: #fff; background: var(--state-attention); box-shadow: 0 2px 8px color-mix(in srgb, var(--state-attention) 35%, transparent);
}
.jv-attention > .jv-badge::before { display: block; background: #fff; animation: none; }

.jv-loading { min-height: 72px; border-radius: var(--radius); background: color-mix(in srgb, var(--border) 45%, transparent); animation: jv-breathe 1.6s ease-in-out infinite; }
@keyframes jv-breathe { 50% { opacity: 0.55; } }
.jv-error { outline: 2px solid #cf5146 !important; outline-offset: 4px; }
.jv-error::after {
  content: attr(data-error);
  position: absolute; left: 12px; bottom: -10px; z-index: 5; max-width: 90%;
  padding: 3px 8px; border-radius: 999px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font: 500 11px/1.3 system-ui, sans-serif; background: #cf5146; color: #fff;
}

/* A new version just swapped in: a soft aurora glow that fades. */
.jv-swapped { animation: jv-swapped 1.4s ease-out; }
@keyframes jv-swapped {
  from { box-shadow: 0 0 0 3px rgb(58 166 255 / 0.5), 0 0 32px rgb(123 92 255 / 0.35); }
  to { box-shadow: 0 0 0 14px rgb(58 166 255 / 0), 0 0 0 rgb(123 92 255 / 0); }
}
.jv-focused { animation: jv-focused 2.4s ease-out; }
@keyframes jv-focused {
  0%, 60% { box-shadow: 0 0 0 3px var(--accent), 0 0 0 8px color-mix(in srgb, var(--accent) 20%, transparent); }
  100% { box-shadow: 0 0 0 3px transparent; }
}

/* Inside Jarvis: pointing at a widget */
.jv-pointing .jv-widget { cursor: pointer; }
.jv-pointing .jv-widget:hover { outline: 3px solid var(--accent) !important; outline-offset: 4px; }
.jv-pointing .jv-widget:hover > .jv-host { opacity: 0.88; }

/* Inside Jarvis: arranging the structure */
.jv-editing .jv-dropzone { outline: 1.5px dashed color-mix(in srgb, var(--accent) 45%, transparent); outline-offset: 6px; border-radius: var(--radius); min-height: 48px; }
.jv-edit-bar {
  position: absolute; top: 8px; left: 8px; z-index: 7;
  display: flex; align-items: center; gap: 4px;
  font: 600 12px/1 system-ui, -apple-system, "Segoe UI", sans-serif;
}
.jv-handle, .jv-remove {
  height: 26px; padding: 0 10px; border-radius: 999px; border: none; display: inline-flex; align-items: center;
  background: #211e1a; color: #fff; box-shadow: 0 4px 14px rgb(0 0 0 / 0.22);
}
.jv-handle { cursor: grab; }
.jv-remove { cursor: pointer; font-size: 15px; padding: 0 9px; }
.jv-remove:hover { background: #cf5146; }
.jv-dragging { opacity: 0.35; }
.jv-drop-line { flex: none; height: 4px; min-width: 4px; border-radius: 2px; background: var(--accent); align-self: stretch; box-shadow: 0 0 12px var(--accent); }
.jv-add {
  flex: none; padding: 12px; border-radius: var(--radius);
  border: 1.5px dashed color-mix(in srgb, var(--accent) 60%, transparent); background: transparent; color: var(--accent);
  font: 600 13px system-ui, -apple-system, "Segoe UI", sans-serif; cursor: pointer;
}
.jv-add:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .jv-widget, .jv-widget::before, .jv-badge::before, .jv-swapped, .jv-focused, .jv-loading, .jv-sketching span { animation: none !important; }
}

/* The owner's menu, in the corner of your own app */
#jv-owner { position: fixed; right: 16px; bottom: 16px; z-index: 50; display: grid; justify-items: end; gap: 8px; font: 13px system-ui, -apple-system, "Segoe UI", sans-serif; }
.jv-owner-toggle {
  height: 34px; padding: 0 14px; border-radius: 999px; border: 0; cursor: pointer; font: 600 13px system-ui, sans-serif;
  background: #1d1b2e; color: #fff; box-shadow: 0 6px 20px rgb(0 0 0 / 0.18);
}
#jv-owner.visitor .jv-owner-toggle { background: #fff; color: #1d1b2e; box-shadow: 0 6px 20px rgb(0 0 0 / 0.12), 0 0 0 1px rgb(0 0 0 / 0.08); }
.jv-owner-menu {
  min-width: 200px; max-height: 60vh; overflow-y: auto; padding: 8px; border-radius: 14px; background: #fff; color: #1d1b2e;
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.18), 0 0 0 1px rgb(0 0 0 / 0.06); display: grid; gap: 2px;
}
.jv-owner-menu[hidden] { display: none; }
.jv-owner-head { margin: 2px 8px 4px; font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: #8a8797; }
.jv-owner-menu a { padding: 7px 10px; border-radius: 9px; color: inherit; text-decoration: none; }
.jv-owner-menu a:hover { background: #f1eff7; }
.jv-owner-switch { margin-top: 4px; border-top: 1px solid #eee; border-radius: 0 0 9px 9px !important; color: #5b4bd8 !important; font-weight: 600; }


/* Pull down to refresh (phone screens): Jarvis's orb drops in; spun and bright once letting go will reload. */
#jv-pull {
  position: fixed; top: 0; left: 50%; z-index: 100; width: 36px; height: 36px; border-radius: 50%; pointer-events: none;
  background: var(--surface, #fff); box-shadow: 0 6px 20px rgb(0 0 0 / 0.25); display: grid; place-items: center;
}
#jv-pull span {
  width: 22px; height: 22px; border-radius: 50%;
  background: conic-gradient(#7b5cff, #3aa6ff, #33cfad, #7b5cff); opacity: 0.55; transition: opacity 0.15s;
}
#jv-pull.ready span { opacity: 1; }
#jv-pull.going span { animation: jv-spin 0.6s linear infinite; }

/* Visitors see the app, not how it is being built (body.jv-builder only for its owner and Jarvis's preview). */
body:not(.jv-builder) .jv-widget > .jv-badge { display: none !important; }
body:not(.jv-builder) .jv-widget[data-state] { outline: none !important; animation: none !important; }
body:not(.jv-builder) .jv-widget[data-state="building"]::before { display: none !important; }
body:not(.jv-builder) .jv-attention { outline: none !important; }
