1import{r as i,j as e,L as c,h as p,t as h,s as u,e as j}from"./index-PFM-xbfZ.js";function g(){const[s,a]=i.useState({name:"",email:"",subject:"",message:""}),[r,n]=i.useState(null),[o,d]=i.useState(!1),x=async t=>{t.preventDefault(),d(!0),n(null);try{const l=await fetch("/api/contact",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),m=await l.json();if(!l.ok)throw new Error(m.error||"Could not send");n({kind:"ok",text:m.message||"Thanks â I'll be in touch shortly."}),a({name:"",email:"",subject:"",message:""})}catch(l){n({kind:"err",text:l instanceof Error?l.message:"Could not send"})}finally{d(!1)}};return e.jsxs("form",{onSubmit:x,className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-[color:var(--line)] pb-3",children:[e.jsx("p",{className:"label",children:"New message"}),e.jsx("p",{className:"label",children:"â [email protected]"})]}),e.jsxs("div",{className:"grid gap-6 sm:grid-cols-2",children:[e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Name"}),e.jsx("input",{required:!0,value:s.name,onChange:t=>a(l=>({...l,name:t.target.value})),placeholder:"Ada Lovelace",className:"field mt-1.5"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Email"}),e.jsx("input",{type:"email",required:!0,value:s.email,onChange:t=>a(l=>({...l,email:t.target.value})),placeholder:"[email protected]",className:"field mt-1.5"})]})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Subject"}),e.jsx("input",{required:!0,value:s.subject,onChange:t=>a(l=>({...l,subject:t.target.value})),placeholder:"What can I help with?",className:"field mt-1.5"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Message"}),e.jsx("textarea",{required:!0,rows:5,value:s.message,onChange:t=>a(l=>({...l,message:t.target.value})),placeholder:"Tell me about your project, idea, or question.",className:"field mt-1.5 resize-y"})]}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 pt-2",children:[e.jsxs("button",{type:"submit",disabled:o,className:"btn-primary disabled:opacity-60",children:[o?"Sendingâ¦":"Send message",e.jsx("span",{"aria-hidden":!0,children:"â"})]}),r?e.jsx("p",{className:`text-sm ${r.kind==="ok"?"text-[color:var(--accent)]":"text-[color:var(--muted)]"}`,children:r.text}):null]})]})}const b=[{label:"Role",value:"CTO, Moradia"},{label:"Building",value:"Togetha"},{label:"Since",value:"2018"},{label:"Location",value:"Manchester · UK"}];function w(){const s=Object.entries(j);return e.jsxs("main",{className:"space-y-32 sm:space-y-40",children:[e.jsx(v,{}),e.jsx("section",{className:"grid grid-cols-2 border-y border-[color:var(--line-strong)] divide-x divide-[color:var(--line)] md:grid-cols-4",children:b.map((a,r)=>e.jsxs("div",{className:"px-5 py-7 sm:px-6 sm:py-8",children:[e.jsxs("p",{className:"label",children:[e.jsx("span",{className:"num mr-2 text-[color:var(--faint)]",children:String(r+1).padStart(2,"0")}),a.label]}),e.jsx("p",{className:"mt-3 font-display text-xl sm:text-2xl tracking-tight",children:a.value})]},a.label))}),e.jsx(N,{}),e.jsx(f,{skillGroups:s}),e.jsx(y,{})]})}function v(){return e.jsxs("section",{className:"relative pt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-b border-[color:var(--line)] pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2.5 text-[color:var(--muted)]",children:[e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-[color:var(--accent)] opacity-75"}),e.jsx("span",{className:"relative inline-flex h-2 w-2 rounded-full bg-[color:var(--accent)]"})]}),e.jsx("p",{className:"label-ink",children:"Available for chats"})]}),e.jsx("p",{className:"label",children:"Index · 01"})]}),e.jsxs("h1",{className:"display mt-14 sm:mt-20 text-[clamp(3.5rem,13vw,10.5rem)]",children:["Kenny",e.jsx("br",{}),"Coffie",e.jsx("span",{className:"text-[color:var(--accent)]",children:"."})]}),e.jsxs("div",{className:"mt-12 grid gap-10 border-t border-[color:var(--line)] pt-10 md:grid-cols-12 md:gap-12",children:[e.jsxs("div",{className:"md:col-span-3",children:[e.jsx("p",{className:"label",children:"Who"}),e.jsx("p",{className:"mt-3 text-sm text-[color:var(--muted)]",children:"Software engineer & designer. Builds calm, useful products with small excellent teams."})]}),e.jsx("div",{className:"md:col-span-6",children:e.jsxs("p",{className:"text-xl sm:text-2xl leading-snug text-[color:var(--ink)]",children:["CTO at"," ",e.jsx("a",{href:"https://moradia.app",target:"_blank",rel:"noreferrer",className:"link-accent",children:"Moradia"}),", shipping"," ",e.jsx("a",{href:"https://togetha.co.uk",target:"_blank",rel:"noreferrer",className:"underline decoration-[color:var(--line-strong)] underline-offset-4 hover:
1decoration-[color:var(--accent)]",children:"Togetha"})," ","â property management software for letting agents and landlords. Previously across the stack for startups and agencies."]})}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2 md:col-span-3 md:justify-end",children:[e.jsxs(c,{to:"/projects",className:"btn-accent",children:["See the work ",e.jsx("span",{"aria-hidden":!0,children:"â"})]}),e.jsx(c,{to:"/profile",className:"btn-ghost",children:"About"})]})]})]})}function N(){return e.jsxs("section",{children:[e.jsxs("div",{className:"flex items-end justify-between border-b border-[color:var(--line-strong)] pb-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"label",children:"Work · 02"}),e.jsx("h2",{className:"display mt-5 text-4xl sm:text-6xl",children:"Selected projects"})]}),e.jsxs(c,{to:"/projects",className:"group hidden items-center gap-2 text-sm text-[color:var(--muted)] hover:text-[color:var(--ink)] sm:inline-flex",children:[e.jsx("span",{className:"label",children:"Index"}),e.jsx("span",{className:"inline-block transition-transform group-hover:translate-x-0.5",children:"â"})]})]}),e.jsx("ul",{className:"divide-y divide-[color:var(--line)]",children:p.map((s,a)=>e.jsx("li",{children:e.jsxs(c,{to:"/project/$slug",params:{slug:u(s.name)},className:"group grid grid-cols-12 items-start gap-4 py-8 transition-colors sm:py-10 md:gap-6",children:[e.jsx("div",{className:"col-span-12 flex items-baseline gap-3 md:col-span-1",children:e.jsx("span",{className:"num text-sm text-[color:var(--faint)]",children:String(a+1).padStart(2,"0")})}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsx("h3",{className:"font-display text-3xl tracking-tight transition-colors group-hover:text-[color:var(--accent)] sm:text-4xl",children:h(s.name)}),s.company?e.jsx("p",{className:"mt-2 label",children:s.company}):null]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsx("p",{className:"text-[color:var(--muted)]",children:s.description}),s.stack?.length?e.jsx("div",{className:"mt-4 flex flex-wrap gap-x-3 gap-y-1",children:s.stack.slice(0,4).map(r=>e.jsx("span",{className:"label",children:r},r))}):null]}),e.jsx("div",{className:"col-span-12 md:col-span-3",children:e.jsxs("div",{className:`relative overflow-hidden border border-[color:var(--line)] ${s.tag==="mobile"?"flex aspect-[4/3] items-center justify-center bg-[color:var(--accent-soft)] p-4":"aspect-[4/3] bg-[color:var(--surface-2)]"}`,children:[e.jsx("img",{src:s.image,alt:s.name,loading:"lazy",className:s.tag==="mobile"?"h-full w-auto max-w-[55%] object-contain shadow-xl shadow-black/20 ring-1 ring-black/10 transition-transform duration-700 group-hover:scale-[1.04]":"h-full w-full object-cover object-[left_top] transition-transform duration-700 group-hover:scale-[1.04]"}),e.jsx("span",{"aria-hidden":!0,className:"absolute bottom-2 right-2 bg-[color:var(--ink)] px-1.5 py-0.5 text-[10px] font-mono tracking-widest uppercase text-[color:var(--bg)] opacity-0 transition-opacity group-hover:opacity-100",children:"View â"})]})})]})},s.name))})]})}function f({skillGroups:s}){return e.jsxs("section",{children:[e.jsxs("div",{className:"border-b border-[color:var(--line-strong)] pb-6",children:[e.jsx("p",{className:"label",children:"Practice · 03"}),e.jsxs("h2",{className:"display mt-5 text-4xl sm:text-6xl",children:["A generalist, ",e.jsx("span",{className:"text-[color:var(--accent)]",children:"with taste"}),"."]}),e.jsx("p",{className:"mt-5 max-w-xl text-[color:var(--muted)]",children:"I move across the stack and the design process â bringing the same care to a bit of animation as I do to an API."})]}),e.jsx("div",{className:"grid divide-y divide-[color:var(--line)] md:grid-cols-3 md:divide-x md:divide-y-0",children:s.map(([a,r])=>e.jsxs("article",{className:"py-8 md:px-8 md:py-10 first:md:pl-0 last:md:pr-0",children:[e.jsx("h3",{className:"font-display text-2xl tracking-tight",children:r.title??a}),e.jsx("ul",{className:"mt-5 space-y-2 text-sm text-[color:var(--muted)]",children:r.skills.map(n=>e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"num text-[color:var(--faint)]",children:"â"}),e.jsx("span",{children:n})]},n))})]},a))})]})}function y(){return e.jsxs("section",{children:[e.jsxs("div",{className:"border-b border-[color:var(--line-strong)] pb-6",children:[e.jsx("p",{className:"label",children:"Contact · 04"}),e.jsxs("h2",{className:"display mt-5 text-4xl sm:text-6xl",children:["Say hi",e.jsx("span",{className:"text-[color:var(--accent)]",children:"."})]})]}),e.jsxs("div",{className:"grid gap-12 pt-10 md:grid-cols-12 md:gap-16",children:[e.jsxs("div",{className:"md:col-span-4",children:[e.jsx("p",{className:"text-[color:var(--muted)]",children:"Work, a collab, or just a hello â drop a line and I'll get back within a day or two."}),e.jsxs("div",{className:"mt-6 flex flex-wrap gap-2",children:[e.jsx("span",{className:"chip",children:"UK · GMT"}
1),e.jsx("span",{className:"chip",children:"Advisory"}),e.jsx("span",{className:"chip",children:"Speaking"})]})]}),e.jsx("div",{className:"md:col-span-8",children:e.jsx(g,{})})]})]})}export{w as component};
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.