MoonshotAI Kimi K3.1 Pro – Religion and Spirituality
via Moonshot AI · Generated
- AIMAC Debt 4.19
- Cost $0.47
- Total Violations 10
- HTML Size 122 KB
- Em Dashes 10
Screenshot
View Live Page
Accessibility Issues Found
10 Serious
-
color-contrast serious 10 instances
Elements must meet minimum color contrast ratio thresholds
Example HTML
<div class="eyebrow">Upcoming Events</div>
Artifacts
View Generated HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Harborlight Community Church is a Christ-centered community in Portland offering Sunday worship, faith formation, practical care, neighborhood service, and spiritual resources for every season.">
<meta name="theme-color" content="#19372e">
<meta property="og:title" content="Harborlight Community Church | Rooted in Grace">
<meta property="og:description" content="A place to belong, a way to become. Join Harborlight for worship, community, and faith that moves into the neighborhood.">
<meta property="og:type" content="website">
<meta property="og:image" content="https://picsum.photos/seed/harborlight-hero/1200/630">
<title>Harborlight Community Church | Rooted in Grace. Making Room for Everyone.</title>
<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=DM+Sans:wght@400;500;600;700&family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&display=swap" rel="stylesheet">
<link rel="icon" href="https://placehold.co/64x64/19372e/f7f3ea?text=HL&font=montserrat">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Church",
"name": "Harborlight Community Church",
"description": "A Christ-centered community rooted in scripture, prayer, hospitality, and neighborhood service.",
"telephone": "+1-503-555-0148",
"email": "hello@harborlight.church",
"address": {
"@type": "PostalAddress",
"streetAddress": "1280 Harbor Way",
"addressLocality": "Portland",
"addressRegion": "OR",
"postalCode": "97209",
"addressCountry": "US"
},
"openingHours": "Mo-Th 09:00-16:00"
}
</script>
<style>
:root {
--ink: #19372e;
--ink-deep: #10271f;
--ink-soft: #315247;
--cream: #f7f3ea;
--paper: #fffdf8;
--sand: #ebe3d3;
--sage: #dbe3da;
--sage-deep: #74897a;
--gold: #d1a35c;
--gold-light: #f1dfba;
--rust: #a9563d;
--rust-dark: #88442f;
--text: #263a33;
--muted: #647069;
--line: rgba(25, 55, 46, 0.15);
--white-line: rgba(255, 255, 255, 0.17);
--shadow: 0 24px 70px rgba(20, 43, 35, 0.12);
--font-body: "DM Sans", sans-serif;
--font-display: "Fraunces", Georgia, serif;
--container: 1180px;
}
*, *::before, *::after {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
scroll-padding-top: 110px;
}
body {
margin: 0;
overflow-x: clip;
background: var(--cream);
color: var(--text);
font-family: var(--font-body);
font-size: 16px;
line-height: 1.7;
-webkit-font-smoothing: antialiased;
}
body.modal-open {
overflow: hidden;
}
[hidden] {
display: none !important;
}
img {
display: block;
max-width: 100%;
}
a {
color: inherit;
text-decoration: none;
}
button, input, select, textarea {
color: inherit;
font: inherit;
}
button, summary {
-webkit-tap-highlight-color: transparent;
}
button {
cursor: pointer;
}
p {
margin: 0 0 1.2em;
}
h1, h2, h3, h4 {
margin: 0;
color: var(--ink);
font-family: var(--font-display);
font-weight: 500;
letter-spacing: -0.025em;
}
h1 {
font-size: clamp(3.35rem, 6.6vw, 6.25rem);
line-height: 0.99;
}
h2 {
font-size: clamp(2.45rem, 4.5vw, 4.25rem);
line-height: 1.06;
}
h3 {
font-size: 1.5rem;
line-height: 1.2;
}
ul, ol {
margin: 0;
padding: 0;
}
address {
font-style: normal;
}
::selection {
background: var(--gold-light);
color: var(--ink-deep);
}
:focus-visible {
outline: 3px solid var(--gold);
outline-offset: 4px;
}
.svg-sprite {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
}
.icon {
width: 20px;
height: 20px;
flex: 0 0 auto;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
.container {
width: min(var(--container), calc(100% - 48px));
margin-inline: auto;
}
.section {
padding: clamp(82px, 9vw, 128px) 0;
}
.section-heading {
max-width: 710px;
margin-bottom: 48px;
}
.section-heading.centered {
margin-inline: auto;
text-align: center;
}
.section-heading p {
max-width: 630px;
margin-top: 22px;
color: var(--muted);
font-size: 1.05rem;
}
.section-heading.centered p {
margin-inline: auto;
}
.eyebrow {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 19px;
color: var(--rust);
font-size: 0.73rem;
font-weight: 700;
letter-spacing: 0.18em;
line-height: 1.4;
text-transform: uppercase;
}
.eyebrow::before {
width: 29px;
height: 1px;
background: currentColor;
content: "";
}
.centered .eyebrow {
justify-content: center;
}
.eyebrow.light {
color: var(--gold-light);
}
.lead {
color: var(--muted);
font-size: clamp(1.05rem, 1.5vw, 1.18rem);
line-height: 1.8;
}
.btn {
display: inline-flex;
min-height: 52px;
align-items: center;
justify-content: center;
gap: 11px;
padding: 13px 23px;
border: 1px solid transparent;
border-radius: 999px;
font-size: 0.9rem;
font-weight: 700;
line-height: 1.2;
text-align: center;
transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.btn:hover {
transform: translateY(-2px);
}
.btn-primary {
background: var(--ink);
color: var(--paper);
}
.btn-primary:hover {
background: var(--ink-soft);
}
.btn-gold {
background: var(--gold);
color: var(--ink-deep);
}
.btn-gold:hover {
background: #e0ba78;
}
.btn-light {
background: var(--paper);
color: var(--ink);
}
.btn-light:hover {
background: var(--gold-light);
}
.btn-outline {
border-color: var(--line);
background: transparent;
color: var(--ink);
}
.btn-outline:hover {
border-color: var(--ink);
background: rgba(25, 55, 46, 0.04);
}
.btn-outline-light {
border-color: rgba(255, 255, 255, 0.35);
background: transparent;
color: var(--paper);
}
.btn-outline-light:hover {
border-color: var(--paper);
background: rgba(255, 255, 255, 0.08);
}
.btn-small {
min-height: 43px;
padding: 10px 18px;
font-size: 0.82rem;
}
.text-link {
display: inline-flex;
align-items: center;
gap: 8px;
color: var(--ink);
font-size: 0.88rem;
font-weight: 700;
}
.text-link .icon {
width: 17px;
transition: transform 180ms ease;
}
.text-link:hover .icon {
transform: translateX(4px);
}
.text-link.light {
color: var(--gold-light);
}
.skip-link {
position: fixed;
z-index: 9999;
top: 12px;
left: 12px;
padding: 12px 18px;
transform: translateY(-160%);
border-radius: 6px;
background: var(--paper);
color: var(--ink);
font-weight: 700;
box-shadow: var(--shadow);
}
.skip-link:focus {
transform: translateY(0);
}
/* Announcement and navigation */
.announcement {
position: relative;
z-index: 60;
padding: 10px 20px;
background: var(--ink-deep);
color: rgba(255, 255, 255, 0.88);
font-size: 0.8rem;
text-align: center;
}
.announcement a {
margin-left: 7px;
color: var(--gold-light);
font-weight: 700;
text-decoration: underline;
text-underline-offset: 3px;
}
.site-header {
position: sticky;
z-index: 50;
top: 0;
border-bottom: 1px solid var(--line);
background: rgba(247, 243, 234, 0.94);
backdrop-filter: blur(16px);
}
.header-inner {
position: relative;
display: flex;
min-height: 91px;
align-items: center;
gap: 24px;
}
.brand {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
gap: 12px;
}
.brand-logo {
width: 49px;
height: 49px;
border-radius: 50%;
box-shadow: 0 0 0 4px rgba(25, 55, 46, 0.06);
}
.brand-name {
display: block;
color: var(--ink);
font-family: var(--font-display);
font-size: 1.13rem;
font-weight: 600;
letter-spacing: -0.02em;
line-height: 1.15;
}
.brand-tagline {
display: block;
max-width: 190px;
margin-top: 5px;
color: var(--muted);
font-size: 0.61rem;
font-weight: 600;
letter-spacing: 0.035em;
line-height: 1.35;
}
.primary-nav {
margin-left: auto;
}
.primary-nav ul {
display: flex;
align-items: center;
gap: clamp(15px, 1.8vw, 26px);
list-style: none;
}
.primary-nav a {
position: relative;
display: block;
padding: 12px 0;
color: var(--ink);
font-size: 0.79rem;
font-weight: 600;
}
.primary-nav a::after {
position: absolute;
right: 0;
bottom: 5px;
left: 0;
height: 1px;
transform: scaleX(0);
transform-origin: right;
background: var(--rust);
content: "";
transition: transform 180ms ease;
}
.primary-nav a:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.header-actions {
display: flex;
align-items: center;
gap: 12px;
}
.menu-toggle {
display: none;
width: 46px;
height: 46px;
align-items: center;
justify-content: center;
border: 1px solid var(--line);
border-radius: 50%;
background: transparent;
}
.menu-lines,
.menu-lines::before,
.menu-lines::after {
display: block;
width: 19px;
height: 1.5px;
background: var(--ink);
content: "";
transition: transform 180ms ease, opacity 180ms ease;
}
.menu-lines {
position: relative;
}
.menu-lines::before {
position: absolute;
top: -6px;
}
.menu-lines::after {
position: absolute;
top: 6px;
}
.nav-open .menu-lines {
background: transparent;
}
.nav-open .menu-lines::before {
top: 0;
transform: rotate(45deg);
}
.nav-open .menu-lines::after {
top: 0;
transform: rotate(-45deg);
}
/* Hero */
.hero {
position: relative;
padding: clamp(62px, 7vw, 96px) 0 clamp(78px, 8vw, 110px);
background:
radial-gradient(circle at 8% 18%, rgba(209, 163, 92, 0.12), transparent 27%),
var(--cream);
}
.hero-grid {
display: grid;
grid-template-columns: 1.05fr 0.82fr;
align-items: center;
gap: clamp(54px, 7vw, 95px);
}
.hero-copy h1 em {
color: var(--rust);
font-weight: 400;
}
.hero-copy .lead {
max-width: 600px;
margin: 28px 0 30px;
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 13px;
}
.hero-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 12px 22px;
margin-top: 32px;
color: var(--muted);
font-size: 0.82rem;
font-weight: 600;
}
.hero-meta span {
display: inline-flex;
align-items: center;
gap: 8px;
}
.hero-meta .icon {
width: 17px;
color: var(--rust);
}
.hero-visual {
position: relative;
max-width: 495px;
margin-left: auto;
padding: 0 12px 22px 0;
}
.hero-visual::before {
position: absolute;
z-index: 0;
right: -10px;
bottom: 0;
width: 85%;
height: 88%;
border: 1px solid rgba(25, 55, 46, 0.2);
border-radius: 220px 220px 20px 20px;
content: "";
}
.hero-arch {
position: relative;
z-index: 1;
aspect-ratio: 5 / 6;
overflow: hidden;
border-radius: 245px 245px 20px 20px;
background: var(--sand);
box-shadow: var(--shadow);
}
.hero-arch img {
width: 100%;
height: 100%;
object-fit: cover;
}
.hero-note {
position: absolute;
z-index: 2;
bottom: 66px;
left: -76px;
width: 230px;
padding: 23px 25px;
border-left: 3px solid var(--gold);
background: var(--paper);
box-shadow: 0 18px 48px rgba(20, 43, 35, 0.17);
}
.hero-note small {
display: block;
margin-bottom: 7px;
color: var(--rust);
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.hero-note strong {
display: block;
color: var(--ink);
font-family: var(--font-display);
font-size: 1.28rem;
font-weight: 500;
line-height: 1.25;
}
.hero-note span {
display: block;
margin-top: 8px;
color: var(--muted);
font-size: 0.75rem;
}
.hero-seal {
position: absolute;
z-index: 2;
top: 42px;
right: -30px;
display: grid;
width: 100px;
height: 100px;
place-items: center;
transform: rotate(8deg);
border: 1px solid rgba(255, 255, 255, 0.55);
border-radius: 50%;
background: var(--rust);
color: var(--paper);
font-family: var(--font-display);
font-size: 0.9rem;
line-height: 1.25;
text-align: center;
box-shadow: 0 12px 30px rgba(69, 31, 20, 0.18);
}
.welcome-strip {
background: var(--ink);
color: var(--paper);
}
.values-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.value-item {
display: flex;
align-items: flex-start;
gap: 18px;
padding: 36px clamp(22px, 3vw, 40px);
border-left: 1px solid var(--white-line);
}
.value-item:first-child {
padding-left: 0;
border-left: 0;
}
.value-item:last-child {
padding-right: 0;
}
.value-item > .icon {
width: 27px;
height: 27px;
margin-top: 2px;
color: var(--gold);
}
.value-item h3 {
margin-bottom: 7px;
color: var(--paper);
font-family: var(--font-body);
font-size: 0.96rem;
font-weight: 700;
letter-spacing: 0;
}
.value-item p {
margin: 0;
color: rgba(255, 255, 255, 0.63);
font-size: 0.78rem;
line-height: 1.6;
}
/* Services */
.services-section {
background: var(--paper);
}
.services-grid {
display: grid;
grid-template-columns: 0.88fr 1.12fr;
align-items: start;
gap: clamp(50px, 7vw, 90px);
}
.services-intro > p {
color: var(--muted);
}
.service-photo {
position: relative;
margin-top: 35px;
}
.service-photo img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
border-radius: 130px 14px 14px 14px;
}
.photo-caption {
display: flex;
align-items: center;
gap: 9px;
margin-top: 14px;
color: var(--muted);
font-size: 0.76rem;
}
.photo-caption::before {
width: 18px;
height: 1px;
background: var(--rust);
content: "";
}
.schedule-heading {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 20px;
padding-bottom: 18px;
border-bottom: 1px solid var(--line);
}
.schedule-heading h3 {
font-size: 1.8rem;
}
.schedule-heading span {
color: var(--muted);
font-size: 0.73rem;
font-weight: 600;
}
.service-row {
display: grid;
grid-template-columns: 112px 1fr;
gap: 20px;
padding: 27px 0;
border-bottom: 1px solid var(--line);
}
.service-time {
color: var(--rust);
font-family: var(--font-display);
font-size: 1.4rem;
line-height: 1.25;
}
.service-time small {
display: block;
margin-top: 5px;
color: var(--muted);
font-family: var(--font-body);
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.service-row h3 {
margin-bottom: 8px;
font-size: 1.35rem;
}
.service-row p {
margin-bottom: 12px;
color: var(--muted);
font-size: 0.86rem;
line-height: 1.65;
}
.service-tag {
display: inline-block;
padding: 4px 10px;
border-radius: 999px;
background: var(--sage);
color: var(--ink);
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.04em;
}
.service-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 22px;
margin-top: 30px;
}
/* Sermon feature */
.sermon-section {
position: relative;
overflow: hidden;
background: var(--ink);
color: rgba(255, 255, 255, 0.74);
}
.sermon-section::after {
position: absolute;
top: -240px;
right: -180px;
width: 560px;
height: 560px;
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: 50%;
content: "";
box-shadow: 0 0 0 80px rgba(255, 255, 255, 0.018), 0 0 0 160px rgba(255, 255, 255, 0.012);
}
.sermon-grid {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: 0.94fr 1.06fr;
align-items: center;
gap: clamp(50px, 7vw, 92px);
}
.sermon-art {
position: relative;
}
.sermon-art img {
width: 100%;
aspect-ratio: 5 / 4;
object-fit: cover;
border-radius: 14px 130px 14px 14px;
filter: saturate(0.78);
}
.sermon-art::after {
position: absolute;
inset: 0;
border-radius: 14px 130px 14px 14px;
background: linear-gradient(180deg, transparent 50%, rgba(16, 39, 31, 0.58));
content: "";
}
.series-label {
position: absolute;
z-index: 2;
right: 25px;
bottom: 22px;
left: 25px;
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 15px;
color: var(--paper);
}
.series-label span {
font-size: 0.66rem;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.series-label strong {
font-family: var(--font-display);
font-size: 2.6rem;
font-weight: 400;
line-height: 1;
}
.sermon-copy h2 {
margin-bottom: 22px;
color: var(--paper);
}
.sermon-copy > p {
max-width: 600px;
}
.scripture-reference {
display: inline-flex;
align-items: center;
gap: 9px;
margin-bottom: 22px;
color: var(--gold-light);
font-family: var(--font-display);
font-size: 1.08rem;
font-style: italic;
}
.pastor-byline {
display: flex;
align-items: center;
gap: 13px;
margin: 25px 0;
}
.pastor-byline img {
width: 47px;
height: 47px;
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
object-fit: cover;
}
.pastor-byline strong {
display: block;
color: var(--paper);
font-size: 0.84rem;
}
.pastor-byline span {
display: block;
color: rgba(255, 255, 255, 0.55);
font-size: 0.72rem;
}
.sermon-notes {
margin: 26px 0;
border-top: 1px solid var(--white-line);
border-bottom: 1px solid var(--white-line);
}
.sermon-notes summary {
position: relative;
padding: 18px 35px 18px 0;
color: var(--paper);
font-size: 0.84rem;
font-weight: 700;
list-style: none;
cursor: pointer;
}
.sermon-notes summary::-webkit-details-marker {
display: none;
}
.sermon-notes summary::after {
position: absolute;
top: 16px;
right: 3px;
color: var(--gold);
content: "+";
font-family: var(--font-display);
font-size: 1.5rem;
font-weight: 400;
}
.sermon-notes[open] summary::after {
content: "−";
}
.sermon-notes-content {
padding: 0 0 22px;
font-size: 0.84rem;
}
.sermon-notes-content ol {
padding-left: 20px;
}
.sermon-notes-content li {
margin-bottom: 9px;
padding-left: 5px;
}
/* Ministries */
.ministries-section {
background: var(--cream);
}
.split-heading {
display: flex;
align-items: end;
justify-content: space-between;
gap: 50px;
margin-bottom: 48px;
}
.split-heading .section-heading {
margin-bottom: 0;
}
.split-heading > p {
max-width: 390px;
margin: 0 0 5px;
color: var(--muted);
font-size: 0.91rem;
}
.ministry-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
}
.ministry-card {
display: flex;
min-height: 360px;
flex-direction: column;
padding: 30px 27px;
border: 1px solid var(--line);
background: var(--paper);
transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
.ministry-card:hover {
transform: translateY(-6px);
border-color: rgba(25, 55, 46, 0.28);
box-shadow: 0 18px 42px rgba(25, 55, 46, 0.08);
}
.ministry-icon {
display: grid;
width: 52px;
height: 52px;
margin-bottom: 30px;
place-items: center;
border-radius: 50%;
background: var(--sage);
color: var(--ink);
}
.ministry-card:nth-child(2) .ministry-icon {
background: var(--gold-light);
}
.ministry-card:nth-child(3) .ministry-icon {
background: #ead9ce;
color: var(--rust-dark);
}
.ministry-card h3 {
margin-bottom: 13px;
font-size: 1.48rem;
}
.ministry-card p {
color: var(--muted);
font-size: 0.83rem;
line-height: 1.7;
}
.ministry-meta {
display: block;
margin: auto 0 17px;
padding-top: 16px;
color: var(--rust);
font-size: 0.67rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
/* Events */
.events-section {
background: var(--sand);
}
.event-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 22px;
}
.event-card {
display: flex;
overflow: hidden;
flex-direction: column;
border: 1px solid rgba(25, 55, 46, 0.1);
border-radius: 15px;
background: var(--paper);
}
.event-image {
position: relative;
overflow: hidden;
aspect-ratio: 16 / 10;
}
.event-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 500ms ease;
}
.event-card:hover .event-image img {
transform: scale(1.035);
}
.event-date {
position: absolute;
top: 16px;
left: 16px;
min-width: 76px;
padding: 10px 13px;
border-radius: 8px;
background: var(--paper);
color: var(--ink);
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.09em;
line-height: 1.3;
text-align: center;
text-transform: uppercase;
box-shadow: 0 6px 20px rgba(20, 43, 35, 0.12);
}
.event-body {
display: flex;
flex: 1;
flex-direction: column;
padding: 26px;
}
.event-kicker {
margin-bottom: 9px;
color: var(--rust);
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.13em;
text-transform: uppercase;
}
.event-body h3 {
margin-bottom: 13px;
font-size: 1.55rem;
}
.event-body > p {
color: var(--muted);
font-size: 0.84rem;
line-height: 1.7;
}
.event-meta {
display: flex;
flex-wrap: wrap;
gap: 10px 16px;
margin: auto 0 21px;
padding-top: 12px;
color: var(--muted);
font-size: 0.7rem;
font-weight: 600;
list-style: none;
}
.event-meta li {
display: inline-flex;
align-items: center;
gap: 6px;
}
.event-meta .icon {
width: 15px;
height: 15px;
color: var(--rust);
}
.event-body .btn {
align-self: flex-start;
}
/* Community and testimonials */
.community-section {
background: var(--paper);
}
.community-grid {
display: grid;
grid-template-columns: 0.92fr 1.08fr;
align-items: center;
gap: clamp(60px, 8vw, 105px);
}
.community-visual {
position: relative;
padding: 0 45px 70px 0;
}
.community-main-image {
width: 100%;
aspect-ratio: 4 / 5;
object-fit: cover;
border-radius: 210px 210px 14px 14px;
}
.community-small-image {
position: absolute;
right: 0;
bottom: 0;
width: 47%;
aspect-ratio: 4 / 3;
object-fit: cover;
border: 8px solid var(--paper);
border-radius: 10px;
box-shadow: var(--shadow);
}
.community-copy > p {
color: var(--muted);
}
.support-list {
margin: 30px 0 34px;
list-style: none;
}
.support-list li {
display: grid;
grid-template-columns: 42px 1fr;
gap: 16px;
padding: 19px 0;
border-top: 1px solid var(--line);
}
.support-list li:last-child {
border-bottom: 1px solid var(--line);
}
.support-number {
color: var(--rust);
font-family: var(--font-display);
font-size: 1.2rem;
}
.support-list h3 {
margin-bottom: 5px;
font-family: var(--font-body);
font-size: 0.92rem;
font-weight: 700;
letter-spacing: 0;
}
.support-list p {
margin: 0;
color: var(--muted);
font-size: 0.8rem;
line-height: 1.65;
}
.community-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.testimonials-heading {
display: flex;
align-items: center;
gap: 20px;
margin: 95px 0 28px;
color: var(--muted);
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.testimonials-heading::after {
height: 1px;
flex: 1;
background: var(--line);
content: "";
}
.testimonial-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.testimonial-card {
padding: 29px;
border-top: 3px solid var(--gold);
background: var(--cream);
}
.quote-mark {
height: 34px;
color: var(--rust);
font-family: var(--font-display);
font-size: 3.3rem;
line-height: 1;
}
.testimonial-card blockquote {
margin: 13px 0 24px;
color: var(--ink-soft);
font-family: var(--font-display);
font-size: 1.08rem;
line-height: 1.55;
}
.testimonial-person {
display: flex;
align-items: center;
gap: 12px;
}
.testimonial-person img {
width: 42px;
height: 42px;
border-radius: 50%;
object-fit: cover;
}
.testimonial-person strong {
display: block;
color: var(--ink);
font-size: 0.77rem;
}
.testimonial-person span {
display: block;
color: var(--muted);
font-size: 0.68rem;
}
/* Interactive devotional */
.devotional-section {
background: var(--sage);
}
.devotional-intro {
max-width: 730px;
margin: 0 auto 44px;
text-align: center;
}
.devotional-intro h2 {
margin-bottom: 20px;
}
.devotional-intro p {
color: var(--ink-soft);
}
.devotional-shell {
display: grid;
overflow: hidden;
grid-template-columns: 235px 1fr;
border: 1px solid rgba(25, 55, 46, 0.12);
border-radius: 22px;
background: var(--paper);
box-shadow: 0 22px 65px rgba(25, 55, 46, 0.1);
}
.day-navigation {
padding: 30px 22px;
background: var(--ink);
color: var(--paper);
}
.day-navigation-label {
display: block;
margin: 0 10px 21px;
color: var(--gold-light);
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.day-buttons {
display: grid;
gap: 5px;
}
.day-button {
display: flex;
width: 100%;
min-height: 46px;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 13px;
border: 0;
border-radius: 7px;
background: transparent;
color: rgba(255, 255, 255, 0.63);
font-size: 0.8rem;
font-weight: 600;
text-align: left;
transition: background-color 160ms ease, color 160ms ease;
}
.day-button:hover {
background: rgba(255, 255, 255, 0.07);
color: var(--paper);
}
.day-button[aria-selected="true"] {
background: rgba(255, 255, 255, 0.13);
color: var(--paper);
}
.day-state {
width: 8px;
height: 8px;
flex: 0 0 auto;
border: 1px solid rgba(255, 255, 255, 0.32);
border-radius: 50%;
}
.day-button.is-complete .day-state {
border-color: var(--gold);
background: var(--gold);
box-shadow: 0 0 0 3px rgba(209, 163, 92, 0.14);
}
.devotional-content {
padding: clamp(32px, 5vw, 58px);
}
.devotional-topline {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
margin-bottom: 26px;
}
.devotional-day {
color: var(--rust);
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.devotional-duration {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--muted);
font-size: 0.7rem;
}
.devotional-duration .icon {
width: 15px;
}
.devotional-scripture {
margin-bottom: 18px;
color: var(--sage-deep);
font-family: var(--font-display);
font-size: 1.05rem;
font-style: italic;
line-height: 1.55;
}
.devotional-content h3 {
margin-bottom: 20px;
font-size: clamp(2rem, 3.4vw, 2.9rem);
}
.devotional-reference {
display: block;
margin-bottom: 7px;
color: var(--rust);
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.devotional-reflection {
max-width: 710px;
color: var(--muted);
font-size: 0.92rem;
}
.practice-box {
margin: 27px 0 22px;
padding: 22px 24px;
border-left: 3px solid var(--gold);
background: var(--cream);
}
.practice-box strong {
display: block;
margin-bottom: 6px;
color: var(--ink);
font-size: 0.72rem;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.practice-box p {
margin: 0;
color: var(--ink-soft);
font-size: 0.85rem;
}
.prayer-line {
margin-bottom: 28px;
color: var(--ink-soft);
font-family: var(--font-display);
font-size: 1rem;
font-style: italic;
}
.prayer-line strong {
color: var(--ink);
font-family: var(--font-body);
font-size: 0.68rem;
font-style: normal;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.devotional-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 14px;
}
.complete-button.is-complete {
border-color: var(--sage-deep);
background: var(--sage);
color: var(--ink);
}
.reset-button {
padding: 9px 3px;
border: 0;
background: transparent;
color: var(--muted);
font-size: 0.73rem;
text-decoration: underline;
text-underline-offset: 4px;
}
.devotional-progress {
margin-top: 31px;
padding-top: 22px;
border-top: 1px solid var(--line);
}
.progress-copy {
display: flex;
justify-content: space-between;
gap: 20px;
margin-bottom: 9px;
color: var(--muted);
font-size: 0.68rem;
font-weight: 600;
}
.progress-track {
height: 5px;
overflow: hidden;
border-radius: 99px;
background: var(--sand);
}
.progress-fill {
width: 0;
height: 100%;
border-radius: inherit;
background: var(--rust);
transition: width 250ms ease;
}
/* About and FAQ */
.about-section {
background: var(--paper);
}
.about-grid {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
align-items: start;
gap: clamp(60px, 8vw, 105px);
}
.about-copy > p {
color: var(--muted);
}
.belief-list {
margin: 30px 0;
list-style: none;
}
.belief-list li {
padding: 17px 0 17px 23px;
border-top: 1px solid var(--line);
border-left: 2px solid var(--gold);
}
.belief-list li:last-child {
border-bottom: 1px solid var(--line);
}
.belief-list strong {
display: block;
margin-bottom: 4px;
color: var(--ink);
font-family: var(--font-display);
font-size: 1.08rem;
font-weight: 500;
}
.belief-list span {
color: var(--muted);
font-size: 0.79rem;
}
.pastor-note {
display: flex;
align-items: center;
gap: 15px;
margin-top: 29px;
}
.pastor-note img {
width: 56px;
height: 56px;
border-radius: 50%;
object-fit: cover;
}
.pastor-note strong {
display: block;
color: var(--ink);
font-size: 0.84rem;
}
.pastor-note span {
color: var(--muted);
font-size: 0.72rem;
}
.faq-heading {
margin-bottom: 20px;
}
.faq-heading h3 {
font-size: 2rem;
}
.faq-heading p {
margin-top: 9px;
color: var(--muted);
font-size: 0.84rem;
}
.faq-item {
border-bottom: 1px solid var(--line);
}
.faq-item:first-of-type {
border-top: 1px solid var(--line);
}
.faq-item summary {
position: relative;
padding: 22px 42px 22px 0;
color: var(--ink);
font-family: var(--font-display);
font-size: 1.15rem;
font-weight: 500;
line-height: 1.35;
list-style: none;
cursor: pointer;
}
.faq-item summary::-webkit-details-marker {
display: none;
}
.faq-item summary::after {
position: absolute;
top: 20px;
right: 6px;
color: var(--rust);
content: "+";
font-family: var(--font-body);
font-size: 1.35rem;
font-weight: 400;
}
.faq-item[open] summary::after {
content: "−";
}
.faq-answer {
padding: 0 34px 23px 0;
color: var(--muted);
font-size: 0.84rem;
}
.faq-answer p:last-child {
margin-bottom: 0;
}
/* Visit banner */
.visit-section {
padding: 0 0 clamp(80px, 8vw, 110px);
background: var(--paper);
}
.visit-banner {
position: relative;
display: grid;
overflow: hidden;
grid-template-columns: 1.15fr 0.85fr;
align-items: center;
gap: 60px;
padding: clamp(42px, 6vw, 72px);
border-radius: 24px;
background: var(--rust);
color: rgba(255, 255, 255, 0.82);
}
.visit-banner::after {
position: absolute;
right: -130px;
bottom: -220px;
width: 450px;
height: 450px;
border: 1px solid rgba(255, 255, 255, 0.14);
border-radius: 50%;
content: "";
box-shadow: 0 0 0 60px rgba(255, 255, 255, 0.035), 0 0 0 120px rgba(255, 255, 255, 0.025);
}
.visit-copy,
.visit-details {
position: relative;
z-index: 1;
}
.visit-copy h2 {
margin-bottom: 19px;
color: var(--paper);
font-size: clamp(2.3rem, 4vw, 3.65rem);
}
.visit-copy p {
max-width: 570px;
margin-bottom: 26px;
}
.visit-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.visit-details {
padding-left: 38px;
border-left: 1px solid rgba(255, 255, 255, 0.24);
}
.visit-details h3 {
margin-bottom: 18px;
color: var(--paper);
font-family: var(--font-body);
font-size: 0.71rem;
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.visit-details ul {
display: grid;
gap: 19px;
list-style: none;
}
.visit-details li {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 0.83rem;
}
.visit-details .icon {
margin-top: 3px;
color: var(--gold-light);
}
.visit-details strong {
display: block;
color: var(--paper);
font-weight: 600;
}
/* Footer */
.site-footer {
background: var(--ink-deep);
color: rgba(255, 255, 255, 0.64);
}
.footer-main {
display: grid;
grid-template-columns: 1.35fr 0.8fr 0.75fr 1.35fr;
gap: clamp(35px, 5vw, 65px);
padding: 75px 0 60px;
}
.footer-brand .brand-name {
color: var(--paper);
}
.footer-brand .brand-tagline {
color: rgba(255, 255, 255, 0.52);
}
.footer-brand .brand-logo {
box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.06);
}
.footer-brand > p {
max-width: 290px;
margin: 22px 0;
font-size: 0.79rem;
}
.social-links {
display: flex;
flex-wrap: wrap;
gap: 8px 16px;
}
.social-links a {
color: var(--gold-light);
font-size: 0.72rem;
font-weight: 600;
text-decoration: underline;
text-decoration-color: rgba(241, 223, 186, 0.3);
text-underline-offset: 4px;
}
.footer-column h2 {
margin-bottom: 21px;
color: var(--paper);
font-family: var(--font-body);
font-size: 0.67rem;
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.footer-links {
display: grid;
gap: 10px;
list-style: none;
font-size: 0.77rem;
}
.footer-links a,
.footer-column address a {
transition: color 160ms ease;
}
.footer-links a:hover,
.footer-column address a:hover {
color: var(--gold-light);
}
.footer-column address {
margin-bottom: 18px;
font-size: 0.77rem;
line-height: 1.8;
}
.footer-column address strong {
display: block;
color: rgba(255, 255, 255, 0.87);
font-weight: 600;
}
.newsletter-copy {
margin-bottom: 17px;
font-size: 0.77rem;
}
.newsletter-form label {
display: block;
margin-bottom: 8px;
color: rgba(255, 255, 255, 0.83);
font-size: 0.7rem;
font-weight: 600;
}
.newsletter-input-row {
display: flex;
gap: 8px;
}
.newsletter-input-row input {
width: 100%;
min-width: 0;
height: 46px;
padding: 10px 14px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
outline: none;
background: rgba(255, 255, 255, 0.06);
color: var(--paper);
font-size: 0.77rem;
}
.newsletter-input-row input::placeholder {
color: rgba(255, 255, 255, 0.38);
}
.newsletter-input-row input:focus {
border-color: var(--gold);
}
.newsletter-input-row .btn {
min-height: 46px;
padding: 10px 16px;
border-radius: 6px;
font-size: 0.72rem;
}
.newsletter-status {
min-height: 20px;
margin: 9px 0 0;
color: var(--gold-light);
font-size: 0.7rem;
}
.footer-bottom {
display: flex;
align-items: center;
justify-content: space-between;
gap: 25px;
padding: 23px 0 28px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
font-size: 0.68rem;
}
.legal-links {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.legal-links a:hover {
color: var(--paper);
}
/* Dialogs and forms */
dialog {
width: min(610px, calc(100% - 32px));
max-height: min(88vh, 850px);
padding: 0;
overflow: auto;
border: 0;
border-radius: 20px;
background: var(--paper);
color: var(--text);
box-shadow: 0 30px 100px rgba(0, 0, 0, 0.28);
}
dialog::backdrop {
background: rgba(10, 29, 23, 0.72);
backdrop-filter: blur(5px);
}
.modal-inner {
position: relative;
padding: clamp(30px, 5vw, 48px);
}
.modal-close {
position: absolute;
z-index: 2;
top: 17px;
right: 17px;
display: grid;
width: 39px;
height: 39px;
place-items: center;
border: 1px solid var(--line);
border-radius: 50%;
background: var(--paper);
color: var(--ink);
}
.modal-close:hover {
background: var(--cream);
}
.modal-kicker {
margin-bottom: 10px;
color: var(--rust);
font-size: 0.66rem;
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.modal-inner h2 {
padding-right: 30px;
font-size: clamp(2rem, 4vw, 2.8rem);
}
.modal-intro {
margin: 15px 0 25px;
color: var(--muted);
font-size: 0.84rem;
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 17px;
}
.form-field {
display: grid;
gap: 7px;
}
.form-field.full {
grid-column: 1 / -1;
}
.form-field label,
.field-label {
color: var(--ink);
font-size: 0.74rem;
font-weight: 700;
}
.form-field input,
.form-field select,
.form-field textarea {
width: 100%;
min-height: 48px;
padding: 11px 13px;
border: 1px solid var(--line);
border-radius: 7px;
outline: none;
background: var(--cream);
font-size: 0.82rem;
}
.form-field textarea {
min-height: 92px;
resize: vertical;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
border-color: var(--ink);
box-shadow: 0 0 0 3px rgba(25, 55, 46, 0.08);
}
.checkbox-field {
display: flex;
grid-column: 1 / -1;
align-items: flex-start;
gap: 10px;
color: var(--muted);
font-size: 0.75rem;
}
.checkbox-field input {
width: 17px;
height: 17px;
margin-top: 4px;
accent-color: var(--ink);
}
.form-submit {
grid-column: 1 / -1;
margin-top: 5px;
}
.form-submit .btn {
width: 100%;
}
.form-privacy {
grid-column: 1 / -1;
margin: -4px 0 0;
color: var(--muted);
font-size: 0.67rem;
text-align: center;
}
.selected-event {
margin: 22px 0;
padding: 17px 19px;
border-left: 3px solid var(--gold);
background: var(--cream);
}
.selected-event strong {
display: block;
color: var(--ink);
font-family: var(--font-display);
font-size: 1.15rem;
font-weight: 500;
}
.selected-event span {
display: block;
margin-top: 4px;
color: var(--muted);
font-size: 0.73rem;
}
.form-success {
padding: 20px 0 4px;
text-align: center;
}
.success-icon {
display: grid;
width: 62px;
height: 62px;
margin: 0 auto 20px;
place-items: center;
border-radius: 50%;
background: var(--sage);
color: var(--ink);
}
.success-icon .icon {
width: 28px;
height: 28px;
}
.form-success h3 {
margin-bottom: 12px;
font-size: 1.8rem;
}
.form-success p {
color: var(--muted);
font-size: 0.84rem;
}
.legal-article {
margin-top: 24px;
color: var(--muted);
font-size: 0.82rem;
}
.legal-article h3 {
margin: 24px 0 8px;
font-family: var(--font-body);
font-size: 0.88rem;
font-weight: 700;
letter-spacing: 0;
}
.back-to-top {
position: fixed;
z-index: 35;
right: 22px;
bottom: 22px;
display: grid;
width: 46px;
height: 46px;
place-items: center;
transform: translateY(12px);
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 50%;
opacity: 0;
background: var(--ink);
color: var(--paper);
box-shadow: 0 8px 24px rgba(16, 39, 31, 0.2);
pointer-events: none;
transition: opacity 180ms ease, transform 180ms ease;
}
.back-to-top.is-visible {
transform: translateY(0);
opacity: 1;
pointer-events: auto;
}
.back-to-top .icon {
transform: rotate(-90deg);
}
.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
@media (prefers-reduced-motion: no-preference) {
.hero-copy {
animation: rise-in 650ms both ease-out;
}
.hero-visual {
animation: rise-in 750ms 100ms both ease-out;
}
@keyframes rise-in {
from {
transform: translateY(18px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
}
/* Responsive layout */
@media (max-width: 1120px) {
.primary-nav {
display: none;
position: absolute;
top: calc(100% + 1px);
right: 0;
left: 0;
margin: 0;
padding: 17px 24px 24px;
border: 1px solid var(--line);
border-radius: 0 0 14px 14px;
background: var(--cream);
box-shadow: 0 18px 35px rgba(25, 55, 46, 0.1);
}
.nav-open .primary-nav {
display: block;
}
.primary-nav ul {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 3px 20px;
}
.primary-nav a {
padding: 12px 0;
}
.header-actions {
margin-left: auto;
}
.menu-toggle {
display: inline-flex;
}
.hero-note {
left: -38px;
}
.ministry-grid {
grid-template-columns: repeat(2, 1fr);
}
.ministry-card {
min-height: 320px;
}
}
@media (max-width: 920px) {
.hero-grid,
.services-grid,
.sermon-grid,
.community-grid,
.about-grid {
grid-template-columns: 1fr;
}
.hero-copy {
max-width: 750px;
}
.hero-visual {
width: min(78%, 540px);
margin: 10px auto 0;
}
.hero-note {
left: -60px;
}
.values-grid {
grid-template-columns: 1fr;
padding: 10px 0;
}
.value-item,
.value-item:first-child,
.value-item:last-child {
padding: 22px 0;
border-top: 1px solid var(--white-line);
border-left: 0;
}
.value-item:first-child {
border-top: 0;
}
.services-intro {
max-width: 700px;
}
.service-photo {
max-width: 650px;
}
.sermon-art {
max-width: 680px;
}
.split-heading {
display: block;
}
.split-heading > p {
max-width: 620px;
margin-top: 20px;
}
.event-grid {
grid-template-columns: repeat(2, 1fr);
}
.event-card:last-child {
grid-column: 1 / -1;
display: grid;
grid-template-columns: 0.9fr 1.1fr;
}
.event-card:last-child .event-image {
aspect-ratio: auto;
min-height: 100%;
}
.community-visual {
width: min(75%, 520px);
margin-inline: auto;
}
.testimonial-grid {
grid-template-columns: 1fr;
}
.testimonial-card {
display: grid;
grid-template-columns: 32px 1fr;
column-gap: 15px;
}
.testimonial-card blockquote {
margin-top: 0;
}
.testimonial-person {
grid-column: 2;
}
.visit-banner {
grid-template-columns: 1fr;
gap: 40px;
}
.visit-details {
padding: 28px 0 0;
border-top: 1px solid rgba(255, 255, 255, 0.24);
border-left: 0;
}
.visit-details ul {
grid-template-columns: repeat(3, 1fr);
}
.footer-main {
grid-template-columns: 1.2fr 1fr;
}
}
@media (max-width: 720px) {
.container {
width: min(var(--container), calc(100% - 34px));
}
.announcement {
font-size: 0.72rem;
}
.header-inner {
min-height: 78px;
}
.brand-logo {
width: 43px;
height: 43px;
}
.header-actions > .btn {
display: none;
}
.primary-nav ul {
grid-template-columns: repeat(2, 1fr);
}
.hero-seal {
right: -12px;
width: 87px;
height: 87px;
font-size: 0.78rem;
}
.hero-note {
bottom: 45px;
left: -25px;
width: 205px;
}
.event-grid {
grid-template-columns: 1fr;
}
.event-card:last-child {
grid-column: auto;
display: flex;
}
.event-card:last-child .event-image {
min-height: 0;
aspect-ratio: 16 / 10;
}
.devotional-shell {
grid-template-columns: 1fr;
}
.day-navigation {
padding: 20px;
}
.day-navigation-label {
margin: 0 0 12px;
}
.day-buttons {
display: flex;
overflow-x: auto;
gap: 6px;
padding-bottom: 5px;
scrollbar-width: thin;
}
.day-button {
width: auto;
min-width: 87px;
flex: 1 0 auto;
}
.visit-details ul {
grid-template-columns: 1fr;
}
.footer-bottom {
align-items: flex-start;
flex-direction: column;
}
}
@media (max-width: 560px) {
.section {
padding: 74px 0;
}
.brand-tagline {
display: none;
}
.brand-name {
max-width: 140px;
font-size: 1.03rem;
}
.hero {
padding-top: 53px;
}
.hero-actions,
.community-actions,
.visit-actions {
align-items: stretch;
flex-direction: column;
}
.hero-actions .btn,
.community-actions .btn,
.visit-actions .btn {
width: 100%;
}
.hero-meta {
align-items: flex-start;
flex-direction: column;
}
.hero-visual {
width: 92%;
padding-right: 0;
}
.hero-visual::before {
display: none;
}
.hero-note {
position: relative;
bottom: auto;
left: auto;
width: calc(100% - 30px);
margin: -35px auto 0;
}
.hero-seal {
top: 25px;
right: -7px;
}
.service-row {
grid-template-columns: 1fr;
gap: 10px;
}
.service-time small {
display: inline;
margin-left: 8px;
}
.schedule-heading {
align-items: flex-start;
flex-direction: column;
gap: 6px;
}
.service-actions {
align-items: flex-start;
flex-direction: column;
}
.ministry-grid {
grid-template-columns: 1fr;
}
.ministry-card {
min-height: 0;
}
.ministry-meta {
margin-top: 15px;
}
.community-visual {
width: 94%;
padding-right: 25px;
}
.testimonial-card {
display: block;
}
.testimonial-card blockquote {
margin-top: 12px;
}
.testimonials-heading {
margin-top: 70px;
}
.devotional-content {
padding: 28px 23px;
}
.devotional-topline {
align-items: flex-start;
flex-direction: column;
gap: 6px;
}
.progress-copy {
flex-direction: column;
gap: 3px;
}
.form-grid {
grid-template-columns: 1fr;
}
.form-field.full,
.checkbox-field,
.form-submit,
.form-privacy {
grid-column: auto;
}
.footer-main {
grid-template-columns: 1fr;
padding-top: 60px;
}
.newsletter-input-row {
align-items: stretch;
flex-direction: column;
}
.back-to-top {
right: 15px;
bottom: 15px;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
*, *::before, *::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body id="top">
<a class="skip-link" href="#main-content">Skip to main content</a>
<svg class="svg-sprite" aria-hidden="true">
<symbol id="i-arrow" viewBox="0 0 24 24">
<path d="M5 12h14M13 6l6 6-6 6"/>
</symbol>
<symbol id="i-calendar" viewBox="0 0 24 24">
<rect x="3" y="5" width="18" height="16" rx="2"/>
<path d="M16 3v4M8 3v4M3 10h18"/>
</symbol>
<symbol id="i-clock" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="9"/>
<path d="M12 7v5l3 2"/>
</symbol>
<symbol id="i-pin" viewBox="0 0 24 24">
<path d="M20 10c0 5-8 11-8 11S4 15 4 10a8 8 0 1 1 16 0Z"/>
<circle cx="12" cy="10" r="2.5"/>
</symbol>
<symbol id="i-book" viewBox="0 0 24 24">
<path d="M4 5.5A2.5 2.5 0 0 1 6.5 3H11v16H6.5A2.5 2.5 0 0 0 4 21.5v-16ZM20 5.5A2.5 2.5 0 0 0 17.5 3H13v16h4.5a2.5 2.5 0 0 1 2.5 2.5v-16Z"/>
</symbol>
<symbol id="i-users" viewBox="0 0 24 24">
<circle cx="9" cy="8" r="3"/>
<path d="M3 20v-2a6 6 0 0 1 12 0v2M16 4.5a3 3 0 0 1 0 7M17 14a5 5 0 0 1 4 4.9V20"/>
</symbol>
<symbol id="i-heart" viewBox="0 0 24 24">
<path d="M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1.1-1.1a5.5 5.5 0 0 0-7.8 7.8L12 21l8.8-8.6a5.5 5.5 0 0 0 0-7.8Z"/>
</symbol>
<symbol id="i-home" viewBox="0 0 24 24">
<path d="m3 11 9-8 9 8M5 10v11h14V10M9 21v-7h6v7"/>
</symbol>
<symbol id="i-flame" viewBox="0 0 24 24">
<path d="M12 22c4 0 7-2.8 7-6.6 0-4.8-4-7.2-5.2-12.4-3.2 2-4.7 5.2-4.4 8.3-1.5-.8-2.5-2.1-2.8-3.7C4.8 9.4 5 12 5 15.4 5 19.2 8 22 12 22Z"/>
<path d="M9.5 17.2c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.5-2.8c0-1.4-.8-2.5-2.2-4.2-.2 1.7-1.1 2.7-2.8 4.2Z"/>
</symbol>
<symbol id="i-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="4"/>
<path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/>
</symbol>
<symbol id="i-check" viewBox="0 0 24 24">
<path d="m5 12 4.5 4.5L19 7"/>
</symbol>
<symbol id="i-close" viewBox="0 0 24 24">
<path d="m6 6 12 12M18 6 6 18"/>
</symbol>
</svg>
<div class="announcement">
New to Harborlight? We’ll make your first Sunday simple and pressure-free.
<a href="#visit">Plan your visit</a>
</div>
<header class="site-header" id="site-header">
<div class="container header-inner">
<a class="brand" href="#top" aria-label="Harborlight Community Church home">
<img class="brand-logo" src="https://placehold.co/96x96/19372e/f7f3ea?text=HL&font=montserrat" width="49" height="49" alt="Harborlight Community Church logo">
<span>
<span class="brand-name">Harborlight Church</span>
<span class="brand-tagline">Rooted in grace. Making room for everyone.</span>
</span>
</a>
<nav class="primary-nav" id="primary-nav" aria-label="Primary navigation">
<ul>
<li><a href="#services">Services</a></li>
<li><a href="#sermons">Sermons</a></li>
<li><a href="#ministries">Ministries</a></li>
<li><a href="#events">Events</a></li>
<li><a href="#community">Community</a></li>
<li><a href="#resources">Resources</a></li>
<li><a href="#about">About</a></li>
</ul>
</nav>
<div class="header-actions">
<button class="btn btn-primary btn-small" type="button" data-open-visit>
Plan a Visit
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
<button class="menu-toggle" id="menu-toggle" type="button" aria-expanded="false" aria-controls="primary-nav" aria-label="Open navigation menu">
<span class="menu-lines" aria-hidden="true"></span>
</button>
</div>
</div>
</header>
<main id="main-content">
<section class="hero" aria-labelledby="hero-title">
<div class="container hero-grid">
<div class="hero-copy">
<div class="eyebrow">A Christ-centered community in Portland</div>
<h1 id="hero-title">Come as you are.<br><em>Grow toward love.</em></h1>
<p class="lead">
Harborlight is a place for steady faith, honest questions, and relationships that last beyond Sunday. Whether church has always felt like home or you are stepping through the doors after years away, there is room here for your story.
</p>
<div class="hero-actions">
<button class="btn btn-primary" type="button" data-open-visit>
Plan Your Visit
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
<a class="btn btn-outline" href="#services">Explore Services</a>
</div>
<div class="hero-meta">
<span>
<svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>
Sundays at 9:00 & 11:00 AM
</span>
<span>
<svg class="icon" aria-hidden="true"><use href="#i-pin"/></svg>
In person and online
</span>
</div>
</div>
<div class="hero-visual">
<div class="hero-arch">
<img src="https://picsum.photos/seed/harborlight-hero/1000/1200" width="1000" height="1200" alt="Warm light filling a peaceful gathering space" fetchpriority="high" decoding="async">
</div>
<div class="hero-note">
<small>This Sunday</small>
<strong>You already have a place here.</strong>
<span>Come early for coffee. Stay as long as you like.</span>
</div>
<div class="hero-seal" aria-hidden="true">All are<br>welcome</div>
</div>
</div>
</section>
<aside class="welcome-strip" aria-label="Our commitments">
<div class="container values-grid">
<article class="value-item">
<svg class="icon" aria-hidden="true"><use href="#i-book"/></svg>
<div>
<h3>Scripture with room for questions</h3>
<p>Thoughtful teaching that takes the Bible seriously and faith personally.</p>
</div>
</article>
<article class="value-item">
<svg class="icon" aria-hidden="true"><use href="#i-users"/></svg>
<div>
<h3>A table where everyone belongs</h3>
<p>Across generations, backgrounds, and seasons of certainty or doubt.</p>
</div>
</article>
<article class="value-item">
<svg class="icon" aria-hidden="true"><use href="#i-heart"/></svg>
<div>
<h3>Faith that moves outward</h3>
<p>Practical care for our neighbors and sustained partnerships in our city.</p>
</div>
</article>
</div>
</aside>
<section class="section services-section" id="services" aria-labelledby="services-title">
<div class="container services-grid">
<div class="services-intro">
<div class="eyebrow">Worship & Service Times</div>
<h2 id="services-title">A rhythm for your week.</h2>
<p class="lead">
Worship at Harborlight brings together scripture, music, prayer, communion, and silence. Each gathering has its own texture, but all are grounded in the same good news: grace meets us before we have anything figured out.
</p>
<p>
You do not need to dress up, know the songs, or arrive with a practiced faith. Our welcome team can help with accessible seating, children’s check-in, or simply finding a good cup of coffee. Services typically last 65–75 minutes.
</p>
<div class="service-photo">
<img src="https://picsum.photos/seed/harborlight-table/1000/760" width="1000" height="760" alt="People sharing conversation around a community table" loading="lazy" decoding="async">
</div>
<div class="photo-caption">Coffee and conversation follow every Sunday gathering.</div>
</div>
<div class="service-schedule">
<div class="schedule-heading">
<h3>Gather with us</h3>
<span>All times Pacific</span>
</div>
<article class="service-row">
<time class="service-time" datetime="09:00">9:00 AM<small>Sunday</small></time>
<div>
<h3>Contemplative Worship</h3>
<p>A quieter service with acoustic music, reflective scripture reading, guided prayer, and space for silence. Communion is shared on the first Sunday of each month.</p>
<span class="service-tag">In person · 65 minutes</span>
</div>
</article>
<article class="service-row">
<time class="service-time" datetime="11:00">11:00 AM<small>Sunday</small></time>
<div>
<h3>Celebration Worship</h3>
<p>A joyful, multigenerational gathering with our worship band, congregational prayer, a practical sermon, and programs for children from nursery through fifth grade.</p>
<span class="service-tag">In person + livestream · 75 minutes</span>
</div>
</article>
<article class="service-row">
<time class="service-time" datetime="18:30">6:30 PM<small>Wednesday</small></time>
<div>
<h3>Midweek Vespers</h3>
<p>A 40-minute candlelit service to help you pause and breathe. We pray for our city, listen to scripture, and end with a simple sung blessing.</p>
<span class="service-tag">Chapel · No registration</span>
</div>
</article>
<div class="service-actions">
<button class="btn btn-primary" type="button" data-open-visit>
Plan Your Visit
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
<a class="text-link" href="#faq">What to expect <svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg></a>
</div>
</div>
</div>
</section>
<section class="section sermon-section" id="sermons" aria-labelledby="sermon-title">
<div class="container sermon-grid">
<div class="sermon-art">
<img src="https://picsum.photos/seed/unhurried-life/1000/800" width="1000" height="800" alt="Artwork for The Unhurried Life sermon series" loading="lazy" decoding="async">
<div class="series-label">
<span>The Unhurried Life<br>Sermon Series</span>
<strong>03</strong>
</div>
</div>
<div class="sermon-copy">
<div class="eyebrow light">Latest Sermon</div>
<div class="scripture-reference">
<svg class="icon" aria-hidden="true"><use href="#i-book"/></svg>
John 14:25–27
</div>
<h2 id="sermon-title">The Peace We Practice</h2>
<p>
Jesus offers peace not as a reward for a perfectly ordered life, but as a presence within the life we actually have. In this sermon, Rev. Elena Marín explores the difference between avoiding discomfort and learning to abide in God’s steadying love.
</p>
<p>
With honest stories and three simple practices, this message invites us to move through the week with less striving and more attention—to notice where fear has set the agenda, and where grace might be making another way.
</p>
<div class="pastor-byline">
<img src="https://i.pravatar.cc/96?u=elena-marin" width="47" height="47" alt="Rev. Elena Marín" loading="lazy">
<div>
<strong>Rev. Elena Marín</strong>
<span>Lead Pastor · 34-minute message</span>
</div>
</div>
<details class="sermon-notes">
<summary>Learn More: sermon notes & discussion questions</summary>
<div class="sermon-notes-content">
<p>Use these prompts personally, around the dinner table, or with your community group:</p>
<ol>
<li>Where are you tempted to treat peace as something you must earn or engineer?</li>
<li>What changes when you hear Christ’s peace as a gift of presence rather than the absence of trouble?</li>
<li>Which daily transition—waking, commuting, eating, or bedtime—could become a deliberate moment of prayer?</li>
<li>Who might need you to be a non-anxious, listening presence this week?</li>
</ol>
</div>
</details>
<a class="btn btn-gold" href="#resources">
Try the Weekly Practice
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</a>
</div>
</div>
</section>
<section class="section ministries-section" id="ministries" aria-labelledby="ministries-title">
<div class="container">
<div class="split-heading">
<div class="section-heading">
<div class="eyebrow">Ministries & Faith Formation</div>
<h2 id="ministries-title">Faith for every season.</h2>
</div>
<p>
Formation happens in worship, around tables, through service, and in the ordinary conversations where we learn to love God and one another. Find a place to begin below.
</p>
</div>
<div class="ministry-grid">
<article class="ministry-card">
<div class="ministry-icon">
<svg class="icon" aria-hidden="true"><use href="#i-sun"/></svg>
</div>
<h3>Children & Families</h3>
<p>
Children encounter scripture through story, art, movement, and play. Secure check-in, background-checked leaders, and a comfortable family room help parents participate with peace of mind.
</p>
<span class="ministry-meta">Sundays · 8:45 & 10:45 AM</span>
<a class="text-link" href="#faq">Learn More <svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg></a>
</article>
<article class="ministry-card">
<div class="ministry-icon">
<svg class="icon" aria-hidden="true"><use href="#i-users"/></svg>
</div>
<h3>Youth & Young Adults</h3>
<p>
Students in grades 6–12 share dinner, honest conversation, and service projects. Young adults gather twice monthly for table fellowship and the questions that do not fit neatly into a sermon.
</p>
<span class="ministry-meta">Alternate Sundays · 5:00 PM</span>
<a class="text-link" href="#events">Find a Gathering <svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg></a>
</article>
<article class="ministry-card">
<div class="ministry-icon">
<svg class="icon" aria-hidden="true"><use href="#i-book"/></svg>
</div>
<h3>Adult Faith Formation</h3>
<p>
Seasonal classes move from scripture foundations to contemplative prayer, Christian ethics, and faithful everyday work. Beginners are welcome, and curiosity counts as a spiritual gift.
</p>
<span class="ministry-meta">Tuesday evenings + Sunday mornings</span>
<a class="text-link" href="#resources">Explore Resources <svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg></a>
</article>
<article class="ministry-card">
<div class="ministry-icon">
<svg class="icon" aria-hidden="true"><use href="#i-heart"/></svg>
</div>
<h3>Care & Prayer</h3>
<p>
When life changes through illness, loss, transition, or celebration, our trained care team listens without judgment. We also coordinate meals, rides, prayer, and confidential pastoral support.
</p>
<span class="ministry-meta">Confidential · Response within 48 hours</span>
<a class="text-link" href="#community">Connect With Care <svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg></a>
</article>
</div>
</div>
</section>
<section class="section events-section" id="events" aria-labelledby="events-title">
<div class="container">
<div class="split-heading">
<div class="section-heading">
<div class="eyebrow">Upcoming Events</div>
<h2 id="events-title">There’s room at the table.</h2>
</div>
<p>
Start with a meal, serve alongside a neighbor, or join a conversation where no question is off-limits. Most events are free, and guests are always welcome.
</p>
</div>
<div class="event-grid">
<article class="event-card">
<div class="event-image">
<img src="https://picsum.photos/seed/community-table-event/800/560" width="800" height="560" alt="A shared neighborhood meal" loading="lazy" decoding="async">
<div class="event-date">1st<br>Sunday</div>
</div>
<div class="event-body">
<div class="event-kicker">Food & Fellowship</div>
<h3>The Community Table</h3>
<p>
Stay after the 11:00 AM service for a relaxed lunch prepared by our hospitality team. Vegetarian and gluten-free options are always available; simply bring yourself and an appetite.
</p>
<ul class="event-meta">
<li><svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>12:30 PM</li>
<li><svg class="icon" aria-hidden="true"><use href="#i-pin"/></svg>Fellowship Hall</li>
</ul>
<button class="btn btn-outline btn-small" type="button" data-open-event data-event="The Community Table" data-event-details="First Sunday of each month · 12:30 PM · Fellowship Hall">
Attend Event
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
</div>
</article>
<article class="event-card">
<div class="event-image">
<img src="https://picsum.photos/seed/neighborhood-serve/800/560" width="800" height="560" alt="Neighbors working together outdoors" loading="lazy" decoding="async">
<div class="event-date">3rd<br>Saturday</div>
</div>
<div class="event-body">
<div class="event-kicker">Neighborhood Service</div>
<h3>Harbor Serve Day</h3>
<p>
Join our partners at Alder Food Pantry and Rose Community Garden for grocery sorting, garden work, and light neighborhood cleanup. Projects are available for all ages and abilities.
</p>
<ul class="event-meta">
<li><svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>9:00 AM–12:00 PM</li>
<li><svg class="icon" aria-hidden="true"><use href="#i-pin"/></svg>Meet in the lobby</li>
</ul>
<button class="btn btn-outline btn-small" type="button" data-open-event data-event="Harbor Serve Day" data-event-details="Third Saturday of each month · 9:00 AM–12:00 PM · Meet in the lobby">
Attend Event
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
</div>
</article>
<article class="event-card">
<div class="event-image">
<img src="https://picsum.photos/seed/faith-doubt-event/800/560" width="800" height="560" alt="A small group gathered for thoughtful conversation" loading="lazy" decoding="async">
<div class="event-date">1st<br>Wednesday</div>
</div>
<div class="event-body">
<div class="event-kicker">Honest Conversation</div>
<h3>Faith & Doubt</h3>
<p>
A facilitated, no-pressure conversation about deconstruction, unanswered prayer, scripture, and rebuilding trust. Come to speak, come to listen, or simply come to know you are not alone.
</p>
<ul class="event-meta">
<li><svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>7:00–8:15 PM</li>
<li><svg class="icon" aria-hidden="true"><use href="#i-pin"/></svg>Commons Room</li>
</ul>
<button class="btn btn-outline btn-small" type="button" data-open-event data-event="Faith & Doubt" data-event-details="First Wednesday of each month · 7:00–8:15 PM · Commons Room">
Attend Event
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
</div>
</article>
</div>
</div>
</section>
<section class="section community-section" id="community" aria-labelledby="community-title">
<div class="container">
<div class="community-grid">
<div class="community-visual">
<img class="community-main-image" src="https://picsum.photos/seed/harborlight-community/900/1100" width="900" height="1100" alt="Friends sharing life together in the Harborlight community" loading="lazy" decoding="async">
<img class="community-small-image" src="https://picsum.photos/seed/harborlight-care/600/450" width="600" height="450" alt="A caring conversation between neighbors" loading="lazy" decoding="async">
</div>
<div class="community-copy">
<div class="eyebrow">Community Support</div>
<h2 id="community-title">You don’t have to carry it alone.</h2>
<p class="lead">
Community is more than recognizing familiar faces on Sunday. It is having someone to call when the diagnosis comes, the baby arrives, the job disappears, or faith feels fragile.
</p>
<p>
Our pastors, trained care volunteers, and community groups offer support without pressure or platitudes. You do not need to be a member to request prayer or practical help, and every conversation is handled with discretion.
</p>
<ul class="support-list">
<li>
<span class="support-number">01</span>
<div>
<h3>Prayer & pastoral care</h3>
<p>Share a confidential request, arrange a conversation with a pastor, or ask someone to pray with you after any service.</p>
</div>
</li>
<li>
<span class="support-number">02</span>
<div>
<h3>Practical help in difficult weeks</h3>
<p>Our care network can coordinate meals, transportation to appointments, emergency grocery cards, and referrals to trusted local services.</p>
</div>
</li>
<li>
<span class="support-number">03</span>
<div>
<h3>Community groups</h3>
<p>Small groups meet in homes and at the church throughout the week for scripture, shared meals, prayer, and friendship across generations.</p>
</div>
</li>
</ul>
<div class="community-actions">
<a class="btn btn-primary" href="mailto:care@harborlight.church?subject=Confidential%20prayer%20request">
Request Prayer
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</a>
<a class="btn btn-outline" href="mailto:groups@harborlight.church?subject=Help%20me%20find%20a%20community%20group">Connect With a Group</a>
</div>
</div>
</div>
<div class="testimonials-heading">Stories from our community</div>
<div class="testimonial-grid">
<article class="testimonial-card">
<div class="quote-mark" aria-hidden="true">“</div>
<blockquote>
I arrived during a season of grief, unsure I belonged in church again. Someone remembered my name the second week, and no one rushed my questions. Harborlight gave my faith room to breathe.
</blockquote>
<div class="testimonial-person">
<img src="https://i.pravatar.cc/96?u=maya-harborlight" width="42" height="42" alt="Maya R." loading="lazy">
<div>
<strong>Maya R.</strong>
<span>Member since 2021</span>
</div>
</div>
</article>
<article class="testimonial-card">
<div class="quote-mark" aria-hidden="true">“</div>
<blockquote>
Our kids are known, our dinner table has grown, and serving our neighbors has become part of our family’s rhythm. Here, belonging and honest doubt seem to strengthen each other.
</blockquote>
<div class="testimonial-person">
<img src="https://i.pravatar.cc/96?u=daniel-harborlight" width="42" height="42" alt="Daniel S." loading="lazy">
<div>
<strong>Daniel & Priya S.</strong>
<span>Harbor Serve volunteers</span>
</div>
</div>
</article>
<article class="testimonial-card">
<div class="quote-mark" aria-hidden="true">“</div>
<blockquote>
Wednesday vespers helped me rediscover prayer in a demanding season. I came for quiet and found a community that shows up with meals, rides, thoughtful messages, and real friendship.
</blockquote>
<div class="testimonial-person">
<img src="https://i.pravatar.cc/96?u=jon-harborlight" width="42" height="42" alt="Jon Bell" loading="lazy">
<div>
<strong>Jon Bell</strong>
<span>Wednesday vespers regular</span>
</div>
</div>
</article>
</div>
</div>
</section>
<section class="section devotional-section" id="resources" aria-labelledby="devotional-section-title">
<div class="container">
<div class="devotional-intro">
<div class="eyebrow centered">Weekly Devotional Calendar</div>
<h2 id="devotional-section-title">A small practice for a whole week.</h2>
<p>
Continue this week’s sermon theme, “Practicing Peace,” with a short scripture reading, reflection, and embodied practice for each day. Choose a day below; completed practices are saved on this device so you can return at your own pace.
</p>
</div>
<div class="devotional-shell">
<div class="day-navigation">
<span class="day-navigation-label" id="day-navigation-label">Practicing Peace</span>
<div class="day-buttons" role="tablist" aria-labelledby="day-navigation-label">
<button class="day-button" id="day-mon" type="button" role="tab" aria-selected="true" aria-controls="devotional-panel" data-day="0">
<span>Monday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-tue" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="1" tabindex="-1">
<span>Tuesday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-wed" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="2" tabindex="-1">
<span>Wednesday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-thu" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="3" tabindex="-1">
<span>Thursday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-fri" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="4" tabindex="-1">
<span>Friday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-sat" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="5" tabindex="-1">
<span>Saturday</span><span class="day-state" aria-hidden="true"></span>
</button>
<button class="day-button" id="day-sun" type="button" role="tab" aria-selected="false" aria-controls="devotional-panel" data-day="6" tabindex="-1">
<span>Sunday</span><span class="day-state" aria-hidden="true"></span>
</button>
</div>
</div>
<div class="devotional-content" id="devotional-panel" role="tabpanel" aria-labelledby="day-mon" tabindex="0">
<div class="devotional-topline">
<span class="devotional-day" id="devotional-day">Monday · Receive</span>
<span class="devotional-duration">
<svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>
About 5 minutes
</span>
</div>
<span class="devotional-reference" id="devotional-reference">John 14:27</span>
<p class="devotional-scripture" id="devotional-scripture">“Peace I leave with you; my peace I give to you… Do not let your hearts be troubled, and do not let them be afraid.”</p>
<h3 id="devotional-title">Receive before you respond.</h3>
<div class="devotional-reflection" id="devotional-reflection">
<p>We often begin the day already braced for what might go wrong. Jesus begins somewhere else: with a gift. His peace is not fragile calm that depends on a quiet inbox or an uncomplicated life. It is the assurance that we are held in love before we accomplish anything.</p>
<p>Today, let receiving be your first spiritual work. You do not have to manufacture a peaceful feeling. Simply make enough room to notice that God is already present.</p>
</div>
<div class="practice-box">
<strong>Today’s practice</strong>
<p id="devotional-practice">Before reaching for your phone, place both feet on the floor and take five slow breaths. With each inhale pray, “I receive your peace.” With each exhale pray, “I release my striving.”</p>
</div>
<p class="prayer-line"><strong>A simple prayer:</strong> <span id="devotional-prayer">Christ, meet me before I meet the demands of this day. Amen.</span></p>
<div class="devotional-actions">
<button class="btn btn-primary btn-small complete-button" id="complete-practice" type="button" aria-pressed="false">
<svg class="icon" aria-hidden="true"><use href="#i-check"/></svg>
<span id="complete-label">Mark practice complete</span>
</button>
<button class="reset-button" id="reset-devotional" type="button">Reset this week</button>
</div>
<div class="devotional-progress">
<div class="progress-copy">
<span id="devotional-count">0 of 7 practices complete</span>
<span>Progress is saved on this device</span>
</div>
<div class="progress-track" id="devotional-progressbar" role="progressbar" aria-label="Weekly devotional progress" aria-valuemin="0" aria-valuemax="7" aria-valuenow="0">
<div class="progress-fill" id="devotional-progress-fill"></div>
</div>
</div>
<div class="sr-only" id="devotional-status" aria-live="polite"></div>
</div>
</div>
</div>
</section>
<section class="section about-section" id="about" aria-labelledby="about-title">
<div class="container about-grid">
<div class="about-copy">
<div class="eyebrow">About Harborlight</div>
<h2 id="about-title">Ancient faith.<br>Open table.<br>Active love.</h2>
<p class="lead">
Harborlight began around a dining-room table in 2012 with fourteen neighbors, a shared meal, and a simple conviction: church should help people become more present to God and more available to one another.
</p>
<p>
Today our congregation includes lifelong churchgoers, people returning after years away, and those exploring Christian faith for the first time. We are an independent, Christ-centered church led by pastors, an elected lay council, and ministry teams who share responsibility for our common life.
</p>
<p>
We read scripture with reverence and curiosity, make space for lament as well as celebration, and believe grace is not a prize for having everything together. Our beliefs shape our hospitality—not the other way around.
</p>
<ul class="belief-list">
<li>
<strong>Scripture, not slogans.</strong>
<span>We wrestle with the whole biblical story and seek to live its call to love, mercy, and justice.</span>
</li>
<li>
<strong>Hospitality without pressure.</strong>
<span>You can participate at your own pace; membership is never a prerequisite for care or belonging.</span>
</li>
<li>
<strong>Love with its sleeves rolled up.</strong>
<span>We build long-term partnerships with local schools, food programs, and housing advocates.</span>
</li>
</ul>
<div class="pastor-note">
<img src="https://i.pravatar.cc/112?u=elena-marin" width="56" height="56" alt="Rev. Elena Marín, Lead Pastor" loading="lazy">
<div>
<strong>Rev. Elena Marín</strong>
<span>Lead Pastor · “We’d be honored to meet you.”</span>
</div>
</div>
</div>
<div class="faq-area" id="faq">
<div class="faq-heading">
<div class="eyebrow">Your First Visit</div>
<h3>Questions are welcome.</h3>
<p>Here are a few things people often wonder before walking through our doors.</p>
</div>
<details class="faq-item" open>
<summary>Do I need to be a Christian or a member to attend?</summary>
<div class="faq-answer">
<p>No. You are welcome to worship, attend a class, join a community meal, or request prayer wherever you are in your spiritual journey. There is no pressure to profess beliefs you are still exploring or to become a member on a particular timeline.</p>
<p>During communion, clear guidance is offered so each person can participate or refrain according to their own conscience and tradition.</p>
</div>
</details>
<details class="faq-item">
<summary>What should I wear, and where do I go?</summary>
<div class="faq-answer">
<p>Wear whatever helps you feel comfortable; you will see jeans, dresses, sneakers, and the occasional clergy collar. Our main entrance faces Harbor Way, with accessible parking close to the door and additional parking across the street.</p>
<p>Greeters wearing simple green lanyards can help you find the sanctuary, restrooms, children’s check-in, or a quiet place to sit.</p>
</div>
</details>
<details class="faq-item">
<summary>Are children welcome in worship?</summary>
<div class="faq-answer">
<p>Absolutely. Children are welcome in every service, and the sounds they make are part of our common life. Nursery and age-specific programs are available during both Sunday gatherings, with secure check-in and at least two screened leaders in every room.</p>
<p>A family room adjacent to the sanctuary offers a viewing window, comfortable seating, and space for little ones who need to move.</p>
</div>
</details>
<details class="faq-item">
<summary>How do you approach giving?</summary>
<div class="faq-answer">
<p>Giving is an invitation for our regular community, never an admission fee for guests. An offering is received during worship, but please let the basket pass without any sense of obligation.</p>
<p>Our lay council publishes an annual financial report, and designated benevolence funds support neighbors facing urgent needs.</p>
</div>
</details>
<details class="faq-item">
<summary>Can I talk with a pastor before visiting?</summary>
<div class="faq-answer">
<p>Yes. Whether you have a question about accessibility, baptism, a past church hurt, or what we teach, a member of our pastoral team would be glad to listen. Email <a class="text-link" href="mailto:hello@harborlight.church?subject=Conversation%20before%20my%20first%20visit">hello@harborlight.church</a> or call the church office during weekday hours.</p>
</div>
</details>
</div>
</div>
</section>
<section class="visit-section" id="visit" aria-labelledby="visit-title">
<div class="container">
<div class="visit-banner">
<div class="visit-copy">
<div class="eyebrow light">Your Seat Is Waiting</div>
<h2 id="visit-title">Make this Sunday your first.</h2>
<p>
Tell us when you hope to come and anything that would make your visit easier. A member of our welcome team will meet you at the door, help your family get settled, and give you plenty of space to simply be our guest.
</p>
<div class="visit-actions">
<button class="btn btn-light" type="button" data-open-visit>
Plan Your Visit
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
<a class="btn btn-outline-light" href="https://www.google.com/maps/search/?api=1&query=1280+Harbor+Way+Portland+OR+97209" target="_blank" rel="noopener">Get Directions</a>
</div>
</div>
<div class="visit-details">
<h3>Good to know</h3>
<ul>
<li>
<svg class="icon" aria-hidden="true"><use href="#i-pin"/></svg>
<div><strong>1280 Harbor Way</strong>Portland, OR 97209</div>
</li>
<li>
<svg class="icon" aria-hidden="true"><use href="#i-clock"/></svg>
<div><strong>Sundays at 9:00 & 11:00 AM</strong>Arrive 15 minutes early for children’s check-in.</div>
</li>
<li>
<svg class="icon" aria-hidden="true"><use href="#i-home"/></svg>
<div><strong>Accessible and family-friendly</strong>Step-free entry, hearing assistance, and all-gender restrooms.</div>
</li>
</ul>
</div>
</div>
</div>
</section>
</main>
<footer class="site-footer" id="contact">
<div class="container footer-main">
<div class="footer-brand">
<a class="brand" href="#top">
<img class="brand-logo" src="https://placehold.co/96x96/19372e/f7f3ea?text=HL&font=montserrat" width="49" height="49" alt="Harborlight Community Church logo" loading="lazy">
<span>
<span class="brand-name">Harborlight Church</span>
<span class="brand-tagline">Rooted in grace. Making room for everyone.</span>
</span>
</a>
<p>
A Christ-centered community learning to love God, welcome our neighbors, and practice an unhurried life of faith.
</p>
<div class="social-links" aria-label="Social media links">
<a href="https://www.instagram.com/harborlightchurch/" target="_blank" rel="noopener" aria-label="Harborlight on Instagram">Instagram</a>
<a href="https://www.youtube.com/@harborlightchurch" target="_blank" rel="noopener" aria-label="Harborlight on YouTube">YouTube</a>
<a href="https://www.facebook.com/harborlightchurch" target="_blank" rel="noopener" aria-label="Harborlight on Facebook">Facebook</a>
</div>
</div>
<div class="footer-column">
<h2>Visit & Contact</h2>
<address>
<strong>Harborlight Community Church</strong>
1280 Harbor Way<br>
Portland, OR 97209
</address>
<ul class="footer-links">
<li><a href="tel:+15035550148">(503) 555-0148</a></li>
<li><a href="mailto:hello@harborlight.church">hello@harborlight.church</a></li>
<li>Office: Mon–Thu, 9 AM–4 PM</li>
</ul>
</div>
<div class="footer-column">
<h2>Explore</h2>
<ul class="footer-links">
<li><a href="#services">Service Times</a></li>
<li><a href="#sermons">Latest Sermon</a></li>
<li><a href="#ministries">Faith Formation</a></li>
<li><a href="#events">Events Calendar</a></li>
<li><a href="#community">Care & Community</a></li>
<li><a href="#resources">Weekly Devotional</a></li>
<li><a href="#about">Our Story & Beliefs</a></li>
</ul>
</div>
<div class="footer-column">
<h2>The Thursday Light</h2>
<p class="newsletter-copy">
One thoughtful email each Thursday: Sunday’s scripture, upcoming events, and a short blessing. No clutter.
</p>
<form class="newsletter-form" id="newsletter-form">
<label for="newsletter-email">Email address</label>
<div class="newsletter-input-row">
<input id="newsletter-email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
<button class="btn btn-gold" type="submit">Subscribe</button>
</div>
<p class="newsletter-status" id="newsletter-status" aria-live="polite"></p>
</form>
</div>
</div>
<div class="container footer-bottom">
<span>© <span id="year">2025</span> Harborlight Community Church. All rights reserved.</span>
<div class="legal-links">
<a href="#privacy" data-legal="privacy">Privacy</a>
<a href="#terms" data-legal="terms">Terms</a>
<a href="mailto:hello@harborlight.church?subject=Website%20accessibility">Accessibility</a>
</div>
</div>
</footer>
<a class="back-to-top" id="back-to-top" href="#top" aria-label="Back to top">
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</a>
<dialog id="visit-dialog" aria-labelledby="visit-dialog-title">
<div class="modal-inner">
<button class="modal-close" type="button" data-close aria-label="Close visit planner">
<svg class="icon" aria-hidden="true"><use href="#i-close"/></svg>
</button>
<div class="modal-kicker">A Warm Welcome</div>
<h2 id="visit-dialog-title">Plan your first visit.</h2>
<p class="modal-intro">
Share a few details and our welcome team will help make your first gathering comfortable, simple, and entirely pressure-free.
</p>
<form id="visit-form">
<div class="form-grid">
<div class="form-field">
<label for="visit-name">Full name</label>
<input id="visit-name" name="name" type="text" autocomplete="name" required>
</div>
<div class="form-field">
<label for="visit-email">Email address</label>
<input id="visit-email" name="email" type="email" autocomplete="email" required>
</div>
<div class="form-field full">
<label for="visit-service">Which gathering would you like to attend?</label>
<select id="visit-service" name="service" required>
<option value="">Choose a service</option>
<option>Sunday at 9:00 AM — Contemplative Worship</option>
<option>Sunday at 11:00 AM — Celebration Worship</option>
<option>Wednesday at 6:30 PM — Midweek Vespers</option>
</select>
</div>
<div class="form-field full">
<label for="visit-notes">Anything you would like us to know? <span class="sr-only">Optional</span></label>
<textarea id="visit-notes" name="notes" placeholder="Accessibility needs, questions, children’s ages, or simply what brings you…"></textarea>
</div>
<label class="checkbox-field">
<input type="checkbox" name="meetGreeter" checked>
<span>I’d like a welcome team member to meet me at the main entrance.</span>
</label>
<div class="form-submit">
<button class="btn btn-primary" type="submit">
Plan My Visit
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
</div>
<p class="form-privacy">Your details are used only to help with your visit. No mailing-list signup unless you request it.</p>
</div>
</form>
<div class="form-success" id="visit-success" tabindex="-1" hidden>
<div class="success-icon">
<svg class="icon" aria-hidden="true"><use href="#i-check"/></svg>
</div>
<h3>You’re all set, <span id="visit-success-name">friend</span>.</h3>
<p id="visit-success-detail"></p>
<p>Look for a greeter wearing a green lanyard near the main entrance. We’re looking forward to welcoming you.</p>
<button class="btn btn-primary" type="button" data-close>Done</button>
</div>
</div>
</dialog>
<dialog id="event-dialog" aria-labelledby="event-dialog-title">
<div class="modal-inner">
<button class="modal-close" type="button" data-close aria-label="Close event registration">
<svg class="icon" aria-hidden="true"><use href="#i-close"/></svg>
</button>
<div class="modal-kicker">You’re Invited</div>
<h2 id="event-dialog-title">Attend this event.</h2>
<div class="selected-event">
<strong id="selected-event-name">Harborlight Event</strong>
<span id="selected-event-details"></span>
</div>
<form id="event-form">
<input id="event-name-input" name="event" type="hidden">
<div class="form-grid">
<div class="form-field">
<label for="event-attendee">Full name</label>
<input id="event-attendee" name="name" type="text" autocomplete="name" required>
</div>
<div class="form-field">
<label for="event-email">Email address</label>
<input id="event-email" name="email" type="email" autocomplete="email" required>
</div>
<div class="form-field full">
<label for="event-guests">Total number attending</label>
<select id="event-guests" name="guests" required>
<option value="1">1 person</option>
<option value="2">2 people</option>
<option value="3">3 people</option>
<option value="4">4 people</option>
<option value="5">5 people</option>
<option value="6">6 or more people</option>
</select>
</div>
<label class="checkbox-field">
<input type="checkbox" name="reminder" checked>
<span>Send me a reminder and any preparation details before the event.</span>
</label>
<div class="form-submit">
<button class="btn btn-primary" type="submit">
Confirm Attendance
<svg class="icon" aria-hidden="true"><use href="#i-arrow"/></svg>
</button>
</div>
</div>
</form>
<div class="form-success" id="event-success" tabindex="-1" hidden>
<div class="success-icon">
<svg class="icon" aria-hidden="true"><use href="#i-check"/></svg>
</div>
<h3>We’ll see you there.</h3>
<p id="event-success-detail"></p>
<p>If your plans change, simply reply to your confirmation or contact the church office.</p>
<button class="btn btn-primary" type="button" data-close>Done</button>
</div>
</div>
</dialog>
<dialog id="legal-dialog" aria-labelledby="legal-dialog-title">
<div class="modal-inner">
<button class="modal-close" type="button" data-close aria-label="Close legal information">
<svg class="icon" aria-hidden="true"><use href="#i-close"/></svg>
</button>
<div class="modal-kicker">Harborlight Community Church</div>
<h2 id="legal-dialog-title">Privacy notice</h2>
<article class="legal-article" id="privacy">
<p>
Harborlight respects the trust you place in us. We collect only the information you choose to provide through visit planning, event registration, prayer requests, or newsletter subscriptions.
</p>
<h3>How information is used</h3>
<p>
Contact details are used to respond to your request, coordinate the service you selected, and provide information directly related to your participation. Confidential care requests are shared only with the appropriate pastoral or care personnel.
</p>
<h3>Your choices</h3>
<p>
You may unsubscribe from general church emails at any time. To request access, correction, or deletion of your information, email <a class="text-link" href="mailto:privacy@harborlight.church">privacy@harborlight.church</a>. Devotional completion data remains in your browser’s local storage and is not transmitted to the church.
</p>
<h3>Safeguards</h3>
<p>We use reasonable administrative and technical safeguards and never sell personal information. Ministry volunteers receive only the information necessary for their assigned responsibilities.</p>
</article>
<article class="legal-article" id="terms" hidden>
<p>
This website provides general information about Harborlight Community Church, its gatherings, ministries, and spiritual resources. By using the site, you agree to use its content lawfully and respectfully.
</p>
<h3>Spiritual resources</h3>
<p>
Devotionals, sermons, and other materials are offered for personal reflection and spiritual formation. They are not substitutes for professional medical, mental-health, legal, or financial advice.
</p>
<h3>Content and event information</h3>
<p>
We work to keep schedules and details accurate, but events may occasionally change because of weather, facility needs, or public-health guidance. Registered attendees will be notified using the contact information supplied.
</p>
<h3>Respectful use</h3>
<p>
Site content may not be misrepresented, used to harass others, or redistributed commercially without permission. Questions about these terms may be sent to <a class="text-link" href="mailto:hello@harborlight.church">hello@harborlight.church</a>.
</p>
</article>
</div>
</dialog>
<script>
(() => {
"use strict";
const $ = (selector, scope = document) => scope.querySelector(selector);
const $$ = (selector, scope = document) => Array.from(scope.querySelectorAll(selector));
$("#year").textContent = new Date().getFullYear();
/* Responsive navigation */
const header = $("#site-header");
const menuToggle = $("#menu-toggle");
const primaryNav = $("#primary-nav");
function setMenu(open) {
header.classList.toggle("nav-open", open);
menuToggle.setAttribute("aria-expanded", String(open));
menuToggle.setAttribute("aria-label", open ? "Close navigation menu" : "Open navigation menu");
}
menuToggle.addEventListener("click", () => {
setMenu(!header.classList.contains("nav-open"));
});
$$("a", primaryNav).forEach(link => {
link.addEventListener("click", () => setMenu(false));
});
document.addEventListener("keydown", event => {
if (event.key === "Escape" && header.classList.contains("nav-open")) {
setMenu(false);
menuToggle.focus();
}
});
document.addEventListener("click", event => {
if (header.classList.contains("nav-open") && !header.contains(event.target)) {
setMenu(false);
}
});
window.addEventListener("resize", () => {
if (window.innerWidth > 1120) setMenu(false);
});
/* Accessible modal helpers */
let lastDialogTrigger = null;
const dialogs = $$("dialog");
function openDialog(dialog, trigger) {
if (!dialog) return;
lastDialogTrigger = trigger || document.activeElement;
if (typeof dialog.showModal === "function") {
dialog.showModal();
} else {
dialog.setAttribute("open", "");
}
document.body.classList.add("modal-open");
}
function closeDialog(dialog) {
if (typeof dialog.close === "function") {
dialog.close();
} else {
dialog.removeAttribute("open");
document.body.classList.remove("modal-open");
}
}
dialogs.forEach(dialog => {
$$('[data-close]', dialog).forEach(button => {
button.addEventListener("click", () => closeDialog(dialog));
});
dialog.addEventListener("click", event => {
if (event.target === dialog) closeDialog(dialog);
});
dialog.addEventListener("close", () => {
if (!$("dialog[open]")) document.body.classList.remove("modal-open");
if (lastDialogTrigger && document.contains(lastDialogTrigger)) {
lastDialogTrigger.focus();
}
});
});
/* Visit planner */
const visitDialog = $("#visit-dialog");
const visitForm = $("#visit-form");
const visitSuccess = $("#visit-success");
$$('[data-open-visit]').forEach(button => {
button.addEventListener("click", () => {
visitForm.reset();
visitForm.hidden = false;
visitSuccess.hidden = true;
openDialog(visitDialog, button);
});
});
visitForm.addEventListener("submit", event => {
event.preventDefault();
const data = new FormData(visitForm);
const fullName = String(data.get("name") || "friend").trim();
const firstName = fullName.split(/\s+/)[0] || "friend";
const service = String(data.get("service"));
const email = String(data.get("email"));
$("#visit-success-name").textContent = firstName;
$("#visit-success-detail").textContent = `Your visit for ${service} is planned. A welcome note with arrival details will be sent to ${email}.`;
visitForm.hidden = true;
visitSuccess.hidden = false;
visitSuccess.focus();
});
/* Event registration */
const eventDialog = $("#event-dialog");
const eventForm = $("#event-form");
const eventSuccess = $("#event-success");
$$('[data-open-event]').forEach(button => {
button.addEventListener("click", () => {
const eventName = button.dataset.event;
const eventDetails = button.dataset.details;
eventForm.reset();
eventForm.hidden = false;
eventSuccess.hidden = true;
$("#selected-event-name").textContent = eventName;
$("#selected-event-details").textContent = eventDetails;
$("#event-name-input").value = eventName;
openDialog(eventDialog, button);
});
});
eventForm.addEventListener("submit", event => {
event.preventDefault();
const data = new FormData(eventForm);
const eventName = String(data.get("event"));
const email = String(data.get("email"));
const guests = String(data.get("guests"));
const guestLabel = guests === "1" ? "1 person" : guests === "6" ? "6 or more people" : `${guests} people`;
$("#event-success-detail").textContent = `Your RSVP for ${eventName} is confirmed for ${guestLabel}. Details will be sent to ${email}.`;
eventForm.hidden = true;
eventSuccess.hidden = false;
eventSuccess.focus();
});
/* Newsletter feedback */
const newsletterForm = $("#newsletter-form");
newsletterForm.addEventListener("submit", event => {
event.preventDefault();
const email = $("#newsletter-email").value;
$("#newsletter-status").textContent = `Thank you. The next Thursday Light will be sent to ${email}.`;
newsletterForm.reset();
});
/* Privacy and terms */
const legalDialog = $("#legal-dialog");
const legalTitle = $("#legal-dialog-title");
$$('[data-legal]').forEach(link => {
link.addEventListener("click", event => {
event.preventDefault();
const requestedArticle = link.dataset.legal;
$$(".legal-article", legalDialog).forEach(article => {
article.hidden = article.id !== requestedArticle;
});
legalTitle.textContent = requestedArticle === "terms" ? "Terms of use" : "Privacy notice";
openDialog(legalDialog, link);
});
});
/* Weekly devotional calendar */
const devotionals = [
{
id: "mon",
day: "Monday",
theme: "Receive",
reference: "John 14:27",
scripture: "“Peace I leave with you; my peace I give to you… Do not let your hearts be troubled, and do not let them be afraid.”",
title: "Receive before you respond.",
reflection: [
"We often begin the day already braced for what might go wrong. Jesus begins somewhere else: with a gift. His peace is not fragile calm that depends on a quiet inbox or an uncomplicated life. It is the assurance that we are held in love before we accomplish anything.",
"Today, let receiving be your first spiritual work. You do not have to manufacture a peaceful feeling. Simply make enough room to notice that God is already present."
],
practice: "Before reaching for your phone, place both feet on the floor and take five slow breaths. With each inhale pray, “I receive your peace.” With each exhale pray, “I release my striving.”",
prayer: "Christ, meet me before I meet the demands of this day. Amen."
},
{
id: "tue",
day: "Tuesday",
theme: "Be Still",
reference: "Psalm 46:10",
scripture: "“Be still, and know that I am God!”",
title: "Stillness is an act of trust.",
reflection: [
"Stillness can feel irresponsible when so much needs attention. Yet the psalmist does not describe stillness as indifference. It is a deliberate refusal to confuse our activity with God’s faithfulness. The world is held by more than our effort.",
"A few quiet minutes will not resolve every concern, but they can reveal which concerns have been allowed to occupy the whole landscape. Stillness gives us our lives back in proper proportion."
],
practice: "Set a timer for three minutes. Silence notifications, sit comfortably, and resist the urge to analyze or improve the moment. When your mind wanders, gently repeat, “You are God; I am held.”",
prayer: "God of the wide world and this small moment, teach me to rest in your care. Amen."
},
{
id: "wed",
day: "Wednesday",
theme: "Name It",
reference: "Philippians 4:6–7",
scripture: "“Do not worry about anything, but in everything by prayer and supplication with thanksgiving let your requests be made known to God.”",
title: "Peace begins with honesty.",
reflection: [
"Prayer is not a performance of serenity. Scripture invites us to bring our actual requests, including the frightened, frustrated, and unfinished parts of ourselves. God is not waiting for a more polished version of our concern.",
"Naming what weighs on us can loosen its secrecy. Thanksgiving belongs here too—not as denial, but as the practice of noticing that difficulty is not the only true thing about this day."
],
practice: "Write three headings: “I’m worried about,” “I need,” and “I’m grateful for.” Complete each sentence without editing. Offer the page to God, then leave it somewhere you can revisit tonight.",
prayer: "Faithful God, receive my unedited heart and guard it with your peace. Amen."
},
{
id: "thu",
day: "Thursday",
theme: "Rest",
reference: "Matthew 11:28–30",
scripture: "“Come to me, all you that are weary and are carrying heavy burdens, and I will give you rest.”",
title: "You were not made to carry everything.",
reflection: [
"Some burdens are visible: work, caregiving, finances, and appointments. Others remain unnamed—hypervigilance, perfectionism, old grief, or the need to prove our worth. Jesus does not shame the weary. He invites them closer.",
"Rest may require more than a nap. It might mean asking for help, declining one more commitment, or admitting that a responsibility was never yours to carry alone."
],
practice: "Identify one burden you can share today. Make the phone call, ask the question, or accept the offered help. Let one concrete act of dependence become your prayer.",
prayer: "Gentle Christ, show me what is mine to carry and give me courage to share the load. Amen."
},
{
id: "fri",
day: "Friday",
theme: "Choose",
reference: "Colossians 3:15",
scripture: "“And let the peace of Christ rule in your hearts, to which indeed you were called in the one body. And be thankful.”",
title: "Let peace have a voice.",
reflection: [
"Peace is not passive. To let Christ’s peace “rule” is to give it authority in our decisions, speech, and relationships. It can mean pausing before replying, refusing to rehearse an old resentment, or choosing the conversation that leads toward repair.",
"This does not require avoiding hard truths. Christian peace is compatible with boundaries, courage, and justice. It asks not only whether something must be said, but how love might shape the saying."
],
practice: "Before one potentially difficult interaction today, pause for ten seconds. Ask: “What response would help truth and peace grow together?” Then listen for at least one full breath before answering.",
prayer: "Prince of Peace, govern my reactions and make my words a place where others can breathe. Amen."
},
{
id: "sat",
day: "Saturday",
theme: "Return",
reference: "Isaiah 30:15",
scripture: "“In returning and rest you shall be saved; in quietness and in trust shall be your strength.”",
title: "Make room for delight.",
reflection: [
"A peace practice is incomplete if it only teaches us to endure. Sabbath also returns us to delight—to the unproductive goodness of creation, friendship, music, food, and play. Joy reminds us that life is a gift, not merely a problem to manage.",
"You may not be able to set aside an entire day. Begin with an hour that is not organized around achievement. Receive something good without needing to document it or turn it into a task."
],
practice: "Choose one simple delight: take a slow walk, cook something you enjoy, tend a plant, call a friend, or sit in the sun. Leave your phone behind for twenty minutes and give the moment your full attention.",
prayer: "Creator, return me to the goodness of being alive and grateful. Amen."
},
{
id: "sun",
day: "Sunday",
theme: "Share",
reference: "Romans 12:18",
scripture: "“If it is possible, so far as it depends on you, live peaceably with all.”",
title: "Carry peace into the room.",
reflection: [
"The peace we practice privately is meant to become a gift others can experience. Sometimes it looks like hospitality; sometimes like patient listening, a sincere apology, or the courage to interrupt cruelty without becoming cruel ourselves.",
"Paul’s words also honor our limits. Peace is not always ours to produce, and reconciliation cannot be demanded from one person alone. We are responsible for faithful presence, not for controlling every outcome."
],
practice: "Offer one tangible act of peace today: set an extra place at the table, check on someone isolated, make a needed apology, or speak a specific word of encouragement. Notice the person in front of you.",
prayer: "God of communion, let your peace become visible in the way I love others. Amen."
}
];
const tabs = $$(".day-button");
const completeButton = $("#complete-practice");
const completeLabel = $("#complete-label");
const devotionalStatus = $("#devotional-status");
const storageKey = "harborlight-practicing-peace-v1";
let currentDay = 0;
let completed = new Set();
try {
const saved = JSON.parse(localStorage.getItem(storageKey) || "[]");
if (Array.isArray(saved)) {
completed = new Set(saved.filter(id => devotionals.some(item => item.id === id)));
}
} catch (error) {
completed = new Set();
}
function saveProgress() {
try {
localStorage.setItem(storageKey, JSON.stringify(Array.from(completed)));
} catch (error) {
/* The devotional remains fully usable if storage is unavailable. */
}
}
function renderProgress() {
const count = completed.size;
$("#devotional-count").textContent = `${count} of 7 ${count === 1 ? "practice" : "practices"} complete`;
$("#devotional-progress-fill").style.width = `${(count / 7) * 100}%`;
$("#devotional-progressbar").setAttribute("aria-valuenow", String(count));
tabs.forEach((tab, index) => {
const isComplete = completed.has(devotionals[index].id);
tab.classList.toggle("is-complete", isComplete);
tab.setAttribute("aria-label", `${devotionals[index].day} devotional${isComplete ? ", completed" : ""}`);
});
const currentComplete = completed.has(devotionals[currentDay].id);
completeButton.classList.toggle("is-complete", currentComplete);
completeButton.setAttribute("aria-pressed", String(currentComplete));
completeLabel.textContent = currentComplete ? "Practice completed" : "Mark practice complete";
}
function selectDay(index, moveFocus = false) {
currentDay = index;
const item = devotionals[index];
tabs.forEach((tab, tabIndex) => {
const selected = tabIndex === index;
tab.setAttribute("aria-selected", String(selected));
tab.tabIndex = selected ? 0 : -1;
});
$("#devotional-panel").setAttribute("aria-labelledby", tabs[index].id);
$("#devotional-day").textContent = `${item.day} · ${item.theme}`;
$("#devotional-reference").textContent = item.reference;
$("#devotional-scripture").textContent = item.scripture;
$("#devotional-title").textContent = item.title;
const reflection = $("#devotional-reflection");
reflection.replaceChildren(...item.reflection.map(text => {
const paragraph = document.createElement("p");
paragraph.textContent = text;
return paragraph;
}));
$("#devotional-practice").textContent = item.practice;
$("#devotional-prayer").textContent = item.prayer;
renderProgress();
if (moveFocus) tabs[index].focus();
devotionalStatus.textContent = `${item.day} devotional loaded.`;
}
tabs.forEach((tab, index) => {
tab.addEventListener("click", () => selectDay(index));
tab.addEventListener("keydown", event => {
let nextIndex;
if (event.key === "ArrowRight" || event.key === "ArrowDown") nextIndex = (index + 1) % tabs.length;
if (event.key === "ArrowLeft" || event.key === "ArrowUp") nextIndex = (index - 1 + tabs.length) % tabs.length;
if (event.key === "Home") nextIndex = 0;
if (event.key === "End") nextIndex = tabs.length - 1;
if (typeof nextIndex === "number") {
event.preventDefault();
selectDay(nextIndex, true);
}
});
});
completeButton.addEventListener("click", () => {
const id = devotionals[currentDay].id;
if (completed.has(id)) {
completed.delete(id);
devotionalStatus.textContent = `${devotionals[currentDay].day} marked incomplete.`;
} else {
completed.add(id);
devotionalStatus.textContent = `${devotionals[currentDay].day} practice completed.`;
}
saveProgress();
renderProgress();
});
$("#reset-devotional").addEventListener("click", () => {
completed.clear();
saveProgress();
renderProgress();
devotionalStatus.textContent = "Weekly devotional progress has been reset.";
});
const todayIndex = (new Date().getDay() + 6) % 7;
selectDay(todayIndex);
/* Back-to-top control */
const backToTop = $("#back-to-top");
function updateBackToTop() {
backToTop.classList.toggle("is-visible", window.scrollY > 750);
}
window.addEventListener("scroll", updateBackToTop, { passive: true });
updateBackToTop();
})();
</script>
</body>
</html>
View Axe Report (JSON)
{
"testEngine": {
"name": "axe-core",
"version": "4.10.2"
},
"testRunner": {
"name": "axe"
},
"testEnvironment": {
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36",
"windowWidth": 1280,
"windowHeight": 720,
"orientationAngle": 0,
"orientationType": "landscape-primary"
},
"timestamp": "2026-11-12T10:16:07.480Z",
"url": "https://benchmark.aimac.invalid/9081aa89c0acf92a6ea8d2242c4ba1bc0059e2357c5e4c3c7144b5e7bd8c3a15.html",
"toolOptions": {
"runOnly": {
"type": "tag",
"values": [
"wcag2a",
"wcag2aa",
"wcag21a",
"wcag21aa",
"wcag22a",
"wcag22aa"
]
},
"resultTypes": [
"violations"
],
"reporter": "v1"
},
"inapplicable": [
{
"id": "area-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <area> elements of image maps have alternative text",
"help": "Active <area> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/area-alt?application=axeAPI",
"nodes": []
},
{
"id": "aria-braille-equivalent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-braillelabel and aria-brailleroledescription have a non-braille equivalent",
"help": "aria-braille attributes must have a non-braille equivalent",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-braille-equivalent?application=axeAPI",
"nodes": []
},
{
"id": "aria-command-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA button, link and menuitem has an accessible name",
"help": "ARIA commands must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-command-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-input-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA input field has an accessible name",
"help": "ARIA input fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-input-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-meter-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA meter node has an accessible name",
"help": "ARIA meter nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-meter-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-toggle-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA toggle field has an accessible name",
"help": "ARIA toggle fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-toggle-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-tooltip-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every ARIA tooltip node has an accessible name",
"help": "ARIA tooltip nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-tooltip-name?application=axeAPI",
"nodes": []
},
{
"id": "avoid-inline-spacing",
"impact": null,
"tags": [
"cat.structure",
"wcag21aa",
"wcag1412",
"EN-301-549",
"EN-9.1.4.12",
"ACT"
],
"description": "Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",
"help": "Inline text spacing must be adjustable with custom stylesheets",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/avoid-inline-spacing?application=axeAPI",
"nodes": []
},
{
"id": "blink",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag222",
"section508",
"section508.22.j",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <blink> elements are not used",
"help": "<blink> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/blink?application=axeAPI",
"nodes": []
},
{
"id": "definition-list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dl> elements are structured correctly",
"help": "<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/definition-list?application=axeAPI",
"nodes": []
},
{
"id": "dlitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dt> and <dd> elements are contained by a <dl>",
"help": "<dt> and <dd> elements must be contained by a <dl>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/dlitem?application=axeAPI",
"nodes": []
},
{
"id": "frame-focusable-content",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure <frame> and <iframe> elements with focusable content do not have tabindex=-1",
"help": "Frames with focusable content must not have tabindex=-1",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-focusable-content?application=axeAPI",
"nodes": []
},
{
"id": "frame-title-unique",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements contain a unique title attribute",
"help": "Frames must have a unique title attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title-unique?application=axeAPI",
"nodes": []
},
{
"id": "frame-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"section508",
"section508.22.i",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements have an accessible name",
"help": "Frames must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title?application=axeAPI",
"nodes": []
},
{
"id": "html-xml-lang-mismatch",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",
"help": "HTML elements with lang and xml:lang must have the same base language",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-xml-lang-mismatch?application=axeAPI",
"nodes": []
},
{
"id": "input-button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure input buttons have discernible text",
"help": "Input buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-button-name?application=axeAPI",
"nodes": []
},
{
"id": "input-image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <input type=\"image\"> elements have alternative text",
"help": "Image buttons must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-image-alt?application=axeAPI",
"nodes": []
},
{
"id": "marquee",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag222",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <marquee> elements are not used",
"help": "<marquee> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/marquee?application=axeAPI",
"nodes": []
},
{
"id": "meta-refresh",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag221",
"TTv5",
"TT8.a",
"EN-301-549",
"EN-9.2.2.1"
],
"description": "Ensure <meta http-equiv=\"refresh\"> is not used for delayed refresh",
"help": "Delayed refresh under 20 hours must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-refresh?application=axeAPI",
"nodes": []
},
{
"id": "object-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure <object> elements have alternative text",
"help": "<object> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/object-alt?application=axeAPI",
"nodes": []
},
{
"id": "role-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure [role=\"img\"] elements have alternative text",
"help": "[role=\"img\"] elements must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/role-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "scrollable-region-focusable",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"wcag213",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1",
"EN-9.2.1.3"
],
"description": "Ensure elements that have scrollable content are accessible by keyboard",
"help": "Scrollable region must have keyboard access",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/scrollable-region-focusable?application=axeAPI",
"nodes": []
},
{
"id": "select-name",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure select element has an accessible name",
"help": "Select element must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/select-name?application=axeAPI",
"nodes": []
},
{
"id": "server-side-image-map",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag211",
"section508",
"section508.22.f",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure that server-side image maps are not used",
"help": "Server-side image maps must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/server-side-image-map?application=axeAPI",
"nodes": []
},
{
"id": "svg-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text",
"help": "<svg> elements with an img role must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/svg-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "td-headers-attr",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table",
"help": "Table cells that use the headers attribute must only refer to cells in the same table",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/td-headers-attr?application=axeAPI",
"nodes": []
},
{
"id": "th-has-data-cells",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe",
"help": "Table headers in a data table must refer to data cells",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/th-has-data-cells?application=axeAPI",
"nodes": []
},
{
"id": "valid-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2aa",
"wcag312",
"TTv5",
"TT11.b",
"EN-301-549",
"EN-9.3.1.2",
"ACT"
],
"description": "Ensure lang attributes have valid values",
"help": "lang attribute must have a valid value",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/valid-lang?application=axeAPI",
"nodes": []
},
{
"id": "video-caption",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag122",
"section508",
"section508.22.a",
"TTv5",
"TT17.a",
"EN-301-549",
"EN-9.1.2.2"
],
"description": "Ensure <video> elements have captions",
"help": "<video> elements must have captions",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/video-caption?application=axeAPI",
"nodes": []
},
{
"id": "no-autoplay-audio",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag142",
"TTv5",
"TT2.a",
"EN-301-549",
"EN-9.1.4.2",
"ACT"
],
"description": "Ensure <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio",
"help": "<video> or <audio> elements must not play automatically",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/no-autoplay-audio?application=axeAPI",
"nodes": []
}
],
"passes": [
{
"id": "aria-allowed-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure an element's role supports its ARIA attributes",
"help": "Elements must only use supported ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-allowed-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attributes are used correctly for the defined role"
}
],
"none": [
{
"id": "aria-unsupported-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute is supported"
}
],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\" aria-label=\"Harborlight Community Church home\">",
"target": [
".header-inner > .brand[href$=\"#top\"]"
]
}
]
},
{
"id": "aria-conditional-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are used as described in the specification of the element's role",
"help": "ARIA attributes must be used as specified for the element's role",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-conditional-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-conditional-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\" aria-label=\"Harborlight Community Church home\">",
"target": [
".header-inner > .brand[href$=\"#top\"]"
]
}
]
},
{
"id": "aria-deprecated-role",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements do not use deprecated roles",
"help": "Deprecated ARIA roles must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-deprecated-role?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "deprecatedrole",
"data": null,
"relatedNodes": [],
"impact": "minor",
"message": "ARIA role is not deprecated"
}
],
"impact": null,
"html": "<div class=\"day-buttons\" role=\"tablist\" aria-labelledby=\"day-navigation-label\">",
"target": [
".day-buttons"
]
}
]
},
{
"id": "aria-hidden-body",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"wcag412",
"EN-301-549",
"EN-9.1.3.1",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden=\"true\" is not present on the document body.",
"help": "aria-hidden=\"true\" must not be present on the document body",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-body?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-hidden-body",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "No aria-hidden attribute is present on document body"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<body id=\"top\">",
"target": [
"#top"
]
}
]
},
{
"id": "aria-hidden-focus",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden elements are not focusable nor contain focusable elements",
"help": "ARIA hidden element must not be focusable or contain focusable elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-focus?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "focusable-modal-open",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements while a modal is open"
},
{
"id": "focusable-disabled",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements contained within element"
},
{
"id": "focusable-not-tabbable",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements contained within element"
}
],
"none": [],
"impact": null,
"html": "<svg class=\"svg-sprite\" aria-hidden=\"true\">",
"target": [
".svg-sprite"
]
}
]
},
{
"id": "aria-progressbar-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA progressbar node has an accessible name",
"help": "ARIA progressbar nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-progressbar-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-label",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "aria-label attribute exists and is not empty"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<div class=\"progress-track\" id=\"devotional-progressbar\" role=\"progressbar\" aria-label=\"Weekly devotional progress\" aria-valuemin=\"0\" aria-valuemax=\"7\" aria-valuenow=\"0\">\n <div class=\"progress-fill\" id=\"devotional-progress-fill\" style=\"width: 0%;\"></div>\n </div>",
"target": [
"#devotional-progressbar"
]
}
]
},
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\" aria-label=\"Harborlight Community Church home\">",
"target": [
".header-inner > .brand[href$=\"#top\"]"
]
}
]
},
{
"id": "aria-required-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements with ARIA roles have all required ARIA attributes",
"help": "Required ARIA attributes must be provided",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-attr?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-required-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "All required ARIA attributes are present"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<div class=\"day-buttons\" role=\"tablist\" aria-labelledby=\"day-navigation-label\">",
"target": [
".day-buttons"
]
}
]
},
{
"id": "aria-required-children",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require child roles contain them",
"help": "Certain ARIA roles must contain particular children",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-children?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-required-children",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Required ARIA children are present"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<div class=\"day-buttons\" role=\"tablist\" aria-labelledby=\"day-navigation-label\">",
"target": [
".day-buttons"
]
}
]
},
{
"id": "aria-required-parent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require parent roles are contained by them",
"help": "Certain ARIA roles must be contained by particular parents",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-parent?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-required-parent",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Required ARIA parent role present"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<button class=\"day-button\" id=\"day-mon\" type=\"button\" role=\"tab\" aria-selected=\"false\" aria-controls=\"devotional-panel\" data-day=\"0\" tabindex=\"-1\" aria-label=\"Monday devotional\">\n <span>Monday</span><span class=\"day-state\" aria-hidden=\"true\"></span>\n </button>",
"target": [
"#day-mon"
]
}
]
},
{
"id": "aria-roles",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all elements with a role attribute use a valid value",
"help": "ARIA roles used must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-roles?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "invalidrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA role is valid"
},
{
"id": "abstractrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Abstract roles are not used"
},
{
"id": "unsupportedrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA role is supported"
}
],
"impact": null,
"html": "<div class=\"day-buttons\" role=\"tablist\" aria-labelledby=\"day-navigation-label\">",
"target": [
".day-buttons"
]
}
]
},
{
"id": "aria-valid-attr-value",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all ARIA attributes have valid values",
"help": "ARIA attributes must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr-value?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-valid-attr-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute values are valid"
},
{
"id": "aria-errormessage",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-errormessage exists and references elements visible to screen readers that use a supported aria-errormessage technique"
},
{
"id": "aria-level",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-level values are valid"
}
],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\" aria-label=\"Harborlight Community Church home\">",
"target": [
".header-inner > .brand[href$=\"#top\"]"
]
}
]
},
{
"id": "aria-valid-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure attributes that begin with aria- are valid ARIA attributes",
"help": "ARIA attributes must conform to valid names",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-valid-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute name is valid"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\" aria-label=\"Harborlight Community Church home\">",
"target": [
".header-inner > .brand[href$=\"#top\"]"
]
}
]
},
{
"id": "autocomplete-valid",
"impact": null,
"tags": [
"cat.forms",
"wcag21aa",
"wcag135",
"EN-301-549",
"EN-9.1.3.5",
"ACT"
],
"description": "Ensure the autocomplete attribute is correct and suitable for the form field",
"help": "autocomplete attribute must be used correctly",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/autocomplete-valid?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "autocomplete-valid",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "the autocomplete attribute is correctly formatted"
}
],
"none": [],
"impact": null,
"html": "<input id=\"newsletter-email\" name=\"email\" type=\"email\" autocomplete=\"email\" placeholder=\"you@example.com\" required=\"\">",
"target": [
"#newsletter-email"
]
}
]
},
{
"id": "button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure buttons have discernible text",
"help": "Buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/button-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "button-has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has inner text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<button class=\"btn btn-primary btn-small\" type=\"button\" data-open-visit=\"\">\n Plan a Visit\n <svg class=\"icon\" aria-hidden=\"true\"><use href=\"#i-arrow\"></use></svg>\n </button>",
"target": [
".btn-small.btn-primary[data-open-visit=\"\"]"
]
}
]
},
{
"id": "bypass",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag241",
"section508",
"section508.22.o",
"TTv5",
"TT9.a",
"EN-301-549",
"EN-9.2.4.1"
],
"description": "Ensure each page has at least one mechanism for a user to bypass navigation and jump straight to the content",
"help": "Page must have means to bypass repeated blocks",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/bypass?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "internal-link-present",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Valid skip link found"
},
{
"id": "header-present",
"data": null,
"relatedNodes": [
{
"html": "<h1 id=\"hero-title\">Come as you are.<br><em>Grow toward love.</em></h1>",
"target": [
"#hero-title"
]
},
{
"html": "<h3>Scripture with room for questions</h3>",
"target": [
".value-item:nth-child(1) > div > h3"
]
},
{
"html": "<h3>A table where everyone belongs</h3>",
"target": [
".value-item:nth-child(2) > div > h3"
]
},
{
"html": "<h3>Faith that moves outward</h3>",
"target": [
".value-item:nth-child(3) > div > h3"
]
},
{
"html": "<h2 id=\"services-title\">A rhythm for your week.</h2>",
"target": [
"#services-title"
]
},
{
"html": "<h3>Gather with us</h3>",
"target": [
".schedule-heading > h3"
]
},
{
"html": "<h3>Contemplative Worship</h3>",
"target": [
".service-row:nth-child(2) > div > h3"
]
},
{
"html": "<h3>Celebration Worship</h3>",
"target": [
".service-row:nth-child(3) > div > h3"
]
},
{
"html": "<h3>Midweek Vespers</h3>",
"target": [
".service-row:nth-child(4) > div > h3"
]
},
{
"html": "<h2 id=\"sermon-title\">The Peace We Practice</h2>",
"target": [
"#sermon-title"
]
},
{
"html": "<h2 id=\"ministries-title\">Faith for every season.</h2>",
"target": [
"#ministries-title"
]
},
{
"html": "<h3>Children & Families</h3>",
"target": [
".ministry-card:nth-child(1) > h3"
]
},
{
"html": "<h3>Youth & Young Adults</h3>",
"target": [
".ministry-card:nth-child(2) > h3"
]
},
{
"html": "<h3>Adult Faith Formation</h3>",
"target": [
".ministry-card:nth-child(3) > h3"
]
},
{
"html": "<h3>Care & Prayer</h3>",
"target": [
".ministry-card:nth-child(4) > h3"
]
},
{
"html": "<h2 id=\"events-title\">There\u2019s room at the table.</h2>",
"target": [
"#events-title"
]
},
{
"html": "<h3>The Community Table</h3>",
"target": [
".event-card:nth-child(1) > .event-body > h3"
]
},
{
"html": "<h3>Harbor Serve Day</h3>",
"target": [
".event-card:nth-child(2) > .event-body > h3"
]
},
{
"html": "<h3>Faith & Doubt</h3>",
"target": [
".event-card:nth-child(3) > .event-body > h3"
]
},
{
"html": "<h2 id=\"community-title\">You don\u2019t have to carry it alone.</h2>",
"target": [
"#community-title"
]
},
{
"html": "<h3>Prayer & pastoral care</h3>",
"target": [
"li:nth-child(1) > div > h3"
]
},
{
"html": "<h3>Practical help in difficult weeks</h3>",
"target": [
"li:nth-child(2) > div > h3"
]
},
{
"html": "<h3>Community groups</h3>",
"target": [
"li:nth-child(3) > div > h3"
]
},
{
"html": "<h2 id=\"devotional-section-title\">A small practice for a whole week.</h2>",
"target": [
"#devotional-section-title"
]
},
{
"html": "<h3 id=\"devotional-title\">You were not made to carry everything.</h3>",
"target": [
"#devotional-title"
]
},
{
"html": "<h2 id=\"about-title\">Ancient faith.<br>Open table.<br>Active love.</h2>",
"target": [
"#about-title"
]
},
{
"html": "<h3>Questions are welcome.</h3>",
"target": [
".faq-heading > h3"
]
},
{
"html": "<h2 id=\"visit-title\">Make this Sunday your first.</h2>",
"target": [
"#visit-title"
]
},
{
"html": "<h3>Good to know</h3>",
"target": [
".visit-details > h3"
]
},
{
"html": "<h2>Visit & Contact</h2>",
"target": [
".footer-column:nth-child(2) > h2"
]
},
{
"html": "<h2>Explore</h2>",
"target": [
".footer-column:nth-child(3) > h2"
]
},
{
"html": "<h2>The Thursday Light</h2>",
"target": [
".footer-column:nth-child(4) > h2"
]
}
],
"impact": "serious",
"message": "Page has a heading"
},
{
"id": "landmark",
"data": null,
"relatedNodes": [
{
"html": "<main id=\"main-content\">",
"target": [
"#main-content"
]
}
],
"impact": "serious",
"message": "Page has a landmark region"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#e2e5e4",
"bgColor": "#10271f",
"contrastRatio": 12.43,
"fontSize": "9.6pt (12.8px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [],
"impact": "serious",
"message": "Element has sufficient color contrast of 12.43"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<div class=\"announcement\">\n New to Harborlight? We\u2019ll make your first Sunday simple and pressure-free.\n <a href=\"#visit\">Plan your visit</a>\n </div>",
"target": [
".announcement"
]
}
]
},
{
"id": "document-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag242",
"TTv5",
"TT12.a",
"EN-301-549",
"EN-9.2.4.2",
"ACT"
],
"description": "Ensure each HTML document contains a non-empty <title> element",
"help": "Documents must have <title> element to aid in navigation",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/document-title?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "doc-has-title",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Document has a non-empty <title> element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "duplicate-id-aria",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every id attribute value used in ARIA and in labels is unique",
"help": "IDs used in ARIA and labels must be unique",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/duplicate-id-aria?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "duplicate-id-aria",
"data": "primary-nav",
"relatedNodes": [],
"impact": "critical",
"message": "Document has no elements referenced with ARIA or labels that share the same id attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<nav class=\"primary-nav\" id=\"primary-nav\" aria-label=\"Primary navigation\">",
"target": [
"#primary-nav"
]
}
]
},
{
"id": "form-field-multiple-labels",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag332",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.3.3.2"
],
"description": "Ensure form field does not have multiple label elements",
"help": "Form field must not have multiple label elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/form-field-multiple-labels?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "multiple-label",
"data": null,
"relatedNodes": [
{
"html": "<label for=\"newsletter-email\">Email address</label>",
"target": [
"label[for=\"newsletter-email\"]"
]
}
],
"impact": "moderate",
"message": "Form field does not have multiple label elements"
}
],
"impact": null,
"html": "<input id=\"newsletter-email\" name=\"email\" type=\"email\" autocomplete=\"email\" placeholder=\"you@example.com\" required=\"\">",
"target": [
"#newsletter-email"
]
}
]
},
{
"id": "html-has-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure every HTML document has a lang attribute",
"help": "<html> element must have a lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "The <html> element has a lang attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "html-lang-valid",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure the lang attribute of the <html> element has a valid value",
"help": "<html> element must have a valid value for the lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-lang-valid?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "valid-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Value of lang attribute is included in the list of valid languages"
}
],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"TT7.b",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <img> elements have alternative text or a role of none or presentation",
"help": "Images must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-alt",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has an alt attribute"
}
],
"all": [],
"none": [
{
"id": "alt-space-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has a valid alt attribute value"
}
],
"impact": null,
"html": "<img class=\"brand-logo\" src=\"https://placehold.co/96x96/19372e/f7f3ea?text=HL&font=montserrat\" width=\"49\" height=\"49\" alt=\"Harborlight Community Church logo\">",
"target": [
".header-inner > .brand[href$=\"#top\"] > .brand-logo[width=\"49\"][height=\"49\"]"
]
}
]
},
{
"id": "label",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every form element has a label",
"help": "Form elements must have labels",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/label?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "explicit-label",
"data": {
"explicitLabel": "Email address"
},
"relatedNodes": [
{
"html": "<label for=\"newsletter-email\">Email address</label>",
"target": [
"label[for=\"newsletter-email\"]"
]
}
],
"impact": "critical",
"message": "Element has an explicit <label>"
},
{
"id": "non-empty-placeholder",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has a placeholder attribute"
}
],
"all": [],
"none": [
{
"id": "hidden-explicit-label",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Form element has a visible explicit <label>"
}
],
"impact": null,
"html": "<input id=\"newsletter-email\" name=\"email\" type=\"email\" autocomplete=\"email\" placeholder=\"you@example.com\" required=\"\">",
"target": [
"#newsletter-email"
]
}
]
},
{
"id": "link-in-text-block",
"impact": "serious",
"tags": [
"cat.color",
"wcag2a",
"wcag141",
"TTv5",
"TT13.a",
"EN-301-549",
"EN-9.1.4.1"
],
"description": "Ensure links are distinguished from surrounding text in a way that does not rely on color",
"help": "Links must be distinguishable without relying on color",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-in-text-block?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "link-in-text-block-style",
"data": null,
"relatedNodes": [
{
"html": "<div class=\"announcement\">\n New to Harborlight? We\u2019ll make your first Sunday simple and pressure-free.\n <a href=\"#visit\">Plan your visit</a>\n </div>",
"target": [
".announcement"
]
}
],
"impact": "serious",
"message": "Links can be distinguished from surrounding text by visual styling"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a href=\"#visit\">Plan your visit</a>",
"target": [
"a[href$=\"#visit\"]"
]
}
]
},
{
"id": "link-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure links have discernible text",
"help": "Links must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [
{
"id": "focusable-no-name",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element is not in tab order or has accessible text"
}
],
"impact": null,
"html": "<a class=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
"target": [
".skip-link"
]
}
]
},
{
"id": "list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that lists are structured correctly",
"help": "<ul> and <ol> must only directly contain <li>, <script> or <template> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/list?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "only-listitems",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List element only has direct children that are allowed inside <li> elements"
}
],
"impact": null,
"html": "<ul>",
"target": [
"#primary-nav > ul"
]
}
]
},
{
"id": "listitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <li> elements are used semantically",
"help": "<li> elements must be contained in a <ul> or <ol>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/listitem?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "listitem",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List item has a <ul>, <ol> or role=\"list\" parent element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<li><a href=\"#services\">Services</a></li>",
"target": [
"#primary-nav > ul > li:nth-child(1)"
]
}
]
},
{
"id": "meta-viewport",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag2aa",
"wcag144",
"EN-301-549",
"EN-9.1.4.4",
"ACT"
],
"description": "Ensure <meta name=\"viewport\"> does not disable text scaling and zooming",
"help": "Zooming and scaling must not be disabled",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-viewport?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "meta-viewport",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "<meta> tag does not disable zooming on mobile devices"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
"target": [
"meta[name=\"viewport\"]"
]
}
]
},
{
"id": "nested-interactive",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies",
"help": "Interactive controls must not be nested",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/nested-interactive?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "no-focusable-content",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element does not have focusable descendants"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<img class=\"brand-logo\" src=\"https://placehold.co/96x96/19372e/f7f3ea?text=HL&font=montserrat\" width=\"49\" height=\"49\" alt=\"Harborlight Community Church logo\">",
"target": [
".header-inner > .brand[href$=\"#top\"] > .brand-logo[width=\"49\"][height=\"49\"]"
]
}
]
},
{
"id": "summary-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure summary elements have discernible text",
"help": "Summary elements must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/summary-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<summary>Learn More: sermon notes & discussion questions</summary>",
"target": [
".sermon-notes > summary"
]
}
]
},
{
"id": "target-size",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag22aa",
"wcag258"
],
"description": "Ensure touch targets have sufficient size and space",
"help": "All touch targets must be 24px large, or leave sufficient space",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/target-size?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "target-size",
"data": {
"minSize": 24,
"width": 198.8,
"height": 51.2
},
"relatedNodes": [],
"impact": "serious",
"message": "Control has sufficient size (198.8px by 51.2px, should be at least 24px by 24px)"
},
{
"id": "target-offset",
"data": {
"closestOffset": 24,
"minOffset": 24
},
"relatedNodes": [],
"impact": "serious",
"message": "Target has sufficient space from its closest neighbors. Safe clickable space has a diameter of 24px which is at least 24px."
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
"target": [
".skip-link"
]
}
]
}
],
"incomplete": [
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": {
"role": null,
"nodeName": "div",
"messageKey": "noRoleSingular",
"prohibited": [
"aria-label"
]
},
"relatedNodes": [],
"impact": "serious",
"message": "aria-label attribute is not well supported on a div with no valid role attribute."
}
],
"impact": "serious",
"html": "<div class=\"social-links\" aria-label=\"Social media links\">",
"target": [
".social-links"
],
"failureSummary": "Fix all of the following:\n aria-label attribute is not well supported on a div with no valid role attribute."
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": null,
"bgColor": null,
"contrastRatio": 0,
"fontSize": "8.8pt (11.68px)",
"fontWeight": "bold",
"messageKey": "bgGradient",
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<section class=\"hero\" aria-labelledby=\"hero-title\">",
"target": [
".hero"
]
}
],
"impact": "serious",
"message": "Element's background color could not be determined due to a background gradient"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div class=\"eyebrow\">A Christ-centered community in Portland</div>",
"target": [
".hero-copy > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element's background color could not be determined due to a background gradient"
}
]
},
{
"id": "link-in-text-block",
"impact": "serious",
"tags": [
"cat.color",
"wcag2a",
"wcag141",
"TTv5",
"TT13.a",
"EN-301-549",
"EN-9.1.4.1"
],
"description": "Ensure links are distinguished from surrounding text in a way that does not rely on color",
"help": "Links must be distinguishable without relying on color",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-in-text-block?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "link-in-text-block",
"data": {
"messageKey": "bgOverlap"
},
"relatedNodes": [
{
"html": "<div class=\"footer-brand\">",
"target": [
".footer-brand"
]
}
],
"impact": "serious",
"message": "Element's contrast ratio could not be determined because of element overlap"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<a class=\"brand\" href=\"#top\">",
"target": [
".footer-brand > .brand[href$=\"#top\"]"
],
"failureSummary": "Fix any of the following:\n Element's contrast ratio could not be determined because of element overlap"
}
]
}
],
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#a9563d",
"bgColor": "#ebe3d3",
"contrastRatio": 4.02,
"fontSize": "8.8pt (11.68px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<section class=\"section events-section\" id=\"events\" aria-labelledby=\"events-title\">",
"target": [
"#events"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.02 (foreground color: #a9563d, background color: #ebe3d3, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div class=\"eyebrow\">Upcoming Events</div>",
"target": [
"#events > .container > .split-heading > .section-heading > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.02 (foreground color: #a9563d, background color: #ebe3d3, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#647069",
"bgColor": "#ebe3d3",
"contrastRatio": 4.05,
"fontSize": "10.9pt (14.56px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<section class=\"section events-section\" id=\"events\" aria-labelledby=\"events-title\">",
"target": [
"#events"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.05 (foreground color: #647069, background color: #ebe3d3, font size: 10.9pt (14.56px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p>\n Start with a meal, serve alongside a neighbor, or join a conversation where no question is off-limits. Most events are free, and guests are always welcome.\n </p>",
"target": [
"#events > .container > .split-heading > p"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.05 (foreground color: #647069, background color: #ebe3d3, font size: 10.9pt (14.56px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#a9563d",
"bgColor": "#dbe3da",
"contrastRatio": 3.91,
"fontSize": "8.8pt (11.68px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<section class=\"section devotional-section\" id=\"resources\" aria-labelledby=\"devotional-section-title\">",
"target": [
"#resources"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.91 (foreground color: #a9563d, background color: #dbe3da, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div class=\"eyebrow centered\">Weekly Devotional Calendar</div>",
"target": [
".centered"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.91 (foreground color: #a9563d, background color: #dbe3da, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#74897a",
"bgColor": "#fffdf8",
"contrastRatio": 3.68,
"fontSize": "12.6pt (16.8px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"devotional-shell\">",
"target": [
".devotional-shell"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.68 (foreground color: #74897a, background color: #fffdf8, font size: 12.6pt (16.8px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"devotional-scripture\" id=\"devotional-scripture\">\u201cCome to me, all you that are weary and are carrying heavy burdens, and I will give you rest.\u201d</p>",
"target": [
"#devotional-scripture"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.68 (foreground color: #74897a, background color: #fffdf8, font size: 12.6pt (16.8px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#f1dfba",
"bgColor": "#a9563d",
"contrastRatio": 3.91,
"fontSize": "8.8pt (11.68px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"visit-banner\">",
"target": [
".visit-banner"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.91 (foreground color: #f1dfba, background color: #a9563d, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div class=\"eyebrow light\">Your Seat Is Waiting</div>",
"target": [
".visit-copy > .light.eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.91 (foreground color: #f1dfba, background color: #a9563d, font size: 8.8pt (11.68px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#f0e1dc",
"bgColor": "#a9563d",
"contrastRatio": 4.04,
"fontSize": "12.0pt (16px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"visit-banner\">",
"target": [
".visit-banner"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p>\n Tell us when you hope to come and anything that would make your visit easier. A member of our welcome team will meet you at the door, help your family get settled, and give you plenty of space to simply be our guest.\n </p>",
"target": [
".visit-copy > p"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#f0e1dc",
"bgColor": "#a9563d",
"contrastRatio": 4.04,
"fontSize": "10.0pt (13.28px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"visit-banner\">",
"target": [
".visit-banner"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div><strong>1280 Harbor Way</strong>Portland, OR 97209</div>",
"target": [
".visit-details > ul > li:nth-child(1) > div"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#f0e1dc",
"bgColor": "#a9563d",
"contrastRatio": 4.04,
"fontSize": "10.0pt (13.28px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"visit-banner\">",
"target": [
".visit-banner"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div><strong>Sundays at 9:00 & 11:00 AM</strong>Arrive 15 minutes early for children\u2019s check-in.</div>",
"target": [
".visit-details > ul > li:nth-child(2) > div"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#f0e1dc",
"bgColor": "#a9563d",
"contrastRatio": 4.04,
"fontSize": "10.0pt (13.28px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"visit-banner\">",
"target": [
".visit-banner"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<div><strong>Accessible and family-friendly</strong>Step-free entry, hearing assistance, and all-gender restrooms.</div>",
"target": [
".visit-details > ul > li:nth-child(3) > div"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.04 (foreground color: #f0e1dc, background color: #a9563d, font size: 10.0pt (13.28px), font weight: normal). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#647069",
"bgColor": "#eae8df",
"contrastRatio": 4.2,
"fontSize": "7.3pt (9.76px)",
"fontWeight": "normal",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<header class=\"site-header\" id=\"site-header\">",
"target": [
"#site-header"
]
},
{
"html": "<div class=\"day-navigation\">",
"target": [
".day-navigation"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.2 (foreground color: #647069, background color: #eae8df, font size: 7.3pt (9.76px), font weight: normal). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<span class=\"brand-tagline\">Rooted in grace. Making room for everyone.</span>",
"target": [
".header-inner > .brand[href$=\"#top\"] > span > .brand-tagline"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.2 (foreground color: #647069, background color: #eae8df, font size: 7.3pt (9.76px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
],
"coverage": {
"contract": "main-document-vertical-scroll",
"complete": true,
"positions": [
{
"y": 0,
"height": 10855
},
{
"y": 576,
"height": 10855
},
{
"y": 1152,
"height": 10855
},
{
"y": 1728,
"height": 12158
},
{
"y": 2304,
"height": 12158
},
{
"y": 2880,
"height": 12158
},
{
"y": 3456,
"height": 12158
},
{
"y": 4032,
"height": 12158
},
{
"y": 4608,
"height": 12158
},
{
"y": 5184,
"height": 12158
},
{
"y": 5760,
"height": 12158
},
{
"y": 6336,
"height": 12158
},
{
"y": 6912,
"height": 12158
},
{
"y": 7488,
"height": 12158
},
{
"y": 8064,
"height": 12158
},
{
"y": 8640,
"height": 12158
},
{
"y": 9216,
"height": 12158
},
{
"y": 9792,
"height": 12158
},
{
"y": 10368,
"height": 12158
},
{
"y": 10944,
"height": 12158
},
{
"y": 11438,
"height": 12158
}
],
"scans": 22,
"max_states": 512,
"settle_ms": 5000,
"page_timeout_seconds": 150,
"layout_stability": "consecutive 100ms size samples within one CSS pixel",
"animation_settling": "finite animations present when scroll resources are ready finish or are cancelled",
"interactive_states": "not exercised",
"horizontal_scroll": "not exercised"
}
}
System Prompt
You are a lead web developer at a top digital agency, tasked with creating a one-page website for a new client based on the given specifications, delivered as an HTML file. First non-whitespace char '<', last non-whitespace char '>'. Use the following services to generate placeholder images where needed:
- placehold.co (text): https://placehold.co/[{w}x{h}|{size}][/{bg-color}/{text-color}]?text={text}&font=[lato|lora|montserrat|noto sans|open sans|oswald|playfair display|poppins|pt sans|raleway|roboto|source sans|source sans pro]
- picsum.photos (photos): https://picsum.photos/[{w}/{h}|{size}]?[grayscale][&blur={1-10}]
- pravatar.cc (avatars): https://i.pravatar.cc/{size}?u={identifier}
Choose sizes appropriate to layout.
User Prompt
Create a **complete, polished, production-quality** primary web page for a new client in the "Religion and Spirituality" sector.
Your goal is to generate the full HTML code for a page that is not just functional but also visually compelling, content-rich, and feels like a finished product ready for launch.
**Client & Category:**
- Industry: "Religion and Spirituality"
- Description: Religious organizations, spiritual resources, faith communities, and worship services.
**Your Creative Task:**
1. **Invent:** Create a unique, professional-sounding site name and a strong tagline fitting the "Religion and Spirituality" category.
2. **Define Page:** Determine the most effective primary page type (e.g., homepage, service landing page, category portal) to showcase this fictional entity.
3. **Design:** Develop an opinionated, modern, and professional layout. Make distinct choices about structure and flow.
**Content & Structure Requirements (Deliver a COMPLETE page):**
- **Overall:** The final page must feel substantial and complete, with realistic amounts of text (multiple paragraphs per section where appropriate, avoid single sentences), well-integrated placeholder images, and logical flow. It should look like a real website a business would proudly use.
- **HEADER:** Include the invented site name, tagline, a logo placeholder image, and a primary navigation bar. Ensure the navigation has **at least 5-7 clearly defined, relevant links** including: "Events", "Services", "Community".
- **MAIN CONTENT:** Structure this area with **at least 3-4 distinct, well-developed sections**.
- Address key topics relevant to the "Religion and Spirituality" category. Consider themes similar to: "Service Times", "Community Support", "Faith Formation".
- **Content Depth:** Populate each section with **substantial, realistic text** (multiple sentences/paragraphs). Use authentic industry language and terminology like: "sermon", "faith formation", "scripture".
- **Visuals:** Integrate relevant placeholder images logically within the content sections.
- **Calls to Action:** Include clear and contextually relevant CTAs. Use strong verbs similar to: "Connect", "Learn More", "Attend Event".
- **ENGAGEMENT (Recommended):** Strongly consider incorporating **one meaningful interactive element** that would genuinely benefit a user in the "Religion and Spirituality" sector. Ideas similar but not limited to: "devotional calendar".
- **SIDEBAR (Optional):** If your design includes a sidebar, populate it with **useful, relevant content**. Ideas: "ministry updates", "weekly announcements", "inspirational messages".
- **FOOTER:** Include a professional footer with invented contact details, copyright (current year), social media links, and standard links (Privacy, Terms).
- **MODERN WEB PATTERNS:** Include modern web patterns like testimonial cards, feature grids, or FAQ accordions where appropriate.