Privacy Policy

This policy explains what we collect, why we collect it, how it’s used, and your choices. It’s written in plain English and designed to be easy to navigate using the on-page contents.

Effective: Last updated: Reading time:

Overview

We provide online knitting courses and related educational content. When you visit our website, we may collect certain information so we can operate the site, keep it secure, measure performance, and respond to your requests. We aim to collect the minimum data necessary and to give you meaningful choices.

Controller Knitting Courses (site operator)
Contact Email: [email protected]
Phone: +1 (415) 902-7731
Jump to your choices

Information We Collect

Depending on how you use the site, we may collect the categories below. Not all visitors provide all types of information.

  • Information you provide: messages you send through forms, your name, email address, and any details you include in your request.
  • Device and usage data: approximate location (city-level), browser type, device identifiers, pages viewed, and interaction events (e.g., button clicks) used for analytics and security.
  • Cookies and similar technologies: small identifiers used to remember your preferences and to understand how the site is used.
  • Support-related information: troubleshooting details you share if you contact us about an issue.

We do not intentionally request sensitive personal information (such as government IDs or precise geolocation). Please do not include sensitive information in free-text fields.

How We Use Data

We use information for the purposes below, depending on what you do on the site and which options you choose.

  • Operate the website: deliver content, ensure functionality, and maintain performance.
  • Security and fraud prevention: detect suspicious activity, protect against abuse, and maintain service integrity.
  • Analytics: understand what content is helpful and improve user experience.
  • Respond to you: answer messages, process requests, and provide support.
  • Legal compliance: meet applicable legal obligations and enforce our terms.

Cookies & Similar Technologies

Cookies help us remember your preferences and measure site performance. You can accept or decline non-essential cookies using the cookie banner or the “Manage cookie preferences” button.

  • Essential cookies: required for core features like saving cookie choices and basic security.
  • Analytics cookies (optional): help us understand traffic patterns and improve the site.
  • Preference cookies: remember settings like theme, where permitted.

We also store your theme preference in local storage so your selection persists across visits.

Sharing & Disclosure

We do not sell your personal information. We may share limited information in these cases:

  • Service providers: vendors helping us run the site (e.g., hosting, email delivery). They are authorized to process information only as needed to provide services to us.
  • Legal requests: where we believe disclosure is required by law or necessary to protect rights and safety.
  • Business transfers: if our business is reorganized or transferred, information may be part of that transaction, subject to appropriate safeguards.

International Transfers

Depending on where you live and where our service providers operate, your information may be processed in countries outside your own. When we do this, we use appropriate safeguards required by applicable law (such as contractual protections) to help ensure your information remains protected.

Data Retention

We keep personal information only as long as needed for the purposes described in this policy, including security, support, and compliance. Retention periods can vary depending on the type of information:

  • Contact messages: typically retained long enough to address your request and for reasonable follow-up.
  • Security logs: retained for a limited period to investigate suspicious activity and maintain site security.
  • Cookie choices: stored to remember your preferences; you can reset them at any time.

Security

We use reasonable technical and organizational measures designed to protect information from unauthorized access, loss, misuse, or alteration. No method of transmission or storage is 100% secure, but we work to continuously improve our safeguards.

  • Access controls and least-privilege principles for operational systems.
  • Monitoring and rate-limiting to reduce abuse.
  • Secure handling of form submissions (avoid sending sensitive info).

Children’s Privacy

Our website is not intended for children under 13 (or the age defined by your local law). We do not knowingly collect personal information from children. If you believe a child has provided personal information, please contact us and we will take appropriate steps to delete it.

Your Choices

You can manage your privacy settings and make requests about your information.

  • Cookie preferences: accept or decline optional cookies (analytics).
  • Access / deletion requests: ask what information we have and request deletion where applicable.
  • Correction: request correction of inaccurate information.
  • Opt-out: where required, opt out of certain processing (like non-essential tracking).

Changes to This Policy

We may update this policy from time to time. We will revise the “Last updated” date at the top. If changes are significant, we may provide additional notice on the website.

Contact

If you have questions about this policy or your privacy choices, contact our privacy team:

You can also use the contact button at the top of this page to send a privacy request.

'; }); } function setDates(){ var now=new Date(); var eff=new Date(now.getFullYear(),0,15); var fmt=function(d){ try{ return new Intl.DateTimeFormat('en-US',{year:'numeric',month:'short',day:'2-digit'}).format(d); }catch(e){ return d.toISOString().slice(0,10); } }; q('#effDate').textContent=fmt(eff); q('#updDate').textContent=fmt(now); } function estimateReadingTime(){ var text=(q('#policyBody')?q('#policyBody').innerText:'')||''; var words=text.trim().split(/\s+/).filter(Boolean).length; var mins=Math.max(2, Math.round(words/210)); q('#readTime').textContent=mins+' min'; } function themeInit(){ var btn=q('#themeBtn'); var label=q('#themeLabel'); function applyTheme(t){ var dark = (t==='dark'); document.documentElement.classList.toggle('dark', dark); try{localStorage.setItem('theme', t);}catch(e){} var meta=q('meta[name="color-scheme"]'); if(meta) meta.setAttribute('content', dark?'dark':'light'); label.textContent = dark ? 'Dark' : 'Light'; btn.setAttribute('aria-pressed', dark?'true':'false'); } var current='light'; try{current=localStorage.getItem('theme')||'light';}catch(e){} applyTheme(current); btn.addEventListener('click', function(){ var isDark=document.documentElement.classList.contains('dark'); applyTheme(isDark?'light':'dark'); }); } function modalController(modalId, openBtnId, closeBtnId){ var modal=q('#'+modalId); var openBtn=openBtnId?q('#'+openBtnId):null; var closeBtn=closeBtnId?q('#'+closeBtnId):null; var lastActive=null; function open(){ lastActive=document.activeElement; modal.setAttribute('data-open','true'); document.body.style.overflow='hidden'; var focusable=qa('button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])', modal).filter(function(el){return !el.disabled && el.getAttribute('aria-hidden')!=='true'}); (focusable[0]||modal).focus && (focusable[0]||modal).focus(); } function close(){ modal.setAttribute('data-open','false'); document.body.style.overflow=''; if(lastActive && lastActive.focus) lastActive.focus(); } if(openBtn) openBtn.addEventListener('click', open); if(closeBtn) closeBtn.addEventListener('click', close); modal.addEventListener('mousedown', function(e){ if(e.target===modal) close(); }); window.addEventListener('keydown', function(e){ if(e.key==='Escape' && modal.getAttribute('data-open')==='true') close(); }); modal.addEventListener('keydown', function(e){ if(e.key!=='Tab') return; var f=qa('button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])', modal).filter(function(el){return !el.disabled && el.offsetParent!==null}); if(!f.length) return; var first=f[0], last=f[f.length-1]; if(e.shiftKey && document.activeElement===first){e.preventDefault();last.focus();} else if(!e.shiftKey && document.activeElement===last){e.preventDefault();first.focus();} }); return {open:open, close:close}; } function tocBuild(){ var toc=q('#tocList'); var sections=qa('section[id][data-toc-title]'); toc.innerHTML=''; sections.forEach(function(sec){ var id=sec.id; var title=sec.getAttribute('data-toc-title')||sec.querySelector('h2')&&sec.querySelector('h2').innerText||id; var desc=sec.getAttribute('data-toc-desc')||''; var a=document.createElement('a'); a.href='#'+encodeURIComponent(id).replace(/%3A/g,':').replace(/%2F/g,'/').replace(/%23/g,'#'); a.setAttribute('data-target', id); a.innerHTML=''+esc(title)+''+esc(desc)+''; a.addEventListener('click', function(){ try{history.replaceState(null,'','#'+id);}catch(e){} }); toc.appendChild(a); }); return sections; } function tocScrollSpy(sections){ var links=qa('#tocList a'); var status=q('#tocStatus'); var currentId=null; function setCurrent(id){ if(id===currentId) return; currentId=id; links.forEach(function(a){ a.setAttribute('aria-current', a.getAttribute('data-target')===id ? 'true' : 'false'); }); var curLink=links.find(function(a){return a.getAttribute('data-target')===id}); if(curLink){ var titleNode=curLink.querySelector('.d2c6a'); status.textContent = 'Now reading: ' + (titleNode ? titleNode.textContent : id); }else{ status.textContent = 'Tracking section…'; } } var io=new IntersectionObserver(function(entries){ var visible=entries.filter(function(e){return e.isIntersecting}) .sort(function(a,b){return (b.intersectionRatio||0)-(a.intersectionRatio||0)}); if(visible.length){ setCurrent(visible[0].target.id); } },{root:null, rootMargin:'-22% 0px -64% 0px', threshold:[0.08,0.15,0.25,0.4,0.6]}); sections.forEach(function(s){io.observe(s)}); function fallback(){ if('IntersectionObserver' in window) return; var top=window.scrollY||document.documentElement.scrollTop||0; var best=null, bestDist=Infinity; sections.forEach(function(s){ var r=s.getBoundingClientRect(); var absTop=r.top + top; var dist=Math.abs(absTop - (top+140)); if(distAnalytics: '+(p.analytics?'on':'off')+''; } if(toggleBtn){ toggleBtn.textContent = p.analytics ? 'Disable' : 'Enable'; } } function openBanner(){ banner.setAttribute('data-open','true'); } function closeBanner(){ banner.setAttribute('data-open','false'); } function openCookieModal(){ modal.setAttribute('data-open','true'); document.body.style.overflow='hidden'; var p=getPrefs(); updateIndicators(p); modalMsg.setAttribute('data-show','false'); modalMsg.textContent=''; toggleBtn.focus(); } function closeCookieModal(){ modal.setAttribute('data-open','false'); document.body.style.overflow=''; } function ensureDecided(){ var p=getPrefs(); updateIndicators(p); if(!p.decided){ openBanner(); } } q('#acceptAll').addEventListener('click', function(){ var p=getPrefs(); p.analytics=true; p.decided=true; setPrefs(p); closeBanner(); }); q('#acceptEssential').addEventListener('click', function(){ var p=getPrefs(); p.analytics=false; p.decided=true; setPrefs(p); closeBanner(); }); q('#openCustomize').addEventListener('click', function(){ closeBanner(); openCookieModal(); }); closeX.addEventListener('click', function(){ closeBanner(); }); modal.addEventListener('mousedown', function(e){ if(e.target===modal) closeCookieModal(); }); window.addEventListener('keydown', function(e){ if(e.key==='Escape'){ if(modal.getAttribute('data-open')==='true') closeCookieModal(); if(banner.getAttribute('data-open')==='true') closeBanner(); } }); var draft=null; q('#toggleAnalyticsBtn').addEventListener('click', function(){ var p=draft||getPrefs(); p.analytics=!p.analytics; draft=p; updateIndicators(p); modalMsg.setAttribute('data-show','true'); modalMsg.textContent = 'Analytics is now ' + (p.analytics?'enabled':'disabled') + '. Click “Save changes” to apply.'; }); q('#cancelCookieChanges').addEventListener('click', function(){ draft=null; closeCookieModal(); }); q('#saveCookieChanges').addEventListener('click', function(){ var p=draft||getPrefs(); p.decided=true; setPrefs(p); draft=null; closeCookieModal(); }); q('#closeCookieModal').addEventListener('click', function(){ draft=null; closeCookieModal(); }); return { getPrefs:getPrefs, setPrefs:setPrefs, openBanner:openBanner, closeBanner:closeBanner, openCookieModal:openCookieModal, closeCookieModal:closeCookieModal, ensureDecided:ensureDecided }; } function formLogic(){ var form=q('#privacyForm'); var err=q('#formError'); var ok=q('#formOk'); var sendBtn=q('#sendBtn'); function showErr(msg){ err.textContent=msg; err.setAttribute('data-show','true'); ok.setAttribute('data-show','false'); ok.textContent=''; } function showOk(msg){ ok.textContent=msg; ok.setAttribute('data-show','true'); err.setAttribute('data-show','false'); err.textContent=''; } function validate(){ var email=q('#emailAddr').value.trim(); var type=q('#requestType').value.trim(); var message=q('#messageTxt').value.trim(); if(!email) return {ok:false, msg:'Please enter your email address.'}; if(!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email)) return {ok:false, msg:'Please enter a valid email address.'}; if(!type) return {ok:false, msg:'Please select a request type.'}; if(message.length<20) return {ok:false, msg:'Please provide a bit more detail (at least 20 characters).'}; if(message.length>4000) return {ok:false, msg:'Message is too long (max 4000 characters).'}; return {ok:true}; } function simulateSend(payload){ return new Promise(function(res){ setTimeout(function(){res({ticket:'PRV-'+Math.floor(100000+Math.random()*900000)})}, 850); }); } form.addEventListener('submit', function(e){ e.preventDefault(); var v=validate(); if(!v.ok){showErr(v.msg); return;} err.setAttribute('data-show','false'); ok.setAttribute('data-show','false'); sendBtn.disabled=true; sendBtn.style.opacity='.75'; var payload={ fullName:q('#fullName').value.trim(), email:q('#emailAddr').value.trim(), requestType:q('#requestType').value.trim(), region:q('#region').value.trim(), message:q('#messageTxt').value.trim(), ts:new Date().toISOString() }; simulateSend(payload).then(function(r){ showOk('Request sent. Your reference number is '+r.ticket+'. We’ll reply to '+payload.email+'.'); try{ sessionStorage.setItem('kc_last_privacy_ticket', r.ticket); }catch(e){} form.reset(); }).catch(function(){ showErr('Something went wrong while sending. Please try again or email [email protected].'); }).finally(function(){ sendBtn.disabled=false; sendBtn.style.opacity=''; }); }); q('#prefillBtn').addEventListener('click', function(){ q('#fullName').value='Alex Morgan'; q('#emailAddr').value='[email protected]'; q('#requestType').value='access'; q('#region').value='California'; q('#messageTxt').value='Hello—please share what personal data you have about me (if any), the purposes of processing, and where it is stored. Thank you.'; err.setAttribute('data-show','false'); ok.setAttribute('data-show','false'); }); } function buttonsWire(cookieApi, contactApi){ q('#openCookiesFromBody').addEventListener('click', function(){ cookieApi.openCookieModal(); }); q('#openRightsRequest').addEventListener('click', function(){ contactApi.open(); setTimeout(function(){q('#requestType').value='deletion'; q('#messageTxt').focus();}, 50); }); q('#resetPrefs').addEventListener('click', function(){ try{ localStorage.removeItem('kc_cookie_prefs_v1'); }catch(e){} cookieApi.ensureDecided(); var p=cookieApi.getPrefs(); p.decided=false; cookieApi.setPrefs(p); cookieApi.openBanner(); var contactOk=q('#formOk'); contactOk && contactOk.setAttribute('data-show','false'); }); } function hashScrollSupport(){ var id=decodeURIComponent((location.hash||'').replace('#','')).trim(); if(!id) return; var el=document.getElementById(id); if(!el) return; setTimeout(function(){ try{el.scrollIntoView({behavior:'smooth', block:'start'})}catch(e){el.scrollIntoView(true)} }, 120); } Promise.all([safeFetchComponent(q('#hdrMount')), safeFetchComponent(q('#ftrMount'))]).then(function(){ setDates(); estimateReadingTime(); themeInit(); var contactApi=modalController('contactModal','openContact','closeContact'); q('#closeContact').addEventListener('click', function(){contactApi.close()}); var cookieApi=cookieEngine(); cookieApi.ensureDecided(); var sections=tocBuild(); tocScrollSpy(sections); formLogic(); buttonsWire(cookieApi, contactApi); hashScrollSupport(); q('#cookieBanner').addEventListener('mousedown', function(e){ var box=q('.m6q2y', q('#cookieBanner')); if(!box) return; if(e.target===q('#cookieBanner')) cookieApi.closeBanner(); }); }); })();