This commit is contained in:
2026-09-23 16:28:48 -07:00
commit 179a710a50
40 changed files with 30037 additions and 0 deletions
+812
View File
@@ -0,0 +1,812 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bex M. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Bex M. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/bex-m/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Bex M.
<span class="pronouns">vey/she</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-02-09">February 9, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/tutoring/" class="post-tag" title="browse providers who offer tutoring">tutoring</a>, </li>
<li><a href="/services/project-management/" class="post-tag" title="browse providers who offer project management">project management</a>, </li>
<li><a href="/services/admin/" class="post-tag" title="browse providers who offer admin">admin</a>, </li>
<li><a href="/services/event-planning/" class="post-tag" title="browse providers who offer event planning">event planning</a></li>
</ul>
<p class="location">Phinney Ridge</p>
</div>
<h2 id="bio">bio</h2>
<p>fox fairy with background in education, administration, and social work.</p>
<h2 id="services">services</h2>
<ul>
<li>weekly check-in/project management services</li>
<li>K-12 tutoring, particular expertise in English and physics</li>
<li>administrative support (drafting, copy editing, scheduling, travel &amp; event planning)</li>
</ul>
<h3 id="payment">payment</h3>
<ul>
<li>sliding scale $30-50/hr, billable by quarter hour</li>
<li>services swap/skill share</li>
<li>pro bono option available as needed</li>
</ul>
<h3 id="time-constraints">time constraints</h3>
<p>5 hrs per week max (under current circumstances)</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
<a href="mailto:fairy.lady@gmail.com?subject=Spoonfairies" target="_blank">fairy.lady [at] gmail [dot] com</a>
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/bex-m/` was built on 2026-09-23T23:25:06.285Z -->
</body>
</html>
+808
View File
@@ -0,0 +1,808 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Blythe S. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Blythe S. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/blythe-s/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Blythe S.
<span class="pronouns">she/her</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-03-17">March 17, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/hairdressing/" class="post-tag" title="browse providers who offer hairdressing">hairdressing</a>, </li>
<li><a href="/services/hygiene/" class="post-tag" title="browse providers who offer hygiene">hygiene</a></li>
</ul>
<p class="location">West Seattle</p>
</div>
<h2 id="bio">bio</h2>
<p>I am an ally, friend and professional hairdresser. I am happiest when interacting with and learning about new people. I do my best to listen and observe as I get to know people.</p>
<h2 id="services">services</h2>
<p>I can do haircutting and styling. I may be able to offer more if I learn of people’s different needs. I can also give personal hygiene products for those in need.</p>
<h3 id="payment">payment</h3>
<p>Pro bono</p>
<h3 id="time-constraints">time constraints</h3>
<p>Appointment only, not available Monday eve or Sunday.</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
<a href="mailto:glamouramalola@msn.com?subject=Spoonfairies" target="_blank">glamouramalola [at] msn [dot] com</a>
</li>
<li>
<a href="tel:206-910-8239" target="_blank">206-910-8239</a>
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/blythe-s/` was built on 2026-09-23T23:25:06.285Z -->
</body>
</html>
+802
View File
@@ -0,0 +1,802 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Brooke O. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Brooke O. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/brooke-o/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Brooke O.
<span class="pronouns">it/its</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-02-09">February 9, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/seamstress/" class="post-tag" title="browse providers who offer seamstress">seamstress</a>, </li>
<li><a href="/services/repair/" class="post-tag" title="browse providers who offer repair">repair</a>, </li>
<li><a href="/services/clothing/" class="post-tag" title="browse providers who offer clothing">clothing</a>, </li>
<li><a href="/services/mending/" class="post-tag" title="browse providers who offer mending">mending</a></li>
</ul>
<p class="location">Vashon</p>
</div>
<h2 id="bio">bio</h2>
<p>I am a self-taught seamstress and fashion-minded punk. I have been stitching my jackets back together for as long as they've been falling apart, generally with a mind towards visible mending and eye-catching colors.</p>
<h2 id="services">services</h2>
<p>Clothing/textile repair and upcycling, with a strong preference for jackets and/or heavier fabrics</p>
<h3 id="payment">payment</h3>
<p>cash/barter</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
<a href="mailto:bsosment@gmail.com?subject=Spoonfairies" target="_blank">bsosment [at] gmail [dot] com</a>
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/brooke-o/` was built on 2026-09-23T23:25:06.285Z -->
</body>
</html>
+905
View File
@@ -0,0 +1,905 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>providers | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="providers | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/" aria-current="page">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<h1>all providers</h1>
<ul class="providerlist">
<li class="providerlist-item">
<a href="/providers/blythe-s/" class="providerlist-link" aria-label="Blythe S.
she/her
is based out of West Seattle
">
Blythe S.
<span class="pronouns">she/her</span>
<span class="location">West Seattle</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/hairdressing/" class="post-tag" title="browse providers who offer hairdressing">hairdressing</a>, </li>
<li><a href="/services/hygiene/" class="post-tag" title="browse providers who offer hygiene">hygiene</a></li>
</ul>
</li>
<li class="providerlist-item">
<a href="/providers/rain-v/" class="providerlist-link" aria-label="Rain V.
she/they
is based out of Redmond
">
Rain V.
<span class="pronouns">she/they</span>
<span class="location">Redmond</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/funds/" class="post-tag" title="browse providers who offer funds">funds</a>, </li>
<li><a href="/services/computers/" class="post-tag" title="browse providers who offer computers">computers</a>, </li>
<li><a href="/services/software/" class="post-tag" title="browse providers who offer software">software</a>, </li>
<li><a href="/services/errands/" class="post-tag" title="browse providers who offer errands">errands</a></li>
</ul>
</li>
<li class="providerlist-item">
<a href="/providers/roz-m/" class="providerlist-link" aria-label="Roz M.
she/her
is based out of Wallingford
">
Roz M.
<span class="pronouns">she/her</span>
<span class="location">Wallingford</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/body-doubling/" class="post-tag" title="browse providers who offer body doubling">body doubling</a>, </li>
<li><a href="/services/art/" class="post-tag" title="browse providers who offer art">art</a>, </li>
<li><a href="/services/mending/" class="post-tag" title="browse providers who offer mending">mending</a>, </li>
<li><a href="/services/admin/" class="post-tag" title="browse providers who offer admin">admin</a>, </li>
<li><a href="/services/medical-advocate/" class="post-tag" title="browse providers who offer medical advocate">medical advocate</a></li>
</ul>
</li>
<li class="providerlist-item">
<a href="/providers/lee-c/" class="providerlist-link" aria-label="Lee C.
ze/he
is digital-only">
Lee C.
<span class="pronouns">ze/he</span>
<span class="online">digital-only</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/webdev/" class="post-tag" title="browse providers who offer webdev">webdev</a>, </li>
<li><a href="/services/web-accessibility/" class="post-tag" title="browse providers who offer web accessibility">web accessibility</a>, </li>
<li><a href="/services/spreadsheets/" class="post-tag" title="browse providers who offer spreadsheets">spreadsheets</a>, </li>
<li><a href="/services/logos/" class="post-tag" title="browse providers who offer logos">logos</a>, </li>
<li><a href="/services/clothing/" class="post-tag" title="browse providers who offer clothing">clothing</a>, </li>
<li><a href="/services/art/" class="post-tag" title="browse providers who offer art">art</a>, </li>
<li><a href="/services/computers/" class="post-tag" title="browse providers who offer computers">computers</a>, </li>
<li><a href="/services/software/" class="post-tag" title="browse providers who offer software">software</a></li>
</ul>
</li>
<li class="providerlist-item">
<a href="/providers/brooke-o/" class="providerlist-link" aria-label="Brooke O.
it/its
is based out of Vashon
">
Brooke O.
<span class="pronouns">it/its</span>
<span class="location">Vashon</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/seamstress/" class="post-tag" title="browse providers who offer seamstress">seamstress</a>, </li>
<li><a href="/services/repair/" class="post-tag" title="browse providers who offer repair">repair</a>, </li>
<li><a href="/services/clothing/" class="post-tag" title="browse providers who offer clothing">clothing</a>, </li>
<li><a href="/services/mending/" class="post-tag" title="browse providers who offer mending">mending</a></li>
</ul>
</li>
<li class="providerlist-item">
<a href="/providers/bex-m/" class="providerlist-link" aria-label="Bex M.
vey/she
is based out of Phinney Ridge
">
Bex M.
<span class="pronouns">vey/she</span>
<span class="location">Phinney Ridge</span>
</a>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/tutoring/" class="post-tag" title="browse providers who offer tutoring">tutoring</a>, </li>
<li><a href="/services/project-management/" class="post-tag" title="browse providers who offer project management">project management</a>, </li>
<li><a href="/services/admin/" class="post-tag" title="browse providers who offer admin">admin</a>, </li>
<li><a href="/services/event-planning/" class="post-tag" title="browse providers who offer event planning">event planning</a></li>
</ul>
</li>
</ul>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/` was built on 2026-09-23T23:25:06.280Z -->
</body>
</html>
+819
View File
@@ -0,0 +1,819 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Lee C. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Lee C. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/lee-c/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Lee C.
<span class="pronouns">ze/he</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-02-09">February 9, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/webdev/" class="post-tag" title="browse providers who offer webdev">webdev</a>, </li>
<li><a href="/services/web-accessibility/" class="post-tag" title="browse providers who offer web accessibility">web accessibility</a>, </li>
<li><a href="/services/spreadsheets/" class="post-tag" title="browse providers who offer spreadsheets">spreadsheets</a>, </li>
<li><a href="/services/logos/" class="post-tag" title="browse providers who offer logos">logos</a>, </li>
<li><a href="/services/clothing/" class="post-tag" title="browse providers who offer clothing">clothing</a>, </li>
<li><a href="/services/art/" class="post-tag" title="browse providers who offer art">art</a>, </li>
<li><a href="/services/computers/" class="post-tag" title="browse providers who offer computers">computers</a>, </li>
<li><a href="/services/software/" class="post-tag" title="browse providers who offer software">software</a></li>
</ul>
<p class="online">digital-only</p>
</div>
<h2 id="bio">bio</h2>
<p>multidisciplinary artist and crafter. reluctant computer toucher. big fan of birds.</p>
<h2 id="services">services</h2>
<p>web dev with a focus on accessibility, incl. accessibility reviews for your existing website. spreadsheets galore. basic logos, functional leatherwork, block printed clothing with <a href="https://leecat.art/tag/print" target="_blank">existing designs</a> or your own design (takes more work and resources, add'l cost).</p>
<h3 id="payment">payment</h3>
<p>sliding scale or skill swap</p>
<h3 id="time-constraints">time constraints</h3>
<p>*shrug emoji*</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
<a href="https://signal.me/#eu/PcJ86iNQeAbC-SFbxqI00gFQb6zL4Y6QDCsFDU2mokM4K40djsdNYa3hJAee79ll" target="_blank">inherentlee.13 on signal</a>
</li>
<li>
<a href="mailto:lee.cattarin@gmail.com?subject=Spoonfairies" target="_blank">lee.cattarin [at] gmail [dot] com</a>
</li>
<li>
<a href="https://leecat.art/contact" target="_blank">leecat.art/contact</a>
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/lee-c/` was built on 2026-09-23T23:25:06.285Z -->
</body>
</html>
+804
View File
@@ -0,0 +1,804 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Rain V. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Rain V. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/rain-v/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Rain V.
<span class="pronouns">she/they</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-02-13">February 13, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/funds/" class="post-tag" title="browse providers who offer funds">funds</a>, </li>
<li><a href="/services/computers/" class="post-tag" title="browse providers who offer computers">computers</a>, </li>
<li><a href="/services/software/" class="post-tag" title="browse providers who offer software">software</a>, </li>
<li><a href="/services/errands/" class="post-tag" title="browse providers who offer errands">errands</a></li>
</ul>
<p class="location">Redmond</p>
</div>
<h2 id="bio">bio</h2>
<p>I have many crafting hobbies such as woodworking and CNC, but I'm too busy and tired to have much time for them. such is life. I'm a software engineer by trade, living the corpo life I guess ᕕ( ᐛ )ᕗ</p>
<h2 id="services">services</h2>
<p>mainly money tbh, and I can help with things if you're near Redmond or Bellevue and it doesn't take a lot of time.</p>
<h3 id="payment">payment</h3>
<p>praise? barter? (clean my place or body doubling with my partner Milo to help him sort and organize his stuff, little art commissions might be cool) or help someone else in this community for me ❤️</p>
<h3 id="time-constraints">time constraints</h3>
<p>1-2 hours per week, generally low availability so flexibility and planning ahead helps</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
rainybean on discord
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/rain-v/` was built on 2026-09-23T23:25:06.286Z -->
</body>
</html>
+823
View File
@@ -0,0 +1,823 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Roz M. | Spoonfairies</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<!-- Meta -->
<link rel="canonical" href="/">
<meta name="description" content="find the services you need from others who need you">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Roz M. | Spoonfairies">
<meta property="og:type" content="article">
<meta property="og:url" content="https://spoonfairies.help/providers/roz-m/">
<meta property="og:description" content="find the services you need from others who need you">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="https://spoonfairies.help/favicon.ico">
<meta property="og:image:alt" content="the Spoonfairies logo, a spoon with wings">
<meta name="generator" content="Eleventy v3.1.5">
<!-- Fonts -->
<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=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
<!-- CSS -->
<style>:root {
color-scheme: light dark;
--font-family: "Atkinson Hyperlegible Next", sans-serif;
/* Theme colors */
--color-light: #fbe8fd;
--color-dark: #110526;
--color-pink-dark: #741189;
--color-pink-light: #d972ef;
--color-purple-dark: #421397;
--color-purple-light: #9d6ff4;
--color-blue-dark: #1243a7;
--color-blue-light: #6586ea;
/* light/dark mode resolved colors */
--color-bg: light-dark(var(--color-light), var(--color-dark));
--color-text: light-dark(var(--color-dark), var(--color-light));
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
}
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
*, *::before, *::after {
box-sizing: border-box; /* 1. Use a more-intuitive box-sizing model */
}
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords; /* 3. Enable keyword animations */
}
}
html,
body {
padding: 0;
margin: 0 auto;
font-family: var(--font-family);
color: var(--color-text);
background-color: var(--color-bg);
}
html {
overflow-y: scroll;
}
body {
max-width: 40rem;
line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
}
main {
padding: 1rem;
}
section + section {
margin-top: 4rem;;
}
img, picture, video, canvas, svg {
display: block; /* 6. Improve media defaults */
max-width: 100%; /* 6. Improve media defaults */
height: auto; /* 6. Improve media defaults */
}
input, button, textarea, select {
font: inherit; /* 7. Inherit fonts for form controls */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* 8. Avoid text overflows */
}
p {
text-wrap: pretty; /* 9. Improve line wrapping */
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
p + p {
margin-top: 2rem;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */
}
h1 {
font-size: 2.5rem;
margin-top: 0;
}
h2 {
font-size: 1.9rem;
padding-bottom: .1rem;
border-bottom: .1rem solid var(--color-pink);
}
h3 {
font-size: 1.5rem;
padding-bottom: .05rem;
border-bottom: .05rem solid var(--color-pink);
}
h4 {
font-size: 1.2rem;
}
li {
line-height: 1.5;
}
.long-items li + li {
margin-top: .75rem;
}
a {
color: var(--color-text);
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-blue);
border-radius: .1rem;
outline-offset: .1rem;
}
a:visited {
text-decoration-color: var(--color-purple);
}
a:hover,
a:active {
text-decoration-color: var(--color-pink);
}
a:focus-visible {
text-decoration: none;
outline: .15rem solid var(--color-pink);
}
a.ha {
color: var(--color-pink);
outline-offset: 0;
}
span.ha-placeholder {
opacity: .55;
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* name coloration */
.brand {
color: var(--color-pink);
font-weight: bold;
}
/* provider pronouns */
.pronouns::after {
content: ")" / "";
}
.pronouns::before {
content: "(pronouns: " / "pronouns: ";
}
.pronouns {
color: var(--color-text);
opacity: .75;
font-size: .8em;
}
/* location spans */
.location::before {
content: "📍" / "is based out of ";
}
.online::before {
content: "🌐" / "is ";
}
.location,
.online {
margin: 0;
text-align: right;
color: var(--color-text);
font-size: 1rem;
font-weight: bold;
}
/* Posts list */
.providerlist {
padding: 0;
}
.providerlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
margin-bottom: 1rem;
}
.providerlist-item + .providerlist-item {
border-top: .1rem dotted;
margin-top: 2.25rem;
padding-top: 1.5rem;
}
.providerlist-link {
font-size: 1.35rem; /* 19px /16 */
font-weight: 700;
flex-basis: 100%;
border-bottom: .05rem solid var(--color-pink);
text-decoration: none;
color: var(--color-blue);
display: inline-flex;
align-items: baseline;
column-gap: .5rem;
flex-flow: row wrap;
}
.providerlist-link:visited {
color: var(--color-purple);
}
.providerlist-link:hover,
.providerlist-link:active {
color: var(--color-pink);
}
.providerlist-link:focus-visible {
border-bottom-color: var(--color-bg);
}
.providerlist-link .location,
.providerlist-link .online {
flex-grow: 5;
}
.providerlist-item-active .providerlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-block;
font-style: italic;
}
/* Tags list */
.taglist {
display: inline-flex;
flex-wrap: wrap;
column-gap: .5rem;
list-style: none;
padding: 0;
margin: 0;
}
/* related providers section on provider pages */
.related-providers {
border-top: .1rem dotted;
padding-top: 1rem;
margin-top: 4rem;
}
/* services page */
.service-list {
display: flex;
flex-flow: row wrap;
padding-left: 0;
column-gap: 1rem;
row-gap: 2rem;
margin-top: 3rem;
}
.service {
list-style: none;
}
.service a {
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
.service a:focus-visible {
border-color: var(--color-bg);
}
/* post metadata */
.post-metadata {
display: flex;
flex-flow: column nowrap;
align-items: flex-end;
gap: .5rem;
}
.post-time {
font-size: .9rem;
opacity: .75;
margin: 0;
}
@media (max-width: 500px) {
.post-metadata .taglist {
justify-content: flex-end;
}
}
/* provider contact info */
.contacts {
text-align: center;
padding: 0;
}
.contacts li {
list-style: none;
}
.contacts li + li {
padding-top: .75rem;
}
/* team page specific */
.team-contact {
display: block;
text-align: center;
}
header {
border-bottom: .2rem dotted;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
#skip-link {
text-decoration: none;
background: var(--color-bg);
color: var(--color-text);
padding: 0.5rem 1rem;
outline-offset: 0;
border-radius: .25rem;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
/* logo and title */
.home-link {
font-weight: 700;
border-radius: .25rem;
display: flex;
gap: .5rem;
outline-offset: .25rem;
text-underline-offset: .2rem;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
a[href].home-link:focus-visible {
outline-width: .25rem;
}
header img {
height: 3rem !important;
width: 3rem !important;
border-radius: .5rem;
}
header h2 {
margin: 0;
outline-offset: .25rem;
border: none;
text-transform: lowercase;
color: var(--color-pink);
}
header a:has(h2):hover {
text-decoration-color: var(--color-text);
}
/* Nav */
.nav {
display: flex;
gap: .5rem 1rem;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
text-decoration-thickness: .2rem;
}
.nav a[href][aria-current="page"]:hover {
text-decoration-color: var(--color-pink);
}
/* Pagination */
.pagination {
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: .2rem dotted;
margin-top: 2.25rem;
padding-top: 2rem;
padding-left: 0;
}
.pagination li {
list-style: none;
}
.pagination li:not(:has(a)),
.pagination a {
display: block;
border: .1rem dotted;
padding: .5rem;
border-radius: .75rem;
}
/* Footer */
footer {
border-top: .2rem dotted;
margin-top: 1.5rem;
padding: 1rem 0;
text-align: center;
}
.footer-links {
display: flex;
gap: 1rem;
justify-content: space-between;
}
footer p {
margin: 0;
}
footer .year {
width: 30%;
padding-top: .5rem;
margin: 1rem auto;
border-top: .05rem solid;
}
@media (max-width: 500px) {
.footer-links {
flex-flow: column;
gap: .1rem;
align-items: center;
}
footer .year {
width: 65%;
}
}</style>
<!-- JS -->
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
let globalInstanceIndex = 0;
class HeadingAnchors extends HTMLElement {
static register(tagName = "heading-anchors", registry = window.customElements) {
if(registry && !registry.get(tagName)) {
registry.define(tagName, this);
}
}
static attributes = {
exclude: "data-ha-exclude",
prefix: "prefix",
content: "content",
}
static classes = {
anchor: "ha",
placeholder: "ha-placeholder",
srOnly: "ha-visualhide",
}
static defaultSelector = "h2,h3,h4,h5,h6";
static css = `
.${HeadingAnchors.classes.srOnly} {
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: var(--ha_offsetx);
top: var(--ha_offsety);
text-decoration: none;
opacity: 0;
}
.${HeadingAnchors.classes.placeholder} {
opacity: .3;
}
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
opacity: 1;
}
.${HeadingAnchors.classes.anchor},
.${HeadingAnchors.classes.placeholder} {
display: inline-block;
padding: 0 .25em;
/* Disable selection of visually hidden label */
-webkit-user-select: none;
user-select: none;
}
@supports (anchor-name: none) {
.${HeadingAnchors.classes.anchor} {
position: absolute;
left: anchor(left);
top: anchor(top);
}
}`;
get supports() {
return "replaceSync" in CSSStyleSheet.prototype;
}
get supportsAnchorPosition() {
return CSS.supports("anchor-name: none");
}
constructor() {
super();
if(!this.supports) {
return;
}
let sheet = new CSSStyleSheet();
sheet.replaceSync(HeadingAnchors.css);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
this.headingStyles = {};
this.instanceIndex = globalInstanceIndex++;
}
connectedCallback() {
if (!this.supports) {
return;
}
this.headings.forEach((heading, index) => {
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
let anchor = this.getAnchorElement(heading);
let placeholder = this.getPlaceholderElement();
// Prefers anchor position approach for better accessibility
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
if(this.supportsAnchorPosition) {
let anchorName = `--ha_${this.instanceIndex}_${index}`;
placeholder.style.setProperty("anchor-name", anchorName);
anchor.style.positionAnchor = anchorName;
}
heading.appendChild(placeholder);
heading.after(anchor);
}
});
}
// Polyfill-only
positionAnchorFromPlaceholder(placeholder) {
if(!placeholder) {
return;
}
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
if(!heading.nextElementSibling) {
return;
}
// TODO next element could be more defensive
this.positionAnchor(heading.nextElementSibling);
}
// Polyfill-only
positionAnchor(anchor) {
if(!anchor || !anchor.previousElementSibling) {
return;
}
// TODO previous element could be more defensive
let heading = anchor.previousElementSibling;
this.setFontProp(heading, anchor);
if(this.supportsAnchorPosition) {
// quit early
return;
}
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
}
}
setFontProp(heading, anchor) {
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
let style = getComputedStyle(placeholder);
let props = ["font-weight", "font-size", "line-height", "font-family"];
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
let vars = style.getPropertyValue("font-variation-settings");
if(vars) {
anchor.style.setProperty("font-variation-settings", vars);
}
}
}
getAccessibleTextPrefix() {
// Useful for i18n
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
}
getContent() {
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
return this.getAttribute(HeadingAnchors.attributes.content);
}
return "#";
}
// Placeholder nests inside of heading
getPlaceholderElement() {
let ph = document.createElement("span");
ph.setAttribute("aria-hidden", true);
ph.classList.add(HeadingAnchors.classes.placeholder);
let content = this.getContent();
if(content) {
ph.textContent = content;
}
ph.addEventListener("mouseover", (e) => {
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
if(placeholder) {
this.positionAnchorFromPlaceholder(placeholder);
}
});
return ph;
}
getAnchorElement(heading) {
let anchor = document.createElement("a");
anchor.href = `#${heading.id}`;
anchor.classList.add(HeadingAnchors.classes.anchor);
let content = this.getContent();
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
anchor.addEventListener("focus", e => {
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
if(anchor) {
this.positionAnchor(anchor);
}
});
anchor.addEventListener("mouseover", (e) => {
// when CSS anchor positioning is supported, this is only used to set the font
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
this.positionAnchor(anchor);
});
return anchor;
}
get headings() {
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
}
get selector() {
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
}
}
HeadingAnchors.register();
export { HeadingAnchors }</script>
</head>
<body>
<header>
<a href="/" class="home-link" title="home page">
<img src="/.11ty/image/?src=src%2Flogo.jpg&width=585&format=jpeg&via=transform" alt="the Spoonfairies logo, showing a spoon with fairy wings" loading="lazy" decoding="async" width="585" height="585">
<h2>Spoonfairies</h2>
</a>
<nav aria-label="main navigation">
<ul class="nav">
<li class="nav-item"><a href="/providers/">all providers</a></li>
<li class="nav-item"><a href="/services/">all services</a></li>
<li class="nav-item"><a href="/get-involved/">get involved</a></li>
</ul>
</nav>
</header>
<main id="main">
<article>
<h1>Roz M.
<span class="pronouns">she/her</span>
</h1>
<div class="post-metadata">
<p class="post-time">last updated <time datetime="2026-02-09">February 9, 2026</time></p>
<p class="visually-hidden">services this provider offers are </p>
<ul class="taglist">
<li><a href="/services/providers/" class="post-tag" title="browse providers who offer providers">providers</a>, </li>
<li><a href="/services/body-doubling/" class="post-tag" title="browse providers who offer body doubling">body doubling</a>, </li>
<li><a href="/services/art/" class="post-tag" title="browse providers who offer art">art</a>, </li>
<li><a href="/services/mending/" class="post-tag" title="browse providers who offer mending">mending</a>, </li>
<li><a href="/services/admin/" class="post-tag" title="browse providers who offer admin">admin</a>, </li>
<li><a href="/services/medical-advocate/" class="post-tag" title="browse providers who offer medical advocate">medical advocate</a></li>
</ul>
<p class="location">Wallingford</p>
</div>
<h2 id="bio">bio</h2>
<p>Roz Martinez is a Seattle-based artist working predominantly in graphite and ink. She grew up on the east coast, learning how to express herself visually from her mother and grandmother, both of whom studied art extensively.</p>
<h2 id="services">services</h2>
<ul>
<li>Body Doubling</li>
<li>Art/Design: commissions, teaching, hosting art parties</li>
<li>Mending/sewing</li>
<li>Admin: email drafting, phone calls &amp; scripting, desktop research</li>
<li>Medical advocate/companion</li>
</ul>
<h3 id="payment">payment</h3>
<p>Open to any upon negotiation</p>
<h3 id="time-constraints">time constraints</h3>
<p>Can dedicate 1 day per week to <span class="brand">Spoonfairies</span> and other projects</p>
<h2>contact information</h2>
<ul class="contacts">
<li>
<a href="mailto:rozmartinez@gmail.com?subject=Spoonfairies" target="_blank">rozmartinez [at] gmail [dot] com</a>
</li>
<li>
<a href="https://www.rozmartinezfineart.com/" target="_blank">rozmartinezfineart.com</a>
</li>
<li>
<a href="https://bsky.app/profile/rozmartinez.bsky.social" target="_blank">rozmartinez.bsky.social on bsky</a>
</li>
</ul>
</article>
<section class="related-providers">
</section>
</main>
<footer>
<div class="footer-links">
<p><a href="/attribution" title="site attribution">attribution</a></p>
<p><a href="/team" title="meet or contact the Spoonfairies team">team</a></p>
<p><a href="/privacy" title="data privacy">privacy</a></p>
<p><a href="/accessibility" title="accessibility statements">accessibility</a></p>
<p><a href="https://heckin.technology/inherentlee/spoonfairies" target="_blank" title="source code">source</a></p>
</div>
<p class="year"><a href="/" title="home page">Spoonfairies 2026</a></p>
</footer>
<!-- This page `/providers/roz-m/` was built on 2026-09-23T23:25:06.286Z -->
</body>
</html>