/* Loop site: the AI section, a small chat over an AI composer (prototypes/loop-ai-band-2026-10-12/round10).
   Every rule is scoped to #ai; motion values are transitions.dev tokens, set on #ai. */
/* Motion tokens (transitions.dev) */
#ai {
    --duration-stagger: 40ms; --duration-micro: 80ms; --duration-quick: 150ms; --duration-fast: 250ms;
    --duration-medium: 350ms; --duration-slow: 400ms; --duration-very-slow: 500ms;
    --ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1); --ease-in-out: ease-in-out; --ease-out: ease-out; --ease-linear: linear;
    --distance-micro: 4px; --distance-base: 8px; --distance-medium: 12px;
    --blur-small: 2px; --blur-medium: 3px;
    --stream-gap: 60ms; --stream-fade: 350ms; --stream-blur: 1px;
    --shimmer-dur: 2000ms; --shimmer-band: 400%;
    --check-draw: 350ms;
    --learn-shift: 2px; --learn-spread: 8deg;

    /* The one big move: the space opens once, slowly, on an iOS sheet curve (outside the token scale on purpose). */
    --duration-open: 700ms;
    --ease-ios: cubic-bezier(0.32, 0.72, 0, 1);

    /* The composer */
    --cp-radius: 26px;
    --cp-shadow: 0 0 0 1px rgba(17, 22, 32, .07), 0 1px 2px rgba(17, 22, 32, .04), 0 8px 24px -10px rgba(17, 22, 32, .10);
    --cp-shadow-on: 0 0 0 1px rgba(17, 22, 32, .10), 0 1px 2px rgba(17, 22, 32, .05), 0 14px 34px -12px rgba(17, 22, 32, .16);
    --bubble: #F1F3F6;
    --caret: var(--accent);
    --chip-h: 32px;
  }
:root[data-theme="dark"] #ai {
    --cp-shadow: 0 0 0 1px rgba(255, 255, 255, .08), 0 1px 0 0 rgba(255, 255, 255, .04) inset, 0 16px 40px -18px rgba(0, 0, 0, .7);
    --cp-shadow-on: 0 0 0 1px rgba(255, 255, 255, .13), 0 1px 0 0 rgba(255, 255, 255, .05) inset, 0 22px 50px -18px rgba(0, 0, 0, .8);
    --bubble: #1C1F26;
  }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #ai {
      --cp-shadow: 0 0 0 1px rgba(255, 255, 255, .08), 0 1px 0 0 rgba(255, 255, 255, .04) inset, 0 16px 40px -18px rgba(0, 0, 0, .7);
      --cp-shadow-on: 0 0 0 1px rgba(255, 255, 255, .13), 0 1px 0 0 rgba(255, 255, 255, .05) inset, 0 22px 50px -18px rgba(0, 0, 0, .8);
      --bubble: #1C1F26;
    }
}
/* ---------- Head ---------- */
#ai .head h2 { font-size: clamp(30px, 3.4vw, 40px); }
#ai .section-sub { margin-top: var(--s3); font-size: 17px; }
/* ---------- The stage: a tiny conversation over a composer ---------- */
#ai .chat { position: relative; width: 100%; max-width: 620px; margin: var(--s7) auto 0; }
/* The convo hugs the box: content is anchored to its bottom edge, so while the space opens the newest line rides down with the box. */
#ai .convo { position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: flex-end; }
/* Every scene shares one cell, bottom-aligned, so the space is always the height of the tallest exchange and never changes. */
#ai .stack { display: grid; padding: 0 6px 22px; }
#ai .scene { grid-area: 1 / 1; align-self: end; display: flex; flex-direction: column; visibility: hidden; opacity: 1; filter: blur(0);
    transition: opacity var(--duration-medium) var(--ease-smooth-out), filter var(--duration-medium) var(--ease-smooth-out); }
#ai .scene.is-live { visibility: visible; }
#ai .scene.is-out { opacity: 0; filter: blur(var(--blur-small)); }
#ai .msg { display: flex; justify-content: flex-end; }
#ai .sent { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; max-width: 82%; }
#ai .bubble { padding: 9px 16px 10px; border-radius: 20px; background: var(--bubble);
    font-size: 15.5px; line-height: 1.45; letter-spacing: -0.005em; color: var(--ink1); text-wrap: balance; }
/* An attached file, as a small pill (in the box while typing, above the bubble once sent) */
#ai .file { display: inline-flex; align-items: center; gap: 7px; height: var(--chip-h); padding: 0 12px 0 9px; border-radius: 12px;
    background: var(--bubble); font-size: 13.5px; font-weight: 500; line-height: 1; letter-spacing: -0.005em; color: var(--ink1); white-space: nowrap; }
#ai .composer .file { background: var(--quiet); box-shadow: inset 0 0 0 1px var(--hairline); }
#ai .file svg { width: 16px; height: 16px; flex: none; fill: none; stroke: var(--ink2); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
#ai .tools { display: flex; flex-direction: column; gap: 6px; margin-top: 16px; padding: 0; list-style: none; }
#ai .tool { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 500; line-height: 20px; letter-spacing: -0.005em; color: var(--ink2); }
#ai .tk { position: relative; display: inline-grid; margin-left: -1px; width: 14px; height: 14px; flex: none; color: var(--ink3); }
#ai .tk svg { grid-area: 1 / 1; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
#ai .tk .spin { stroke-width: 1.6; opacity: 0; transform: scale(.25); filter: blur(var(--blur-small));
    transition: opacity var(--duration-fast) var(--ease-in-out), transform var(--duration-fast) var(--ease-in-out), filter var(--duration-fast) var(--ease-in-out); }
#ai .tk .spin circle { transform-origin: 7px 7px; animation: ai-spin 800ms var(--ease-linear) infinite; }
#ai .tk .chk { stroke-width: 1.8; }
#ai .tk .chk path { stroke-dasharray: 14; stroke-dashoffset: 0; }
#ai .tn { position: relative; display: inline-block; }
#ai .reply { margin-top: 18px; }
#ai .app { display: block; font-size: 12px; font-weight: 500; line-height: 16px; color: var(--ink3); letter-spacing: 0; }
/* The reply sits in a bubble of the same shape as the ask, on the left, in the card colour */
#ai .ans { margin-top: 6px; max-width: 82%; padding: 9px 16px 10px; border-radius: 20px; background: var(--card); box-shadow: var(--cp-shadow);
    font-size: 15.5px; line-height: 1.45; letter-spacing: -0.005em; color: var(--ink1); text-wrap: balance; }
/* No app names: the label stays in the markup only as the reply's cue */
#ai .app { display: none; }
#ai .chat.is-anim .ans { opacity: 0; transform: translateY(var(--distance-micro)); }
#ai .chat.is-anim .app.on + .ans { opacity: 1; transform: none;
    transition: opacity var(--duration-fast) var(--ease-smooth-out), transform var(--duration-fast) var(--ease-smooth-out); }
/* Animated: no space until the first message is sent, then it opens once and stays open. */
#ai .chat.is-anim .convo { height: 0; overflow: hidden; transition: height var(--duration-open) var(--ease-ios); }
#ai .chat.is-anim .convo.is-open { overflow: visible; }
/* Composer */
#ai .composer { position: relative; z-index: 2; border-radius: var(--cp-radius); background: var(--card); box-shadow: var(--cp-shadow);
    transition: box-shadow var(--duration-fast) var(--ease-smooth-out); }
#ai .composer.is-focus { box-shadow: var(--cp-shadow-on); }
/* The box is one line tall at rest and grows only when it needs to (a file, a second line), downward,
     so its top edge never moves. interpolate-size lets the height glide where the browser supports it. */
#ai .field { interpolate-size: allow-keywords; height: auto; transition: height var(--duration-fast) var(--ease-smooth-out);
    position: relative; display: grid; padding: 17px 22px 2px; font-size: 16.5px; line-height: 1.5; letter-spacing: -0.008em; color: var(--ink1); }
#ai .field > * { grid-area: 1 / 1; }
#ai .ghost { display: none; }
#ai .ghost .gap { display: block; height: calc(var(--chip-h) + 10px); }
#ai .live { align-self: start; display: grid; grid-template-rows: auto auto; min-width: 0; }
/* Attachment slot: grows open inside the box (accordion), so only the text inside moves, never the box */
#ai .slot { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--duration-fast) var(--ease-smooth-out); }
#ai .slot.is-open { grid-template-rows: 1fr; }
#ai .slot-in { min-height: 0; overflow: hidden; }
#ai .slot-in .file { margin-bottom: 10px; }
#ai .composer .file { opacity: 0; transform: scale(.96); filter: blur(var(--blur-small));
    transition: opacity var(--duration-fast) var(--ease-smooth-out), transform var(--duration-fast) var(--ease-smooth-out), filter var(--duration-fast) var(--ease-smooth-out); transform-origin: left center; }
#ai .composer .file.on { opacity: 1; transform: none; filter: blur(0); }
#ai .composer .file.is-leaving { opacity: 0; transform: translateY(calc(var(--distance-micro) * -1)); filter: blur(0);
    transition: opacity var(--duration-quick) var(--ease-out), transform var(--duration-quick) var(--ease-out); }
#ai .row { display: grid; min-width: 0; }
#ai .row > * { grid-area: 1 / 1; }
#ai .line { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
#ai .txt { transition: opacity var(--duration-quick) var(--ease-out), transform var(--duration-quick) var(--ease-out); }
#ai .txt.is-leaving { opacity: 0; transform: translateY(calc(var(--distance-micro) * -1)); }
#ai .ph { color: var(--ink3); pointer-events: none; }
#ai .ph.is-hidden { visibility: hidden; }
#ai .caret { display: inline-block; width: 2px; height: 1.15em; margin-left: 1px; margin-right: -3px; border-radius: 1px; background: var(--caret);
    vertical-align: -0.2em; opacity: 0; }
#ai .chat.is-anim .caret { opacity: 1; animation: ai-blink 1060ms steps(1, end) infinite; }
#ai .chat.is-anim .caret.is-solid { animation: none; opacity: 1; }
#ai .txt:empty + .caret { transform: translateX(-3px); }
#ai .bar { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px 10px 12px; }
#ai .plus { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; color: var(--ink2);
    box-shadow: inset 0 0 0 1px var(--hairline); }
#ai .plus svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
#ai .send { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--quiet); color: var(--ink4);
    transition: background-color var(--duration-fast) var(--ease-smooth-out), color var(--duration-fast) var(--ease-smooth-out), transform var(--duration-quick) var(--ease-smooth-out); }
#ai .send[data-state="ready"], #ai .send[data-state="busy"] { background: var(--solid); color: var(--on-solid); }
#ai .send.is-press { transform: scale(.9); transition-duration: var(--duration-fast), var(--duration-fast), var(--duration-micro); }
#ai .send .t-icon { grid-area: 1 / 1; width: 18px; height: 18px;
    transition: opacity var(--duration-fast) var(--ease-in-out), filter var(--duration-fast) var(--ease-in-out), transform var(--duration-fast) var(--ease-in-out); }
#ai .send .arrow { fill: none; stroke: currentColor; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }
#ai .send .stop { fill: currentColor; opacity: 0; filter: blur(var(--blur-small)); transform: scale(.25); }
#ai .send[data-state="busy"] .arrow { opacity: 0; filter: blur(var(--blur-small)); transform: scale(.25); }
#ai .send[data-state="busy"] .stop { opacity: 1; filter: blur(0); transform: scale(1); }
/* Setup guide link (learn-more hover) */
#ai .ai-guide { display: flex; justify-content: center; margin-top: var(--s5); }
#ai .t-learn { display: inline-flex; align-items: center; gap: 4px; font-size: 14.5px; font-weight: 500; line-height: 1.4; color: var(--ink2); text-decoration: none;
    transition: color var(--duration-quick) var(--ease-smooth-out); }
#ai .t-learn:hover, #ai .t-learn:focus-visible { color: var(--ink1); }
#ai .t-learn-chevron { display: inline-flex; transform: translateX(0); transition: transform var(--duration-medium) var(--ease-smooth-out); }
#ai .t-learn-chevron svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; overflow: visible; }
#ai .t-learn-arm { transform-box: view-box; transform-origin: 10px 8px; transition: transform var(--duration-medium) var(--ease-smooth-out); }
#ai .t-learn:hover .t-learn-chevron { transform: translateX(var(--learn-shift)); }
#ai .t-learn:hover .t-learn-arm-top { transform: rotate(var(--learn-spread)); }
#ai .t-learn:hover .t-learn-arm-bot { transform: rotate(calc(var(--learn-spread) * -1)); }
/* ---------- Animated states (only once the script runs; the default is a finished, still conversation) ---------- */
#ai .chat.is-anim .sent { opacity: 0; }
#ai .chat.is-anim .sent.on { opacity: 1; transform: none;
    transition: transform var(--duration-very-slow) var(--ease-smooth-out), opacity var(--duration-medium) var(--ease-smooth-out); }
/* Texts reveal for each tool line and the app label */
#ai .chat.is-anim .tool, #ai .chat.is-anim .app { opacity: 0; transform: translateY(var(--distance-medium)); filter: blur(var(--blur-medium)); }
#ai .chat.is-anim .tool.on, #ai .chat.is-anim .app.on { opacity: 1; transform: none; filter: blur(0);
    transition: opacity var(--duration-very-slow) var(--ease-smooth-out), transform var(--duration-very-slow) var(--ease-smooth-out), filter var(--duration-very-slow) var(--ease-smooth-out); }
/* A running tool shimmers and spins; a finished one draws its tick */
#ai .chat.is-anim .tool .chk path { stroke-dashoffset: 14; opacity: 0; }
#ai .chat.is-anim .tool.done .chk path { stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset var(--check-draw) var(--ease-smooth-out), opacity var(--duration-micro) var(--ease-out); }
#ai .chat.is-anim .tool.run .spin { opacity: 1; transform: scale(1); filter: blur(0); }
#ai .tool.run .tn { color: var(--ink4); }
#ai .tool.run .tn::before { content: attr(data-text); position: absolute; inset: 0; pointer-events: none;
    background-image: linear-gradient(90deg, transparent 0%, transparent 40%, var(--ink1) 50%, transparent 60%, transparent 100%);
    background-size: var(--shimmer-band) 100%; background-repeat: no-repeat; -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent; animation: ai-shimmer var(--shimmer-dur) var(--ease-linear) infinite; }
/* Streaming answer */
#ai .w { white-space: nowrap; }
#ai .chat.is-anim .w { opacity: 0; filter: blur(var(--stream-blur)); }
#ai .chat.is-anim .w.in { opacity: 1; filter: blur(0); transition: opacity var(--stream-fade) var(--ease-smooth-out), filter var(--stream-fade) var(--ease-smooth-out); }
#ai .chat.is-paused *, #ai .chat.is-paused *::before { animation-play-state: paused !important; }
@keyframes ai-spin { to { transform: rotate(360deg); } }
@keyframes ai-blink { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes ai-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0% 0; } }
#ai .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@media (max-width: 720px) {
  #ai .head h2 .soft { display: inline; }
  #ai .chat { margin-top: var(--s6); }
  #ai .stack { padding: 0 2px 18px; }
  #ai .sent { max-width: 88%; }
  #ai .bubble { font-size: 15px; padding: 8px 14px 9px; border-radius: 18px; }
  #ai .ans { font-size: 15px; padding: 8px 14px 9px; border-radius: 18px; max-width: 88%; }
  #ai .field { padding: 15px 18px 2px; font-size: 16px; }
  #ai .bar { padding: 6px 8px 8px 10px; }
  #ai { --cp-radius: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  #ai .scene, #ai .sent, #ai .bubble, #ai .tool, #ai .app, #ai .w, #ai .txt, #ai .send, #ai .send .t-icon, #ai .composer, #ai .composer .file, #ai .slot, #ai .tk .spin, #ai .tool .chk path, #ai .t-learn-chevron, #ai .t-learn-arm { transition: none !important; }
  #ai .tk .spin circle, #ai .caret, #ai .tool.run .tn::before { animation: none !important; }
}
/* Round 8: one step at a time. Every step shares one line; each new step takes the last one's place
     (transitions.dev text states swap), and the last step stays, ticked. */
#ai .tools { display: grid; }
#ai .tool { grid-area: 1 / 1; }
#ai .chat:not(.is-anim) .tool:not(:last-child) { visibility: hidden; }
#ai .chat.is-anim .tool.past { opacity: 0; transform: translateY(calc(var(--distance-micro) * -1)); filter: blur(var(--blur-small));
    transition: opacity var(--duration-quick) var(--ease-in-out), transform var(--duration-quick) var(--ease-in-out), filter var(--duration-quick) var(--ease-in-out); }
#ai .chat.is-anim .tool.on:not(.past) { transform: none; }
#ai .chat.is-anim .tool { transform: translateY(var(--distance-micro)); filter: blur(var(--blur-small)); }
#ai .chat.is-anim .tool.on:not(.past) { transition: opacity var(--duration-fast) var(--ease-in-out), transform var(--duration-fast) var(--ease-in-out), filter var(--duration-fast) var(--ease-in-out); }
/* Round 7: quieter steps (variant 2) */
#ai .tools { gap: 3px; margin-top: 12px; }
#ai .tool { font-weight: 400; color: var(--ink3); font-size: 12px; line-height: 17px; gap: 7px; }
#ai .tk, #ai .tk svg { width: 12px; height: 12px; }
#ai .tk { color: var(--ink4); }
#ai .tool.run .tn { color: var(--ink4); }
