/* /tools index: three live demos (swap, scale, plan) built from real data,
   then the bench of ten tools, each with a small drawing of what it does.
   Loops pause off screen (visuals.js sets .is-idle on [data-loop]); with
   reduced motion every drawing shows its finished state. */
.tl { width: min(1180px, 100% - 2 * var(--shell-pad, 24px)); margin-inline: auto; padding-bottom: clamp(2.5rem, 6vw, 4.5rem); }
.tl-hero { padding-top: clamp(1.8rem, 5vw, 3.4rem); }
.tl-title { margin: .6rem 0 .9rem; max-width: 17ch; font: 800 clamp(2.4rem, 5.6vw, 4.5rem)/1 var(--font-display); font-stretch: 92%; letter-spacing: -.03em; text-wrap: balance; color: var(--ink-deep); }
.tl-lead { max-width: 52ch; margin: 0; font-size: clamp(1.02rem, 1.4vw, 1.15rem); line-height: 1.6; color: var(--text-secondary); }

/* ------------------------------------------------------------ demos */
.tl-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem; margin-top: 1.8rem; }
.tl-demo {
  display: flex; flex-direction: column; min-width: 0; padding: 1.1rem 1.1rem 1.15rem; border: 1px solid var(--line); border-radius: 18px;
  background: var(--f-soft); color: var(--text-primary); text-decoration: none; box-shadow: var(--lift);
  transition: transform .22s var(--ease-spring), box-shadow .22s var(--ease-out);
}
.tl-demo:hover { transform: translateY(-3px); box-shadow: var(--lift-2); }
.tl-demo:focus-visible { outline: 3px solid var(--ink-deep); outline-offset: 3px; }
.tl-demo-head { display: grid; gap: .2rem; }
.tl-demo-head strong { font: 800 clamp(1.35rem, 2vw, 1.6rem)/1.05 var(--font-display); letter-spacing: -.025em; }
.tl-demo-head span { font: 600 .9rem/1.4 var(--font-body); color: var(--text-secondary); }
.tl-stage { position: relative; display: grid; min-height: 12rem; margin: .9rem 0 .85rem; padding: .95rem; overflow: hidden; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.tl-demo-foot { margin-top: auto; font: 800 .95rem var(--font-body); color: var(--f-deep, var(--text-primary)); }
.tl-demo:hover .tl-demo-foot span { display: inline-block; transform: translateX(3px); transition: transform .2s var(--ease-spring); }

/* swap */
.tl-swap { justify-items: center; align-content: center; gap: .55rem; }
.tl-swap-from { position: relative; padding: .45rem 1rem; border: 1px dashed var(--border-strong); border-radius: 999px; background: var(--bg-primary); font: 700 1rem var(--font-body); color: var(--text-secondary); }
.tl-swap-from::after { content: ""; position: absolute; left: .7rem; right: .7rem; top: 50%; height: 2px; background: var(--tomato); transform-origin: left; }
.tl-swap-arrow { color: var(--f-deep, var(--ink-deep)); }
.tl-swap-to { display: grid; justify-items: center; }
.tl-swap-to > span { grid-area: 1 / 1; display: grid; justify-items: center; gap: .1rem; padding: .55rem 1.15rem; border-radius: 16px; background: var(--f); color: #fff; font: 700 1.02rem/1.2 var(--font-body); text-align: center; box-shadow: var(--lift); }
.tl-swap-to > span small { font: 650 .74rem var(--font-body); opacity: .92; }
.tl-swap-to > span:not(:first-child) { visibility: hidden; }

/* scale */
.tl-scale { align-content: center; gap: 0; }
.tl-scale-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .45rem; }
.tl-plates { display: flex; gap: .26rem; }
.tl-plates i { width: .95rem; height: .95rem; border: 1.5px solid var(--ink-deep); border-radius: 50%; background: var(--f); box-shadow: inset 0 0 0 2.5px #fff; }
.tl-plates i.add { background: var(--saffron); }
.tl-serves { display: grid; }
.tl-serves b { grid-area: 1 / 1; justify-self: end; padding: .18rem .7rem; border-radius: 999px; background: var(--ink-deep); color: #fff; font: 800 .8rem var(--font-body); white-space: nowrap; }
.tl-serves .b { background: var(--saffron); color: var(--ink-deep); visibility: hidden; }
.tl-scale-row { display: grid; grid-template-columns: minmax(0, 1fr) 3.6rem auto; gap: .55rem; align-items: center; padding: .42rem 0; border-top: 1px dashed var(--border-strong); }
.tl-scale-row > span { overflow: hidden; font: 600 .86rem var(--font-body); white-space: nowrap; text-overflow: ellipsis; }
.tl-scale-row i { position: relative; height: .5rem; overflow: hidden; border-radius: 999px; background: var(--f-soft); }
.tl-scale-row i::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--f); transform-origin: left; }
.tl-scale-row em { display: grid; justify-items: end; font: 800 .86rem var(--font-body); font-style: normal; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tl-scale-row em span { grid-area: 1 / 1; }
.tl-scale-row em .a { visibility: hidden; }

/* plan */
.tl-plan { align-content: center; }
.tl-plan-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .3rem; }
.tl-plan-day { display: grid; justify-items: center; gap: .25rem; min-width: 0; }
.tl-plan-day small { font: 800 .68rem var(--font-body); color: var(--text-secondary); }
.tl-plan-day img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border: 1px solid var(--line); border-radius: 50%; background: var(--f); }
.tl-plan-list { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .5rem; margin-top: .95rem; padding: .55rem .75rem; border-radius: 12px; background: var(--ink-deep); color: #fff; }
.tl-plan-list b { font: 800 .84rem var(--font-body); }
.tl-plan-list span { margin-left: auto; font: 600 .74rem var(--font-body); opacity: .82; }

/* ------------------------------------------------------------ bench */
.tl-bench { margin-top: clamp(2.6rem, 6vw, 4.2rem); }
.tl-bench h2 { margin: 0 0 1.2rem; font-size: clamp(1.7rem, 3.4vw, 2.5rem); }
.tl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 16.5rem), 1fr)); gap: 1rem; }
.tl-card {
  position: relative; display: flex; flex-direction: column; min-width: 0; overflow: hidden; border: 1px solid var(--line); border-radius: 16px;
  background: #fff; color: var(--text-primary); text-decoration: none; box-shadow: var(--lift);
  transition: transform .22s var(--ease-spring), box-shadow .22s var(--ease-out);
}
.tl-card:hover { transform: translateY(-3px); box-shadow: var(--lift-2); }
.tl-card:focus-visible { outline: 3px solid var(--ink-deep); outline-offset: 3px; }
.tl-card-art { display: grid; place-items: center; height: 8.4rem; border-bottom: 1px solid var(--line); background: var(--f-soft); }
.tl-card-art svg { width: 9.6rem; height: auto; overflow: visible; stroke: var(--ink-deep); stroke-width: 2.2; }
.tl-card-body { display: grid; gap: .35rem; padding: .95rem 1.05rem 1.1rem; }
.tl-card-name { font: 760 1.18rem/1.15 var(--font-display); letter-spacing: -.02em; }
.tl-card-name .tool-card-badge { display: inline-block; margin-left: .3rem; padding: .05rem .5rem; border: 1px solid var(--line); border-radius: 999px; background: var(--saffron); color: var(--ink-deep); font: 800 .7rem/1.5 var(--font-body); vertical-align: .18em; }
.tl-card-line { font-size: .95rem; line-height: 1.45; color: var(--text-secondary); }
.tl-chips { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .15rem; }
.tl-chips span { padding: .08rem .55rem; border-radius: 999px; background: var(--f-soft); color: var(--f-deep, var(--text-secondary)); font: 700 .74rem/1.6 var(--font-body); }
.tl-card-arrow { position: absolute; top: .7rem; right: .75rem; display: grid; place-items: center; width: 2rem; height: 2rem; border: 1px solid var(--line); border-radius: 50%; background: #fff; font: 800 1rem var(--font-body); transition: transform .2s var(--ease-spring), background-color .15s; }
.tl-card:hover .tl-card-arrow { transform: translate(2px, -2px); background: var(--saffron); }
.tl-cookbook { margin-top: clamp(2rem, 5vw, 3rem); }

/* drawing fills */
.tl svg .w { fill: #fff; }
.tl svg .f { fill: var(--f); }
.tl svg .s { fill: color-mix(in srgb, var(--f) 38%, #fff); }
.tl svg .d { stroke-dasharray: 3 5; }
:where(.tl svg [class*="tl-"]) { transform-box: fill-box; transform-origin: center; }

@media (max-width: 980px) { .tl-trio { grid-template-columns: 1fr; max-width: 34rem; } }

/* ------------------------------------------------------------ motion */
@media (prefers-reduced-motion: no-preference) {
  [data-loop].is-idle, [data-loop].is-idle * { animation-play-state: paused !important; }

  /* swap: three real swaps, 3s each */
  .tl-swap-to > span { visibility: visible !important; animation: tl-swap-in 9s var(--ease-spring) infinite both; animation-delay: calc(var(--n) * 3s - 9s); }
  .tl-swap-arrow svg { animation: tl-spin 3s var(--ease-spring) infinite; }
  .tl-swap-from::after { animation: tl-strike 3s var(--ease-out) infinite; }

  /* scale: 4 -> 6 servings */
  .tl-plates i.add { animation: tl-plate-add 7s var(--ease-spring) infinite both; }
  .tl-plates i.add + i.add { animation-delay: .15s; }
  .tl-serves b { visibility: visible !important; animation: tl-fade-a 7s ease infinite both; }
  .tl-serves .b { animation-name: tl-fade-b; }
  .tl-scale-row em .a, .tl-scale-row em .b { visibility: visible !important; animation: tl-fade-a 7s ease infinite both; animation-delay: calc(var(--k) * .12s); }
  .tl-scale-row em .b { animation-name: tl-fade-b; }
  .tl-scale-row i::before { animation: tl-grow 7s var(--ease-out) infinite both; animation-delay: calc(var(--k) * .12s); }

  /* plan: seven plates drop in, then the list */
  .tl-plan-day { animation: tl-day 8s var(--ease-spring) infinite both; animation-delay: calc(var(--d) * .3s); }
  .tl-plan-list { animation: tl-list 8s var(--ease-out) infinite both; }

  /* bench drawings */
  .tl-a { animation: tl-pop 5.5s var(--ease-spring) infinite both; }
  .tl-a1 { animation-delay: .1s; } .tl-a2 { animation-delay: .4s; } .tl-a3 { animation-delay: .7s; } .tl-a4 { animation-delay: 1s; }
  .tl-a5 { animation-delay: 1.3s; } .tl-a6 { animation-delay: 1.6s; } .tl-a7 { animation-delay: 1.9s; } .tl-a8 { animation-delay: 2.3s; }
  .tl-swap-a { animation: tl-swap-a 4.5s cubic-bezier(.65, 0, .35, 1) infinite; }
  .tl-swap-b { animation: tl-swap-b 4.5s cubic-bezier(.65, 0, .35, 1) infinite; }
  .tl-copy-l { animation: tl-copy-l 4.5s var(--ease-spring) infinite both; }
  .tl-copy-r { animation: tl-copy-r 4.5s var(--ease-spring) infinite both; }
  .tl-level { transform-origin: 50% 100%; animation: tl-level 5s cubic-bezier(.65, 0, .35, 1) infinite alternate; }
  .tl-merc { transform-origin: 50% 100%; animation: tl-level 5s cubic-bezier(.65, 0, .35, 1) infinite alternate; }
  .tl-steam { animation: tl-steam 3.2s ease-in-out infinite both; }
  .tl-st2 { animation-delay: .9s; } .tl-st3 { animation-delay: 1.8s; }
  .tl-bub { animation: tl-bub 2.4s ease-in infinite both; }
  .tl-b2 { animation-delay: .8s; } .tl-b3 { animation-delay: 1.5s; }
  .tl-pin { animation: tl-pin 3.6s var(--ease-spring) infinite both; }
  .tl-ripple { stroke: var(--f-deep, var(--ink-deep)); animation: tl-ripple 3.6s ease-out infinite both; }
  .tl-coin { animation: tl-coin 3.8s cubic-bezier(.5, 0, .75, 0) infinite both; }
  .tl-tag { transform-origin: 0% 50%; animation: tl-tag 3.8s ease-in-out infinite; }
  .tl-lines { stroke-dasharray: 4 5; animation: tl-dash 2.4s linear infinite; }
  .tl-pulse { animation: tl-pulse 2.4s ease-in-out infinite; }
  .tl-page { transform-origin: 0% 50%; animation: tl-page 5s cubic-bezier(.65, 0, .35, 1) infinite both; }
}

@keyframes tl-swap-in { 0% { opacity: 0; transform: translateY(1rem) scale(.9); } 5%, 30% { opacity: 1; transform: none; } 33.3%, 100% { opacity: 0; transform: translateY(-.7rem) scale(.96); } }
@keyframes tl-spin { 0% { transform: rotate(0); } 14%, 100% { transform: rotate(180deg); } }
@keyframes tl-strike { 0% { transform: scaleX(0); } 14%, 88% { transform: scaleX(1); } 100% { transform: scaleX(0); } }
@keyframes tl-plate-add { 0%, 38% { opacity: 0; transform: scale(0); } 46%, 90% { opacity: 1; transform: none; } 97%, 100% { opacity: 0; transform: scale(0); } }
@keyframes tl-fade-a { 0%, 38% { opacity: 1; } 44%, 92% { opacity: 0; } 98%, 100% { opacity: 1; } }
@keyframes tl-fade-b { 0%, 38% { opacity: 0; transform: translateY(4px); } 44%, 92% { opacity: 1; transform: none; } 98%, 100% { opacity: 0; } }
@keyframes tl-grow { 0%, 38% { transform: scaleX(.667); } 48%, 92% { transform: scaleX(1); } 100% { transform: scaleX(.667); } }
@keyframes tl-day { 0% { opacity: 0; transform: translateY(-.8rem) scale(.7); } 6%, 86% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; transform: scale(.9); } }
@keyframes tl-list { 0%, 34% { opacity: 0; transform: translateY(.8rem); } 40%, 88% { opacity: 1; transform: none; } 95%, 100% { opacity: 0; } }
@keyframes tl-pop { 0% { opacity: 0; transform: scale(0); } 5% { opacity: 1; transform: scale(1.2); } 9%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: scale(.6); } }
@keyframes tl-swap-a { 0%, 12% { transform: none; } 30% { transform: translate(30px, -15px); } 48%, 62% { transform: translate(64px, 0); } 80% { transform: translate(30px, 15px); } 98%, 100% { transform: none; } }
@keyframes tl-swap-b { 0%, 12% { transform: none; } 30% { transform: translate(-30px, 15px); } 48%, 62% { transform: translate(-64px, 0); } 80% { transform: translate(-30px, -15px); } 98%, 100% { transform: none; } }
@keyframes tl-copy-l { 0%, 15% { opacity: 0; transform: translateX(30px) scale(.8); } 35%, 85% { opacity: 1; transform: none; } 97%, 100% { opacity: 0; transform: translateX(30px) scale(.8); } }
@keyframes tl-copy-r { 0%, 25% { opacity: 0; transform: translateX(-30px) scale(.8); } 45%, 85% { opacity: 1; transform: none; } 97%, 100% { opacity: 0; transform: translateX(-30px) scale(.8); } }
@keyframes tl-level { from { transform: scaleY(.35); } to { transform: scaleY(1); } }
@keyframes tl-steam { 0% { opacity: 0; transform: translateY(4px); } 40% { opacity: 1; } 100% { opacity: 0; transform: translateY(-8px); } }
@keyframes tl-bub { 0% { opacity: 0; transform: translateY(4px); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateY(-8px); } }
@keyframes tl-pin { 0% { opacity: 0; transform: translateY(-16px); } 14% { opacity: 1; transform: translateY(2px); } 20%, 88% { transform: none; opacity: 1; } 100% { opacity: 0; transform: none; } }
@keyframes tl-ripple { 0%, 16% { opacity: 0; transform: scale(.4); } 20% { opacity: 1; } 60%, 100% { opacity: 0; transform: scale(3); } }
@keyframes tl-coin { 0% { opacity: 0; transform: translateY(-6px); } 10% { opacity: 1; } 38%, 85% { opacity: 1; transform: translateY(16px); } 100% { opacity: 0; transform: translateY(16px); } }
@keyframes tl-tag { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
@keyframes tl-dash { to { stroke-dashoffset: -18; } }
@keyframes tl-pulse { 0%, 100% { transform: scale(.8); } 50% { transform: scale(1.35); } }
@keyframes tl-page { 0% { opacity: 0; transform: none; } 10%, 22% { opacity: 1; transform: none; } 50%, 74% { opacity: 1; transform: scaleX(-1); } 90%, 100% { opacity: 0; transform: scaleX(-1); } }

@media (prefers-reduced-motion: reduce) {
  .tl-serves .a { visibility: hidden; }
  .tl-serves .b { visibility: visible; }
  .tl-scale-row em { display: flex; gap: .3rem; }
  .tl-scale-row em .a { visibility: visible; color: var(--text-secondary); font-weight: 600; }
  .tl-scale-row em .b::before { content: "→ "; }
  .tl-demo, .tl-card, .tl-card-arrow { transition: none; }
}
