/* Shared styles for the display, helper, test and landing pages. */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #000;
  color: #f5f5f5;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* ---------- Landing ---------- */
.landing-body {
  background:
    radial-gradient(1200px 600px at 20% -10%, rgba(31, 111, 235, 0.25), transparent 60%),
    radial-gradient(900px 500px at 90% 110%, rgba(255, 45, 45, 0.16), transparent 55%),
    #0a0a0a;
  min-height: 100%;
}
.landing {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(2rem, 6vh, 5rem) clamp(1rem, 4vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: 2rem;
  min-height: 100dvh;
  justify-content: center;
}
.landing-header { text-align: center; }
.landing-header h1 {
  margin: 0 0 0.4rem;
  font-size: clamp(1.8rem, 5vw, 2.6rem);
  font-weight: 800;
  letter-spacing: -0.01em;
}
.landing-header .tagline {
  margin: 0;
  color: #a0a0a0;
  font-size: clamp(0.95rem, 2.2vw, 1.05rem);
}

.role-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
@media (max-width: 820px) {
  .role-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 540px) {
  .role-grid { grid-template-columns: 1fr; }
}

.role-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  text-align: center;
  padding: 1.75rem 1.25rem;
  background: rgba(20, 20, 22, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 18px;
  color: inherit;
  text-decoration: none;
  transition: transform 120ms ease-out, border-color 120ms ease-out,
              background 120ms ease-out, box-shadow 120ms ease-out;
}
.role-card:hover, .role-card:focus-visible {
  transform: translateY(-2px);
  background: rgba(28, 28, 32, 0.95);
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35);
  outline: none;
}
.role-card:active { transform: translateY(0); }

.role-icon {
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px;
}
.role-icon svg { width: 36px; height: 36px; }

.role-card--helper .role-icon {
  background: linear-gradient(135deg, #ff2d2d, #ff7373);
  color: #fff;
  box-shadow: 0 8px 24px rgba(255, 45, 45, 0.3);
}
.role-card--display .role-icon {
  background: linear-gradient(135deg, #1f6feb, #6da7ff);
  color: #fff;
  box-shadow: 0 8px 24px rgba(31, 111, 235, 0.35);
}
.role-card--test .role-icon {
  background: linear-gradient(135deg, #14b8a6, #5eead4);
  color: #fff;
  box-shadow: 0 8px 24px rgba(20, 184, 166, 0.3);
}

.role-card-title {
  font-size: 1.1rem;
  font-weight: 700;
}
.role-card-desc {
  margin-top: 0.35rem;
  color: #aaa;
  font-size: 0.92rem;
  line-height: 1.45;
}

.landing-footer {
  text-align: center;
  color: #777;
  font-size: 0.85rem;
}
.landing-footer p { margin: 0; }

code { background: #222; padding: 0.1rem 0.35rem; border-radius: 4px; }

/* ---------- Stage (video container, shared) ---------- */
.stage {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #000;
}
/* Helper-only: the video + marker live inside this layer so a two-finger
   pinch/pan can transform both together. The freeze thumbnail sits outside
   the layer so it stays anchored to the stage corner regardless of zoom. */
.zoom-layer {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
  will-change: transform;
}
.stage video {
  width: 100%;
  height: 100%;
  object-fit: contain;        /* letterboxed; overlay math accounts for this */
  display: block;
  /* Suppress double-tap-to-zoom and pan gestures so our pointerdown handler
     is the only response to a tap. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

/* ---------- Splash ring (set-dot animation) ---------- */
.splash {
  position: absolute;
  pointer-events: none;
  width: 24px;
  height: 24px;
  margin-left: -12px;          /* center on (left, top) */
  margin-top:  -12px;
  border-radius: 50%;
  border: 3px solid rgba(255, 45, 45, 0.85);
  background: transparent;
  z-index: 1;                  /* below the marker, above the video */
  animation: splash-ring 480ms cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}
@keyframes splash-ring {
  from { transform: scale(0.6); opacity: 0.9; border-width: 3px; }
  to   { transform: scale(5);   opacity: 0;   border-width: 1px; }
}

/* ---------- Trail dot (drag breadcrumbs) ---------- */
.trail {
  position: absolute;
  pointer-events: none;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  margin-top:  -6px;
  border-radius: 50%;
  background: rgba(255, 45, 45, 0.75);
  box-shadow: 0 0 8px rgba(255, 45, 45, 0.55);
  z-index: 1;
  animation: trail-fade 700ms ease-out forwards;
}
@keyframes trail-fade {
  from { opacity: 0.75; transform: scale(1); }
  to   { opacity: 0;    transform: scale(0.3); }
}

/* ---------- Marker overlay ---------- */

/* The .marker is a 0×0 anchor at the click position. Each shape is a child
   element that's only visible when the corresponding shape class is active. */
.marker {
  --marker-size: 20px;
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
  transition: left 60ms linear, top 60ms linear;
  z-index: 2;                  /* above trail breadcrumbs and splashes */
}
.marker.hidden { display: none; }
/* During a drag the marker should track the incoming marks 1:1 instead of
   easing toward each new position. */
.marker.dragging { transition: none; }

.marker-dot,
.marker-arrow,
.marker-cursor,
.marker-label {
  display: none;
  position: absolute;
  pointer-events: none;
}

/* Circle: hollow ring. Stroke is fixed (not scaled) so only the diameter
   responds to the size slider. */
.marker-dot {
  width:  var(--marker-size);
  height: var(--marker-size);
  left: calc(var(--marker-size) / -2);
  top:  calc(var(--marker-size) / -2);
  border-radius: 50%;
  transition:
    width 120ms ease-out, height 120ms ease-out,
    left 120ms ease-out, top 120ms ease-out;
}
.marker.shape-circle .marker-dot {
  display: block;
  background: transparent;
  border: 2px solid #ff2d2d;
}

/* Arrow: SVG with its tip at the right-middle of its viewBox (100, 15).
   Anchored so the tip sits at the marker position, then rotated around the
   tip toward the nearest corner. The angle is set by JS via --marker-angle. */
.marker-arrow {
  width:  calc(var(--marker-size) * 5);
  height: calc(var(--marker-size) * 1.5);
  left: calc(var(--marker-size) * -5);
  top:  calc(var(--marker-size) * -0.75);
  transform-origin: 100% 50%;
  transform: rotate(var(--marker-angle, 0deg));
  filter: drop-shadow(0 0 calc(var(--marker-size) * 0.3) rgba(255, 45, 45, 0.6));
  transition:
    width 120ms ease-out, height 120ms ease-out,
    left 120ms ease-out, top 120ms ease-out;
}
.marker.shape-arrow .marker-arrow { display: block; }

/* Cursor (pencil): does not rotate. Tip is at the bottom-center of the
   viewBox (≈ 30, 76 of 60×80); the container is offset so that point lands
   at the marker anchor. The label "write" is placed below the tip. */
.marker-cursor {
  width:  calc(var(--marker-size) * 1.5);
  height: calc(var(--marker-size) * 2);
  left: calc(var(--marker-size) * -0.75);
  top:  calc(var(--marker-size) * -1.9);
  filter: drop-shadow(0 0 calc(var(--marker-size) * 0.3) rgba(255, 45, 45, 0.5));
  transition:
    width 120ms ease-out, height 120ms ease-out,
    left 120ms ease-out, top 120ms ease-out;
}
.marker.shape-cursor-write .marker-cursor { display: block; }

/* Label used by cursor-write. JS sets text + left/top. */
.marker-label {
  font-size: clamp(16px, calc(var(--marker-size) * 0.95), 48px);
  font-weight: 800;
  color: #fff;
  white-space: nowrap;
  letter-spacing: 0.02em;
  transform: translate(-50%, -50%);
}
.marker.shape-cursor-write .marker-label { display: block; }

/* ---------- UI overlays ---------- */
.helper-ui {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  padding: 1rem;
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
  background: linear-gradient(to top, rgba(0,0,0,0.6), transparent);
}
.primary {
  appearance: none;
  border: none;
  padding: 0.9rem 1.4rem;
  border-radius: 999px;
  background: #1f6feb;
  color: white;
  font-size: 1rem;
  font-weight: 600;
}
.primary:disabled { background: #555; }
.status {
  color: #ddd;
  font-size: 0.9rem;
  background: rgba(0,0,0,0.4);
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
}

/* ---------- Code entry overlay (helper) ---------- */
.code-entry {
  position: fixed;
  inset: 0;
  z-index: 10;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.code-entry.hidden { display: none; }
.code-entry-card {
  width: 100%;
  max-width: 420px;
  background: #111;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  padding: 1.75rem;
  text-align: center;
}
.code-entry-card h2 { margin: 0 0 0.5rem; font-weight: 700; }
.code-entry-card p {
  color: #aaa;
  margin: 0 0 1.25rem;
  font-size: 0.95rem;
}
.code-entry-card input[type="text"] {
  width: 100%;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 2.2rem;
  font-weight: 700;
  letter-spacing: 0.25em;
  text-align: center;
  text-transform: uppercase;
  padding: 0.6rem 0.5rem;
  border-radius: 12px;
  border: 1px solid #333;
  background: #000;
  color: #fff;
  outline: none;
  margin-bottom: 1rem;
}
.code-entry-card input[type="text"]:focus {
  border-color: #1f6feb;
  box-shadow: 0 0 0 3px rgba(31, 111, 235, 0.25);
}
.code-entry-card .primary { width: 100%; }
.code-error {
  margin-top: 0.85rem;
  color: #ff7a7a;
  font-size: 0.9rem;
  min-height: 1.2em;
}
.code-error.hidden { display: none; }

/* ---------- Frozen-frame thumbnail (helper only) ----------
   Picture-in-picture reminder of what the display is currently showing the
   user. Sits above the toolbar so it's not obscured by it. */
.freeze-thumb {
  position: absolute;
  top: env(safe-area-inset-top, 12px);
  right: 12px;
  width: clamp(120px, 22vw, 220px);
  height: auto;
  z-index: 3;
  border-radius: 10px;
  border: 2px solid rgba(255, 45, 45, 0.85);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.55);
  background: #000;
  pointer-events: none;
}
.freeze-thumb.hidden { display: none; }

/* ---------- Freeze / Live toggle (helper only) ---------- */
.freeze-btn {
  appearance: none;
  border: none;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: #f5f5f5;
  background: rgba(0, 0, 0, 0.4);
  padding: 0.45rem 0.95rem;
  border-radius: 999px;
  transition: background 120ms ease-out, color 120ms ease-out;
}
.freeze-btn:hover { color: #fff; }
.freeze-btn[aria-pressed="true"] {
  background: rgba(255, 45, 45, 0.85);
  color: #fff;
}

/* ---------- Dot size slider (helper only) ---------- */
.size-control {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: #ddd;
  font-size: 0.9rem;
  background: rgba(0,0,0,0.4);
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
}
.size-control input[type="range"] {
  width: 140px;
  accent-color: #ff2d2d;
}
.size-value {
  font-variant-numeric: tabular-nums;
  min-width: 2ch;
  text-align: right;
  color: #f5f5f5;
}

/* ---------- Shape selector (helper only) ---------- */
.shape-control {
  display: inline-flex;
  gap: 0.2rem;
  background: rgba(0, 0, 0, 0.4);
  padding: 0.25rem;
  border-radius: 999px;
}
.shape-btn {
  appearance: none;
  border: none;
  background: transparent;
  color: #aaa;
  min-width: 34px;
  height: 38px;
  border-radius: 14px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0 6px;
  transition: background 120ms ease-out, color 120ms ease-out;
}
.shape-btn:hover { color: #fff; }
.shape-btn.active {
  background: rgba(255, 45, 45, 0.85);
  color: #fff;
}
.shape-btn svg { width: 20px; height: 20px; display: block; }
.shape-btn-tall svg { width: 22px; height: 14px; }
.shape-btn-label {
  font-size: 9px;
  line-height: 1;
  margin-top: 1px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* ---------- Display page: waiting overlay ----------
   Shown full-screen on the user-facing display while there is no live
   camera yet (Pi offline / connecting). Large and calm — the elderly user
   may glance at it. */
.waiting {
  position: fixed;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background: #000;
  text-align: center;
  padding: 2rem;
}
.waiting.hidden { display: none; }
.waiting-spinner {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 5px solid rgba(255, 255, 255, 0.15);
  border-top-color: #1f6feb;
  animation: waiting-spin 1s linear infinite;
}
@keyframes waiting-spin { to { transform: rotate(360deg); } }
.waiting-text {
  font-size: clamp(1.1rem, 4vw, 1.6rem);
  font-weight: 600;
  color: #ddd;
}

/* ---------- Display page: corner status badge ----------
   A small, unobtrusive connection indicator. Not meant to draw the user's
   attention — it's for whoever sets the device up. */
.display-status {
  position: fixed;
  bottom: env(safe-area-inset-bottom, 10px);
  left: 10px;
  z-index: 4;
  color: #888;
  font-size: 0.75rem;
  background: rgba(0, 0, 0, 0.45);
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  pointer-events: none;
}
