Ship base Jinja layout (header/nav/main/footer with skip link and aria-current), mobile-first single-file CSS using the ROADMAP palette tokens, and four public routes: /, /about, /contact, /shop. Blog index renders via a stable PostService.list_published() stub returning [] — Phase 2 only swaps the body. About is static placeholder copy, /contact ships an inert form plus a mailto: link driven by ADMIN_CONTACT_EMAIL, /shop shows a "Coming soon" card. Adds a Pillow-based scripts/generate_static_assets.py producing resized logo PNG + WebP, multi-size favicon.ico, and a 180x180 apple-touch-icon on a cream background. Outputs committed for a reproducible build. Also ship docs/MANUAL_TESTING.md with per-route / responsive / a11y / static- asset checklists, and mark Phase 1 complete in docs/ROADMAP.md.
497 lines
9.2 KiB
CSS
497 lines
9.2 KiB
CSS
/* -------------------------------------------------------------------------
|
|
* Chicken Babies R Us — site.css
|
|
*
|
|
* Single stylesheet for the public brochure site. Mobile-first; one
|
|
* breakpoint at 48rem (~768px) for tablet and up. Self-hosted only; no
|
|
* external font imports or third-party CSS.
|
|
*
|
|
* Table of contents
|
|
* 1. Reset
|
|
* 2. Design tokens (:root custom properties from ROADMAP palette)
|
|
* 3. Base typography + body
|
|
* 4. Layout primitives (.wrap, header, nav, main, footer)
|
|
* 5. Components (.post-card, .shop-card, .contact-form, .btn, skip-link)
|
|
* 6. Responsive (48rem breakpoint)
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
|
/* 1. Reset ---------------------------------------------------------------- */
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body,
|
|
h1, h2, h3, h4, h5, h6,
|
|
p,
|
|
figure,
|
|
blockquote,
|
|
dl,
|
|
dd {
|
|
margin: 0;
|
|
}
|
|
|
|
body {
|
|
line-height: 1.5;
|
|
min-height: 100vh;
|
|
text-rendering: optimizeSpeed;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
img,
|
|
picture {
|
|
max-width: 100%;
|
|
display: block;
|
|
}
|
|
|
|
button,
|
|
input,
|
|
textarea,
|
|
select {
|
|
font: inherit;
|
|
color: inherit;
|
|
}
|
|
|
|
|
|
/* 2. Design tokens -------------------------------------------------------- */
|
|
:root {
|
|
/* Palette (authoritative values from docs/ROADMAP.md Visual Design). */
|
|
--c-sky: #A9CCE3;
|
|
--c-sky-deep: #5D8AA8;
|
|
--c-cream: #FAF3E7;
|
|
--c-wheat: #E4D4A8;
|
|
--c-ink: #2B3A42;
|
|
--c-leaf: #7FA66B;
|
|
|
|
/* Type stacks: system fonts only so we never hit a third-party CDN. */
|
|
--font-serif: Georgia, "Times New Roman", serif;
|
|
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
|
|
/* Spacing scale (rem-based; base = 1rem = 16px). */
|
|
--space-1: 0.25rem;
|
|
--space-2: 0.5rem;
|
|
--space-3: 1rem;
|
|
--space-4: 1.5rem;
|
|
--space-5: 2.5rem;
|
|
--space-6: 4rem;
|
|
|
|
--radius: 0.5rem;
|
|
--max-width: 68rem;
|
|
}
|
|
|
|
|
|
/* 3. Base typography + body ---------------------------------------------- */
|
|
body {
|
|
font-family: var(--font-sans);
|
|
background-color: var(--c-cream);
|
|
color: var(--c-ink);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
h1, h2, h3, h4, h5, h6 {
|
|
font-family: var(--font-serif);
|
|
color: var(--c-ink);
|
|
line-height: 1.2;
|
|
}
|
|
|
|
h1 { font-size: 2rem; }
|
|
h2 { font-size: 1.5rem; }
|
|
h3 { font-size: 1.25rem; }
|
|
|
|
p {
|
|
margin-block: var(--space-3);
|
|
}
|
|
|
|
a {
|
|
color: var(--c-sky-deep);
|
|
text-decoration: underline;
|
|
text-underline-offset: 2px;
|
|
}
|
|
|
|
a:hover,
|
|
a:focus-visible {
|
|
color: var(--c-ink);
|
|
}
|
|
|
|
/* Utility: visually hide but keep available to assistive tech. */
|
|
.visually-hidden {
|
|
position: absolute !important;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip: rect(0 0 0 0);
|
|
white-space: nowrap;
|
|
border: 0;
|
|
}
|
|
|
|
|
|
/* 4. Layout primitives ---------------------------------------------------- */
|
|
.wrap {
|
|
width: 100%;
|
|
max-width: var(--max-width);
|
|
margin-inline: auto;
|
|
padding-inline: var(--space-3);
|
|
}
|
|
|
|
/* Skip link — hidden offscreen until focused by keyboard. */
|
|
.skip-link {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
padding: var(--space-2) var(--space-3);
|
|
background-color: var(--c-ink);
|
|
color: var(--c-cream);
|
|
text-decoration: none;
|
|
transform: translateY(-120%);
|
|
transition: transform 0.15s ease-out;
|
|
z-index: 100;
|
|
}
|
|
|
|
.skip-link:focus {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* Header / brand / nav ---------------------------------------------------- */
|
|
.site-header {
|
|
background-color: var(--c-sky);
|
|
border-bottom: 1px solid rgba(43, 58, 66, 0.1);
|
|
}
|
|
|
|
.site-header__wrap {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
padding-block: var(--space-3);
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.site-header__brand {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.site-header__logo {
|
|
height: 48px;
|
|
width: auto;
|
|
}
|
|
|
|
/* Mobile nav toggle (shown < 48rem, hidden ≥ 48rem). */
|
|
.site-nav__toggle {
|
|
appearance: none;
|
|
background: transparent;
|
|
border: 1px solid var(--c-ink);
|
|
border-radius: var(--radius);
|
|
padding: var(--space-2);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
gap: 4px;
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
}
|
|
|
|
.site-nav__toggle-bar {
|
|
display: block;
|
|
height: 2px;
|
|
width: 100%;
|
|
background-color: var(--c-ink);
|
|
border-radius: 2px;
|
|
}
|
|
|
|
/* Collapsed by default on narrow viewports. */
|
|
.site-nav {
|
|
flex-basis: 100%;
|
|
display: none;
|
|
}
|
|
|
|
.site-nav.is-open {
|
|
display: block;
|
|
}
|
|
|
|
.site-nav__list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
padding-block: var(--space-2);
|
|
}
|
|
|
|
.site-nav__link {
|
|
display: block;
|
|
padding: var(--space-2) var(--space-3);
|
|
border-radius: var(--radius);
|
|
text-decoration: none;
|
|
color: var(--c-ink);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.site-nav__link:hover,
|
|
.site-nav__link:focus-visible {
|
|
background-color: rgba(255, 255, 255, 0.35);
|
|
color: var(--c-ink);
|
|
}
|
|
|
|
.site-nav__link.is-active {
|
|
background-color: var(--c-cream);
|
|
color: var(--c-sky-deep);
|
|
}
|
|
|
|
/* Muted link for not-yet-live destinations (Shop in Phase 1). */
|
|
.site-nav__link.nav--muted {
|
|
opacity: 0.65;
|
|
}
|
|
|
|
/* Main + footer ----------------------------------------------------------- */
|
|
.site-main {
|
|
flex: 1 0 auto;
|
|
padding-block: var(--space-5);
|
|
}
|
|
|
|
/* Remove default focus ring on <main> when focused via the skip link. */
|
|
.site-main:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.site-footer {
|
|
background-color: var(--c-ink);
|
|
color: var(--c-cream);
|
|
padding-block: var(--space-4);
|
|
margin-top: var(--space-6);
|
|
}
|
|
|
|
.site-footer a {
|
|
color: var(--c-sky);
|
|
}
|
|
|
|
.site-footer__tag {
|
|
margin: 0;
|
|
font-family: var(--font-serif);
|
|
}
|
|
|
|
.site-footer__legal {
|
|
margin-top: var(--space-2);
|
|
font-size: 0.875rem;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
|
|
/* 5. Components ---------------------------------------------------------- */
|
|
|
|
/* Page intro block on home. */
|
|
.page-intro {
|
|
margin-bottom: var(--space-5);
|
|
}
|
|
|
|
.page-intro__title {
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.page-intro__lede {
|
|
font-size: 1.125rem;
|
|
color: var(--c-ink);
|
|
max-width: 48rem;
|
|
}
|
|
|
|
/* Generic article wrapper for About, Contact, Shop. */
|
|
.page-article {
|
|
max-width: 48rem;
|
|
}
|
|
|
|
.page-article__header {
|
|
margin-bottom: var(--space-4);
|
|
}
|
|
|
|
.page-article__title {
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
/* Post list + card. */
|
|
.post-list {
|
|
display: grid;
|
|
gap: var(--space-4);
|
|
}
|
|
|
|
.post-list__empty {
|
|
padding: var(--space-4);
|
|
background-color: var(--c-wheat);
|
|
border-radius: var(--radius);
|
|
text-align: center;
|
|
font-style: italic;
|
|
}
|
|
|
|
.post-card {
|
|
background-color: #ffffff;
|
|
border: 1px solid var(--c-wheat);
|
|
border-radius: var(--radius);
|
|
padding: var(--space-4);
|
|
box-shadow: 0 1px 2px rgba(43, 58, 66, 0.06);
|
|
}
|
|
|
|
.post-card__header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-1);
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.post-card__title {
|
|
margin: 0;
|
|
}
|
|
|
|
.post-card__title a {
|
|
color: var(--c-ink);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.post-card__title a:hover,
|
|
.post-card__title a:focus-visible {
|
|
color: var(--c-sky-deep);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.post-card__date {
|
|
font-size: 0.875rem;
|
|
color: var(--c-sky-deep);
|
|
font-family: var(--font-sans);
|
|
}
|
|
|
|
.post-card__excerpt {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Shop "coming soon" card. */
|
|
.shop-card {
|
|
background-color: var(--c-wheat);
|
|
border-radius: var(--radius);
|
|
padding: var(--space-4);
|
|
}
|
|
|
|
.shop-card__title {
|
|
margin-bottom: var(--space-2);
|
|
color: var(--c-ink);
|
|
}
|
|
|
|
.shop-card__body {
|
|
margin-block: var(--space-2);
|
|
}
|
|
|
|
/* Contact form (inert in Phase 1). */
|
|
.contact-mailto {
|
|
background-color: var(--c-sky);
|
|
border-radius: var(--radius);
|
|
padding: var(--space-3);
|
|
}
|
|
|
|
.contact-mailto--muted {
|
|
background-color: var(--c-wheat);
|
|
font-style: italic;
|
|
}
|
|
|
|
.contact-form {
|
|
display: grid;
|
|
gap: var(--space-3);
|
|
max-width: 32rem;
|
|
margin-top: var(--space-3);
|
|
}
|
|
|
|
.contact-form__note {
|
|
margin-top: var(--space-3);
|
|
font-style: italic;
|
|
color: var(--c-sky-deep);
|
|
}
|
|
|
|
.contact-form__field {
|
|
display: grid;
|
|
gap: var(--space-1);
|
|
}
|
|
|
|
.contact-form__field label {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.contact-form__field input,
|
|
.contact-form__field textarea {
|
|
padding: var(--space-2);
|
|
border: 1px solid var(--c-wheat);
|
|
border-radius: var(--radius);
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
.contact-form__field input:disabled,
|
|
.contact-form__field textarea:disabled {
|
|
background-color: #f5f1e6;
|
|
color: #7a7a7a;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.contact-form__actions {
|
|
margin-top: var(--space-2);
|
|
}
|
|
|
|
/* Generic button. */
|
|
.btn {
|
|
display: inline-block;
|
|
padding: var(--space-2) var(--space-4);
|
|
border-radius: var(--radius);
|
|
border: 1px solid transparent;
|
|
font-weight: 600;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.btn--primary {
|
|
background-color: var(--c-sky-deep);
|
|
color: var(--c-cream);
|
|
}
|
|
|
|
.btn--primary:hover,
|
|
.btn--primary:focus-visible {
|
|
background-color: var(--c-ink);
|
|
}
|
|
|
|
.btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
|
|
/* 6. Responsive — tablet & up ------------------------------------------- */
|
|
@media (min-width: 48rem) {
|
|
h1 { font-size: 2.5rem; }
|
|
h2 { font-size: 1.75rem; }
|
|
|
|
.site-header__wrap {
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
/* Hide the mobile toggle; show the nav inline. */
|
|
.site-nav__toggle {
|
|
display: none;
|
|
}
|
|
|
|
.site-nav {
|
|
display: block;
|
|
flex-basis: auto;
|
|
}
|
|
|
|
.site-nav__list {
|
|
flex-direction: row;
|
|
gap: var(--space-3);
|
|
padding-block: 0;
|
|
}
|
|
|
|
.post-list {
|
|
gap: var(--space-5);
|
|
}
|
|
}
|