`; document.body.appendChild(el); return el; } const bubble = ensureBubble(); const elH = bubble.querySelector("#tt-title"); const elB = bubble.querySelector("#tt-body"); const elClose = bubble.querySelector(".tt-close"); // ---------------- Parse [[term|heading|body]] anywhere ---------------- const TOKEN_RE = /\[\[([^|\]]+)\|([^|\]]+)\|([^\]]+)\]\]/g; const BLOCK_SKIP = new Set(["SCRIPT","STYLE","NOSCRIPT","TEXTAREA","INPUT","SELECT","CODE","PRE","TEMPLATE","IFRAME"]); function shouldSkipTextNode(n){ let el = n.parentElement; while (el){ if (BLOCK_SKIP.has(el.tagName) || el.isContentEditable) return true; el = el.parentElement; } return false; } const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT); const textNodes = []; while (walker.nextNode()){ const n = walker.currentNode; if (!n.nodeValue || shouldSkipTextNode(n)) continue; if (TOKEN_RE.test(n.nodeValue)) textNodes.push(n); TOKEN_RE.lastIndex = 0; } textNodes.forEach(node => { const frag = document.createDocumentFragment(); const insideLink = !!node.parentElement.closest("a"); let text = node.nodeValue, last = 0; TOKEN_RE.lastIndex = 0; let m; while ((m = TOKEN_RE.exec(text))){ if (m.index > last) frag.appendChild(document.createTextNode(text.slice(last, m.index))); const term=m[1].trim(), heading=m[2].trim(), body=m[3].trim(); const t = insideLink ? document.createElement("span") : document.createElement("button"); if (insideLink){ t.setAttribute("role","button"); t.setAttribute("tabindex","0"); } else { t.type="button"; } t.className="tt-trigger"; t.textContent=term; t.setAttribute("data-tt-h", heading); t.setAttribute("data-tt-b", body); t.setAttribute("aria-haspopup","dialog"); t.setAttribute("aria-expanded","false"); frag.appendChild(t); last = TOKEN_RE.lastIndex; } if (last < text.length) frag.appendChild(document.createTextNode(text.slice(last))); node.parentNode.replaceChild(frag, node); }); // ---------------- State ---------------- let current = null; let hoverCount = 0; let closeTimer = null; // Dimming bookkeeping let dimCtx = null; // { container, dimEls:[], wrappedTexts:[], pathEls:[] } // ---------------- Find the correct "text element" container ---------------- function findTextContainer(trigger){ // Prefer common RTE wrappers let el = trigger.closest(".w-richtext, .rich-text, .rte, [data-rte]"); if (el) return el; // Otherwise climb until we find an ancestor that contains multiple block nodes anywhere inside. const BLOCK_SEL = "p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre,figure,figcaption"; el = trigger.parentElement; while (el && el !== document.body){ const blockCount = el.querySelectorAll(BLOCK_SEL).length; if (blockCount >= 2) return el; el = el.parentElement; } // Fallback: nearest non-inline container el = trigger.parentElement || document.body; while (el && el !== document.body){ const d = getComputedStyle(el).display; if (d !== "inline" && d !== "contents") return el; el = el.parentElement; } return document.body; } // Utility: child of `ancestor` that contains `target` (direct child) function directChildContaining(ancestor, target){ for (const ch of ancestor.children){ if (ch === target || ch.contains(target)) return ch; } return null; } function getElementTarget(e) { // If target is already an Element, use it if (e.target instanceof Element) return e.target; // Otherwise, walk the composed/path for the first Element const path = (typeof e.composedPath === 'function') ? e.composedPath() : []; for (const n of path) if (n instanceof Element) return n; return null; } // ---------------- Dim everything except the trigger branch (sibling branches only) ---------------- function dimAllOtherBranches(container, trigger){ undim(); // clear previous const dimEls = []; const wrappedTexts = []; const pathEls = []; // Build ELEMENT-only path [container -> ... -> trigger] const path = []; for (let el = trigger; el && el !== container; el = el.parentElement) path.push(el); path.push(container); path.reverse(); // At each ancestor level, find the *direct* child that leads to the trigger for (let i = 0; i < path.length; i++){ const anc = path[i]; const branchChild = (i < path.length - 1) ? directChildContaining(anc, path[i+1]) : path[i]; // last step is the trigger itself // Fade element siblings (whole branches) for (const child of anc.children){ if (child === branchChild) continue; // keep the path branch crisp // Never fade any element that is (or contains) the trigger if (child === trigger || child.contains(trigger)) continue; child.style.transition = `opacity ${DIM_EASE_MS}ms ease`; child.style.opacity = String(DIM_OPACITY); dimEls.push(child); } // Fade TEXT NODE siblings directly under this ancestor (outside branchChild) anc.childNodes.forEach(node => { if (node.nodeType !== 3) return; // text only if (!node.nodeValue || !node.nodeValue.trim()) return; // If this text node sits inside branchChild, skip if (branchChild && branchChild.contains && branchChild.contains(node)) return; const span = document.createElement("span"); span.style.transition = `opacity ${DIM_EASE_MS}ms ease`; span.style.opacity = String(DIM_OPACITY); span.textContent = node.nodeValue; node.parentNode.replaceChild(span, node); wrappedTexts.push(span); }); // Keep a reference to the path elements (so we can explicitly restore opacity if needed) if (anc && anc.nodeType === 1) pathEls.push(anc); } // Hard-guard: explicitly set opacity:1 on the entire path to neutralize any inherited fade pathEls.forEach(el => { el.style.opacity = "1"; }); dimCtx = { container, dimEls, wrappedTexts, pathEls }; } function undim(){ if (!dimCtx) return; const { dimEls, wrappedTexts, pathEls } = dimCtx; // Animate back dimEls.forEach(el => { el.style.transition = `opacity ${DIM_EASE_MS}ms ease`; el.style.opacity = "1"; // remove inline style after the animation so we don't override site CSS setTimeout(() => { if (el) el.style.opacity = ""; }, DIM_EASE_MS + 50); }); wrappedTexts.forEach(span => { span.style.transition = `opacity ${DIM_EASE_MS}ms ease`; span.style.opacity = "1"; span.addEventListener("transitionend", () => { if (!span.parentNode) return; span.parentNode.replaceChild(document.createTextNode(span.textContent || ""), span); }, { once:true }); }); // Clear hard-guard on path pathEls.forEach(el => { if (el) el.style.opacity = ""; }); dimCtx = null; } // ---------------- Positioning (centered, edge-aware, flip) ---------------- function clamp(v,min,max){ return Math.max(min,Math.min(max,v)); } function measureBubbleForPlacement(){ const wasOpen = bubble.classList.contains("is-open"); if (!wasOpen){ bubble.style.visibility="hidden"; bubble.classList.add("is-open"); } const rect = bubble.getBoundingClientRect(); if (!wasOpen){ bubble.classList.remove("is-open"); bubble.style.visibility=""; } return { w: rect.width, h: rect.height }; } function placeAnchored(trigger){ const vw=innerWidth, vh=innerHeight; const r = trigger.getBoundingClientRect(); const { w, h } = measureBubbleForPlacement(); let left = r.left + (r.width/2) - (w/2); left = clamp(left, EDGE_PADDING, Math.max(EDGE_PADDING, vw - EDGE_PADDING - w)); const topBelow = r.bottom + OFFSET_Y; const spaceBelow = vh - topBelow - EDGE_PADDING; const placeBelow = spaceBelow >= h; let top = placeBelow ? topBelow : (r.top - h - OFFSET_Y); top = clamp(top, EDGE_PADDING, Math.max(EDGE_PADDING, vh - EDGE_PADDING - h)); bubble.style.left = left + "px"; bubble.style.top = top + "px"; const br = bubble.getBoundingClientRect(); if (br.bottom > vh - EDGE_PADDING){ bubble.style.maxHeight = (vh - 2*EDGE_PADDING) + "px"; bubble.style.overflowY = "auto"; } else { bubble.style.maxHeight = "none"; bubble.style.overflowY = "visible"; } } // ---------------- Open / Close (place → fade/scale) ---------------- function animateIn(){ bubble.style.transition = "none"; bubble.style.opacity = "0"; bubble.style.transform = "scale(0.95)"; void bubble.offsetWidth; bubble.style.transition = "opacity .18s ease, transform .18s ease"; bubble.style.opacity = "1"; bubble.style.transform = "scale(1)"; } function animateOut(done){ bubble.style.transition = "opacity .16s ease, transform .16s ease"; bubble.style.opacity = "0"; bubble.style.transform = "scale(0.95)"; const end = () => { bubble.removeEventListener("transitionend", end); done && done(); }; bubble.addEventListener("transitionend", end); setTimeout(end, 260); } function openFromTrigger(trigger){ if (current && current !== trigger) forceClose(); current = trigger; trigger.setAttribute("aria-expanded","true"); elH.textContent = trigger.getAttribute("data-tt-h") || ""; elB.textContent = trigger.getAttribute("data-tt-b") || ""; bubble.classList.add("is-open"); bubble.setAttribute("aria-hidden","false"); placeAnchored(trigger); animateIn(); const container = findTextContainer(trigger); dimAllOtherBranches(container, trigger); hoverCount = 0; cancelCloseTimer(); } function forceClose(){ if (!current) return; bubble.classList.remove("is-open"); bubble.setAttribute("aria-hidden","true"); current.setAttribute("aria-expanded","false"); current = null; undim(); hoverCount = 0; cancelCloseTimer(); } function closeWithAnim(){ if (!current) return; const t = current; animateOut(() => { bubble.classList.remove("is-open"); bubble.setAttribute("aria-hidden","true"); t.setAttribute("aria-expanded","false"); current = null; undim(); }); } function scheduleClose(){ cancelCloseTimer(); closeTimer = setTimeout(() => { if (hoverCount <= 0 && !isCoarse()) closeWithAnim(); }, CLOSE_DELAY); } function cancelCloseTimer(){ if (closeTimer){ clearTimeout(closeTimer); closeTimer = null; } } // ---------------- Hover-intent (desktop) ---------------- function onZoneEnter(){ if (isCoarse()) return; hoverCount++; cancelCloseTimer(); } function onZoneLeave(){ if (isCoarse()) return; hoverCount = Math.max(0, hoverCount - 1); if (hoverCount === 0) scheduleClose(); } bubble.addEventListener("pointerenter", onZoneEnter, true); bubble.addEventListener("mouseenter", onZoneEnter, true); bubble.addEventListener("pointerleave", onZoneLeave, true); bubble.addEventListener("mouseleave", onZoneLeave, true); const handleEnter = (e) => { if (isCoarse()) return; const target = getElementTarget(e); if (!target) return; const t = target.closest(".tt-trigger"); if (!t) return; onZoneEnter(); if (!current || current !== t) openFromTrigger(t); }; const handleLeave = (e) => { if (isCoarse()) return; const target = getElementTarget(e); if (!target) return; const t = target.closest(".tt-trigger"); if (!t) return; onZoneLeave(); }; document.addEventListener("pointerenter", handleEnter, true); document.addEventListener("mouseenter", handleEnter, true); document.addEventListener("pointerleave", handleLeave, true); document.addEventListener("mouseleave", handleLeave, true); // ---------------- Keyboard ---------------- document.addEventListener("focusin", (e) => { if (!e.target) return; const t = e.target.closest(".tt-trigger"); if (t) openFromTrigger(t); }); document.addEventListener("focusout", (e) => { if (!e.target) return; const t = e.target.closest(".tt-trigger"); if (t && current === t) closeWithAnim(); }); // ---------------- Mobile / coarse ---------------- document.addEventListener("pointerdown", (e) => { if (!isCoarse()) return; const t = e.target.closest(".tt-trigger"); if (!t) return; e.preventDefault(); e.stopPropagation(); if (current === t && bubble.classList.contains("is-open")) { closeWithAnim(); return; } openFromTrigger(t); }, true); document.addEventListener("click", (e) => { if (!isCoarse()) return; if (!bubble.classList.contains("is-open")) return; const inBubble = !!e.target.closest(".tt-bubble"); const onTrigger = !!e.target.closest(".tt-trigger"); if (!inBubble && !onTrigger) closeWithAnim(); }, true); // Close button + ESC elClose.addEventListener("click", closeWithAnim); document.addEventListener("keydown", (e) => { if (e.key === "Escape") closeWithAnim(); }); // Reposition on resize/scroll while open const reposition = () => { if (!current) return; placeAnchored(current); }; addEventListener("resize", reposition, { passive: true }); addEventListener("scroll", reposition, { passive: true }); });

Blog

Product news and best practices for teams building with Claude.

Try Claude

Cowork: Claude Code for the rest of your work

January 12, 2026
Read more

How enterprises are building AI agents in 2026

December 9, 2025
Read more

Improving frontend design through Skills

November 12, 2025
Read more

Building AI agents for financial services

October 30, 2025
Read more

Claude Code on the web

October 20, 2025
Read more

Claude and Slack

October 1, 2025
Read more

Piloting Claude in Chrome

August 25, 2025
Read more

How Anthropic teams use Claude Code

July 24, 2025
Read more

Claude can now connect to your world

May 1, 2025
Read more

Introducing the Max Plan

April 9, 2025
Read more

Cowork: Claude Code for the rest of your work

January 12, 2026
Read more

How enterprises are building AI agents in 2026

December 9, 2025
Read more

Improving frontend design through Skills

November 12, 2025
Read more

Building AI agents for financial services

October 30, 2025
Read more

Claude Code on the web

October 20, 2025
Read more

Claude and Slack

October 1, 2025
Read more

Piloting Claude in Chrome

August 25, 2025
Read more

How Anthropic teams use Claude Code

July 24, 2025
Read more

Claude can now connect to your world

May 1, 2025
Read more

Introducing the Max Plan

April 9, 2025
Read more
Filter and sort
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Feb 12, 2026
Claude Enterprise, now available self-serve
Enterprise AI
Claude Enterprise, now available self-serve
February 12, 2026
Claude Enterprise, now available self-serve
Claude Enterprise, now available self-serve
Feb 9, 2026
Behind the model launch: What customers discovered testing Claude Opus 4.6 early
Enterprise AI
Behind the model launch: What customers discovered testing Claude Opus 4.6 early
February 9, 2026
Behind the model launch: What customers discovered testing Claude Opus 4.6 early
Behind the model launch: What customers discovered testing Claude Opus 4.6 early
Feb 5, 2026
Advancing finance with Claude Opus 4.6
Enterprise AI
Advancing finance with Claude Opus 4.6
February 5, 2026
Advancing finance with Claude Opus 4.6
Advancing finance with Claude Opus 4.6
Jan 30, 2026
Customize Cowork with plugins
Product announcements
Customize Cowork with plugins
January 30, 2026
Customize Cowork with plugins
Customize Cowork with plugins
Jan 29, 2026
A complete guide to building skills for Claude
Claude Code
A complete guide to building skills for Claude
January 29, 2026
A complete guide to building skills for Claude
A complete guide to building skills for Claude
Jan 29, 2026
Understand Claude Code’s impact with contribution metrics
Claude Code
Understand Claude Code’s impact with contribution metrics
January 29, 2026
Understand Claude Code’s impact with contribution metrics
Understand Claude Code’s impact with contribution metrics
Jan 28, 2026
How leading retailers are turning AI pilots into enterprise-wide transformation
Enterprise AI
How leading retailers are turning AI pilots into enterprise-wide transformation
January 28, 2026
How leading retailers are turning AI pilots into enterprise-wide transformation
How leading retailers are turning AI pilots into enterprise-wide transformation
Jan 28, 2026
Updates to Claude Team
Product announcements
Updates to Claude Team
January 28, 2026
Updates to Claude Team
Updates to Claude Team
Jan 26, 2026
Your favorite work tools are now interactive inside Claude
Product announcements
Your favorite work tools are now interactive inside Claude
January 26, 2026
Your favorite work tools are now interactive inside Claude
Your favorite work tools are now interactive inside Claude
Jan 26, 2026
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code
Enterprise AI
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code
January 26, 2026
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code
Jan 23, 2026
Building multi-agent systems: when and how to use them
Agents
Building multi-agent systems: when and how to use them
January 23, 2026
Building multi-agent systems: when and how to use them
Building multi-agent systems: when and how to use them
Jan 22, 2026
Building agents with Skills: Equipping agents for specialized work
Agents
Building agents with Skills: Equipping agents for specialized work
January 22, 2026
Building agents with Skills: Equipping agents for specialized work
Building agents with Skills: Equipping agents for specialized work
Jan 21, 2026
Eight trends defining how software gets built in 2026
Agents
Eight trends defining how software gets built in 2026
January 21, 2026
Eight trends defining how software gets built in 2026
Eight trends defining how software gets built in 2026
Jan 12, 2026
Cowork: Claude Code for the rest of your work
Product announcements
Cowork: Claude Code for the rest of your work
January 12, 2026
Cowork: Claude Code for the rest of your work
Cowork: Claude Code for the rest of your work
Dec 19, 2025
Extending Claude’s capabilities with skills and MCP servers
Agents
Extending Claude’s capabilities with skills and MCP servers
December 19, 2025
Extending Claude’s capabilities with skills and MCP servers
Extending Claude’s capabilities with skills and MCP servers
Category
Product
Usecase

How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code

Category
Enterprise AI
Product
Usecase
January 26, 2026
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code
How Anthropic's Growth Marketing team cut ad creation time from 30 minutes to 30 seconds with Claude Code

No posts for those filters

Try another search or clear some of your filters.

Clear all filters
eBook
Webinar
Link

Building trusted
AI in the enterprise

Anthropic’s guide to starting, scaling, and succeeding based on real-world examples and best practices

Download now
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Transform how your organization operates with Claude

See pricing
Contact sales

Get the developer newsletter

Product updates, how-tos, community spotlights, and more. Delivered monthly to your inbox.

Subscribe

Please provide your email address if you'd like to receive our monthly developer newsletter. You can unsubscribe at any time.

Thank you! You’re subscribed.
Sorry, there was a problem with your submission, please try again later.