/* ============================================================================
   demo.css — the memory demonstration page
   ----------------------------------------------------------------------------
   Three regions, in load order below:

     1. PAGE CHROME  — transcribed unchanged from prototype/demo/demo.css, which
        the user approved. Nothing here moves, so light renders as it did.
     2. CARD         — the marketplace's detail-card component, transcribed
        verbatim from src/marketplace/marketplace.css (provenance per block).
        Same class names, same declarations; only the placement differs, because
        this page anchors the card to a world-space stop instead of to a node
        click. marketplace.css is not linked: it pins #graph, a five-tile fixed
        toolbar, the sidebar, the strip and the tour, and its phone `.detail`
        block is `!important` and keyed to the strip's --strip-chrome. The card
        block is restated here instead, the way every module stylesheet in this
        repo restates the `.panel` chrome under its own root.
     3. STAGE CONTENT — the demo's own rows, written in the card's vocabulary
        (.kv / .fsec / .chip / .compat), so a stage reads as the same object.

   Every declaration resolves through src/shared/tokens.css. tokens-dark.css is
   one [data-theme="dark"] block re-pointing those same names, so dark comes for
   free except for the handful of fixes at the foot of this file — the same
   fixes, for the same reasons, that marketplace.css carries.

   Load order: tokens.css, tokens-dark.css, shell.css, this file.
   ========================================================================== */

@font-face{font-family:Jost;src:url('../../assets/fonts/jost.ttf') format('truetype');font-display:swap;font-weight:100 900}

/* ==========================================================================
   1 · PAGE CHROME — prototype/demo/demo.css, unchanged
   Scene, leaders, editorial labels, controls: 0 / 1 / 2 / 3 / 4.
   ========================================================================== */
*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:var(--paper);color:var(--ink);font-family:var(--font-body)}
button,a,select{-webkit-tap-highlight-color:transparent}button,select{font:inherit;color:inherit}button,a{touch-action:manipulation}button{cursor:pointer}button:disabled{cursor:default;opacity:.35}button:active:not(:disabled){transform:scale(.97)}
a{color:inherit;text-decoration:none}button:focus-visible,a:focus-visible,select:focus-visible{outline:2px solid var(--ink);outline-offset:4px}[hidden]{display:none!important}
#demo{height:100dvh;min-height:400px;position:relative;isolation:isolate}#scene,#leaders{position:absolute;inset:0;width:100%;height:100%}#scene{z-index:0}#leaders{z-index:1;pointer-events:none}#scene canvas{display:block}
.page-head{position:absolute;z-index:2;top:23px;left:34px;right:34px;display:flex;align-items:center;gap:22px;height:35px}.wordmark{font:300 29px/1 Jost,sans-serif;letter-spacing:.23em}.head-divider{height:18px;width:1px;background:var(--border)}.page-label{font:10px var(--font-mono);letter-spacing:.12em;color:var(--graphite)}.market-link{margin-left:auto;font-size:12px}.market-link span{margin-left:10px}
.scene-caption{position:absolute;left:36px;top:111px;z-index:2;pointer-events:none;max-width:460px}.eyebrow{font:10px/1.4 var(--font-mono);letter-spacing:.1em;color:var(--graphite);margin:0 0 13px}.scene-caption h1{font:400 clamp(27px,3.05vw,43px)/1.14 Jost,sans-serif;letter-spacing:-.035em;margin:0}.caption-body{font-size:12px;color:var(--graphite);margin-top:15px}
#load-state{position:absolute;top:47%;left:30%;color:var(--graphite);font-size:13px}#node-label{position:absolute;z-index:2;pointer-events:none;font:10px var(--font-mono);color:var(--ink);white-space:nowrap;background:var(--paper-78);padding:5px 7px;border-radius:3px}
.journey-info{position:absolute;bottom:125px;left:36px;right:36px;z-index:2;display:flex;justify-content:space-between;font:10px var(--font-mono);color:var(--graphite)}#stage-status{color:var(--ink)}.controls{position:absolute;z-index:4;bottom:51px;left:36px;right:36px;display:flex;align-items:center;height:58px;border-top:1px solid var(--border);border-bottom:1px solid var(--border);gap:26px;background:var(--paper-66);backdrop-filter:blur(10px)}.controls button{min-width:38px;min-height:40px;border:0;background:transparent;border-radius:8px;font:17px var(--font-mono);transition:background 140ms ease,transform 140ms ease}.playback,.stepping{display:flex;align-items:center;gap:7px}.speed-label{font-size:10px;color:var(--graphite);margin-left:8px;display:flex;align-items:center;gap:7px}select{border:0;background:transparent;padding:10px 2px;font:11px var(--font-mono);cursor:pointer}#stage-count{font:10px var(--font-mono);white-space:nowrap}.stage-nav{display:flex;justify-content:center;flex:1;gap:7px}.stage-nav button{font:10px var(--font-mono);position:relative;color:var(--graphite);min-width:32px;min-height:40px}.stage-nav button[aria-current="step"]{color:var(--ink);background:var(--glass-fill-85)}.stage-nav button[aria-current="step"]::after{content:'';position:absolute;height:2px;width:14px;bottom:3px;left:calc(50% - 7px);background:var(--brand)}.gesture-note{position:absolute;bottom:16px;left:36px;margin:0;color:var(--graphite);font:9px var(--font-mono);letter-spacing:.015em}#show-card{position:fixed;z-index:3;right:30px;top:90px;padding:13px;border:1px solid var(--border);border-radius:8px;background:var(--paper)}
.controls{bottom:20px;height:44px}.journey-info{bottom:77px}.gesture-note{bottom:5px;font-size:8px}

/* The theme tile. shell.css owns its look — 38px, radius 11, --paper-72 under
   --blur-tile, a --brand-20 edge, --sh-3-tile, and the moon/sun cross-fade on
   the tile row's 140ms budget. This page is full-bleed, so the tile sits in the
   floating header rather than in shell.css's sticky bar; only placement is
   restated here. Nothing else about the tile is redeclared. */
.page-head .shell-tile{margin-left:18px}
/* brand block: mark left of the wordmark, page label stacked beneath (user
   ruling). The head grows to the two-line block; the caption below starts at
   111px, which still clears it. Mark size and radius match the marketplace
   sidebar's .brandlogo; it carries no dark filter there either. */
/* z-index 6, not the shared 2: the nav's floating panel lives inside the head,
   and .scene-caption (z 2, later in the DOM) was painting the headline over
   the open menu. The card is z 3 and the controls z 4; the head sits above
   all of them only while its panel is open — the closed brand row occupies
   no shared ground. */
.page-head{height:auto;min-height:35px;z-index:6}
/* v2: the nav component supplies the mark + wordmark row; the label stacks
   beneath it. The row's own type and mark sizes come from nav.css/shell.css. */
.brand{display:flex;flex-direction:column;align-items:flex-start;gap:5px}
.brand .page-label{padding-left:42px}   /* aligns under the wordmark, past the 30px mark + gap */

/* ==========================================================================
   2 · CARD — src/marketplace/marketplace.css, transcribed
   ========================================================================== */

/* the shell (marketplace.css "detail card", orig L178-205). 330px wide, 18px
   radius, 66% paper under blur(22px) saturate(1.25), a 1px brand-20 edge, the
   same shadow; a fixed-height flex column with pinned .dh and .dfoot and only
   .body scrolling. Two departures, both because the anchor is a world-space
   stop rather than a node click: `top`/`right` are replaced by the inline
   left/top rail.js's cardAnchor() writes, and the height uses dvh so the phone
   dock lands on the visual viewport. */
.detail{ position:fixed; z-index:3; width:330px;
  height:min(560px, calc(100dvh - 32px));
  border-radius:var(--r-18, 18px);
  background:var(--paper-66);
  -webkit-backdrop-filter:var(--blur-detail); backdrop-filter:var(--blur-detail);
  border:1px solid var(--brand-20); box-shadow:var(--sh-4-detail);
  display:flex; flex-direction:column; overflow:hidden;
  transition:opacity 180ms ease; }
/* the card fades out for the duration of a flight and back in on arrival */
.detail.travelling{ opacity:0; pointer-events:none; }

.detail .dh{ padding:14px 16px; border-bottom:1px solid var(--border); position:relative;
  cursor:grab; flex:0 0 auto; }
.detail .x{ position:absolute; top:6px; right:8px; z-index:5; cursor:pointer;
  color:var(--graphite); font-size:var(--fs-18); line-height:1; padding:6px 9px;
  border-radius:var(--r-8, 8px); background:none; border:0; }
.detail .x:hover{ background:var(--brand-12); color:var(--ink); }

/* the header's logo-tile row (orig L191-193, .dh .top / .flogo) */
.detail .dh .top{ display:flex; align-items:center; gap:11px; padding-right:26px; }
.detail .flogo{ width:46px; height:46px; border-radius:var(--r-10, 10px); overflow:hidden;
  background:var(--white); border:1px solid var(--border); flex:0 0 auto; }
.detail .flogo svg{ display:block; width:100%; height:100%; }
/* eight of the nine stops have no creator to draw, so the tile carries the stop
   number in the wordmark's face — the same tile, one variant fill */
.detail .flogo.stage{ display:grid; place-items:center; background:var(--glass-fill-50);
  font:300 24px Jost, var(--font-display); color:var(--ink); }
.detail .dh .ti{ min-width:0; flex:1; }
.detail h2{ font-family:var(--font-display); font-size:var(--fs-17); font-weight:var(--fw-semibold);
  margin:0; letter-spacing:var(--ls-tight); line-height:1.25; }
.detail .sub{ font:var(--fs-md) var(--font-mono); color:var(--graphite); margin-top:4px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* The rule above is the marketplace's, and it is right for what it was written
   for: stop 2's one-line `published Feb 2026 · agent://0x168F` meta, which must
   ellipsis rather than wrap. The other eight stops put a SENTENCE in this slot,
   and three of them ("Same task. Same starting environment.", "A known path
   through the same problem.", "One agent learns. The next remembers.") overrun
   213px and were being clipped to "…environme…". A card must not truncate its
   own copy, so a prose sub wraps instead. */
.detail .sub.prose{ white-space:normal; overflow:visible; text-overflow:clip; }
.detail .chip{ display:inline-block; font-size:var(--fs-sm); font-weight:var(--fw-semibold);
  text-transform:uppercase; letter-spacing:var(--ls-06); color:var(--white);
  padding:2px 7px; margin-right:5px; border-radius:3px; }
.detail .chip.ghost{ color:var(--graphite); background:transparent; border:1px solid var(--border); }
.detail .chiprow{ margin-top:9px; }

/* the icon-button row (orig L194-196, .socrow / .socbtn) */
.socrow{ display:flex; flex-wrap:wrap; gap:7px; margin-top:12px; }
.socbtn{ width:34px; height:34px; display:grid; place-items:center; border-radius:var(--r-8, 8px);
  border:1px solid var(--glass-edge-60); background:var(--glass-fill-50);
  box-shadow:var(--sh-1-card); text-decoration:none;
  font:var(--fw-bold) var(--fs-lg) var(--font-body); color:var(--ink); }
.socbtn:hover{ background:var(--brand-12); border-color:var(--brand); }
.socbtn[aria-pressed="true"]{ background:var(--brand); border-color:var(--brand); color:var(--white); }

/* only the body scrolls */
.detail .body{ padding:14px 16px; flex:1 1 auto; min-height:0;
  overflow-y:auto; overscroll-behavior:contain; scrollbar-width:thin;
  scrollbar-color:var(--border) transparent; }
.detail .body p{ font-size:var(--fs-base-p); line-height:var(--lh-loose); margin:0 0 12px; }
.detail .kv{ font-size:var(--fs-md); color:var(--graphite); margin-bottom:6px; }
.detail .kv b{ color:var(--ink); }
.detail .kv .kvn{ font-family:var(--font-mono); font-variant-numeric:tabular-nums;
  color:var(--ink); }
.detail .kv .sv{ margin-left:4px; }
.detail .kv .sv b{ font-family:var(--font-mono); font-weight:var(--fw-semibold); }

/* the slim pinned footer — the card's one action */
.detail .dfoot{ display:flex; align-items:center; gap:10px; flex:0 0 auto; min-height:59px;
  padding:9px 16px; border-top:1px solid var(--border); background:var(--paper-97);
  -webkit-backdrop-filter:var(--blur-10); backdrop-filter:var(--blur-10); }
.detail .dfoot .amt{ font:var(--fs-lg-p) var(--font-mono); font-variant-numeric:tabular-nums; }
.detail .dfoot .amt span{ font-size:var(--fs-sm); color:var(--graphite); }
.detail .dfoot .btn-recall{ margin-left:auto; padding:7px 15px; }
.btn-recall{ border:1px solid var(--brand); background:var(--brand);
  color:var(--white); font:var(--fw-semibold) var(--fs-base-p) var(--font-display);
  padding:9px 16px; border-radius:11px; transition:background .14s ease, transform .12s ease; }
.btn-recall:hover{ background:var(--brand-88); border-color:var(--brand-88); }
.btn-recall:active{ transform:scale(.97); }

.fsec{ margin-top:16px; }
.fsec .fh{ font-size:var(--fs-sm); font-weight:var(--fw-bold); text-transform:uppercase;
  letter-spacing:.1em; color:var(--acc); margin-bottom:9px; }
.creator-row{ display:flex; align-items:center; gap:10px; padding:8px;
  border:1px solid var(--glass-edge-60); border-radius:11px; background:var(--glass-fill-50);
  box-shadow:var(--sh-1-card); }
.creator-row .cav{ width:34px; height:34px; border-radius:9px; overflow:hidden; flex:0 0 auto;
  border:1px solid var(--border); background:var(--white); }
.creator-row .cav svg{ display:block; width:100%; height:100%; }
.creator-row .ci{ min-width:0; flex:1; }
/* `display:block` is the one addition to this block. marketplace.css leaves both
   spans inline and gets two lines only because its own row is narrow enough to
   force a wrap — which lands mid-phrase ("… AGENT · 7 / memories"). `.cm`'s
   `margin-top` and `.cn`'s `text-overflow` both apply to a block box only, so
   the intent is stated here rather than left to depend on a string's length.
   Worth fixing at source in marketplace.css too; that file is out of scope. */
.creator-row .cn{ display:block; font:var(--fw-semibold) var(--fs-base-p) var(--font-mono);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.creator-row .cm{ display:block; font-size:var(--fs-sm-p); color:var(--graphite); margin-top:2px; }

/* compatibility chips */
.compat{ display:flex; flex-wrap:wrap; gap:5px; }
.compat .cchip{ font-size:var(--fs-sm-p); font-weight:var(--fw-semibold); color:var(--ink);
  padding:2px 9px; border-radius:20px; background:var(--glass-fill-55);
  border:1px solid var(--glass-edge-85); box-shadow:var(--sh-1-tight); }
.compat .cchip.limited{ color:var(--graphite); }
.compat .cchip i{ font-style:normal; margin-right:4px; }

/* freshness meter — SPEC §29 */
.fresh-meter{ margin-top:4px; }
.fresh-bar{ height:8px; border-radius:4px; background:color-mix(in srgb, var(--border) 70%, transparent);
  overflow:hidden; }
.fresh-bar i{ display:block; height:100%; border-radius:4px; background:var(--brand); opacity:.85; }
.fresh-bar.aging i{ background:var(--regdot); }
.fresh-bar.stale i{ background:var(--danger); }
.fresh-num{ display:flex; justify-content:space-between; font-size:var(--fs-sm);
  color:var(--graphite); margin-top:5px; }
.fresh-num b{ font-family:var(--font-mono); color:var(--ink); }

/* lineage links */
.lineage{ display:flex; flex-direction:column; gap:6px; }
.lin-link{ display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:9px;
  background:var(--glass-fill-50); border:1px solid var(--glass-edge-60);
  font-size:var(--fs-md); color:var(--ink); text-align:left; width:100%;
  box-shadow:var(--sh-1-card); }
.lin-link:hover{ border-color:var(--brand-55); background:var(--glass-fill-72); }
.lin-link .lid{ font-family:var(--font-mono); font-weight:var(--fw-semibold); flex:0 0 auto; }
.lin-link .lnm{ min-width:0; flex:1; color:var(--graphite); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; }
.lin-link .lrole{ font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:var(--ls-05);
  color:var(--brand); flex:0 0 auto; }
.lin-none{ font-size:var(--fs-md); color:var(--graphite); }

/* ==========================================================================
   3 · STAGE CONTENT — the demo's rows, in the card's vocabulary
   ========================================================================== */

/* the footnote half of the pinned footer. `.amt` is the card's price slot and
   is used as one only at stop 2, where the figure really is a recall fee; every
   other stop puts its footnote here instead, at the metadata size. */
.dfoot .foot-note{ font:var(--fs-xs) var(--font-mono); line-height:1.5;
  color:var(--graphite); max-width:150px; }

/* the task line — the one display-scale sentence in the deck */
.detail .task{ font:var(--fw-medium) 24px/1.27 Jost, var(--font-display);
  letter-spacing:-.025em; margin:4px 0 22px; }
.detail .task small{ display:block; font:var(--fs-base-p)/1.55 var(--font-body);
  margin-top:15px; letter-spacing:0; color:var(--graphite); }
.detail .note{ color:var(--graphite); font-size:var(--fs-sm) !important; }

/* A | B — the two-column comparison, on the card's own `.kv` row rhythm: the
   label keeps its column, the two figures take one monospace column each so a
   stop's numbers stay aligned down the card. */
.kv.ab{ display:grid; grid-template-columns:1fr auto auto; gap:0 12px; align-items:baseline; }
.kv.ab .kvn{ min-width:66px; text-align:right; }
.kv.ab .kvn.win{ color:var(--brand); font-weight:var(--fw-semibold); }
.ab-head{ display:grid; grid-template-columns:1fr auto auto; gap:0 12px;
  font-size:var(--fs-sm); letter-spacing:var(--ls-06); text-transform:uppercase;
  color:var(--graphite); margin-bottom:7px; }
.ab-head span+span{ min-width:66px; text-align:right; }

/* the two live step logs. The columns are the approved prototype's; only their
   colours and sizes are restated through the card's tokens. */
.agents{display:grid;grid-template-columns:1fr 1fr;gap:0;margin:0 0 15px}
.agent{min-width:0;padding-right:11px}.agent+.agent{padding:0 0 0 12px;border-left:1px solid var(--border)}
.agent-heading{font-size:var(--fs-md);font-weight:650;margin-bottom:5px}
.agent-mode{font:var(--fs-3xs)/1.4 var(--font-mono);letter-spacing:.04em;color:var(--graphite);min-height:25px}
.agent-summary{font:var(--fs-sm)/1.5 var(--font-mono);margin:8px 0;color:var(--ink);min-height:15px}
.agent-summary b{font-weight:var(--fw-medium)}
.log{height:166px;overflow-y:auto;scrollbar-width:none;overscroll-behavior:contain;mask-image:linear-gradient(to bottom,transparent,#000 9px);padding-top:10px}
.log-entry{font:var(--fs-sm)/1.55 var(--font-mono);color:var(--graphite);padding:0 0 10px;overflow-wrap:anywhere}
.log-entry .log-time{display:block;font-size:var(--fs-3xs);color:var(--graphite);opacity:.8;margin-bottom:2px}
.log-entry:last-child{color:var(--ink)}

/* #4 — real benchmark apparatus, shown inside the final comparison card (tokens only) */
.dm-wrap{margin-top:14px;padding-top:12px;border-top:1px solid var(--border)}
.dm-h{font:var(--fw-bold) var(--fs-3xs)/1.2 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--brand);margin-bottom:9px}
.dm-h span{color:var(--graphite);letter-spacing:.02em;font-weight:var(--fw-regular);text-transform:none}
.dm-kv{display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.dm-kv b{font-weight:var(--fw-regular);color:var(--graphite)}
.dm-kv .kvn{font-family:var(--font-mono);color:var(--ink);white-space:nowrap}
.dm-note{font-size:var(--fs-xs);line-height:1.5;color:var(--graphite);margin:10px 0 0}
.dm-note b{color:var(--ink)}
.dm-transfer{margin-top:8px;font-size:var(--fs-xs);color:var(--graphite)}
.dm-transfer b{color:var(--ink);font-family:var(--font-mono)}
.dm-badge{display:inline-block;border:1px solid var(--border);color:var(--graphite);border-radius:999px;padding:1px 8px;font:var(--fw-semibold) var(--fs-3xs)/1.3 var(--font-mono);letter-spacing:.08em;text-transform:uppercase}
.log-entry[data-kind="success"]{font-weight:var(--fw-bold)}
.log-entry[data-kind="failure"]{text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px}
.agent-state{font:var(--fs-3xs) var(--font-mono);letter-spacing:.08em;border-top:1px solid var(--border);padding-top:9px;margin-top:9px}
.agent-state.done{font-weight:var(--fw-bold)}

/* the recall ladder — the drawer's five rungs and its 462ms presentation
   stagger, compressed into the card (src/recall-drawer/README.md) */
.recall{list-style:none;padding:0;margin:0 0 18px}
.recall li{font:var(--fs-xs) var(--font-mono);display:flex;align-items:center;gap:10px;min-height:28px;color:var(--graphite)}
.recall li::before{content:'';width:7px;height:7px;border:1px solid var(--graphite);flex:0 0 auto}
.recall li.complete{color:var(--ink)}.recall li.complete::before{background:var(--ink)}
.recall li.pending{opacity:.35}
.recall+.agents .log{height:95px}
.memory-active{font:var(--fs-xs) var(--font-mono);margin-bottom:12px;letter-spacing:.05em}

/* the scoreboard and the memory effect */
.scoreboard{width:100%;border-collapse:collapse;font:var(--fs-md) var(--font-mono);margin:0 0 20px;table-layout:fixed;font-variant-numeric:tabular-nums}
.scoreboard th{text-align:right;font-size:var(--fs-sm);font-weight:var(--fw-medium);padding:8px 0 13px}
.scoreboard th:first-child{text-align:left;width:34%;color:var(--graphite)}
.scoreboard td{text-align:right;padding:10px 0;border-bottom:1px solid var(--border)}
.scoreboard td:first-child{text-align:left;color:var(--graphite);font-family:var(--font-body)}
.scoreboard tr:last-child td{font-size:var(--fs-xs)}
.effect-label{font:var(--fs-sm) var(--font-mono);letter-spacing:var(--ls-12);color:var(--acc)}
.effects{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:11px}
.effect strong{font:var(--fw-regular) 26px/1.3 Jost, var(--font-display);letter-spacing:-.06em}
.effect span{display:block;font:var(--fs-xs) var(--font-mono);color:var(--graphite);margin-top:4px}
.loop-title{font:var(--fw-regular) 30px/1.16 Jost, var(--font-display);margin:13px 0 19px;letter-spacing:-.03em}
.market-cta{display:block;margin-top:18px;font-size:var(--fs-base);text-decoration:underline;text-underline-offset:5px}
.compile-result{padding:13px 0;font:var(--fs-md)/1.6 var(--font-mono)}

/* stop 8's placeholder. The publish flow is a later build, so the action opens
   a dialog that says exactly that rather than implying a pipeline exists. */
#publish-ph{ border:1px solid var(--brand-20); border-radius:var(--r-18, 18px); padding:0;
  width:min(370px, calc(100vw - 32px)); background:var(--paper-97); color:var(--ink);
  box-shadow:var(--sh-4-detail); }
#publish-ph::backdrop{ background:var(--scrim-modal); }
#publish-ph .ph-head{ padding:14px 16px; border-bottom:1px solid var(--border); position:relative; }
#publish-ph h2{ font-family:var(--font-display); font-size:var(--fs-17);
  font-weight:var(--fw-semibold); margin:0; letter-spacing:var(--ls-tight); }
#publish-ph .ph-body{ padding:14px 16px; }
#publish-ph .ph-body p{ font-size:var(--fs-base-p); line-height:var(--lh-loose); margin:0 0 12px; }
#publish-ph .ph-foot{ display:flex; align-items:center; gap:10px; padding:9px 16px;
  border-top:1px solid var(--border); }
#publish-ph .ph-foot .foot-note{ font:var(--fs-xs) var(--font-mono); color:var(--graphite); }
#publish-ph .ph-foot button{ margin-left:auto; }

@media(hover:hover) and (pointer:fine){.controls button:hover,.detail .x:hover{background:var(--brand-12)}a:hover{text-decoration:underline;text-underline-offset:4px}}

/* ==========================================================================
   phone — the prototype's block, plus the card component's own phone sizes
   ========================================================================== */
@media(max-width:767px){
  .page-head{top:17px;left:20px;right:20px;gap:14px}.wordmark{font-size:25px}
  .page-label{font-size:8px;letter-spacing:.07em}
  .market-link{font-size:0}.market-link span{font-size:19px;margin:0}
  .page-head .shell-tile{margin-left:12px;width:34px;height:34px}
  .scene-caption{left:21px;top:85px;max-width:290px}.scene-caption .eyebrow{font-size:8px;margin-bottom:10px}
  .scene-caption h1{font-size:29px}.caption-body{display:none}
  .detail{left:6px!important;right:6px!important;top:auto!important;bottom:118px!important;width:auto;height:min(48dvh,430px);max-width:none}
  /* the card component's own phone metrics (marketplace.css) */
  .detail .dh{padding:12px 13px;cursor:default}
  .detail .dh .top{gap:9px}
  .detail .flogo{width:38px;height:38px}.detail .flogo.stage{font-size:21px}
  .detail h2{font-size:var(--fs-2xl)}
  .detail .sub{font-size:var(--fs-sm-p);margin-top:8px}
  .detail .body{padding:12px 13px 8px}
  .detail .body p{font-size:var(--fs-base);margin-bottom:10px}
  .detail .kv{font-size:var(--fs-sm-p)}
  .detail .x{width:44px;height:44px;display:grid;place-items:center;padding:0}
  .socbtn{width:30px;height:30px;font-size:var(--fs-md)}
  .detail .dfoot{padding:9px 13px calc(9px + env(safe-area-inset-bottom,0px));min-height:53px}
  .kv.ab .kvn,.ab-head span+span{min-width:56px}
  .detail .task{font-size:22px;margin-bottom:13px}.detail .task small{margin-top:10px}
  .agents{margin-bottom:10px}.agent-mode{min-height:15px}.log{height:100px}
  .recall{display:grid;grid-template-columns:1fr 1fr;column-gap:12px;margin-bottom:8px}
  .recall li{font-size:8px;min-height:22px}.recall+.agents .log{height:63px}
  .memory-active{margin:5px 0}
  .fsec{margin-top:12px}
  .scoreboard{margin-bottom:13px}.scoreboard th{padding:0 0 9px}.scoreboard td{padding:7px 0}
  .scoreboard tr:last-child td{font-size:8px}
  .effect strong{font-size:24px}.effects{margin-top:5px}.effect span{margin-top:0}
  .loop-title{font-size:25px;margin:4px 0 12px}
  .journey-info{left:20px;right:20px;bottom:95px;font-size:9px}.timing-note{font-size:8px}
  .controls{bottom:20px;left:14px;right:14px;height:65px;gap:4px;justify-content:space-between}
  .stage-nav{position:absolute;top:-38px;left:0;right:0;display:none}
  .controls button{min-width:34px;min-height:44px}
  .speed-label{margin-left:0;font-size:9px;gap:1px}.playback,.stepping{gap:2px}
  .gesture-note{display:none}#stage-count{font-size:9px}#node-label{font-size:8px}
}

/* ==========================================================================
   accessibility fallbacks — the prototype's two, unchanged
   ========================================================================== */
@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}.gesture-note{font-size:0}.gesture-note::after{content:'Reduced motion enabled. Use the stage controls to explore.';font-size:9px}}
@media(prefers-reduced-transparency:reduce){.detail,.controls{background:var(--paper);backdrop-filter:none;-webkit-backdrop-filter:none}}

/* ==========================================================================
   dark — the fixes a token swap cannot express. These are marketplace.css's
   own dark rules for the same components, for the same reasons; every one is
   scoped to [data-theme="dark"], so light cannot match any of it.
   ========================================================================== */
/* 1 · foregrounds on filled brand controls: --white is a SURFACE on dark */
[data-theme="dark"] :is(.btn-recall,.socbtn[aria-pressed="true"]){ color:var(--on-brand); }
[data-theme="dark"] .detail .chip:not(.ghost){ color:var(--on-category); }
/* 2 · the freshness track needs a real boundary once the tint goes dark */
[data-theme="dark"] .fresh-bar{ background:var(--paper); border:1px solid var(--border); }
[data-theme="dark"] .fresh-bar i{ opacity:1; }
/* 3 · the editorial labels sit on the canvas, so they need a stable ground */
[data-theme="dark"] #node-label{ border:1px solid var(--border); }
/* 4 · the stage tile's numeral is ink in both themes; the fill is the surface */
[data-theme="dark"] .detail .flogo.stage{ background:var(--surface-raised); }
/* 5 · reduced transparency: opaque --surface, both filters removed */
@media (prefers-reduced-transparency: reduce){
  [data-theme="dark"] :is(.detail,.controls){ background:var(--surface); }
}
/* the switch itself is instant, never a crossfade: demo.js sets this attribute
   for the commit and drops it two frames later. Identical to marketplace.css. */
html[data-theme-switching],
html[data-theme-switching] *,
html[data-theme-switching] *::before,
html[data-theme-switching] *::after{ transition:none !important; }
