PageSourceSearch

https://claudeacademy.ca/host

html claudeacademy.ca collected 2026-10-04 14:31:15 UTC 54,099 bytes, 626 lines download raw bytes

1<!DOCTYPE html><html lang="en-CA"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>A free lunch-hour session for your members | Reclaim Your Time with AI</title><meta name="description" content="For co-working and business-centre managers in Ottawa-Gatineau: a free one-hour lunch-and-learn where each member hands off one of their own tasks to AI. Everyone learns to connect their AI agent to 1,500 tools at no cost, and leaves with a free book. English or French."><link rel="canonical" href="https://claudeacademy.ca/host"><link rel="icon" href="/favicon.svg" type="image/svg+xml"><link rel="alternate" hreflang="en-CA" href="https://claudeacademy.ca/host"><link rel="alternate" hreflang="fr-CA" href="https://claudeacademy.ca/fr/accueillir"><link rel="alternate" hreflang="x-default" href="https://claudeacademy.ca/host"><meta property="og:type" content="website"><meta property="og:site_name" content="Reclaim Your Time with AI"><meta property="og:title" content="A free lunch-hour session for your members | Reclaim Your Time with AI"><meta property="og:description" content="For co-working and business-centre managers in Ottawa-Gatineau: a free one-hour lunch-and-learn where each member hands off one of their own tasks to AI. Everyone learns to connect their AI agent to 1,500 tools at no cost, and leaves with a free book. English or French."><meta property="og:url" content="https://claudeacademy.ca/host"><meta property="og:locale" content="en_CA"><meta name="twitter:card" content="summary_large_image"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;600&family=Inter:wght@400;500;600;700&family=Caveat:wght@500;700&display=swap" rel="stylesheet"><style>*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}img,svg,video{display:block;max-width:100%}a{color:inherit}button,input,textarea,select{font:inherit;color:inherit}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.skip-link{position:absolute;left:-9999px;top:0;z-index:999;padding:.7rem 1.1rem;background:#2e6fb5;color:#10151b;border-radius:0 0 10px;font-weight:600;text-decoration:none}.skip-link:focus{left:0}:focus-visible{outline:2px solid #a8d4f5;outline-offset:3px;border-radius:4px}.apply{display:flex;flex-direction:column;gap:2rem;max-width:620px}.apply fieldset{border:none;padding:0;margin:0;display:flex;flex-direction:column;gap:1.1rem}.apply legend{font-family:var(--mono);font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);padding:0 0 .9rem;border-bottom:1px solid var(--line);width:100%;display:flex;align-items:baseline;gap:.7rem}.apply .step-n{color:var(--hot)}.field{display:flex;flex-direction:column;gap:.42rem}.field-row{display:grid;grid-template-columns:1fr;gap:1.1rem}@media (min-width: 620px){.field-row{grid-template-columns:1.4fr 1fr}}.field label{font-size:.94rem;font-weight:500;line-height:1.45}.field input,.field select,.field textarea{font:inherit;font-size:1rem;color:var(--ink-1);background:var(--bg-2);border:1px solid var(--line);border-radius:10px;padding:.72rem .85rem;width:100%;transition:border-color .15s ease,box-shadow .15s ease}.field textarea{resize:vertical;line-height:1.6}.field input::placeholder,.field textarea::placeholder{color:var(--ink-3)}.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px #7eb8e833}.field input[aria-invalid=true],.field select[aria-invalid=true],.field textarea[aria-invalid=true]{border-color:var(--red)}.hint{font-size:.82rem;color:var(--ink-3);margin:0;line-height:1.5}.apply .micro{margin-top:.2rem}.applied{max-width:620px}.applied h2{margin-top:.3rem}.applied .btn{margin-top:1rem}@media (prefers-reduced-motion: reduce){.field input,.field select,.field textarea{transition:none}}.nav-actions{display:flex;align-items:center;gap:.75rem}.lang-switch{font-size:.78rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft, #536072);text-decoration:none;padding:.35rem .6rem;border:1px solid var(--line, #d3dce6);border-radius:999px;white-space:nowrap;transition:color .15s ease,border-color .15s ease}.lang-switch:hover,.lang-switch:focus-visible{color:var(--ink, #0d1b2a);border-color:var(--ink-soft, #536072)}@media (max-width: 560px){.lang-switch{border-color:transparent;padding-left:.25rem;padding-right:.25rem}}.book-band{display:grid;grid-template-columns:240px 1fr;gap:clamp(2rem,5vw,4rem);align-items:center}.book-cover{display:block;line-height:0;border-radius:6px;transition:transform .2s ease,box-shadow .2s ease;box-shadow:0 24px 48px -18px #000000a6}.book-cover img{width:100%;height:auto;border-radius:6px}.book-cover:hover{transform:translateY(-4px) rotate(-.6deg);box-shadow:0 30px 56px -18px #000000bf}@media (max-width: 720px){.book-band{grid-template-columns:1fr}
1.book-cover{max-width:200px;margin:0 auto}}
2</style>
3<link rel="stylesheet" href="/_astro/book.CzdAyAfc.css">
4<link rel="stylesheet" href="/_astro/accueillir.P4yuLrYB.css">
5<style>.chooser-band[data-astro-cid-w4bfa2eq]{padding-top:1.5rem;padding-bottom:1.5rem}.chooser[data-astro-cid-w4bfa2eq]{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-top:.6rem}.chooser-card[data-astro-cid-w4bfa2eq]{background:var(--paper-warm);border:1px solid var(--border);border-radius:4px;padding:1.1rem 1.2rem;display:flex;flex-direction:column;gap:.45rem}.chooser-card[data-astro-cid-w4bfa2eq].current{border:2px solid var(--red-pen)}.chooser-card[data-astro-cid-w4bfa2eq] p[data-astro-cid-w4bfa2eq]{margin:0}.chooser-tag[data-astro-cid-w4bfa2eq]{font-weight:700;color:var(--red-pen);text-transform:uppercase;letter-spacing:.06em;font-size:.8rem;display:flex;gap:.5rem;align-items:center;flex-wrap:wrap}.chooser-here[data-astro-cid-w4bfa2eq]{background:var(--red-pen);color:var(--paper-warm);border-radius:3px;padding:.05rem .4rem;font-size:.7rem}.chooser-who[data-astro-cid-w4bfa2eq]{font-weight:700;color:var(--ink)}.chooser-what[data-astro-cid-w4bfa2eq]{font-size:.94rem;flex:1}.chooser-card[data-astro-cid-w4bfa2eq] .btn[data-astro-cid-w4bfa2eq]{align-self:flex-start;margin-top:.3rem}.chooser-more[data-astro-cid-w4bfa2eq]{font-size:.85rem}@media (max-width: 760px){.chooser[data-astro-cid-w4bfa2eq]{grid-template-columns:1fr}}
6</style>
7<link rel="stylesheet" href="/_astro/host.Cuu4_RFN.css">
8<link rel="stylesheet" href="/_astro/host.DgV8SrVK.css">
9<style>.wordmark-warm{font-family:var(--f-display);font-weight:900;font-size:1.15rem;color:var(--ink);text-decoration:none;letter-spacing:-.01em}.wordmark-warm em{font-style:italic;color:var(--red-pen)}.links-warm{display:flex;gap:1.5rem;font-family:var(--f-type);font-size:.76rem;letter-spacing:.05em;text-transform:uppercase}.links-warm a{color:var(--muted-fg);text-decoration:none}.links-warm a:hover{color:var(--red-pen)}.btn-sm{padding:.55rem 1rem;font-size:.85rem}.nav-actions{display:flex;align-items:center;gap:.75rem}.lang-switch-warm{font-family:var(--f-type);font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--muted-fg);text-decoration:none;border-bottom:1px dashed var(--border);white-space:nowrap}.lang-switch-warm:hover{color:var(--red-pen)}@media (max-width: 780px){.links-warm{display:none}}
10</style>
10<script type="module" src="/_astro/hoisted.CO0E25on.js"></script>
10</head> <body> <a class="skip-link" href="#main">Skip to content</a> <header class="nav"> <div class="nav-inner"> <a class="wordmark-warm" href="/">Claude <em>Academy</em></a> <nav class="links-warm" aria-label="Primary"> <a href="https://www.skool.com/claudeacademy">Community</a><a href="/#audit">AI Audit</a><a href="/skills">Skills Pack</a><a href="/workshops">Workshops</a><a href="/host">In person</a> </nav> <span class="nav-actions"> <a href="/fr/accueillir" class="lang-switch-warm" hreflang="fr-CA" lang="fr" aria-label="Voir ce site en français">
11Français
12</a> <a href="https://www.skool.com/claudeacademy" class="btn btn-light btn-sm">Join free</a> </span> </div> </header> <main id="main">  <div class="host-page"> <!-- HERO --> <section class="hero pad"> <div class="wrap"> <div class="host-hero"> <div> <p class="kicker hot">For community managers &middot; free &middot; one hour &middot; Ottawa-Gatineau</p> <h1>A free lunch-hour session <em>for your members.</em></h1> <p class="lede">
13Thank you for taking a look. I'm Denis from Claude Academy. We help people and
14            companies reclaim their time using Claude skills, plugins and off-the-shelf AI tools.
15</p> <p>
16The offer is a free lunch-and-learn for your members. In one hour, each person takes
17            one of their own tasks and sees how to hand it off to AI, with the right workflow and
18            skills set up for it.
19</p> <p class="cta-row">
19 <a href="#request" class="btn btn-accent btn-lg">Request a lunch at my space</a> <a href="#hour" class="btn btn-light btn-lg">See the hour</a> </p> <p class="lang-badge"> <span class="lang-tag">EN</span><span class="lang-tag fr">FR</span>
20Runs in English, French, or the mix your members speak
21</p> </div> <div class="handoff" aria-label="Three tasks going from done by hand to handed off"> <p class="handoff-title">Over lunch, on the screen</p> <div class="job"> <div class="job-head"> <p class="job-name">The quote</p> <span class="job-state"><span class="from">By hand</span><span class="to">Handed off</span></span> </div> <p class="job-note">Written from their own price list while they watch.</p> <div class="job-bar"><i></i></div> </div><div class="job"> <div class="job-head"> <p class="job-name">The follow-up</p> <span class="job-state"><span class="from">By hand</span><span class="to">Handed off</span></span> </div> <p class="job-note">Sent the same day, not next week.</p> <div class="job-bar"><i></i></div> </div><div class="job"> <div class="job-head"> <p class="job-name">The inbox</p> <span class="job-state"><span class="from">By hand</span><span class="to">Handed off</span></span> </div> <p class="job-note">Sorted and drafted before the first coffee.</p> <div class="job-bar"><i></i></div> </div> </div> </div> </div> </section> <!-- WHICH ONE IS FOR YOU (Denis, 2026-09-25) --> <section class="pad chooser-band" aria-labelledby="chooser-title" data-astro-cid-w4bfa2eq> <div class="wrap" data-astro-cid-w4bfa2eq> <p class="kicker" id="chooser-title" data-astro-cid-w4bfa2eq>Which one is for you?</p> <div class="chooser" data-astro-cid-w4bfa2eq> <div class="chooser-card" data-astro-cid-w4bfa2eq> <p class="chooser-tag" data-astro-cid-w4bfa2eq> Online  </p> <p class="chooser-who" data-astro-cid-w4bfa2eq>Just me.</p> <p class="chooser-what" data-astro-cid-w4bfa2eq>Every second Thursday, 1:00pm Eastern. Sixty minutes, on my screen.</p> <a href="https://cal.com/claudeacademy.ca/reclaim-your-hours-workshop" class="btn btn-light" data-astro-cid-w4bfa2eq>Save my online seat</a> <a href="/workshops" class="chooser-more" data-astro-cid-w4bfa2eq>Learn more</a> </div><div class="chooser-card current" data-astro-cid-w4bfa2eq> <p class="chooser-tag" data-astro-cid-w4bfa2eq> At your space <span class="chooser-here" data-astro-cid-w4bfa2eq>You are here</span> </p> <p class="chooser-who" data-astro-cid-w4bfa2eq>I run a co-working space or centre.</p> <p class="chooser-what" data-astro-cid-w4bfa2eq>A free lunch hour for your members. We set the date together.</p> <a href="/host#request" class="btn btn-accent" data-astro-cid-w4bfa2eq>Request a lunch at my space</a>  </div><div class="chooser-card" data-astro-cid-w4bfa2eq> <p class="chooser-tag" data-astro-cid-w4bfa2eq> At your company  </p> <p class="chooser-who" data-astro-cid-w4bfa2eq>My team, at our office.</p> <p class="chooser-what" data-astro-cid-w4bfa2eq>The same hour, at lunch, for one company.</p> <a href="/lunch-and-learn#request" class="btn btn-light" data-astro-cid-w4bfa2eq>Request a lunch at my office</a> <a href="/lunch-and-learn" class="chooser-more" data-astro-cid-w4bfa2eq>Learn more</a> </div> </div> </div> </section>  <!-- GUARANTEE --> <section class="pad guarantee" id="guarantee"> <div class="wrap" style="max-width:980px"> <div class="guarantee-grid" data-reveal> <div class="g-badge" aria-hidden="true"> <div> <span class="g-num" data-count="1500">1,500</span> <span class="g-unit">tools &middot; no cost</span> </div> </div> <div> <p class="kicker">Our guarantee</p> <p class="g-line">
22Everyone who comes learns how to connect their AI agent, whichever one they use, to
23            1,500 tools at no cost.
24</p> <p>Nothing to buy, and it works with the agent they already have.</p> </div> </div> </div> </section> <!-- TRUST --> <section class="pad band-letter"> <div class="wrap"> <div class="tiles trust-tiles"> <div class="tile" data-reveal style="--i:0"> <p class="kicker">Free</p> <p>No fee to the space, no fee to members, no upsell from the front.</p> </div> <div class="tile" data-reveal style="--i:1"> <p class="kicker">60 minutes</p> <p>11:30 to 12:30, on the clock. Members are back at their desks by 12:31.</p> </div> <div class="tile" data-reveal style="--i:2"> <p class="kicker">Live</p> <p>Nothing pre-recorded. Real tasks get handed off on the screen while the room watches.</p> </div> <div class="tile" data-reveal style="--i:3"> <p class="kicker">A free book</p> <p>Everyone who comes leaves with a copy of <em>Reclaiming Your Hours with AI</em>.</p> </div> </div> </div> </section> <!-- WHAT MEMBERS GET --> <section class="pad"> <div class="wrap" style="max-width:820px" data-reveal> <p class="kicker">What your members walk out with</p> <h2>At least one task handed off, and the know-how to do the next.</h2> <ul class="checklist"> <li>How to hand off at least one task of their own, with the right workflow and skills set up for it</li> <li>How to connect their AI agent, whichever one they use, to 1,500 tools at no cost</li> <li>Their own number: roughly how many hours a week the task they hate is costing them<
24/li> <li>A free copy of the book that walks through the same steps</li> <li>If they want help with the rest, an AI assessment they can book that finds where the other hours are going</li> </ul> <p class="micro">
25How many hours this gives back depends on the task and on the person; the point of the
26        two questions is that each person measures their own.
27</p> </div> </section> <!-- WHAT THE HOST GETS / COSTS --> <section class="pad band-letter"> <div class="wrap" style="max-width:920px"> <div data-reveal> <p class="kicker">What it costs you</p> <h2>Nothing. A room and a screen.</h2> <p class="lede">
28You get a useful hour of programming for your members without planning it. I bring the
29          hour and the words for your newsletter.
30</p> </div> <div class="split parts"> <div class="part" data-reveal style="--i:0"> <h3>Your part</h3> <ul class="checklist"> <li>Pick a date that suits your space</li> <li>A room and a screen I can plug into</li> <li>Lunch for the room, if you would like to offer it</li> <li>Send the invitation to your members</li> </ul> </div> <div class="part mine" data-reveal style="--i:1"> <h3>My part</h3> <ul class="checklist"> <li>The whole hour, on time, in English or French</li> <li>The demo, built on the tasks your members bring</li> <li>Invitation text ready for your newsletter or member list</li> <li>A print flyer for the kitchen, the front desk, or the elevator</li> <li>A free copy of the book for everyone who comes</li> </ul> </div> </div> </div> </section> <!-- THE HOUR --> <section id="hour" class="pad"> <div class="wrap" style="max-width:820px"> <div data-reveal> <p class="kicker">What actually happens</p> <h2>Sixty minutes. Your members. Their own tasks handed off.</h2> </div> <ol class="steps run-of-show" data-reveal> <li class="step"> <p class="mono-num">11:30</p> <div> <h3>Lunch, and two questions</h3> <p>Everyone eats. Each person answers the two questions I ask every owner: what eats the most time that you wish it did not, and roughly how many hours a week it costs. Ten minutes, and the room has its own numbers before the demo starts.</p> </div> </li><li class="step"> <p class="mono-num">11:45</p> <div> <h3>Their own tasks, handed off live</h3> <p>Claude Desktop on the screen. Each person brings one task of their own, and I hand the ones the room names off to AI one at a time, on real examples, with the right workflow and skills set up for each. For a room full of owners that usually looks like a quote that writes itself from their own price list, the follow-up after a meeting, and the inbox sorted before the first coffee.</p> </div> </li><li class="step"> <p class="mono-num">12:10</p> <div> <h3>What it took</h3> <p>The setup behind what they just watched, shown rather than described, including how to connect their AI agent, whichever one they use, to 1,500 tools at no cost. Chapter 6 of the free book walks through the same setup.</p> </div> </li><li class="step"> <p class="mono-num">12:20</p> <div> <h3>Questions</h3> <p>In English or in French. The ones about their business, not about the technology.</p> </div> </li><li class="step"> <p class="mono-num">12:30</p> <div> <h3>Done, on time</h3> <p>Each person knows how to hand off at least one task, has their own number for the week, and leaves with the book. Anyone who wants help with the rest can book an AI assessment that finds where the other hours are going.</p> </div> </li> </ol> </div> </section> <!-- THE BOOK --> <section class="pad band-letter"> <div class="wrap" style="max-width:920px"> <div class="media-row" data-reveal> <a href="/book" class="media-img book-img"> <img src="/images/cover-front.png" alt="Cover of the book Reclaiming Your Hours with AI" width="1200" height="1800" loading="lazy" decoding="async"> </a> <div> <p class="kicker">Everyone in the room gets it free</p> <h2>Reclaiming Your Hours with AI</h2> <p>
31The working manual behind the hour: twenty-six chapters on the automations owners build
32            themselves, and the hours they get back. Chapter 6 walks through the same setup your
33            members watch on the screen. Every reader gets every future edition.
34</p> <p><a href="/book" class="btn btn-light">See the book</a></p> </div> </div> </div> </section> <!-- WHO --> <section class="pad"> <div class="wrap" style="max-width:920px"> <div class="media-row" data-reveal> <div class="media-img portrait"> <img src="/images/denis-hero.jpg" alt="Denis Laflamme" width="1726" height="1512" loading="lazy" decoding="async"> </div> <div> <p class="kicker">Who is running it</p> <h2>Denis Laflamme, based in Ottawa.</h2> <p>
35I have spent 30 years helping business owners save time with better technology, and I
36            am a registered Anthropic partner. An hour in your space is the shortest honest way to
37            show what that looks like on a real desk. Some of your members will want more
38            afterward. Most will just keep the hour they got back. Both are fine with me.
39</p> <p class="micro">
40Educational content. Results depend on your business and how you apply it.
41</p> </div> </div> </div> </section> <!-- REQUEST --> <section id="request" class="pad band-letter"> <div class="wrap" style="max-width:720px"> <div data-reveal> <p class="kicker hot">Request a lunch at your space</p> <h2>Tell me about your space, and pick a few dates.</h2> <p class="lede">
42Takes about a minute. I reply within two business days with a date, the invitation text,
43          and the flyer.
44</p> </div> <div class="reg-card"> <form class="apply" id="ll-form" novalidate> <div class="field-row"> <div class="field"> <label for="ll-name">Your name</label> <input type="text" id="ll-name" name="name" autocomplete="name" maxlength="120" required> </div> <div class="field"> <label for="ll-email">Email</label> <input type="email" id="ll-email" name="email" placeholder="[email protected]" autocomplete="email" maxlength="200" required> </div> </div> <div class="field-row"> <div class="field"> <label for="ll-company">Name of the space</label> <input type="text" id="ll-company" name="company" autocomplete="organization" maxlength="200" required> </div> <div class="field"> <label for="ll-phone">Phone <span class="opt">(optional)</span></label> <input type="tel" id="ll-phone" name="phone" autocomplete="tel" maxlength="40"> </div> </div> <!-- Fixed industry value so Denis sees at a glance this came from a venue. --> <input type="hidden" name="industry" value="Co-working space or business centre"> <div class="field-row"> <div class="field"> <label for="ll-team">How many members might come?</label> <select id="ll-team" name="team_size"> <option value="">Choose one</option> <option>Under 15</option> <option>15 to 30</option> <option>31 to 50</option> <option>More than 50</option> <option>Not sure yet</option> </select> </div> <div class="field"> <label for="ll-language">Language in the room</label> <select id="ll-language" name="language"> <option>English</option> <option>Fran&ccedil;ais</option> <option>Both</option> </select> </div> </div> <div class="field-row"> <div class="field"> <label for="ll-city">City</label> <input type="text" id="ll-city" name="city" placeholder="Ottawa, Gatineau, Kanata…" maxlength="120"> </div> <div class="field"> <label for="ll-dates">A few dates that could work</label> <input type="text" id="ll-dates" name="preferred_dates" placeholder="Any Tuesday in October, 11:30" maxlength="500"> </div> </div> <div class="field"> <label for="ll-notes">Anything I should know <span class="opt">(optional)</span></label> <textarea id="ll-notes" name="notes" rows="3" maxlength="2000"></textarea> <p class="hint">The kind of businesses your members run, the room, whether lunch is on the house.</p> </div> <!-- Honeypot. Bots fill every field they find. --> <div class="hp-field" aria-hidden="true"> <label for="ll-website">Company website</label> <input type="text" id="ll-website" name="company_website" tabindex="-1" autocomplete="off"> </div> <button type="submit" class="btn btn-accent btn-lg" id="ll-btn">Send the request</button> <p class="form-msg" id="ll-msg" role="status" aria-live="polite"></p> <p class="micro">
45Rather talk first? <a href="https://cal.com/claudeacademy.ca/claudeacademy-discovery">Book a free 15 minute call</a>, or write to
46<a href="mailto:[email protected]">[email protected]</a>.
47</p> </form> <div class="applied" id="ll-done" hidden> <div class="win"> <svg class="win-mark" viewBox="0 0 80 80" aria-hidden="true"> <circle cx="40" cy="40" r="36"></circle> <path d="M24 41 L35 52 L57 29"></path> </svg> <h2>Thank you. Your date request is in.</h2> <p>
48I reply within two business days with a date, the invitation text for your members,
49            and the flyer.
50</p> <div class="offer"> <p> <strong>As a thank-you, we'd like to offer you a free 30-minute AI assessment for
51              your co-working space's own operations.</strong> Bookings, member questions,
52              invoicing, onboarding: we find the admin AI can take off your plate.
53</p> <a href="https://cal.com/claudeacademy.ca/space-ai-assessment" class="btn btn-lg">Book your free assessment</a> </div> <p class="fine">
54Nothing turned up? Check your promotions tab, or email [email protected].
55</p> </div> </div> </div> </div> </section> <!-- FAQ --> <section class="pad"> <div class="wrap" style="max-width:820px" data-reveal> <p class="kicker">
55Questions managers ask</p> <h2>The short answers.</h2> <div class="faq"> <details> <summary>Is it a sales pitch?</summary> <p>Not from the front of the room. Some people will want more afterward: the free book, the community, an AI assessment that finds where the rest of their hours are going. That is their move to make, not mine, and it happens after the hour, not during it. Your members will not be put on a list for coming.</p> </details><details> <summary>What does the guarantee mean?</summary> <p>Nobody leaves with just a demo. Everyone who comes learns how to connect their AI agent, whichever one they use, to 1,500 tools at no cost. Nothing to buy, and it works with the agent they already have.</p> </details><details> <summary>What does it cost the space?</summary> <p>Nothing. A room and a screen I can plug into. Lunch is up to you: offer it, make it bring-your-own, or skip it. I bring the hour, the invitation text for your newsletter, a print flyer, and the books.</p> </details><details> <summary>How many members should come?</summary> <p>The session is kept small so the Q&amp;A works. Tell me roughly how many you expect in the form, and if interest is bigger than one room, we can run a second date.</p> </details><details> <summary>Do members need to prepare or bring a laptop?</summary> <p>No. They watch the screen and answer two questions over lunch. If they already know the task that eats their week, they should bring it.</p> </details><details> <summary>Can it run in French?</summary> <p>Yes. English, French, or the mix your members already speak.</p> </details><details> <summary>Where do you go?</summary> <p>Ottawa and Gatineau, and the towns around them. Further out, ask; a morning drive is usually fine.</p> </details> </div> <p class="faq-foot micro">
56Running an office rather than a shared space? The <a href="/lunch-and-learn">lunch and
57        learn for teams</a> is the same hour, built for one company. Questions:
58<a href="mailto:[email protected]">[email protected]</a>.
59</p> </div> </section> </div>  </main> <footer class="site"> <div class="wrap foot-grid"> <div> <div class="foot-name">Reclaim Your Time with AI &middot; Denis Laflamme</div> <div class="foot-name">Claude Academy, a product of The Agent Factory</div> <p class="foot-phone"> <a href="tel:+15485543214">(548) 554-3214</a> </p> </div> <nav class="foot-links" aria-label="Footer"> <a href="/">WEBSITE</a> <a href="https://www.skool.com/claudeacademy">COMMUNITY</a> <a href="/workshops">WORKSHOPS</a> <a href="/partners">PARTNERS</a> <a href="/audit">AI AUDIT</a> <a href="https://x.com/theagentfactory" rel="me">X</a> <a href="https://www.youtube.com/@myclaudeacademy" rel="me">YOUTUBE</a> </nav> </div> </footer> <!-- Vincent, the voice agent. --> <div class="va" data-va hidden data-astro-cid-je6adg2j> <!-- Collapsed: a quiet pill until someone wants to talk. --> <div class="va-collapsed" data-va-collapsed data-astro-cid-je6adg2j> <p class="va-toast" data-va-toast role="status" aria-live="polite" hidden data-astro-cid-je6adg2j></p> <button type="button" class="va-launch" data-va-start aria-label="Talk to Vincent" data-astro-cid-je6adg2j> <span class="va-launch-dot" aria-hidden="true" data-astro-cid-je6adg2j></span> <span data-astro-cid-je6adg2j>Talk to Vincent</span> </button> </div> <!-- Expanded: the live call panel. --> <div class="va-panel" data-va-panel role="dialog" aria-label="Call with Vincent" hidden data-astro-cid-je6adg2j> <!-- Vincent. Output amplitude only. --> <div class="va-orb" data-va-orb aria-hidden="true" data-astro-cid-je6adg2j> <span class="va-orb-halo" data-astro-cid-je6adg2j></span> <span class="va-orb-halo va-orb-halo-2" data-astro-cid-je6adg2j></span> <span class="va-orb-body" data-astro-cid-je6adg2j></span> <span class="va-orb-sheen" data-astro-cid-je6adg2j></span> </div> <!-- The visitor. A separate element in a cooler colour. --> <div class="va-listen" data-va-listen aria-hidden="true" data-astro-cid-je6adg2j> <span class="va-listen-bar" style="--w:.25;--i:0" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:.5;--i:1" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:.75;
59--i:2" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:1;--i:3" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:.75;--i:4" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:.5;--i:5" data-astro-cid-je6adg2j></span> <span class="va-listen-bar" style="--w:.25;--i:6" data-astro-cid-je6adg2j></span> </div> <p class="va-name" data-astro-cid-je6adg2j>Vincent</p> <p class="va-status" data-va-status role="status" aria-live="polite" data-astro-cid-je6adg2j>Listening, go ahead</p> <!--
60      The capture form. Hidden until Vincent asks for it through the
61      collect_details client tool, so the call is never gated: a visitor clicks
62      and is talking in two seconds, and the ask lands only after he has been
63      useful.
64
65      Typed, never spoken. Denis's ruling 2026-09-09 stands: a misheard email
66      address becomes a no-show and a bad first impression. The visitor types
67      their own address here while Vincent keeps talking.
68    --> <!-- novalidate: the browser's own bubble fires before the submit handler
69         and suppresses our own message, so the field would silently reject
70         with no explanation. We validate in the handler instead, matching the
71         server's rules. --> <form class="va-capture" data-va-capture hidden novalidate data-astro-cid-je6adg2j> <p class="va-capture-lead" data-va-capture-lead data-astro-cid-je6adg2j>Where should I send it?</p> <label class="va-sr" for="va-first" data-astro-cid-je6adg2j>First name</label> <input class="va-field" id="va-first" data-va-first type="text" name="first_name" autocomplete="given-name" placeholder="First name" maxlength="120" required data-astro-cid-je6adg2j> <label class="va-sr" for="va-email" data-astro-cid-je6adg2j>Email</label> <input class="va-field" id="va-email" data-va-email type="email" name="email" autocomplete="email" placeholder="Email" maxlength="200" required data-astro-cid-je6adg2j> <label class="va-consent" data-astro-cid-je6adg2j> <input type="checkbox" data-va-consent data-astro-cid-je6adg2j> <span data-astro-cid-je6adg2j>Yes, email me Reclaiming Your Hours with AI, plus new editions and the occasional note about getting hours back. I can unsubscribe from any email, and Claude Academy will action it within 10 days.</span> </label> <button type="submit" class="va-send" data-va-send data-astro-cid-je6adg2j>Send it</button> <p class="va-capture-note" data-va-capture-note role="status" aria-live="polite" data-astro-cid-je6adg2j></p> </form> <button type="button" class="va-end" data-va-end data-astro-cid-je6adg2j>End call</button> </div> </div>  
71<script>(function(){const SDK = "https://cdn.jsdelivr.net/npm/@elevenlabs/[email protected]/dist/lib.iife.js";
72const destinations = {"call":"https://cal.com/claudeacademy.ca/claudeacademy-discovery","workshop":"https://cal.com/claudeacademy.ca/reclaim-your-hours-workshop","book":"/book","skills":"/skills","audit":"/audit","community":"https://www.skool.com/claudeacademy"};
73const agentId = "agent_5301ka29j8qyepft4rp8x0w8jwxw";
74const copy = {"idle":"Talk to Vincent","connecting":"Connecting...","listening":"Listening, go ahead","speaking":"Vincent is speaking","end":"End call","micDenied":"Microphone access was blocked. Allow it in your browser settings, then try again.","failed":"Could not start the call. Please try again in a moment.","closingNotice":"Still there? Wrapping up shortly.","endedIdle":"Call ended. Thanks for chatting."};
75const idle = {"promptAfterMs":10000,"graceMs":8000,"closingPrompt":"The visitor has gone quiet. Ask, warmly and briefly, whether there is anything else you can help them with."};
76const capture = {"lead":"Where should I send it?","firstLabel":"First name","emailLabel":"Email","consent":"Yes, email me Reclaiming Your Hours with AI, plus new editions and the occasional note about getting hours back. I can unsubscribe from any email, and Claude Academy will action it within 10 days.","send":"Send it","sending":"Sending...","done":"Sent. Check your inbox.","badEmail":"That email does not look right.","failed":"That did not go through. Try again in a moment."};
77
78  (function () {
79    var root = document.querySelector('[data-va]');
80    if (!root) return;
81
82    var elCollapsed = root.querySelector('[data-va-collapsed]');
83    var elPanel = root.querySelector('[data-va-panel]');
84    var elStart = root.querySelector('[data-va-start]');
85    var elEnd = root.querySelector('[data-va-end]');
86    var elOrb = root.querySelector('[data-va-orb]');
87    var elListen = root.querySelector('[data-va-listen]');
88    var elStatus = root.querySelector('[data-va-status]');
89    var elToast = root.querySelector('[data-va-toast]');
90    var elCapture = root.querySelector('[data-va-capture]');
91    var elFirst = root.querySelector('[data-va-first]');
92    var elEmail = root.querySelector('[data-va-email]');
93    var elConsent = root.querySelector('[data-va-consent]');
94    var elSend = root.querySelector('[data-va-send]');
95    var elNote = root.querySelector('[data-va-capture-note]');
96    var elCaptureLead = root.querySelector('[data-va-capture-lead]');
97
98    // Tuning. Rising fast and falling slow is what makes a level meter look
99    // alive rather than jittery: syllables hit immediately, then the glow eases
100    // out instead of snapping to zero between every word.
101    var IDLE_LEVEL = 0.18;
102    var ATTACK = 0.35;
103    var DECAY = 0.09;
104    var IN_ATTACK = 0.42;
105    var IN_DECAY = 0.14;
106    // Slower than the amplitude on purpose: the shape should feel like it has
107    // mass and swings, rather than snapping around every frame.
108    var SHAPE_SMOOTH = 0.12;
109    var SILENCE = 0.02;
110    // getOutputByteFrequencyData is focused on 100 to 8000 Hz. The low third is
111    // roughly vowels and chest, the top third sibilance and consonants.
112    var BASS_END = 0.28;
113    var TREBLE_START = 0.55;
114
115    var conversation = null;
116    var starting = false;
117    var raf = null;
118    var reduced = false;
119    try {
120      reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
121    } catch (err) {
122      reduced = false;
123    }
124
125    var level = 0;
126    var inLevel = 0;
127    var stretch = 0;
128    var skew = 0;
129    var lastSound = 0;
130    var prompted = false;
131    var closingByUs = false;
132
133    // The widget only exists if the browser can actually run it. A visitor on
134    // a browser with no getUserMedia should see nothing rather than a button
135    // that cannot work.
136    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) return;
137    root.hidden = false;
138
139    function toast(text, tone) {
140      if (!elToast) return;
141      if (!text) {
142        elToast.hidden = true;
143        elToast.textContent = '';
144        return;
145      }
146      elToast.textContent = text;
147      if (tone) elToast.setAttribute('data-tone', tone);
148      else elToast.removeAttribute('data-tone');
149      elToast.hidden = false;
150    }
151
152    function setStatus(text) {
153      if (elStatus) elStatus.textContent = text;
154    }
155
156    function showPanel(live) {
157      // Measure BEFORE hiding the pill: once it is hidden its box is 0x0.
158      // The panel pins to these coordinates so a call opens exactly where the
159      // visitor clicked, rather than flying to the bottom of the screen, and
160      // then stays put while they scroll.
161      if (live && elStart) {
162        var r = elStart.getBoundingClientRect();
163        // Keep the panel on screen when the pill sits near an edge. The panel
164        // is wider (232) and taller (311) than the pill.
165        var x = Math.max(12, Math.min(r.left, window.innerWidth - 244));
166        var y = Math.max(12, Math.min(r.top, window.innerHeight - 323));
167        root.style.setProperty('--va-x', x + 'px');
168        root.style.setProperty('--va-y', y + 'px');
169      }
170
171      if (elCollapsed) elCollapsed.hidden = live;
172      if (elPanel) elPanel.hidden = !live;
173
174      // Inline placement pins the panel for the duration of a call, so
175      // scrolling the page does not carry an open conversation off screen.
176      // Harmless on the floating placement, which is already fixed.
177      if (live) {
178        root.setAttribute('data-live', '');
179      } else {
180        root.removeAttribute('data-live');
181        root.style.removeProperty('--va-x');
182        root.style.removeProperty('--va-y');
183      }
184    }
185
186    function bandLevel(buf, from, to) {
187      var a = Math.floor(buf.length * from);
188      var b = Math.max(a + 1, Math.floor(buf.length * to));
189      var sum = 0;
190      for (var i = a; i < b; i++) sum += buf[i];
191      return sum / (b - a) / 255;
192    }
193
194    function resetVisual() {
195      level = 0;
196      inLevel = 0;
197      stretch = 0;
198      skew = 0;
199      if (elOrb) {
200        elOrb.style.setProperty('--v', '0');
201        elOrb.style.setProperty('--stretch', '0');
202        elOrb.style.setProperty('--skew', '0');
203      }
204      if (elListen) elListen.style.setProperty('--in', '0');
205    }
206
207    // One loop owns both the animation and the idle watchdog, because both
208    // need the same per frame amplitude read.
209    function frame() {
210      if (!conversation) return;
211
212      var out = 0;
213      var inp = 0;
214      var spectrum = null;
215      try {
216        out = conversation.getOutputVolume();
217        inp = conversation.getInputVolume();
218        spectrum = conversation.getOutputByteFrequencyData();
219      } catch (err) {
220        // The analyser can be torn down a frame before the loop stops.
221      }
222
223      // Vincent drives the orb.
224      var target = Math.min(1, Math.max(0, out));
225      level += (target - level) * (target > level ? ATTACK : DECAY);
226
227      var stretchTarget = 0;
228      var skewTarget = 0;
229      if (spectrum && spectrum.length && target > SILENCE) {
230        var bass = bandLevel(spectrum, 0, BASS_END);
231        var treble = bandLevel(spectrum, TREBLE_START, 1);
232        var mid = bandLevel(spectrum, BASS_END, TREBLE_START);
233        stretchTarget = Math.max(-1, Math.min(1, (treble - bass) * 2.6));
234        skewTarget = Math.max(-1, Math.min(1, (mid - treble) * 2.2));
235      }
236      stretch += (stretchTarget - stretch) * SHAPE_SMOOTH;
237      skew += (skewTarget - skew) * SHAPE_SMOOTH;
238
239      if (elOrb) {
240        var shown = reduced ? IDLE_LEVEL : Math.max(IDLE_LEVEL, level);
241        elOrb.style.setProperty('--v', shown.toFixed(3));
242        elOrb.style.setProperty('--stretch', reduced ? '0' : stretch.toFixed(3));
243        elOrb.style.setProperty('--skew', reduced ? '0' : skew.toFixed(3));
244      }
245
246      // The visitor drives the bars, and nothing else.
247      var inTarget = Math.min(1, Math.max(0, inp));
248      inLevel += (inTarget - inLevel) * (inTarget > inLevel ? IN_ATTACK : IN_DECAY);
249      if (elListen) elListen.style.setProperty('--in', reduced ? '0' : inLevel.toFixed(3));
250
251      // Idle hang up.
252      //
253      // Typing is silent, so a visitor filling in the capture form would trip
254      // the watchdog and get hung up on mid word. While the form is open and
255      // unsent, they are demonstrably still here: hold the clock.
256      var now = Date.now();
257      if (elCapture && !elCapture.hidden && !captureDone) {
258        lastSound = now;
259        if (prompted) {
260          prompted = false;
261          setStatus(copy.listening);
262        }
263      } else if (out > SILENCE || inp > SILENCE) {
264        lastSound = now;
265        // Only the VISITOR speaking stands the hang up down. If Vincent's own
266        // voice counted, he would clear the timer just by asking the question.
267        if (prompted && inp > SILENCE) {
268          prompted = false;
269          setStatus(copy.listening);
270        }
271      } else {
272        var quietFor = now - lastSound;
273        if (!prompted && quietFor > idle.promptAfterMs) {
274          prompted = true;
275          setStatus(copy.closingNotice);
276          try {
277            conversation.sendContextualUpdate(idle.closingPrompt);
278          } catch (err) {
279            /* the session may already be closing */
280          }
281          // Give him the floor to actually say it before the grace clock runs.
282          lastSound = now;
283        } else if (prompted && quietFor > idle.graceMs) {
284          closingByUs = true;
285          stop();
286          return;
287        }
288      }
289
290      // Do not stamp over the closing notice, or the "sent, check your inbox"
291      // confirmation the visitor has just earned.
292      if (!prompted && !captureDone) {
293        setStatus(level > 0.04 ? copy.speaking : copy.listening);
294      }
295
296      raf = requestAnimationFrame(frame);
297    }
298
299    function loadSdk() {
300      if (window.ElevenLabsClient) return Promise.resolve(window.ElevenLabsClient);
301      return new Promise(function (resolve, reject) {
302        var s = document.createElement('script');
303        s.src = SDK;
304        s.async = true;
305        s.onload = function () {
306          if (window.ElevenLabsClient) resolve(window.ElevenLabsClient);
307          else reject(new Error('SDK loaded but ElevenLabsClient is undefined'));
308        };
309        s.onerror = function () {
310          reject(new Error('could not load the ElevenLabs SDK'));
311        };
312        document.head.appendChild(s);
313      });
314    }
315
316    // The one client tool Vincent has: open the page a visitor just asked for,
317    // in a new tab, while he keeps talking.
318    //
319    // Denis's ruling 2026-09-09: Vincent does NOT take a name and email by
320    // voice and book on the visitor's behalf. A misheard email address becomes
321    // a no-show and a bad first impression, and the booking page already does
322    // that job properly. So the agent hands the visitor to the real page and
323    // the human types their own address.
324    // Vincent's second tool: raise the capture form. He calls this once he has
325    // been useful and the visitor wants something sent, NOT as a greeting.
326    //
327    // It returns immediately rather than waiting for the visitor to type,
328    // because a tool call blocks the agent: waiting here would leave Vincent
329    // silent and the call feeling dead while they fill in two fields.
330    function collectDetails(args) {
331      if (!elCapture) return 'The form is not available on this page.';
332      if (captureDone) {
333        return 'They have already sent their details. Do not ask again; carry on.';
334      }
335
336      var reason = String((args && args.reason) || '').trim();
337      if (reason && elCaptureLead) elCaptureLead.textContent = reason.slice(0, 120);
338
339      elCapture.hidden = false;
340      note(null);
341      try {
342        elFirst.focus();
343      } catch (err) {
344        /* focus is a nicety, never a failure */
345      }
346
347      return (
348        'The form is open on their screen with a first name field, an email ' +
349        'field and a send button. Tell them briefly to pop their name and ' +
350        'email in, then keep the conversation going. Do NOT ask them to say ' +
351        'the address out loud, and do not wait in silence.'
352      );
353    }
354
355    function note(text, tone) {
356      if (!elNote) return;
357      elNote.textContent = text || '';
358      if (tone) elNote.setAttribute('data-tone', tone);
359      else elNote.removeAttribute('data-tone');
360    }
361
362    var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
363    var captureDone = false;
364    var sending = false;
365    // The last page Vincent opened. When he then offers to email the link, this
366    // is what decides WHICH email goes out, so a booking link request does not
367    // come back as a book.
368    var lastPage = null;
369
370    async function submitCapture(ev) {
371      if (ev) ev.preventDefault();
372      if (sending || captureDone) return;
373
374      var first = (elFirst.value || '').trim();
375      var email = (elEmail.value || '').trim();
376
377      elFirst.removeAttribute('aria-invalid');
378      elEmail.removeAttribute('aria-invalid');
379
380      if (!first) {
381        elFirst.setAttribute('aria-invalid', 'true');
382        elFirst.focus();
383        return;
384      }
385      if (!EMAIL_RE.test(email)) {
386        elEmail.setAttribute('aria-invalid', 'true');
387        elEmail.focus();
388        note(capture.badEmail, 'error');
389        return;
390      }
391
392      sending = true;
393      elSend.disabled = true;
394      note(capture.sending);
395
396      try {
397        // Reuses the book gate, which already validates, records the exact
398        // consent wording with a timestamp and IP, and delivers the book.
399        // `source: 'vincent'` is what separates these leads in the table.
400        var r = await fetch('/api/book-signup', {
401          method: 'POST',
402          headers: { 'Content-Type': 'application/json' },
403          body: JSON.stringify({
404            name: first,
405            email: email,
406            consent: !!(elConsent && elConsent.checked),
407            source: 'vincent',
408            // Null unless Vincent opened a page first, in which case the server
409            // sends that link instead of the book.
410            page: lastPage,
411          }),
412        });
413        var data = await r.json().catch(function () {
414          return {};
415        });
416
417        if (!r.ok) {
418          sending = false;
419          elSend.disabled = false;
420          note(data.error || capture.failed, 'error');
421          return;
422        }
423
424        captureDone = true;
425        sending = false;
426        elCapture.hidden = true;
427        setStatus(capture.done);
428
429        // Tell Vincent it landed, so he can acknowledge it in his own voice
430        // instead of the visitor wondering whether anything happened.
431        try {
432          var sent =
433            lastPage && lastPage !== 'book' ? 'the link they asked for' : 'the book';
434          conversation.sendContextualUpdate(
435            'They just sent their details: first name ' +
436              first +
437              '. You have emailed them ' +
438              sent +
439              '. Confirm in ONE short sentence, six words if you can, then carry on.',
440          );
441        } catch (err) {
442          /* the session may have ended while the request was in flight */
443        }
444      } catch (err) {
445        sending = false;
446        elSend.disabled = false;
447        note(capture.failed, 'error');
448      }
449    }
450
451    function openDestination(args) {
452      var key = String((args && args.destination) || '')
453        .toLowerCase()
454        .trim();
455      var url = destinations[key];
456
457      if (!url) {
458        // Tell the model, not the visitor. Vincent then says where to look
459        // instead of pretending something opened.
460        return (
461          'No page matched "' +
462          key +
463          '". Tell the visitor which page to look for instead of claiming you opened it.'
464        );
465      }
466
467      var win = window.open(url, '_blank', 'noopener,noreferrer');
468      if (!win) {
469        return 'The browser blocked the popup. Tell the visitor to look for the link on the page instead.';
470      }
471      // Remember it, so an offer to email "that link" sends THIS page.
472      lastPage = key;
473      return 'Opened ' + url + ' in a new tab. Confirm briefly that it is open, and stop talking so they can use it.';
474    }
475
476    async function start() {
477      if (starting || conversation) return;
478      starting = true;
479      if (elStart) elStart.disabled = true;
480      toast(copy.connecting);
481
482      // The microphone, from inside the user gesture. Browsers only grant
483      // access on one.
484      try {
485        await navigator.mediaDevices.getUserMedia({ audio: true });
486      } catch (err) {
487        starting = false;
488        if (elStart) elStart.disabled = false;
489        toast(copy.micDenied, 'error');
490        return;
491      }
492
493      var Sdk;
494      try {
495        Sdk = await loadSdk();
496      } catch (err) {
497        starting = false;
498        if (elStart) elStart.disabled = false;
499        toast(copy.failed, 'error');
500        return;
501      }
502
503      try {
504        // Public session: the agent has auth disabled, so there is no token to
505        // mint and no server round trip. See the note at the top of this file.
506        conversation = await Sdk.Conversation.startSession({
507          agentId: agentId,
508          connectionType: 'webrtc',
509          clientTools: {
510            open_page: openDestination,
511            collect_details: collectDetails,
512          },
513          onDisconnect: function () {
514            teardown();
515          },
516          onError: function (message) {
517            teardown();
518            toast(copy.failed, 'error');
519          },
520        });
521      } catch (err) {
522        starting = false;
523        conversation = null;
524        if (elStart) elStart.disabled = false;
525        toast(copy.failed, 'error');
526        return;
527      }
528
529      starting = false;
530      closingByUs = false;
531      prompted = false;
532      lastSound = Date.now();
533
534      // Page context. A page that has something Vincent should know before
535      // he speaks (the calculator hands him the visitor's live numbers)
536      // defines window.vaPageContext as a function returning one string.
537      // Every other page defines nothing and this is a no-op.
538      try {
539        if (typeof window.vaPageContext === 'function') {
540          var pageCtx = window.vaPageContext();
541          if (pageCtx) conversation.sendContextualUpdate(String(pageCtx));
542        }
543      } catch (err) {
544        /* context is a nice to have; never let it break the call */
545      }
546      resetVisual();
547      toast(null);
548      setStatus(copy.listening);
549      showPanel(true);
550      raf = requestAnimationFrame(frame);
551    }
552
553    function teardown() {
554      if (raf) cancelAnimationFrame(raf);
555      raf = null;
556      conversation = null;
557      starting = false;
558      prompted = false;
559      resetVisual();
560      showPanel(false);
561      // Reset the form between calls, or the next visitor on this page opens
562      // the panel to the previous person's name and email sitting in it.
563      if (elCapture) {
564        elCapture.hidden = true;
565        try {
566          elCapture.reset();
567        } catch (err) {
568          /* not fatal */
569        }
570        elFirst && elFirst.removeAttribute('aria-invalid');
571        elEmail && elEmail.removeAttribute('aria-invalid');
572      }
573      if (elSend) elSend.disabled = false;
574      note(null);
575      captureDone = false;
576      sending = false;
577      if (elCaptureLead) elCaptureLead.textContent = capture.lead;
578      if (elStart) elStart.disabled = false;
579      // A hang up we initiated on idle should explain itself, so it never
580      // looks like the call simply dropped.
581      if (closingByUs) {
582        toast(copy.endedIdle);
583        window.setTimeout(function () {
584          toast(null);
585        }, 4000);
586        closingByUs = false;
587      }
588    }
589
590    function stop() {
591      var active = conversation;
592      // Clear our handle first, so the loop and any late callback stop
593      // touching a session that is on its way out.
594      if (raf) cancelAnimationFrame(raf);
595      raf = null;
596      conversation = null;
597      if (active) {
598        try {
599          Promise.resolve(active.endSession()).catch(function () {});
600        } catch (err) {
601          /* already closed */
602        }
603      }
604      teardown();
605    }
606
607    if (elCapture) elCapture.addEventListener('submit', submitCapture);
608    if (elStart) elStart.addEventListener('click', start);
609    if (elEnd)
610      elEnd.addEventListener('click', function () {
611        closingByUs = false;
612        stop();
613      });
614
615    // Never leave a live microphone open behind a navigation.
616    window.addEventListener('pagehide', function () {
617      if (conversation) {
618        try {
619          conversation.endSession();
620        } catch (err) {
621          /* already closed */
622        }
623      }
624    });
625  })();
626})();</script>
626 <div class="bp" data-book-popup data-locale="en" hidden data-astro-cid-4ifyvisz> <div class="bp-backdrop" data-bp-close data-astro-cid-4ifyvisz></div> <div class="bp-panel" role="dialog" aria-modal="true" aria-labelledby="bp-title" aria-describedby="bp-body" data-astro-cid-4ifyvisz> <button type="button" class="bp-x" data-bp-close aria-label="Close" data-astro-cid-4ifyvisz> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true" data-astro-cid-4ifyvisz><path d="M6 6l12 12M18 6L6 18" data-astro-cid-4ifyvisz></path></svg> </button> <div class="bp-cover" data-astro-cid-4ifyvisz> <img src="/images/cover-front.png" alt="Front cover of Reclaiming Your Hours with AI" width="1200" height="1800" loading="lazy" decoding="async" data-astro-cid-4ifyvisz> </div> <div class="bp-copy" data-astro-cid-4ifyvisz> <p class="bp-kicker" data-astro-cid-4ifyvisz>The free book</p> <h2 class="bp-title" id="bp-title" data-astro-cid-4ifyvisz>One task off your plate, per chapter.</h2> <p class="bp-body" id="bp-body" data-astro-cid-4ifyvisz>Reclaiming Your Hours with AI: twenty-six chapters, each one takes a repeating task off your week and prices it in the hours you get back. The first build takes one evening. Free, and every future edition arrives at the same address.</p> <form class="bp-form" novalidate data-astro-cid-4ifyvisz> <div class="bp-row" data-astro-cid-4ifyvisz> <label class="bp-sr" for="bp-name" data-astro-cid-4ifyvisz>First name</label> <input id="bp-name" name="name" type="text" autocomplete="given-name" placeholder="First name" required data-astro-cid-4ifyvisz> <label class="bp-sr" for="bp-email" data-astro-cid-4ifyvisz>Email</label> <input id="bp-email" name="email" type="email" autocomplete="email" inputmode="email" placeholder="Email" required data-astro-cid-4ifyvisz> </div> <label class="bp-consent" data-astro-cid-4ifyvisz> <input type="checkbox" name="consent" data-astro-cid-4ifyvisz> <span data-astro-cid-4ifyvisz>Yes, email me Reclaiming Your Hours with AI, plus new editions and the occasional note about getting hours back. I can unsubscribe from any email, and Claude Academy will action it within 10 days.</span> </label> <div class="bp-actions" data-astro-cid-4ifyvisz> <button type="submit" class="bp-send" data-astro-cid-4ifyvisz>Send me the book</button> <button type="button" class="bp-later" data-bp-close data-astro-cid-4ifyvisz>Not now</button> </div> <p class="bp-msg" aria-live="polite" data-astro-cid-4ifyvisz></p> </form> <p class="bp-done" hidden data-astro-cid-4ifyvisz>Sent. Check your inbox in the next minute.</p> </div> </div> </div>   </body></html> 

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.