/* =====================================================================
   EasyDebug motion + art-direction layer (award-tier pass)
   Big idea: "Every failure, replayed." EasyDebug is a flight recorder for one
   Spring Boot app, so motion speaks in clocks, playheads and time bars.
   Rules: only transform / opacity / clip-path animate. Linear easing is
   reserved for things that ARE time (clocks, timeout bars, playhead).
   Everything hidden before reveal is gated behind html.motion, which is only
   set when prefers-reduced-motion is not "reduce" (see inline script).
   ===================================================================== */
@font-face{font-family:"Departure Mono";src:url(assets/fonts/DepartureMono-Regular.woff2) format("woff2");font-display:swap;font-weight:400}

:root{
  /* ---- motion tokens (single source of truth, mirrored in motion.js) ---- */
  --ease-out:cubic-bezier(.16,1,.3,1);      /* entrances, settles (expo out) */
  --ease-out-2:cubic-bezier(.22,1,.36,1);   /* UI state swaps (quint out) */
  --ease-inout:cubic-bezier(.65,0,.35,1);   /* line draws, wipes */
  --ease-time:linear;                        /* clocks, timeouts, playheads only */
  --dur-1:.18s;   /* hover, press, focus */
  --dur-2:.45s;   /* state swaps inside product UI */
  --dur-3:.9s;    /* entrances */
  --dur-4:1.4s;   /* line draws */
  --stagger:.06s; /* lists, trace lines */
  --stagger-2:.12s;/* cards, story beats */
  --dist-1:12px; --dist-2:28px;
  /* ---- type ---- */
  --pixel:"Departure Mono", var(--mono);
  /* ---- light ---- */
  --glow-amber:rgba(235,161,58,.10);
  --glow-red:rgba(229,83,75,.16);
}

/* ---------- art direction: texture, light, type tuning ---------- */
::selection{background:var(--accent);color:var(--accent-ink)}
html{scrollbar-color:var(--line-2) var(--bg)}
body::after{ /* film grain: fixed, non-interactive, never on a scrolling layer */
  content:"";position:fixed;inset:0;pointer-events:none;z-index:50;opacity:.045;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
h1,h2{text-wrap:balance}
.body,.lede,.card p{text-wrap:pretty}
h1{font-size:clamp(38px,2.2rem + 2.4vw,64px);letter-spacing:-.045em;line-height:1.02;font-weight:750}
.h1-a{color:var(--text-2)}
h2{letter-spacing:-.035em}
.eyebrow{font-family:var(--pixel);font-weight:400;letter-spacing:.08em}
.num{font-variant-numeric:tabular-nums}

/* hero light: amber wash behind the mock, red wash arrives with the 500 */
.hero{position:relative;isolation:isolate}
.hero::before,.hero::after{content:"";position:absolute;z-index:-1;pointer-events:none;inset:auto -10% -20% 30%;height:85%;
  background:radial-gradient(50% 55% at 60% 55%,var(--glow-amber),transparent 70%)}
.hero::after{background:radial-gradient(40% 45% at 62% 52%,var(--glow-red),transparent 70%);opacity:1;transition:opacity var(--dur-4) var(--ease-out)}
.motion .hero:not(:has(.hero-app.resolved))::after{opacity:0}

/* ---------- shared state-swap primitive (pending -> final, zero layout shift) ---------- */
.swap{display:grid}
.swap>*{grid-area:1/1}
.s-pend{color:var(--text-3);background:var(--surface-2);letter-spacing:.1em}
.badge-pend{color:var(--text-3);border-color:var(--line-2);background:var(--surface-2)}
.s-pend,.badge-pend,.rd-meta-pend{opacity:0} /* default (no motion / no JS): final state only */
.rd-meta-swap{display:grid}

/* ---------- micro-interactions (only real interactive elements) ---------- */
.btn{transition:background-color var(--dur-1) var(--ease-out-2),border-color var(--dur-1) var(--ease-out-2),transform var(--dur-1) var(--ease-out-2)}
.btn:active{transform:translateY(1px) scale(.985)}
.btn .ico{transition:transform var(--dur-1) var(--ease-out-2)}
.btn-ghost:hover .ico{transform:translateX(3px)}
.btn-primary:hover .ico{transform:rotate(-8deg) scale(1.06)}
.nav-links a,.foot nav a{position:relative}
.nav-links a::after,.foot nav a::after{content:"";position:absolute;left:0;right:0;bottom:-4px;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:right;transition:transform var(--dur-2) var(--ease-out)}
.nav-links a:hover::after,.foot nav a:hover::after,.nav-links a:focus-visible::after{transform:scaleX(1);transform-origin:left}
.tab-labels label{transition:color var(--dur-1) var(--ease-out-2)}
.tab-labels label:hover{color:var(--text)}
.motion .pane{animation:pane-in var(--dur-2) var(--ease-out) both}
@keyframes pane-in{from{opacity:0;transform:translateY(4px)}}
.copy-btn{position:relative;background:transparent;cursor:pointer;font:inherit;transition:border-color var(--dur-1) var(--ease-out-2),transform var(--dur-1) var(--ease-out-2)}
.copy-btn:hover{border-color:var(--text-3);color:var(--text)}
.copy-btn:active{transform:scale(.92)}
.copy-btn:focus-visible,.replay:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.copy-tip{position:absolute;right:0;bottom:calc(100% + 8px);font:600 11px/1 var(--mono);color:var(--accent-ink);background:var(--accent);border-radius:var(--r-chip);padding:6px 8px;white-space:nowrap;
  opacity:0;transform:translateY(4px);pointer-events:none;transition:opacity var(--dur-1) var(--ease-out-2),transform var(--dur-2) var(--ease-out)}
.copy-btn.copied .copy-tip{opacity:1;transform:none}
.replay{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;margin-left:8px;border:1px solid var(--line-2);border-radius:var(--r-chip);background:transparent;
  color:var(--text-2);font:600 10.5px/1 var(--mono);letter-spacing:.04em;text-transform:uppercase;cursor:pointer;transition:border-color var(--dur-1) var(--ease-out-2),color var(--dur-1) var(--ease-out-2)}
html:not(.motion) .replay{display:none}
.replay .ico{width:13px;height:13px;transition:transform var(--dur-2) var(--ease-out)}
.replay:hover{border-color:var(--text-3);color:var(--text)}
.replay:hover .ico{transform:rotate(-200deg)}
.replay:disabled{opacity:.45;cursor:default}
@media (max-width:767px){.motion .nav:has(#menu:target) .m-menu{animation:menu-in var(--dur-2) var(--ease-out) both}}
@keyframes menu-in{from{opacity:0;transform:translateY(-8px)}}

/* ---------- footer flourish ---------- */
.foot-mark{overflow:hidden;margin-top:var(--s7);user-select:none}
.foot-mark span{display:block;font:800 clamp(64px,17vw,250px)/.8 var(--sans);letter-spacing:-.065em;color:transparent;-webkit-text-stroke:1px var(--line-2);
  transform:translateY(12%);white-space:nowrap}

/* =====================================================================
   SIGNATURE: the replay section (scroll = request time)
   ===================================================================== */
.replay-sec{position:relative;border-top:1px solid var(--line);background:var(--bg)}
.replay-stage{padding:var(--s9) 0}
.replay-grid{display:grid;grid-template-columns:5fr 7fr;gap:var(--s8);align-items:center}
.replay-grid>*{min-width:0}
.replay-copy h2{max-width:12ch}
.readout{display:flex;align-items:baseline;gap:.08em;margin-top:var(--s6);font-family:var(--pixel);color:var(--text);line-height:.9;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.ro-num{font-size:clamp(72px,3rem + 6vw,148px)}
.ro-sign,.ro-unit{font-size:clamp(28px,1rem + 2vw,52px);color:var(--text-3)}
.replay-sec.is-failed .ro-num{color:#F07A73}
.beats{list-style:none;margin:var(--s6) 0 0;padding:0;display:grid;gap:14px;max-width:44ch}
.beat{display:grid;grid-template-columns:88px 1fr;gap:var(--s4);align-items:baseline;color:var(--text-2);font-size:16px;line-height:1.5}
.beat time{font:500 12.5px/1.5 var(--mono);color:var(--text-3)}
.beat b{color:var(--text);font-weight:650}
.wf{box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 40px 90px -40px rgba(0,0,0,.8)}
.wf-id{color:var(--text-2)}
.wf-body{padding:var(--s4) var(--s5) var(--s5)}
.wf-axis{position:relative;margin-left:calc(190px + 12px);margin-right:calc(70px + 12px);height:22px;color:var(--text-3);font-size:10.5px;border-bottom:1px solid var(--line)}
.wf-axis span{position:absolute;top:0;bottom:0;left:calc(var(--x)*100%);border-left:1px solid var(--line);padding-left:6px;white-space:nowrap}
.wf-axis span:last-child{border-left:0;border-right:1px solid var(--line);padding:0 6px 0 0;transform:translateX(-100%)}
.wf-rows{position:relative}
.wf-row{display:grid;grid-template-columns:190px minmax(0,1fr) 70px;gap:12px;align-items:center;height:48px;border-bottom:1px solid var(--line)}
.wf-name{display:flex;align-items:center;gap:8px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-child .wf-name{padding-left:18px}
.wf-track{position:relative;height:14px}
.wf-bar{position:absolute;left:0;top:0;bottom:0;width:calc(var(--w)*100%);min-width:3px;border-radius:3px;background:var(--line-2);transform-origin:left}
.wf-root .wf-bar{background:color-mix(in oklab,var(--text-3) 55%,transparent)}
.wf-ok{background:var(--ok)!important}
.wf-bad{background:repeating-linear-gradient(135deg,var(--err) 0 6px,#c4453e 6px 12px)!important}
.wf-limit{position:absolute;left:99.67%;top:-8px;bottom:-8px;width:0;border-left:1px dashed var(--err-line)}
.wf-row .swap{justify-self:end}
.wf-head{position:absolute;top:-22px;bottom:0;left:calc(190px + 12px);width:1px;background:var(--accent);opacity:0;pointer-events:none}
.wf-head::before{content:"";position:absolute;top:0;left:-4px;width:9px;height:9px;background:var(--accent);transform:rotate(45deg)}
.wf-out{margin-top:var(--s5)}
.wf-result{display:grid;gap:var(--s3)}
.wf-wait{display:flex;justify-content:space-between;gap:var(--s4);align-self:start;padding:12px 14px;border:1px dashed var(--line-2);border-radius:var(--r-ctl);color:var(--text-3);opacity:0}
.wf-wait b{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums}
.motion .replay-sec .wf-wait{opacity:1;transition:opacity var(--dur-2) var(--ease-out-2)}
.motion .replay-sec.is-failed .wf-wait{opacity:0}
.wf-result .rd-rule{margin:0}

/* =====================================================================
   MOTION-ONLY STATES (html.motion). Without it the page is fully static.
   ===================================================================== */

/* ---- P1 rise: blocks and cards ---- */
.motion .rv{opacity:0;transform:translateY(var(--dist-2));
  transition:opacity var(--dur-3) var(--ease-out),transform var(--dur-3) var(--ease-out);transition-delay:calc(var(--i,0) * var(--stagger-2))}
.motion .rv.in{opacity:1;transform:none}
/* ---- P2 wipe: headings reveal through a mask, not a slide ---- */
/* static overflow clip + transform on the inner span = compositor-only (clip-path repainted every frame) */
.motion h2.rv{opacity:1;transform:none;transition:none;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.motion h2.rv .h2-in{display:block;transform:translateY(105%);transition:transform var(--dur-3) var(--ease-out)}
.motion h2.rv.in .h2-in{transform:none}

/* ---- hero replay (auto, once, 2x speed: ~2.7 s; Replay button re-runs) ---- */
.motion .hero-app .s-pend,.motion .hero-app .badge-pend,.motion .hero-app .rd-meta-pend{opacity:1}
.motion .hero-app .s-final,.motion .hero-app .call-1 .t,.motion .hero-app .rd-late,.motion .hero-app .tl{opacity:0}
.motion .hero-app .s-pend,.motion .hero-app .badge-pend,.motion .hero-app .rd-meta-pend,.motion .hero-app .s-final,.motion .hero-app .rd-late,.motion .hero-app .tl,.motion .hero-app .call-1 .t{
  transition:opacity var(--dur-2) var(--ease-out-2),transform var(--dur-2) var(--ease-out)}
.motion .hero-app.run .s-pend{animation:pend 1s var(--ease-inout) infinite}
@keyframes pend{50%{opacity:.35}}
.motion .hero-app [data-clock]{contain:layout paint}
/* selected row + timed-out call: state wash lives on an overlay so only opacity animates */
.motion .hero-app .req.is-sel,.motion .hero-app .call-2{position:relative;background:transparent;box-shadow:none;border-color:var(--line)}
.motion .hero-app .req.is-sel::after,.motion .hero-app .call-2::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity var(--dur-2) var(--ease-out-2)}
.motion .hero-app .req.is-sel::after{background:var(--err-soft);box-shadow:inset 2px 0 0 var(--err)}
.motion .hero-app .call-2::after{inset:-1px;border:1px solid var(--err-line);border-radius:var(--r-ctl);background:var(--err-soft)}
/* the timeout clock: a 2px bar that fills linearly over the 3.00 s timeout, played at 2x (--hero-timeout set by motion.js) */
.motion .hero-app .call-2::before{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--err);transform:scaleX(0);transform-origin:left;opacity:.9;border-radius:2px}
.motion .hero-app.run .call-2::before{transform:scaleX(1);transition:transform var(--hero-timeout,1.5s) var(--ease-time)}
.motion .hero-app.c2 .call-2::before{opacity:0;transition:transform var(--hero-timeout,1.5s) var(--ease-time),opacity var(--dur-2) var(--ease-out-2)}
/* call 1 resolves fast */
.motion .hero-app.c1 .call-1 .s-pend{opacity:0;animation:none}
.motion .hero-app.c1 .call-1 .s-final,.motion .hero-app.c1 .call-1 .t{opacity:1}
/* call 2 times out */
.motion .hero-app.c2 .call-2 .s-pend{opacity:0;animation:none}
.motion .hero-app.c2 .call-2 .s-final,.motion .hero-app.c2 .call-2::after{opacity:1}
/* the 500 lands */
.motion .hero-app.resolved .req.is-sel .s-pend,.motion .hero-app.resolved .badge-pend,.motion .hero-app.resolved .rd-meta-pend{opacity:0;animation:none}
.motion .hero-app.resolved .req.is-sel .s-final,.motion .hero-app.resolved .rd-meta-swap .s-final,.motion .hero-app.resolved .req.is-sel::after{opacity:1}
.motion .hero-app .rd-badge .s-final{transform:scale(1.18)}
.motion .hero-app.resolved .rd-badge .s-final{opacity:1;transform:none;transition:opacity var(--dur-1) var(--ease-out-2),transform var(--dur-3) var(--ease-out)}
.motion .hero-app.resolved .rd-late{opacity:1;transition-delay:.15s}
.motion .hero-app.resolved .rd-sec.rd-late{transition-delay:.3s}
.motion .hero-app.resolved .tl{opacity:1;transition-delay:calc(.38s + var(--i) * var(--stagger))}
.rd-rule code{position:relative}
.motion .hero-app.resolved .rd-rule code::after,.motion .replay-sec.is-failed .rd-rule code::after{content:"";position:absolute;inset:-1px;border-radius:var(--r-chip);box-shadow:0 0 0 3px var(--accent-line);opacity:0;animation:flash 1.1s var(--ease-out) .35s 1 both}
@keyframes flash{30%{opacity:1}}

/* ---- problem: the afternoon draws itself ---- */
.motion .hunt{border-top-color:transparent;position:relative}
.motion .hunt::after{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--line-2);transform:scaleX(0);transform-origin:left;transition:transform var(--dur-4) var(--ease-inout)}
.motion .hunt li{opacity:0;transform:translateY(var(--dist-1));transition:opacity var(--dur-3) var(--ease-out),transform var(--dur-3) var(--ease-out);transition-delay:calc(.2s + var(--i) * .26s)}
.motion .hunt li::before{transform:rotate(45deg) scale(0);transition:transform var(--dur-2) var(--ease-out);transition-delay:calc(.2s + var(--i) * .26s)}
.motion .hunt-wrap.in .hunt::after{transform:none}
.motion .hunt-wrap.in .hunt li{opacity:1;transform:none}
.motion .hunt-wrap.in .hunt li::before{transform:rotate(45deg) scale(1)}
.hunt li:last-child::after{content:"";position:absolute;top:-5px;left:0;width:9px;height:9px;border:1px solid var(--err);transform:rotate(45deg);opacity:0;pointer-events:none}
.motion .hunt-wrap.in .hunt li:last-child::after{animation:ring 1.2s var(--ease-out) 1.25s 1 both}
@keyframes ring{0%{opacity:.9;transform:rotate(45deg) scale(1)}100%{opacity:0;transform:rotate(45deg) scale(3.2)}}
.motion .answer.rv .answer-row{opacity:0;transform:translateX(var(--dist-1));transition:opacity var(--dur-3) var(--ease-out) .3s,transform var(--dur-3) var(--ease-out) .3s}
.motion .answer.rv.in .answer-row{opacity:1;transform:none}

/* ---- features: each card tells its piece of the same incident ---- */
.motion .c-http.rv .sr{opacity:0;transform:translateX(-8px);transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out);transition-delay:calc(.35s + var(--i) * var(--stagger-2))}
.motion .c-http.rv.in .sr{opacity:1;transform:none}
.bars-wrap{position:relative;display:block;overflow:hidden}
.bars-wrap .bars{display:block}
.motion .bars-wrap::after{content:"";position:absolute;inset:0;background:var(--bg-2);transform-origin:right;transition:transform var(--dur-4) var(--ease-inout) .3s}
.motion .c-health.rv.in .bars-wrap::after{transform:scaleX(0)}
.motion .c-health.rv .st-row:nth-of-type(3) .bars-wrap::after{transition-delay:.42s}
.motion .c-health.rv .st-row:nth-of-type(4) .bars-wrap::after{transition-delay:.54s}
.motion .c-health.rv .st-row:nth-of-type(5) .bars-wrap::after{transition-delay:.66s}
.motion .c-health.rv .st-lbl.down{opacity:0;transition:opacity var(--dur-2) var(--ease-out-2) 1.6s}
.motion .c-health.rv.in .st-lbl.down{opacity:1}
.count{display:inline-block;min-width:2ch;text-align:right;font-variant-numeric:tabular-nums}
@media (max-width:767px){.bars-wrap{grid-column:1/-1;grid-row:2}}

/* ---- how: the request lands; the rail fills as you read ---- */
.motion .browser.rv-group .req.is-new{opacity:0;transform:translateY(-10px);transition:opacity var(--dur-2) var(--ease-out) .5s,transform var(--dur-3) var(--ease-out) .5s}
.motion .browser.rv-group.in .req.is-new{opacity:1;transform:none}
.motion .browser.rv-group .req:not(.is-new):not(.is-empty){transform:translateY(-40px);transition:transform var(--dur-3) var(--ease-out) .5s}
.motion .browser.rv-group.in .req:not(.is-new):not(.is-empty){transform:none}
@supports (animation-timeline:view()){
  .motion .step:not(:last-child)::after{transform-origin:top;animation:rail linear both;animation-timeline:view();animation-range:entry 40% cover 55%}
  @keyframes rail{from{transform:scaleY(0)}to{transform:scaleY(1)}}
}

/* ---- footprint: what you don't run gets struck out ---- */
.motion .skip s{text-decoration:none;position:relative}
.motion .skip s::after{content:"";position:absolute;left:-2px;right:-2px;top:52%;height:1.5px;background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-2) var(--ease-inout);transition-delay:calc(.25s + var(--i) * var(--stagger-2))}
.motion .skip li{--i:0}
.motion .skip li:nth-child(2) s::after{--i:1} .motion .skip li:nth-child(3) s::after{--i:2} .motion .skip li:nth-child(4) s::after{--i:3}
.motion .skip.in s::after{transform:none}
.motion .onramp>*{opacity:0;transform:translateX(-10px);transition:opacity var(--dur-3) var(--ease-out),transform var(--dur-3) var(--ease-out)}
.motion .onramp>:nth-child(2){transition-delay:.18s} .motion .onramp>:nth-child(3){transition-delay:.36s}
.motion .onramp.in>*{opacity:1;transform:none}

/* ---- signature replay: tall scroll track + sticky stage, JS drives progress ---- */
.motion .replay-sec{height:340vh}
.motion .replay-sec .replay-stage{position:sticky;top:0;height:100vh;height:100dvh;display:flex;align-items:center;padding:64px 0 0}
.motion .replay-sec .wf-head{opacity:1}
.motion .replay-sec .beat{opacity:.28;transition:opacity var(--dur-2) var(--ease-out-2)}
.motion .replay-sec .beat.on{opacity:1}
.motion .replay-sec .beat.past{opacity:.55}
.motion .replay-sec .wf-bar{transform:scaleX(0)}
.motion .replay-sec .s-pend{opacity:1}
.motion .replay-sec .s-final{opacity:0}
.motion .replay-sec .s-pend,.motion .replay-sec .s-final{transition:opacity var(--dur-2) var(--ease-out-2)}
.motion .replay-sec .wf-row.done .s-pend{opacity:0}
.motion .replay-sec .wf-row.done .s-final{opacity:1}
.motion .replay-sec .wf-result{opacity:0;transform:translateY(var(--dist-2));transition:opacity var(--dur-3) var(--ease-out),transform var(--dur-3) var(--ease-out)}
.motion .replay-sec.is-failed .wf-result{opacity:1;transform:none}
.motion .replay-sec .ro-num{transition:color var(--dur-2) var(--ease-out-2)}
.replay-stage{position:relative}
.replay-stage::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:-1;opacity:0;background:radial-gradient(40% 45% at 72% 50%,var(--glow-red),transparent 70%);transition:opacity var(--dur-4) var(--ease-out)}
.replay-sec{isolation:isolate}
.replay-sec.is-failed .replay-stage::after{opacity:1}
html:not(.motion) .ro-num{color:#F07A73}
html:not(.motion) .replay-stage::after{opacity:1}

/* ---------- responsive ---------- */
@media (max-width:1100px){
  .replay-grid{grid-template-columns:1fr;gap:var(--s6)}
  .replay-copy h2{max-width:none}
}
@media (max-width:767px){
  .replay-stage{padding:var(--s8) 0}
  .motion .replay-sec{height:300vh}
  .motion .replay-sec .replay-stage{align-items:flex-start;padding-top:84px}
  .replay-grid{gap:var(--s4)}
  .readout{margin-top:var(--s3)}
  .ro-num{font-size:64px}
  .beats{margin-top:var(--s4);gap:8px}
  .motion .replay-sec .beat{grid-area:1/1;background:var(--bg)} /* mobile: beats crossfade in one cell, no reflow */
  .motion .replay-sec .beat:not(.on){opacity:0}
  .beat{grid-template-columns:72px 1fr;font-size:14.5px}
  .wf-body{padding:var(--s3)}
  .wf-row{grid-template-columns:118px minmax(0,1fr) 58px;gap:8px;height:42px}
  .wf-child .wf-name{padding-left:10px}
  .wf-name .dir{display:none}
  .wf-axis{margin-left:calc(118px + 8px);margin-right:calc(58px + 8px)}
  .wf-head{left:calc(118px + 8px)}
  .wf-id{display:none}
  .wf .trace{font-size:10.5px}
  .foot-mark{margin-top:var(--s5)}
}
.replay-sec.is-failed .wf-root .wf-bar,html:not(.motion) .wf-root .wf-bar{background:color-mix(in oklab,var(--err) 55%,var(--surface))}

/* ---------- polish pass 2 ---------- */
/* rhythm: alternate tight / airy instead of 96px everywhere */
.features{padding:128px 0 112px}
.footprint{padding:128px 0}
.problem{padding-bottom:80px}
@media (max-width:767px){.features,.footprint{padding:80px 0}.problem{padding-bottom:64px}}
.ro-sign{align-self:center;transform:translateY(-.1em)}
@media (max-width:767px){
  .replay .ico{margin:0}
  .hero-app .replay{font-size:0;gap:0;width:28px;padding:0;justify-content:center}
  .hero-app .replay .ico{width:14px;height:14px}
  .app-title{white-space:nowrap}
  .wf-axis span:nth-child(2),.wf-axis span:nth-child(3){color:transparent}
  .wf-row{grid-template-columns:128px minmax(0,1fr) 58px;font-size:11px}
  .wf-axis{margin-left:calc(128px + 8px)}
  .wf-head{left:calc(128px + 8px)}
  .motion .replay-sec .replay-stage{align-items:center;padding-top:56px}
}
.motion .hero-app .trace{opacity:0;transition:opacity var(--dur-2) var(--ease-out-2)}
.motion .hero-app.resolved .trace{opacity:1;transition-delay:.3s}
