/* shell/gallery.css — keynote shell (grid · flip · ROI popover · unpack · mode toggle)
 *
 * Visual language extends docs/datadog-alert-iphone.html: glassy panels,
 * cubic-bezier easing, iOS chrome, Apple/Keynote polish.
 *
 * NOTE ON F03: the shared kit (shared/tokens.css, shared/frames.js) lands in
 * parallel. The token custom-property names and the .iphone-frame / .macbook-frame
 * class names below are the F03 contract — when F03 ships, these frame/token
 * blocks can be lifted into shared/ and imported. Kept shell-local here so the
 * shell is self-contained and serves with zero 404s before F03 exists.
 */

:root {
  color-scheme: dark;

  /* ---- type ---- */
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Segoe UI", Roboto, system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- palette (datadog-iPhone lineage: purple-anchored, deep space bg) ---- */
  --bg-0: #060509;
  --bg-1: #0b0a12;
  --ink:  #f4f2fb;
  --ink-dim:  #b7b2c8;
  --ink-faint:#7d778f;
  --line: rgba(255, 255, 255, 0.10);
  --line-strong: rgba(255, 255, 255, 0.18);

  --accent-purple:    #9B6FE0;
  --accent-purple-br: #C29BEE;

  /* ---- glass ---- */
  --glass-bg:   rgba(30, 27, 42, 0.55);
  --glass-bg-2: rgba(38, 34, 52, 0.72);
  --glass-blur: blur(22px) saturate(140%);
  --glass-brd:  rgba(255, 255, 255, 0.12);
  --shadow-card: 0 18px 40px -18px rgba(0, 0, 0, 0.7);
  --shadow-lift: 0 40px 90px -28px rgba(0, 0, 0, 0.82), 0 0 120px -40px rgba(155, 111, 224, 0.35);

  /* ---- motion ---- */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-out:    cubic-bezier(0.22, 0.9, 0.32, 1);
  --ease-inout:  cubic-bezier(0.4, 0, 0.2, 1);
  --dur-flip:  0.55s;
  --dur-unpack: 0.62s;

  /* radii / spacing */
  --r-card: 18px;
  --r-lg: 26px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

body {
  font-family: var(--sans);
  color: var(--ink);
  background:
    radial-gradient(1200px 800px at 50% -6%, rgba(155, 111, 224, 0.14) 0%, transparent 58%),
    radial-gradient(900px 900px at 50% 118%, #120f1c 0%, transparent 60%),
    var(--bg-0);
  overflow-x: hidden;
  min-height: 100%;
}

/* ============================================================= HEADER */
.gallery-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding: 34px clamp(24px, 4vw, 64px) 22px;
  max-width: 1920px;
  margin: 0 auto;
}
.gallery-header .titles h1 {
  font-size: clamp(24px, 2.2vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.gallery-header .titles .eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-purple-br);
  margin-bottom: 7px;
}
.gallery-header .titles p {
  color: var(--ink-dim);
  font-size: 14px;
  margin-top: 6px;
  max-width: 56ch;
}

/* ---- mode toggle (segmented control) ---- */
.mode-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-brd);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  position: relative;
  flex-shrink: 0;
}
.mode-toggle .seg {
  position: relative;
  z-index: 2;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: color 0.2s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.mode-toggle .seg svg { width: 15px; height: 15px; fill: currentColor; }
.mode-toggle .seg[aria-pressed="true"] { color: #fff; }
.mode-toggle .thumb {
  position: absolute;
  z-index: 1;
  top: 4px;
  bottom: 4px;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(155, 111, 224, 0.9), rgba(120, 80, 200, 0.9));
  box-shadow: 0 4px 14px -4px rgba(155, 111, 224, 0.8);
  transition: left var(--dur-flip) var(--ease-spring), width var(--dur-flip) var(--ease-spring);
}

/* ============================================================= GRID */
.wall {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(16px, 1.6vw, 26px);
  padding: 8px clamp(24px, 4vw, 64px) 72px;
  max-width: 1920px;
  margin: 0 auto;
  perspective: 1600px;
  transition: filter 0.5s var(--ease-out);
}
@media (max-width: 1180px) { .wall { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 860px)  { .wall { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .wall { grid-template-columns: repeat(1, 1fr); } }

/* ---- card ---- */
.card {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-card);
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  font-family: var(--sans);
  text-align: left;
  color: inherit;
  transform-style: preserve-3d;
  transition:
    transform 0.5s var(--ease-out),
    opacity 0.5s var(--ease-out),
    filter 0.5s var(--ease-out);
  --accent: var(--accent-purple);
  --accent-soft: rgba(155, 111, 224, 0.16);
}
.card:focus-visible { outline: none; }
.card:focus-visible .card-inner { box-shadow: 0 0 0 2px var(--accent-purple-br), var(--shadow-card); }

.card-inner {
  position: absolute;
  inset: 0;
  border-radius: var(--r-card);
  transform-style: preserve-3d;
  transition: transform var(--dur-flip) var(--ease-out);
}
/* flip on hover or keyboard focus */
.card:hover .card-inner,
.card:focus-within .card-inner { transform: rotateY(180deg); }

.card-face {
  position: absolute;
  inset: 0;
  border-radius: var(--r-card);
  padding: 16px 16px 15px;
  display: flex;
  flex-direction: column;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  overflow: hidden;
  background: var(--glass-bg);
  border: 1px solid var(--glass-brd);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-card);
}
/* accent wash keyed to the bucket, so the 2 cards of a bucket read as a pair */
.card-face::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 100% 0%, var(--accent-soft), transparent 55%);
  pointer-events: none;
}
.card-face--front { z-index: 2; }
.card-face--back {
  transform: rotateY(180deg);
  background: var(--glass-bg-2);
  justify-content: space-between;
}

.card .eyebrow {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 7px;
}
.card .eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px -1px var(--accent);
  flex-shrink: 0;
}
.card .card-title {
  font-size: clamp(15px, 1.1vw, 18px);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: 12px;
}
.card .card-title-back {
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  margin-bottom: 8px;
}
.card .card-pitch {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-dim);
  flex: 1;
}
.card .card-foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 12px;
}
.device-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-dim);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 9px;
}
.device-chip svg { width: 12px; height: 12px; fill: currentColor; opacity: 0.85; }
.card-foot .open-hint {
  margin-left: auto;
  font-size: 11px;
  color: var(--ink-faint);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}
.card:hover .open-hint { opacity: 1; transform: translateX(0); }

/* back face: pitch + ROI icon button */
.card-face--back .back-body { position: relative; z-index: 1; }
.roi-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  padding: 7px 12px 7px 9px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: rgba(255, 255, 255, 0.07);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  position: relative;
  z-index: 3;
  transition: transform 0.12s var(--ease-out), border-color 0.15s, background 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.roi-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.roi-btn:active { transform: scale(0.95); }
.roi-btn .roi-glyph {
  width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent);
  color: #fff; flex-shrink: 0;
}
.roi-btn .roi-glyph svg { width: 12px; height: 12px; fill: currentColor; }

/* ---- keynote "live thumbnail" preview back face ---- */
.card-face--preview { padding: 13px 13px 12px; }
.card-preview {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.card-preview .cp-top { display: flex; align-items: flex-start; gap: 8px; }
.card-preview .card-title-back { margin: 0; flex: 1; line-height: 1.2; }
.cp-live {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 9px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent);
}
.cp-live .dot { width: 6px; height: 6px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 8px #4ade80; }
.card:hover .cp-live .dot,
.card:focus-within .cp-live .dot { animation: cp-blink 1.6s var(--ease-inout) infinite; }

.cp-map {
  flex: 1 1 auto;
  min-height: 62px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--line);
  background:
    radial-gradient(120% 100% at 46% 30%, var(--accent-soft), transparent 62%),
    rgba(255, 255, 255, 0.03);
}
.cp-map svg { display: block; width: 100%; height: 100%; }
.cp-land { fill: rgba(160, 180, 230, 0.06); stroke: var(--line-strong); stroke-width: 0.35; stroke-linejoin: round; }
.cp-arc { fill: none; stroke: var(--accent); stroke-width: 0.5; opacity: 0.42; stroke-linecap: round; }
.cp-pulse {
  fill: none; stroke: var(--accent); stroke-width: 1.1; stroke-linecap: round;
  stroke-dasharray: 8 92; stroke-dashoffset: 100; opacity: 0;
  filter: drop-shadow(0 0 1.6px var(--accent));
}
.cp-node .cp-halo {
  fill: none; stroke: var(--accent); stroke-width: 0.5; opacity: 0;
  transform-box: fill-box; transform-origin: center;
}
.cp-node .cp-core { fill: var(--accent); stroke: #eef2ff; stroke-width: 0.3; }
.cp-node.is-hot .cp-core { fill: #fff; filter: drop-shadow(0 0 2.4px var(--accent)); }
/* animate only while the card is engaged (hover / keyboard focus) */
.card:hover .cp-pulse,
.card:focus-within .cp-pulse { opacity: 0.95; animation: cp-dash 1.9s linear infinite; }
.card:hover .cp-node .cp-halo,
.card:focus-within .cp-node .cp-halo { animation: cp-ping 2.6s var(--ease-out) infinite; animation-delay: calc(var(--i) * 0.22s); }

.cp-stats { display: flex; gap: 6px; }
.cp-stat {
  flex: 1; text-align: center;
  border: 1px solid var(--line); border-radius: 9px;
  background: rgba(255, 255, 255, 0.04);
  padding: 5px 4px; font-size: 9.5px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cp-stat b { display: block; font-size: 14px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); }
.cp-roi {
  font-size: 11px; font-weight: 700; letter-spacing: -0.005em; text-align: center;
  color: var(--accent);
  padding: 6px 8px; border-radius: 9px;
  background: var(--accent-soft); border: 1px solid var(--line);
}
.cp-foot {
  position: relative; z-index: 3;
  margin-top: 10px;
  display: flex; align-items: center; gap: 8px;
}
.card-face--preview .roi-btn { margin-top: 0; }
.cp-cta {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 700; color: var(--ink-dim);
}
.cp-cta svg { width: 13px; height: 13px; fill: currentColor; }

@keyframes cp-dash { to { stroke-dashoffset: 0; } }
@keyframes cp-ping { 0% { transform: scale(0.5); opacity: 0.5; } 70% { opacity: 0; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes cp-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ============================================================= PRODUCT SHOT
 * Keynote "floating device" preview: a real screenshot of the module UI
 * floating inside a mini iPhone/MacBook over a soft shadow. Resting view =
 * title + device; on hover the device slides aside and a details block reveals.
 * These cards do NOT flip. */
.card--shot .card-inner { transform: none !important; }
.card-face--shot {
  /* inherits position:absolute; inset:0 from .card-face so it fills the whole
   * card — that lets .shot-stage (flex:1) vertically center a short landscape
   * device instead of it sticking to the top */
  padding: 15px 14px 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  isolation: isolate; /* self-contained stacking so .shot-details always sits on top */
}
.shot-head { position: relative; z-index: 4; } /* title stays crisp above the hover frost */
.card-face--shot .card-title { margin-top: 6px; }

.shot-stage {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-height: 0;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
/* keynote spotlight behind the device, in the domain accent (not mono-violet) */
.shot-stage::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(58% 52% at 50% 44%, var(--accent-soft), transparent 72%);
  pointer-events: none;
}
.shot-shadow {
  position: absolute; z-index: 0;
  bottom: 6%; left: 50%; transform: translateX(-50%);
  width: 42%; height: 18px; border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.62), transparent 72%);
  filter: blur(9px);
  transition: width 0.42s var(--ease-out), opacity 0.42s var(--ease-out), bottom 0.42s var(--ease-out);
}

.card-device {
  position: relative; z-index: 1;
  transform-origin: center center;
  transition: transform 0.5s var(--ease-out);
}
/* portrait (4:5) card: both devices sized by WIDTH so they fill the tall card */
.card-device--iphone { width: 47%; }
.card-device--mac { width: 96%; }
.device-float {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}

/* mini iPhone (screenshot already carries the notch) — width-driven to fill the
 * tall portrait card; height follows from the aspect ratio */
.mini-phone {
  position: relative;
  width: 100%; aspect-ratio: 390 / 844;
  background: #050506;
  border-radius: 24px;
  box-shadow: 0 0 0 2px #24222b, 0 22px 38px -16px rgba(0, 0, 0, 0.8);
}
.mini-phone .mini-screen {
  position: absolute; inset: 5px;
  border-radius: 20px; overflow: hidden;
  background: #0a0817;
}

/* mini MacBook */
.mini-mac { width: 100%; display: flex; flex-direction: column; align-items: center; }
.mini-mac .mini-lid {
  position: relative;
  width: 100%; aspect-ratio: 16 / 10;
  background: #050506;
  border-radius: 10px 10px 3px 3px;
  padding: 6px;
  box-shadow: 0 0 0 2px #24222b, 0 20px 34px -16px rgba(0, 0, 0, 0.78);
}
.mini-mac .mini-camera {
  position: absolute; top: 3px; left: 50%; transform: translateX(-50%);
  width: 3px; height: 3px; border-radius: 50%; background: #1a1820;
}
.mini-mac .mini-screen {
  width: 100%; height: 100%;
  border-radius: 4px; overflow: hidden; background: #0a0817;
}
.mini-mac .mini-base {
  width: 112%; height: 7px;
  background: linear-gradient(180deg, #3a3744 0%, #201e28 55%, #14121a 100%);
  border-radius: 0 0 8px 8px;
  box-shadow: 0 14px 22px -14px rgba(0, 0, 0, 0.8);
}
.shot-img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }

/* hover / focus: device lifts a touch (the glass scrim fades up over the lower
 * card beneath it) + a gentle "schwebend" bob */
.card--shot:hover .card-device,
.card--shot:focus-within .card-device { transform: translateY(-6%); }
.card--shot:hover .shot-shadow,
.card--shot:focus-within .shot-shadow { width: 50%; bottom: 3%; opacity: 0.72; }
.card--shot:hover .device-float,
.card--shot:focus-within .device-float { animation: shot-bob 3.2s var(--ease-inout) infinite; }
@keyframes shot-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }

/* hover-revealed details: a light frosted-glass sheet over the WHOLE card, so
 * the device screenshot stays faintly visible through it. Kept low-intensity
 * (light tint + soft blur) on purpose; the brief description + inline ROI +
 * actions sit at the bottom. Absolute overlay — never moves the device. */
.shot-details {
  position: absolute; inset: 0; z-index: 3;
  padding: 15px 15px 15px;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 8px;
  /* mostly-uniform light frost, a touch denser at the bottom for text contrast */
  background: linear-gradient(
    180deg,
    rgba(15, 13, 24, 0.30) 0%,
    rgba(15, 13, 24, 0.34) 60%,
    rgba(15, 13, 24, 0.58) 100%);
  -webkit-backdrop-filter: blur(3px) saturate(1.05);
  backdrop-filter: blur(3px) saturate(1.05);
  border-radius: var(--r-card);
  opacity: 0; pointer-events: none;
  transition: opacity 0.4s var(--ease-out);
}
.card--shot:hover .shot-details,
.card--shot:focus-within .shot-details {
  opacity: 1; pointer-events: auto;
}
.shot-desc { font-size: 12px; line-height: 1.42; color: var(--ink-dim); }
.shot-roi-line {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 700; letter-spacing: -0.005em;
  color: var(--accent);
}
.shot-roi-line .roi-spark { display: inline-flex; flex-shrink: 0; }
.shot-roi-line .roi-spark svg { width: 13px; height: 13px; fill: currentColor; }
.shot-foot { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.card-face--shot .roi-btn { margin-top: 0; }
.shot-cta {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 700; color: var(--ink-dim);
}
.shot-cta svg { width: 13px; height: 13px; fill: currentColor; }

/* ---- ROI popover ---- */
.roi-popover {
  position: fixed;
  z-index: 200;
  width: 264px;
  padding: 15px 16px 16px;
  border-radius: 16px;
  background: var(--glass-bg-2);
  border: 1px solid var(--line-strong);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.8);
  opacity: 0;
  transform: translateY(8px) scale(0.96);
  transform-origin: top left;
  transition: opacity 0.24s var(--ease-out), transform 0.28s var(--ease-spring);
  pointer-events: none;
}
.roi-popover[data-open="true"] { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.roi-popover .roi-head {
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent-purple-br); margin-bottom: 11px;
}
.roi-popover ul { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.roi-popover li {
  display: flex; gap: 9px; font-size: 12.5px; line-height: 1.42; color: var(--ink);
}
.roi-popover li .num {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 800; color: #fff;
  background: var(--accent-purple); margin-top: 1px;
}
/* brief-highlight variant: punchy headline + short metric fragments */
.roi-popover .roi-headline {
  font-size: 15px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2;
  color: #fff; margin-bottom: 11px;
}
.roi-popover ul.roi-brief { gap: 8px; }
.roi-popover .roi-brief li { align-items: center; font-size: 12px; color: var(--ink-dim); }
.roi-popover .roi-brief li .tick {
  flex-shrink: 0; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-purple-br);
  box-shadow: 0 0 8px -1px var(--accent-purple-br);
}

/* ============================================================= DOMAIN FILTER */
/* one pill in the header (same glass/pill language as the mode toggle) that
 * opens a compact glass menu of buckets — low-footprint, no wall chrome added. */
.header-tools { display: inline-flex; align-items: center; gap: 12px; flex-shrink: 0; }

.filter { position: relative; }
.filter-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 15px; border-radius: 999px;
  background: var(--glass-bg); border: 1px solid var(--glass-brd);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  color: var(--ink-dim); font-family: var(--sans); font-size: 13px; font-weight: 600;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}
.filter-pill:hover { color: #fff; }
.filter-pill .fl-glyph { display: inline-flex; }
.filter-pill .fl-glyph svg { width: 15px; height: 15px; fill: currentColor; }
.filter-pill .fl-label { max-width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-pill.is-active { color: #fff; border-color: rgba(155, 111, 224, 0.55); }
.filter-pill.is-active .fl-glyph { color: var(--accent-purple-br); }

.filter-menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 210;
  width: 268px; max-height: min(62vh, 470px); overflow-y: auto;
  padding: 6px; border-radius: 16px;
  background: var(--glass-bg-2); border: 1px solid var(--line-strong);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.8);
  opacity: 0; transform: translateY(-6px) scale(0.98); transform-origin: top right;
  transition: opacity 0.22s var(--ease-out), transform 0.26s var(--ease-spring);
  pointer-events: none;
}
.filter-menu[data-open="true"] { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.filter-opt {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border: 0; background: transparent; border-radius: 10px;
  color: var(--ink-dim); font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  text-align: left; cursor: pointer;
  transition: background 0.16s var(--ease-out), color 0.16s var(--ease-out);
}
.filter-opt:hover { background: rgba(255, 255, 255, 0.06); color: #fff; }
.filter-opt .fo-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; box-shadow: 0 0 8px -1px currentColor; }
.filter-opt .fo-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-opt .fo-check { flex-shrink: 0; display: inline-flex; opacity: 0; transition: opacity 0.16s var(--ease-out); }
.filter-opt .fo-check svg { width: 14px; height: 14px; fill: var(--accent-purple-br); }
.filter-opt[aria-checked="true"] { color: #fff; }
.filter-opt[aria-checked="true"] .fo-check { opacity: 1; }

/* ============================================================= REORDER (iOS lift) */
.card--filtered-out { display: none !important; }

body.is-reordering { cursor: grabbing; -webkit-user-select: none; user-select: none; }

/* jiggle every remaining card, iOS edit-mode style (alternate phase per card) */
.wall--reordering .card { animation: card-jiggle-a 0.24s var(--ease-inout) infinite; will-change: transform; }
.wall--reordering .card:nth-child(2n) { animation-name: card-jiggle-b; animation-duration: 0.26s; }
.wall--reordering .card:nth-child(3n) { animation-duration: 0.22s; }
@keyframes card-jiggle-a {
  0%, 100% { transform: rotate(-0.9deg) translate(-0.5px, 0.4px); }
  50%      { transform: rotate(0.9deg)  translate(0.5px, -0.4px); }
}
@keyframes card-jiggle-b {
  0%, 100% { transform: rotate(0.9deg)  translate(0.5px, -0.4px); }
  50%      { transform: rotate(-0.9deg) translate(-0.5px, 0.4px); }
}

/* dotted drop-target that occupies the grid cell where the card will land */
.drop-placeholder {
  aspect-ratio: 4 / 5;
  border-radius: var(--r-card);
  border: 2px dashed var(--accent-purple-br);
  background: rgba(155, 111, 224, 0.07);
  pointer-events: none;
  animation: ph-breathe 1.5s var(--ease-inout) infinite;
}
@keyframes ph-breathe {
  0%, 100% { opacity: 0.72; box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.7), inset 0 0 22px -8px rgba(155, 111, 224, 0.22); }
  50%      { opacity: 1;    box-shadow: 0 22px 50px -18px rgba(0, 0, 0, 0.78), inset 0 0 30px -4px rgba(155, 111, 224, 0.38); }
}

/* the small floating "icon of the selected card" that follows the cursor */
.drag-ghost {
  position: fixed; z-index: 320; left: 0; top: 0;
  width: 172px; padding: 8px 8px 9px;
  transform: translate(-50%, -64%) rotate(-3deg);
  border-radius: 16px;
  background: var(--glass-bg-2); border: 1px solid var(--line-strong);
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: 0 30px 60px -18px rgba(0, 0, 0, 0.85), 0 0 90px -30px rgba(155, 111, 224, 0.5);
  pointer-events: none;
  animation: ghost-pop 0.16s var(--ease-out);
}
@keyframes ghost-pop {
  from { opacity: 0; transform: translate(-50%, -64%) rotate(-3deg) scale(0.82); }
  to   { opacity: 1; transform: translate(-50%, -64%) rotate(-3deg) scale(1); }
}
.drag-ghost .dg-thumb {
  width: 100%; aspect-ratio: 16 / 10;
  border-radius: 9px; overflow: hidden; background: #0a0817;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  display: flex; align-items: center; justify-content: center;
}
.drag-ghost .dg-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.drag-ghost .dg-glyph { display: inline-flex; }
.drag-ghost .dg-glyph svg { width: 32px; height: 32px; fill: var(--accent-purple-br); }
.drag-ghost .dg-title {
  display: block; margin-top: 7px; padding: 0 2px;
  font-size: 11px; font-weight: 700; letter-spacing: -0.005em; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* settle bounce when a card lands in its new slot */
.card--dropped { animation: card-drop 0.36s var(--ease-spring); }
@keyframes card-drop {
  0%   { transform: scale(0.9); }
  60%  { transform: scale(1.03); }
  100% { transform: scale(1); }
}

/* ============================================================= FOCUS / UNPACK */
/* recede state on the wall when a card is unpacked */
.gallery[data-focused] .wall { filter: saturate(0.6) brightness(0.5); }
.gallery[data-focused] .card:not(.card--source) {
  transform: scale(0.9) translateZ(-120px);
  opacity: 0.28;
  filter: blur(2px);
  pointer-events: none;
}
.gallery[data-focused] .card.card--source { opacity: 0; }

.stage-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: radial-gradient(1200px 900px at 50% 40%, rgba(20, 16, 34, 0.55), rgba(4, 3, 8, 0.92));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.5s var(--ease-out);
  pointer-events: none;
}
.stage-backdrop[data-open="true"] { opacity: 1; pointer-events: auto; }

.stage-close {
  position: fixed;
  top: 26px; right: 28px;
  z-index: 130;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px 9px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--glass-bg-2);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: var(--ink);
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  cursor: pointer;
  opacity: 0; transform: translateY(-8px);
  transition: opacity 0.35s var(--ease-out) 0.15s, transform 0.35s var(--ease-out) 0.15s;
  pointer-events: none;
}
.stage-close svg { width: 15px; height: 15px; fill: currentColor; }
.gallery[data-focused] .stage-close { opacity: 1; transform: translateY(0); pointer-events: auto; }

.stage-caption {
  position: fixed;
  left: 50%;
  bottom: 34px;
  transform: translateX(-50%);
  z-index: 120;
  text-align: center;
  opacity: 0;
  transition: opacity 0.4s var(--ease-out) 0.25s;
  pointer-events: none;
}
.gallery[data-focused] .stage-caption { opacity: 1; }
.stage-caption .cap-eyebrow {
  font-size: 11px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent-purple-br); margin-bottom: 5px;
}
.stage-caption .cap-title { font-size: 17px; font-weight: 700; }
.stage-caption .cap-hint { font-size: 12px; color: var(--ink-faint); margin-top: 8px; }
.stage-caption kbd {
  font-family: var(--mono); font-size: 11px;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 6px; color: var(--ink-dim);
}

/* ============================================================= PRESENTER HUD
 * F14 guided-tour pacing readout. Glassy pill, top-center, only in guided mode.
 * Sits above the grid; non-interactive (keyboard drives the tour). */
.presenter {
  position: fixed;
  left: 50%;
  top: 22px;
  transform: translateX(-50%) translateY(-14px);
  z-index: 130;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--glass-bg-2);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-brd);
  box-shadow: var(--shadow-card);
  font-size: 13px;
  color: var(--ink-dim);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-spring);
}
.gallery[data-mode="guided"] .presenter {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.presenter .pace-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-purple-br);
  box-shadow: 0 0 10px 1px rgba(194, 155, 238, 0.7);
  animation: pace-pulse 2s var(--ease-inout) infinite;
}
@keyframes pace-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.presenter .pace-label {
  font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  font-size: 11px; color: var(--accent-purple-br);
}
.presenter .pace-count {
  font-family: var(--mono); font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.presenter .pace-title {
  max-width: 30ch; overflow: hidden; text-overflow: ellipsis;
  color: var(--ink); font-weight: 600;
}
.presenter .pace-hint {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--ink-faint);
  padding-left: 12px; margin-left: 2px;
  border-left: 1px solid var(--line);
}
.presenter .pace-hint svg { width: 13px; height: 13px; fill: currentColor; }
.presenter kbd {
  font-family: var(--mono); font-size: 11px;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 6px; color: var(--ink-dim);
}

/* device host wrapper — the element we FLIP from card rect to center */
.stage-frame {
  position: fixed;
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  will-change: transform;
  transform-origin: center center;
}

/* ============================================================= DEVICE FRAMES (F03 contract) */
/* .iphone-frame / .macbook-frame — shell-local until F03's shared/frames.js lands */
.iphone-frame {
  position: relative;
  height: 78vh;
  max-height: 780px;
  aspect-ratio: 390 / 844;
  background: #050506;
  border-radius: 52px;
  padding: 12px;
  box-shadow:
    0 0 0 2px #24222b,
    0 2px 3px 3px #000 inset,
    var(--shadow-lift);
}
.iphone-frame::before, .iphone-frame::after {
  content: ""; position: absolute; background: #1a1820; border-radius: 2px;
}
.iphone-frame::before { left: -3px; top: 140px; width: 3px; height: 32px; box-shadow: 0 50px 0 #1a1820, 0 104px 0 #1a1820; }
.iphone-frame::after { right: -3px; top: 178px; width: 3px; height: 80px; }
.iphone-frame .device-screen {
  position: relative;
  height: 100%; width: 100%;
  border-radius: 42px;
  overflow: hidden;
  background: linear-gradient(165deg, #241a3f 0%, #141029 45%, #0a0817 78%, #050409 100%);
}
.iphone-frame .island {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  width: 34%; height: 28px; background: #000; border-radius: 20px; z-index: 40;
}

.macbook-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(84vw, 1040px);
}
.macbook-frame .lid {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: #050506;
  border-radius: 20px 20px 8px 8px;
  padding: 14px 14px 16px;
  box-shadow: 0 0 0 2px #24222b, var(--shadow-lift);
}
.macbook-frame .camera {
  position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: #1a1820;
}
.macbook-frame .device-screen {
  position: relative;
  height: 100%; width: 100%;
  border-radius: 8px;
  overflow: hidden;
  background: linear-gradient(160deg, #1b1730 0%, #12102a 48%, #0a0817 100%);
}
.macbook-frame .base {
  width: 116%;
  height: 15px;
  background: linear-gradient(180deg, #3a3744 0%, #201e28 55%, #14121a 100%);
  border-radius: 0 0 14px 14px;
  box-shadow: 0 24px 40px -20px rgba(0, 0, 0, 0.8);
  position: relative;
}
.macbook-frame .base::after {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 15%; height: 6px; border-radius: 0 0 8px 8px;
  background: #0c0b12;
}

/* the module's mount target fills the device screen */
.device-screen .module-root {
  position: absolute;
  inset: 0;
  overflow: auto;
  color: var(--ink);
}
.device-screen .module-root::-webkit-scrollbar { display: none; }

/* placeholder shown if a module import fails */
.module-fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center; padding: 30px;
  color: var(--ink-dim);
}
.module-fallback .mf-title { font-size: 16px; font-weight: 700; color: #fff; }

/* stub-module styling (cases ship .case-stub markup) */
.case-stub { padding: 26px 24px; display: flex; flex-direction: column; gap: 10px; height: 100%; }
.case-stub__badge {
  align-self: flex-start;
  font-size: 10px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent-purple-br);
  background: rgba(155, 111, 224, 0.16); border: 1px solid rgba(155, 111, 224, 0.3);
  border-radius: 6px; padding: 3px 8px;
}
.case-stub h2 { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }
.case-stub p { font-size: 14px; line-height: 1.5; color: var(--ink-dim); }

/* ============================================================= REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  /* flip on hover still works but is instant; still legible */
}

/* ============================================================= MOBILE / TOUCH
 * Everything below is scoped to (hover:none) and/or a small-width query so the
 * desktop rendering is byte-for-byte unchanged. Touch has no hover and no Esc,
 * so we surface the ROI bar without hover, make "Back" the close affordance,
 * and keep the product shot the hero on a narrow screen. */

/* snappier taps + no double-tap zoom on interactive chrome (harmless on desktop) */
.card,
.roi-btn,
.filter-pill,
.filter-opt,
.mode-toggle .seg,
.stage-close,
.shot-cta { touch-action: manipulation; }

/* caption hint: keyboard wording is default; the touch variant is hidden until (hover:none) */
.stage-caption .cap-hint .hint-touch { display: none; }

@media (hover: none) {
  .stage-caption .cap-hint .hint-desktop { display: none; }
  .stage-caption .cap-hint .hint-touch { display: inline; }

  /* No hover to reveal the frost → show each card's ROI as a persistent, LIGHT
   * bottom bar. Lose the full-card blur/tint so the real product shot still reads;
   * keep the sheet click-through (pointer-events:none) so a tap opens the case,
   * and re-enable only the ROI button so it can pop its brief. */
  .card--shot .shot-details {
    opacity: 1;
    pointer-events: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    justify-content: flex-end;
    background: linear-gradient(
      180deg,
      transparent 0%,
      transparent 44%,
      rgba(15, 13, 24, 0.52) 74%,
      rgba(15, 13, 24, 0.86) 100%);
  }
  .card--shot .shot-desc { display: none; }             /* keep the bar tight; shot is the hero */
  .card--shot .shot-details .roi-btn { pointer-events: auto; }
  .card--shot .device-float { animation: none !important; } /* idle bob never fires on touch */

  /* lock the wall behind an open case so it can't scroll under the overlay */
  body.case-open { overflow: hidden; }
}

@media (max-width: 560px) {
  /* header: stack, drop the desktop lede, keep filter + toggle on one tidy row */
  .gallery-header {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    padding: 20px 18px 14px;
  }
  .gallery-header .titles p { display: none; }
  /* wrap instead of overflowing: the mode-toggle is wider than one narrow row,
   * so the filter fills line 1 and the toggle drops to line 2 (both full-width) */
  .header-tools { width: 100%; flex-wrap: wrap; gap: 10px; }
  .filter { flex: 1 1 100%; display: flex; }
  .filter-pill { flex: 1; min-width: 0; justify-content: center; }
  .filter-pill .fl-label { max-width: none; }
  .mode-toggle { flex: 1 1 100%; justify-content: center; }

  .wall { padding: 6px 16px 56px; gap: 16px; }

  /* the MacBook module is inherently laptop-shaped — give it back some width */
  .macbook-frame { width: 94vw; }
  .iphone-frame { height: 74vh; }

  /* bigger, unmistakable close affordance (there is no Esc key on a phone) */
  .stage-close {
    top: 16px; right: 16px;
    padding: 11px 16px 11px 13px;
    font-size: 14px;
  }
  .stage-caption { bottom: 18px; width: max-content; max-width: 92vw; }
  .stage-caption .cap-title { font-size: 15px; }
  .stage-caption .cap-hint { margin-top: 6px; }

  /* filter menu: fit a narrow screen with comfortable tap targets */
  .filter-menu { width: min(78vw, 300px); max-height: 62vh; overflow-y: auto; }
  .filter-opt { padding: 11px 12px; font-size: 13px; }
  .roi-btn { min-height: 40px; }
}
