/* ═══════════════════════════════════════════════════════════════════
   demo-shell.css — the DEMO SHELL layer (.ds-* namespace only).
   Owns: the entry chooser, the presentation→tutorial handoff card and
   the persistent sandbox bottom bar.

   Rules this file obeys (demo-src/DEMO-DIRECTION.md):
     · derives every colour from the app's own tokens, never invents one
     · light AND dark (the theme flag is written to BOTH #root and <html>
       by applyTheme(), so plain [data-theme=dark] selectors resolve here
       even though these elements are appended to document.body)
     · one saturated green mark per screen, one filled CTA
     · two easings, nothing bounces, nothing loops
     · everything degrades to an instant readable state under
       prefers-reduced-motion
   It styles NOTHING in the .dp-* (presentation) or .dt-* (tutorial)
   namespaces. The only app selectors it touches are layout offsets so
   the bottom bar never covers a control (see §5).
   ═══════════════════════════════════════════════════════════════════ */

/* ── §1 tokens ──────────────────────────────────────────────────── */
.ds-root{
  --d-ink:var(--text);
  --d-ink-2:var(--text-2);
  --d-ink-3:var(--text-3);
  --d-page:var(--bg);
  --d-card:var(--surface);
  --d-card-2:var(--surface-2);
  --d-line:var(--border);
  --d-line-2:var(--border-2);
  --d-brand:var(--brand);
  --d-accent:var(--accent);
  --d-stage:var(--nav);
  --d-stage-2:var(--nav-2);
  --d-stage-fg:var(--nav-fg);
  --d-stage-fg-2:var(--nav-fg-2);
  --d-ease:cubic-bezier(.2,.8,.2,1);
  --d-ease-io:cubic-bezier(.4,0,.2,1);
  font-family:var(--font);
  -webkit-font-smoothing:antialiased;
  font-variant-numeric:tabular-nums;
}
.ds-root *{box-sizing:border-box}
.ds-root :focus-visible{outline:2px solid var(--ring,var(--d-accent));outline-offset:2px;border-radius:6px}

/* screen-reader-only announcer */
.ds-live{position:fixed;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;padding:0;margin:-1px}

/* ── §2 shared type ─────────────────────────────────────────────── */
.ds-eyebrow{
  display:inline-flex;align-items:center;gap:8px;
  font-size:11px;font-weight:600;letter-spacing:.10em;text-transform:uppercase;
  color:var(--d-ink-3);line-height:1.2;
}
.ds-dot{width:7px;height:7px;border-radius:50%;background:var(--d-brand);flex-shrink:0}
.ds-headline{
  font-size:clamp(30px,4.4vw,56px);line-height:1.06;font-weight:640;
  letter-spacing:-.025em;color:var(--d-ink);margin:20px 0 0;
}
.ds-support{
  font-size:clamp(15px,1.35vw,19px);line-height:1.5;font-weight:400;
  color:var(--d-ink-2);max-width:46ch;margin:24px 0 0;
}
.ds-fine{font-size:12px;line-height:1.5;color:var(--d-ink-3);margin:0}

/* ── §3 the chooser ─────────────────────────────────────────────── */
.ds-chooser{
  position:fixed;inset:0;z-index:9500;
  background:var(--d-page);
  display:flex;flex-direction:column;
  overflow-y:auto;overflow-x:hidden;
  padding:0 clamp(24px,6vw,104px);
}
.ds-ch-top{
  flex-shrink:0;height:72px;display:flex;align-items:center;justify-content:flex-end;
}
.ds-ch-inner{
  flex:1;display:flex;flex-direction:column;justify-content:center;
  width:100%;max-width:1180px;margin:0 auto;
  padding:24px 0 56px;
}
.ds-ch-cards{
  display:flex;gap:20px;align-items:stretch;
  margin:56px 0 0;flex-wrap:wrap;
}
.ds-ch-foot{margin:28px 0 0}

/* card — one <button> per path, so the whole card is the target */
.ds-card{
  position:relative;
  width:300px;flex:0 1 300px;min-height:196px;
  display:flex;flex-direction:column;align-items:flex-start;
  text-align:left;font-family:var(--font);
  background:var(--d-card);color:var(--d-ink);
  border:1px solid var(--d-line);border-radius:var(--radius-lg);
  padding:22px 22px 20px;cursor:pointer;
  transition:transform 160ms var(--d-ease-io),box-shadow 160ms var(--d-ease-io),border-color 160ms var(--d-ease-io);
}
.ds-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-2);border-color:var(--d-line-2)}
.ds-card-primary{min-height:202px;box-shadow:var(--shadow-2)}
.ds-card-primary:hover{box-shadow:var(--shadow-3)}
.ds-card-t{display:block;font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.25;color:var(--d-ink)}
.ds-card-d{display:block;font-size:13px;line-height:1.5;color:var(--d-ink-2);margin:10px 0 0}
.ds-card-meta{display:block;font-size:12px;line-height:1.4;color:var(--d-ink-3);margin:8px 0 0}
.ds-cta{
  margin-top:auto;padding-top:18px;display:inline-flex;align-items:center;gap:7px;
  font-size:13px;font-weight:600;color:var(--d-ink-2);
}
.ds-cta-solid{margin-top:auto;padding-top:0}
.ds-cta-solid .ds-cta-box{
  margin-top:18px;display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 16px;
  border-radius:999px;background:var(--ink);color:var(--on-ink);font-size:13px;font-weight:600;
}
.ds-cta-ghost .ds-cta-box{
  margin-top:18px;display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 15px;
  border-radius:999px;background:transparent;color:var(--d-ink);
  border:1px solid var(--d-line-2);font-size:13px;font-weight:600;
}
.ds-card svg{flex-shrink:0}
.ds-tab{
  position:absolute;top:-11px;left:20px;height:22px;padding:0 11px;
  display:inline-flex;align-items:center;border-radius:999px;
  background:var(--d-brand);color:#0b1a12;
  font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
}
/* a path whose script did not load: still shown, plainly unavailable */
.ds-card[aria-disabled="true"]{opacity:.55;cursor:not-allowed;box-shadow:none}
.ds-card[aria-disabled="true"]:hover{transform:none;box-shadow:none;border-color:var(--d-line)}

/* theme toggle — the only other control in the chooser chrome */
.ds-theme{
  width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:999px;border:1px solid var(--d-line);background:var(--d-card);
  color:var(--d-ink-2);cursor:pointer;
  transition:color 160ms var(--d-ease-io),border-color 160ms var(--d-ease-io);
}
.ds-theme:hover{color:var(--d-ink);border-color:var(--d-line-2)}

/* ── §4 the handoff card (presentation → tutorial) ──────────────── */
.ds-handoff{
  position:fixed;inset:0;z-index:9500;
  background:var(--overlay);
  display:flex;align-items:center;justify-content:center;padding:24px;
}
.ds-ho-card{
  width:520px;max-width:100%;
  background:var(--d-card);border:1px solid var(--d-line);border-radius:var(--radius-xl);
  box-shadow:var(--shadow-3);padding:32px;
}
.ds-ho-card .ds-headline{font-size:clamp(24px,2.6vw,32px);margin-top:14px}
.ds-ho-card .ds-support{font-size:14px;margin-top:14px;max-width:none}
.ds-ho-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:26px}
.ds-btn{
  height:38px;padding:0 18px;border-radius:999px;border:1px solid transparent;
  font-family:var(--font);font-size:13px;font-weight:600;cursor:pointer;
  display:inline-flex;align-items:center;gap:8px;
  transition:background 160ms var(--d-ease-io),color 160ms var(--d-ease-io),border-color 160ms var(--d-ease-io);
}
.ds-btn-solid{background:var(--ink);color:var(--on-ink)}
.ds-btn-solid:hover{background:var(--accent-ink)}
.ds-btn-ghost{background:transparent;color:var(--d-ink);border-color:var(--d-line-2)}
.ds-btn-ghost:hover{background:var(--d-card-2)}

/* ── §5 the sandbox bottom bar ──────────────────────────────────── */
/* The bar is chrome, not product: it sits on the app's one dark plane so
   it never reads as part of a view. The app is SHRUNK by the bar's height
   (below) rather than covered, so no control can ever hide behind it. */
.ds-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:95;
  background:var(--d-stage);color:var(--d-stage-fg);
  border-top:1px solid var(--d-stage-2);
}
.ds-bar-in{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:52px;padding:8px clamp(12px,2vw,20px);
}
.ds-bar-note{
  display:flex;align-items:center;gap:9px;min-width:0;
  font-size:12px;line-height:1.3;color:var(--d-stage-fg-2);
}
.ds-bar-note strong{color:var(--d-stage-fg);font-weight:600}
.ds-bar-note .ds-bar-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-bar-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}
.ds-bbtn{
  height:32px;padding:0 13px;border-radius:999px;
  background:transparent;border:1px solid var(--d-stage-2);color:var(--d-stage-fg-2);
  font-family:var(--font);font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;
  transition:background 160ms var(--d-ease-io),color 160ms var(--d-ease-io),border-color 160ms var(--d-ease-io);
}
.ds-bbtn:hover{background:var(--d-stage-2);color:var(--d-stage-fg)}
.ds-bbtn-solid{background:var(--d-brand);border-color:var(--d-brand);color:#0b1a12}
.ds-bbtn-solid:hover{background:var(--d-brand);border-color:var(--d-brand);color:#0b1a12;filter:brightness(1.06)}
.ds-ico{
  width:32px;height:32px;border-radius:999px;
  background:transparent;border:1px solid var(--d-stage-2);color:var(--d-stage-fg-2);
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  transition:background 160ms var(--d-ease-io),color 160ms var(--d-ease-io);
}
.ds-ico:hover{background:var(--d-stage-2);color:var(--d-stage-fg)}
.ds-bar :focus-visible{outline:2px solid var(--d-brand);outline-offset:2px}
.ds-short{display:none}

/* the app gives the bar its own strip of the viewport, so nothing is
   ever underneath it. .screen/.app-wrap are height:100vh in the app. */
html.ds-bar-on .screen,
html.ds-bar-on .screen.active,
html.ds-bar-on .app-wrap{height:calc(100vh - var(--ds-bar-h,52px))}
/* the app's two floating strips move up with it */
html.ds-bar-on .toast{bottom:calc(20px + var(--ds-bar-h,52px))}
html.ds-bar-on .ui-toast-undo{bottom:calc(20px + var(--ds-bar-h,52px))}

/* ── §6 responsive ──────────────────────────────────────────────── */
@media (max-width:1024px){
  .ds-ch-cards{gap:16px}
}
@media (max-width:860px){
  .ds-ch-inner{padding:8px 0 40px;justify-content:flex-start}
  .ds-ch-cards{flex-direction:column;margin-top:40px}
  .ds-card,.ds-card-primary{width:100%;flex:0 0 auto;min-height:0}
  .ds-headline{font-size:clamp(28px,7vw,38px)}
  .ds-support{margin-top:18px}
}
@media (max-width:720px){
  .ds-bar-note .ds-bar-txt{display:none}
  .ds-full{display:none}
  .ds-short{display:inline}
  .ds-bbtn{padding:0 11px}
}
@media (max-width:420px){
  .ds-bar-note{display:none}
  .ds-bar-in{justify-content:center}
}

/* ── §7 print — demo chrome is never paper ──────────────────────── */
@media print{
  .ds-chooser,.ds-handoff,.ds-bar,.ds-live{display:none!important}
  html.ds-bar-on .screen,
  html.ds-bar-on .screen.active,
  html.ds-bar-on .app-wrap{height:auto!important}
}

/* ── §8 motion ──────────────────────────────────────────────────── */
/* entrances only; nothing loops, nothing drifts, everything is still
   within 1.0s of arriving. Durations/delays per DEMO-DIRECTION.md §3. */
@keyframes ds-in-eyebrow{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes ds-in-headline{from{opacity:0;transform:translateY(16px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}
@keyframes ds-in-support{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes ds-in-card{from{opacity:0;transform:translateY(24px) scale(.985)}to{opacity:1;transform:none}}
@keyframes ds-in-fade{from{opacity:0}to{opacity:1}}
@keyframes ds-in-bar{from{opacity:0;transform:translateY(100%)}to{opacity:1;transform:none}}

.ds-anim .ds-eyebrow{animation:ds-in-eyebrow 420ms var(--d-ease) 40ms both}
.ds-anim .ds-headline{animation:ds-in-headline 560ms var(--d-ease) 90ms both}
.ds-anim .ds-support{animation:ds-in-support 480ms var(--d-ease) 180ms both}
.ds-anim .ds-card{animation:ds-in-card 640ms var(--d-ease) both}
.ds-anim .ds-card:nth-child(1){animation-delay:260ms}
.ds-anim .ds-card:nth-child(2){animation-delay:320ms}
.ds-anim .ds-card:nth-child(3){animation-delay:380ms}
.ds-anim .ds-ch-foot,.ds-anim .ds-ch-top{animation:ds-in-fade 480ms var(--d-ease) 440ms both}
.ds-anim .ds-ho-actions{animation:ds-in-support 480ms var(--d-ease) 220ms both}
.ds-handoff.ds-anim{animation:ds-in-fade 220ms var(--d-ease-io) both}
.ds-bar.ds-anim{animation:ds-in-bar 380ms var(--d-ease) both}

@media (prefers-reduced-motion:reduce){
  /* every entrance collapses to one short cross-fade with a no-motion
     end state — nothing may be left invisible. */
  .ds-anim .ds-eyebrow,
  .ds-anim .ds-headline,
  .ds-anim .ds-support,
  .ds-anim .ds-card,
  .ds-anim .ds-ch-foot,
  .ds-anim .ds-ch-top,
  .ds-anim .ds-ho-actions,
  .ds-handoff.ds-anim,
  .ds-bar.ds-anim{animation:ds-in-fade 140ms linear both;transform:none!important;filter:none!important}
  .ds-card,.ds-btn,.ds-bbtn,.ds-ico,.ds-theme{transition:none}
  .ds-card:hover{transform:none}
}
