, which is why the UI half lives in panel.ts at the "page" stage.
A11Y_CSS is effects.css, passed in as a string argument by the integration.
========================================================================== */
try {
var W = window;
var D = document;
var H = D.documentElement;
/* Bail. /admin and /login are operator-only SSR surfaces that run their own
dark-mode system (src/layouts/Layout.astro), and data-a11y-disable is the
documented client escape hatch. On a bail we return WITHOUT defining
window.a11y — that absence is the single signal panel.ts keys on, so it
also covers this file having thrown. */
if (/^\/(admin|login)(\/|$)/.test(W.location.pathname)) return;
if (H.hasAttribute("data-a11y-disable")) return;
var KEY = "a11y:prefs";
var VERSION = 1;
/* Every value is a string enum, never a boolean: costs nothing today and
lets a future third state land without a storage migration.
`always:1` means the attribute is present whatever the value, so clients
test one thing (data-a11y-motion) rather than presence-or-value. */
var DEFS = [
{ k: "motion", attr: "data-a11y-motion", on: "reduce", off: "allow", os: "(prefers-reduced-motion: reduce)", always: 1 },
{ k: "links", attr: "data-a11y-links", on: "underline", off: null },
{ k: "spacing", attr: "data-a11y-spacing", on: "loose", off: null },
{ k: "font", attr: "data-a11y-font", on: "readable", off: null },
{ k: "focus", attr: "data-a11y-focus", on: "strong", off: null },
{ k: "audio", attr: "data-a11y-audio", on: "mute", off: null },
{ k: "images", attr: "data-a11y-images", on: "soft", off: null },
{ k: "align", attr: "data-a11y-align", on: "start", off: null },
{ k: "targets", attr: "data-a11y-targets", on: "outline", off: null },
{ k: "contrast", attr: "data-a11y-contrast", enums: ["standard", "high"], off: null, os: "(prefers-contrast: more)", osValue: "high" },
{ k: "scheme", attr: "data-a11y-scheme", enums: ["light", "dark"], off: null, os: "(prefers-color-scheme: dark)", osValue: "dark" }
];
/* side + min are host-only: stored here, applied by panel.ts. They get no
attribute on because nothing in client CSS should key on them. */
var HOST = { side: ["start", "end"], min: ["yes"] };
/* ---- storage -----------------------------------------------------------
localStorage throws outright in some privacy modes, so every access is
wrapped and falls back to an in-memory object: the panel still works for
the session, it just does not persist. */
var mem = null;
var memOn = false;
function rawRead() {
if (memOn) return mem;
var s;
try { s = W.localStorage.getItem(KEY); } catch (e) { memOn = true; return mem; }
if (s == null) return null;
var o;
try { o = JSON.parse(s); } catch (e) { return null; }
if (!o || typeof o !== "object") return null;
if (Object.prototype.toString.call(o) === "[object Array]") return null;
if (typeof o.v !== "number") return null;
return o;
}
function rawWrite(o) {
if (!memOn) {
try { W.localStorage.setItem(KEY, JSON.stringify(o)); return; } catch (e) { memOn = true; }
}
mem = o;
}
/* Effective preferences. A future version is IGNORED but never deleted, so
rolling the build back loses nothing. A past version would migrate here. */
function prefs() {
var o = rawRead();
if (!o) return {};
if (o.v > VERSION) return {};
return o;
}
/* ---- resolution --------------------------------------------------------
explicit stored value > OS media query > built-in default
Never write a value just because the OS said so. Persisting a detected
value makes "unset" indistinguishable from "chosen" and the site stops
tracking the OS forever — the bug that silently kills OS-following. */
function mq(q) {
try { return W.matchMedia(q); } catch (e) { return null; }
}
function mqOn(q) {
var m = mq(q);
return !!(m && m.matches);
}
function defOf(k) {
for (var i = 0; i < DEFS.length; i++) { if (DEFS[i].k === k) return DEFS[i]; }
return null;
}
function allowed(d, v) {
var list = d.enums;
if (list) {
for (var i = 0; i < list.length; i++) { if (list[i] === v) return true; }
return false;
}
return v === d.on || v === d.off;
}
function hostAllowed(k, v) {
var list = HOST[k];
if (!list) return false;
for (var i = 0; i < list.length; i++) { if (list[i] === v) return true; }
return false;
}
function resolved(k) {
var p = prefs();
var v = p[k];
var d = defOf(k);
if (!d) return hostAllowed(k, v) ? v : null;
if (v != null && allowed(d, v)) return v;
if (d.os && mqOn(d.os)) return d.osValue || d.on;
return d.off;
}
function apply() {
for (var i = 0; i < DEFS.length; i++) {
var d = DEFS[i];
var v = resolved(d.k);
if (v == null) H.removeAttribute(d.attr);
else H.setAttribute(d.attr, v);
}
}
/* ---- effects sheet ----------------------------------------------------
Inserted unconditionally: predictability beats micro-optimisation, and
every selector is gated on a root attribute that fails immediately when
absent, so the universal-selector motion rules cost nothing when motion
resolves to "allow". */
function injectCss() {
if (D.getElementById("a11y-effects")) return;
var s = D.createElement("style");
s.id = "a11y-effects";
s.appendChild(D.createTextNode(A11Y_CSS));
(D.head || H).appendChild(s);
}
function fire(k) {
try {
D.dispatchEvent(new W.CustomEvent("a11y:change", {
detail: {
key: k,
value: k == null ? null : prefs()[k],
resolved: k == null ? null : resolved(k)
}
}));
} catch (e) {}
}
function set(k, v) {
if (v != null) {
var d = defOf(k);
if (d ? !allowed(d, v) : !hostAllowed(k, v)) return;
}
var stored = rawRead();
/* A stored version ahead of ours cannot be safely merged, so the first
explicit change replaces it wholesale. Acceptable: the user is actively
choosing at that moment. Otherwise read-modify-write preserves unknown
keys so a newer build's settings survive a rollback. */
var future = !!(stored && stored.v > VERSION);
var o = future || !stored ? {} : stored;
o.v = VERSION;
if (v == null) delete o[k];
else o[k] = v;
rawWrite(o);
apply();
fire(k);
}
function reset() {
if (!memOn) {
try { W.localStorage.removeItem(KEY); } catch (e) { memOn = true; }
}
mem = null;
apply();
fire(null);
}
apply();
injectCss();
var api = {
version: VERSION,
get: function (k) { return prefs()[k]; },
resolved: resolved,
set: set,
reset: reset,
motionReduced: function () { return resolved("motion") === "reduce"; }
};
/* caps is a LIVE getter and is never read pre-paint. In a production build
the client CSS is a before this script and a classic blocking
script waits on pending stylesheets, so getComputedStyle would resolve —
but under `astro dev` the CSS arrives through Vite's module graph and a
pre-paint read can return empty. That failure would be silent and
byte-identical to a client that never opted in. Nothing pre-paint needs
capabilities: the gated fieldsets live in the lazily-imported panel body. */
try {
Object.defineProperty(api, "caps", {
enumerable: true,
get: function () {
var raw = "";
try {
raw = getComputedStyle(H).getPropertyValue("--a11y-caps") || "";
} catch (e) {}
/* getPropertyValue returns the token stream verbatim, leading space and
literal quotes included, so a naive split yields ["", "\"contrast",
"dark\""] and every capability check silently fails. */
return raw.replace(/["']/g, " ").replace(/^\s+|\s+$/g, "").split(/\s+/)
.filter(function (t) { return !!t; });
}
});
} catch (e) {
api.caps = [];
}
W.a11y = api;
/* While a key is absent the OS query is authoritative and LIVE. Once the
user has chosen, an OS change must not move the site under them. */
for (var i = 0; i < DEFS.length; i++) {
(function (d) {
if (!d.os) return;
var m = mq(d.os);
if (!m) return;
var onChange = function () {
if (prefs()[d.k] != null) return;
apply();
fire(d.k);
};
if (m.addEventListener) m.addEventListener("change", onChange);
else if (m.addListener) m.addListener(onChange);
})(DEFS[i]);
}
try {
W.addEventListener("storage", function (e) {
if (e && e.key && e.key !== KEY) return;
mem = null;
memOn = false;
apply();
fire(null);
});
} catch (e) {}
} catch (e) {}
})("/* ============================================================================\n a11y effects sheet.\n\n Injected pre-paint by boot.js as the LAST node in
.\n ------------------------------------------------------------------------- */\n:root[data-a11y-spacing=\"loose\"]\n :is(main, article, footer, [role=\"main\"], [role=\"contentinfo\"], [data-a11y-prose])\n :is(p, li, dd, dt, blockquote, figcaption, summary, td, th):not(nav *, [data-a11y-exempt], [data-a11y-exempt] *) {\n line-height: 1.5 !important;\n letter-spacing: 0.12em !important;\n word-spacing: 0.16em !important;\n overflow-wrap: break-word !important;\n min-width: 0;\n}\n:root[data-a11y-spacing=\"loose\"]\n :is(main, article, footer, [role=\"main\"], [role=\"contentinfo\"], [data-a11y-prose])\n :is(p, blockquote, figcaption):not(nav *, [data-a11y-exempt], [data-a11y-exempt] *) { margin-block-end: 2em !important; }\n\n/* ---------- Readable font (prose only) -------------------------------------\n Honest scope: this switches PROSE type to the system stack. The strongest\n real win is a client's condensed display face — on 4bkstorage that is\n --f-display, a \"Google Sans Flex Cond\" family pinned to a 75% width axis,\n used for every heading inside main/footer.\n\n It deliberately does NOT touch letter-spacing (the spacing setting owns\n that) and does NOT touch text-transform: killing uppercase would render the\n brand as \"bk storage\" — misrepresentation, not accessibility. Nav micro-\n labels (.brand-l2 :397, .sheet-title :516) are out of scope by the header\n rule above; that is the price of deleting the header regression, and it is\n the right trade.\n\n `font-stretch: normal` and `font-variation-settings: normal` are NOT set,\n and must not be: a client may pin a variable font's width axis with a\n `font-stretch` DESCRIPTOR inside @font-face rather than a declaration on the\n element (4bkstorage does exactly this to get a condensed display family and a\n normal body family out of one file). A descriptor belongs to the @font-face,\n so replacing font-family drops the pinned width along with it. Resetting\n those properties here would instead fight any client that legitimately sets\n them on elements, for no gain.\n\n CONTRACT NOTE for clients: if you set `font-variation-settings` on ELEMENTS\n rather than as an @font-face descriptor, this override cannot reset it and\n the system stack may inherit meaningless axis values. Pin axes in\n @font-face.\n\n Ligatures: `none` includes `no-contextual`, which breaks Arabic and several\n Indic scripts. Narrowed to the three Latin-disambiguation families only.\n ------------------------------------------------------------------------- */\n:root[data-a11y-font=\"readable\"]\n :is(main, article, footer, [role=\"main\"], [role=\"contentinfo\"], [data-a11y-prose]),\n:root[data-a11y-font=\"readable\"]\n :is(main, article, footer, [role=\"main\"], [role=\"contentinfo\"], [data-a11y-prose])\n *:not(code, pre, kbd, samp, svg, svg *, iframe, nav, nav *, a11y-prefs, a11y-prefs *,\n [data-a11y-exempt], [data-a11y-exempt] *) {\n font-family: var(--a11y-readable-stack,\n system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif) !important;\n font-variant-ligatures: no-common-ligatures no-discretionary-ligatures\n no-historical-ligatures !important;\n}\n\n/* ---------- Strong focus ---------------------------------------------------\n White halo hugged by a black outline. Verified on 4bkstorage's palette:\n #fff is 13.69:1 on --navy #0c2e54 and 11.43:1 on --deep #0f3a6b; #000 is\n 21:1 on white. So one edge always clears SC 1.4.11's 3:1 whatever it lands\n on. GOV.UK yellow alone would not (#ffdd00 is 1.35:1 on white).\n\n !important is mandatory: .field input:focus{outline:none} (bkstorage.css\n :1489-1495) is (0,2,1) and beats :root[data-a11y-focus] :focus-visible at\n (0,2,0) — it would kill the ring on exactly the form fields where it matters\n most.\n\n NO border-radius declaration. At (0,3,0) it would outrank .btn's 11px\n (:265) and .btn-lg's var(--radius) (:275) and snap every focused button to a\n near-square on focus and back on blur. `outline` follows the element's own\n border shape in every current engine, which is the desired result for free.\n\n offset 2px + a 2px halo (5px total beyond the border box, was 7px) plus\n scroll-margin, because the ring is drawn inside the client's own clipping\n ancestors: .hero (:592), .type (:947), .cta (:1296), and body{overflow-x:\n hidden} (:134).\n ------------------------------------------------------------------------- */\n:root[data-a11y-focus=\"strong\"] :focus-visible {\n outline: 3px solid #000 !important;\n outline-offset: 2px !important;\n box-shadow: 0 0 0 2px #fff !important;\n scroll-margin: 12px;\n}\n@media (forced-colors: active) {\n :root[data-a11y-focus=\"strong\"] :focus-visible {\n outline-color: Highlight !important;\n box-shadow: none !important;\n }\n}\n\n/* ---------- Align text to one edge (prose only) ----------------------------\n Centred and justified body text makes every line start somewhere new, and\n justification opens uneven \"rivers\" between words — both hard going for\n dyslexic and low-vision readers (SC 1.4.8 asks for no justification).\n `start`, not `left`, so RTL pages align to the right edge.\n\n Body-text elements only. Headings keep their alignment: a centred hero\n heading is one short line and costs nobody anything, and pulling it to the\n edge would break the composition for no gain. No layout properties change,\n so this cannot cause overflow.\n ------------------------------------------------------------------------- */\n:root[data-a11y-align=\"start\"]\n :is(main, article, footer, [role=\"main\"], [role=\"contentinfo\"], [data-a11y-prose])\n :is(p, li, dd, dt, blockquote, figcaption, td, th):not(nav *, [data-a11y-exempt], [data-a11y-exempt] *) {\n text-align: start !important;\n text-align-last: auto !important;\n hyphens: manual !important;\n}\n\n/* ---------- Highlight links and buttons (whole page) -----------------------\n Every link and button gets a dashed outline, so what is clickable no longer\n depends on recognising a client's styling. Page-wide INCLUDING nav, unlike\n the prose effects above: outline and box-shadow take up no space, so they\n cannot reflow the header the way underline/spacing would.\n\n Same two-channel trick as Strong focus: a black dashed outline over a white\n halo, so one of them clears 3:1 whatever surface it lands on. Dashed and\n 2px (focus is solid and 3px) so the two stay distinguishable when both are\n on. :not(:focus-visible) hands the focused element back to the focus ring\n — at (0,2,1) this rule would otherwise outrank Strong focus's (0,2,0).\n\n Cost the user opts into: the halo replaces a client's own box-shadow on\n buttons while the setting is on.\n ------------------------------------------------------------------------- */\n:root[data-a11y-targets=\"outline\"]\n :is(a[href], button, [role=\"button\"], [role=\"link\"], summary,\n input:is([type=\"button\"], [type=\"submit\"], [type=\"reset\"])):not(:focus-visible, [data-a11y-exempt], [data-a11y-exempt] *) {\n outline: 2px dashed #000 !important;\n outline-offset: 2px !important;\n box-shadow: 0 0 0 2px #fff !important;\n}\n@media (forced-colors: active) {\n :root[data-a11y-targets=\"outline\"]\n :is(a[href], button, [role=\"button\"], [role=\"link\"], summary,\n input:is([type=\"button\"], [type=\"submit\"], [type=\"reset\"])):not(:focus-visible) {\n outline-color: LinkText !important;\n box-shadow: none !important;\n }\n}\n\n/* ---------- Soften image colours -------------------------------------------\n Tones down saturated photos and video for visitors who find bright,\n busy imagery overwhelming (sensory sensitivity, migraine). Applied to\n replaced elements ONLY:\n * never to html/body/a wrapper — `filter` makes a containing block for\n fixed descendants (DOCS.md rule 6) and would trap this panel's host;\n * never to a container — it would grey out brand buttons and text too.\n Honest limit, stated in the help copy: CSS background images (most hero\n photos) are not elements and are not reached. A client can opt one in by\n labelling a TEXT-FREE element [data-a11y-image]; see the labelling guide.\n\n Content containers only (main/article, not header/nav/footer), because\n those are where the logo lives and a greyed-out logo is misrepresentation,\n not comfort. A logo inside main gets [data-a11y-exempt].\n ------------------------------------------------------------------------- */\n:root[data-a11y-images=\"soft\"]\n :is(main, article, [role=\"main\"], [data-a11y-prose]) :is(img, video, canvas):not([data-a11y-exempt], [data-a11y-exempt] *),\n:root[data-a11y-images=\"soft\"] [data-a11y-image]:not([data-a11y-exempt]) {\n filter: saturate(0.35) !important;\n}\n\n/* ---------- Panel plumbing ------------------------------------------------\n No scroll lock. `:root{overflow:hidden}` was deleted: 4bkstorage's\n body{overflow-x:hidden} (:134) makes viewport-overflow propagation\n engine-dependent, and iOS Safari — the only platform where the bottom-sheet\n layout exists — ignores overflow:hidden for touch scrolling. It was\n unverifiable behaviour that changed the page under the user and contradicted\n the non-modal ruling. overscroll-behavior:contain on the sheet plus\n focusout-closes at <=40rem replaces it. Never write body.style.overflow:\n both clients' Nav.tsx reset it to \"\" unconditionally (4bkstorage :29-32,\n rockin2ind :40-43) and whichever closed last would destroy the other's lock.\n ------------------------------------------------------------------------- */\n@media print { a11y-prefs { display: none !important; } }\n"); Skip to content
Welcome to our website! We appreciate you taking a moment to stop by and look around! Here you'll be able to learn more about our staff, our beliefs, what ministries we offer for you and your family, service times and location, what's coming up and so much more.
We hope that you will find our website easy to navigate, and equipped with all the info you're looking for! Whether you're new in town or looking for a new church, we appreciate you stopping by and hope to see you soon!
It’s understandable that you may have some questions about what you and your family can expect on a typical Sunday morning at Centro Cristiano Hosanna. That’s why we’ve listed some common questions and answers below. If we don’t answer your questions here, give us a call or message us. We’d love to hear from you, and we look forward to seeing you this Sunday.
When are your services?
Our Sunday service begins at 10:00 a.m. There are no Sunday evening services at this time. Our Wednesday service begins at 7:00 p.m.
Where are your services held?
The worship services are held in the main building.
How do I get to Centro Cristiano Hosanna?
We are located at 5026 Link Rd. There are two ways that you can get to Centro Cristiano Hosanna. Link Road is off the Old Christoval Road and by going underneath the Ben Ficklin Bridge off South Bryant.
Parking is available only in front of the main building. This lot also has reserved spaces for those who need handicap parking.
What is a Sunday service like?
While words cannot thoroughly describe the worship experience at Centro Cristiano Hosanna, our Praise and Worship team is committed to presenting God’s truth in compelling, creative, and challenging ways.
What should I wear when I attend Centro Cristiano Hosanna?
At Centro Cristiano Hosanna, we like to keep things comfortable for you. This means something different to everyone. We welcome you to dress as nicely as you would like, but the vast majority of those attending on Sunday mornings dress to please our Heavenly Father.
What is the music like?
At Centro Cristiano Hosanna, we understand that people have varying tastes in music, but we believe that worship is not about us, it is about God. Worship should be God-focused and we desire to make our music exactly that. Styles, songs, and musical talents change, but our God will never change. We do not define our music by styles or tempos; we simply take whatever we have to offer each Sunday and lay it at the throne of God.
Where do I take my children?
Sunday mornings we have Sunday school (ages 5-10) and Nursery (ages 0-4), where we have wonderful and talented people caring for the children in a safe and friendly environment.
Do you have anything for Middle School and High School students?
We have Youth Services on Wednesday nights at 7:00 p.m.
Do you offer adult Sunday School?
No, not at the present time. However, we do believe that adults need to engage in meaningful community with others and to have regular times of fellowship, Bible study, and prayer. We accomplish this with Bible Studies that meet on Wednesday nights at 7:00 p.m. At Centro Cristiano Hosanna, our Bible Study group exists to encourage people to get connected and grow.
How can I meet people or ask additional questions about the church?
The best way to meet people at Centro Cristiano Hosanna is to get involved in a Bible Study or Ladies Ministry Group. We understand that personal relationships are the primary glue for permanent connection to Centro Cristiano Hosanna and a relationship with God. If you have any questions, please feel free to call the church office at (325) 617-2246 or send us an email at [email protected].