/* Earthen — theme utilities injected via CSSManifest.InputCSSAppend. */ /* All colour values reference the 19-token HSL custom properties so they */ /* shift with the active preset (mossbed, clay-field, wet-loam). */ /* Paper grain backdrop — a single inline SVG noise pattern keeps page weight inside the marketplace gate (≤ 81920 bytes). */ .bg-paper-grain { background-color: hsl(var(--background)); background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27160%27%20height%3D%27160%27%20viewBox%3D%270%200%20160%20160%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.9%27%20numOctaves%3D%272%27%20seed%3D%274%27%2F%3E%3CfeColorMatrix%20values%3D%270%200%200%200%200.36%200%200%200%200%200.32%200%200%200%200%200.24%200%200%200%200.05%200%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27160%27%20height%3D%27160%27%20filter%3D%27url%28%23n%29%27%2F%3E%3C%2Fsvg%3E"); background-repeat: repeat; background-size: 240px 240px; } /* Botanical hairline divider — used inside .botanical-rule sections. */ .botanical-rule > span { display: inline-block; } /* Hand-drawn crayon underline on h2 — uses currentColor and primary token. */ .crayon-underline { position: relative; padding-bottom: 0.35em; } .crayon-underline::after { content: ""; position: absolute; left: 0; right: auto; bottom: 0; height: 6px; width: 2.5em; background-color: hsl(var(--accent) / 0.4); border-radius: 4px 8px 6px 12px; transform: skewY(-1deg); } /* Botanical drop cap — applied to the first paragraph of .drop-cap-host. */ .drop-cap-host > p:first-of-type::first-letter, .drop-cap > p:first-of-type::first-letter, .drop-cap::first-letter { font-family: var(--font-heading, "Fraunces", "Playfair Display", Georgia, serif); color: hsl(var(--primary)); float: left; font-size: 3.4em; line-height: 0.85; margin: 0.15em 0.18em 0 0; font-weight: 600; } /* Tile selection (donation CTA) — uses primary ring when checked. */ .earthen-tile input[type="radio"]:checked + span { color: hsl(var(--primary)); } .earthen-tile:has(input[type="radio"]:checked) { box-shadow: 0 0 0 2px hsl(var(--primary)); } /* Partner logos — grayscale at rest, full colour on hover. */ .earthen-partner-img, .earthen-partner-fallback { filter: grayscale(1); opacity: 0.85; transition: filter 200ms ease, opacity 200ms ease; } .earthen-partner-tile:hover .earthen-partner-img, .earthen-partner-link:hover .earthen-partner-img, .earthen-partner-link:focus-visible .earthen-partner-img, .earthen-partner-tile:hover .earthen-partner-fallback, .earthen-partner-link:hover .earthen-partner-fallback { filter: grayscale(0); opacity: 1; } /* Paper-grain frame around field-note imagery. */ .earthen-paper-frame { box-shadow: inset 0 0 0 1px hsl(var(--border) / 0.6); } .earthen-paper-frame-inner { box-shadow: 0 1px 2px hsl(var(--foreground) / 0.06); } /* Footer links — botanical underline on hover. */ .earthen-footer-link { text-decoration: none; border-bottom: 1px solid transparent; transition: color 150ms ease, border-color 150ms ease; } .earthen-footer-link:hover, .earthen-footer-link:focus-visible { color: hsl(var(--primary-foreground)); border-bottom-color: hsl(var(--accent)); } /* Buttons — focus ring follows the active preset. */ .earthen-button:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; } /* Article aside — keeps the byline rail comfortable on mobile. */ .earthen-aside { color: hsl(var(--muted-foreground)); } /* Ensure article main column uses the Work Sans body fallback. */ .earthen-article { font-family: var(--font-body, "Work Sans", ui-sans-serif, system-ui, sans-serif); color: hsl(var(--foreground)); } /* Divider glyph — softer stroke at rest. */ .earthen-glyph { color: hsl(var(--primary)); } /* Organic blob — soft asymmetric corners for cards, media frames and hero art. The signature earthen shape: hand-crafted, never a hard rectangle. */ .earthen-blob { border-radius: 42% 58% 62% 38% / 42% 44% 56% 58%; } .earthen-blob-soft { border-radius: 1.75rem 2.25rem 1.75rem 2.25rem; } /* Soft card / panel frame — cream surface with a hairline botanical border. */ .earthen-panel { background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); border: 1px solid hsl(var(--border)); box-shadow: inset 0 0 0 1px hsl(var(--border) / 0.35); } /* Terracotta seedling button — the primary call to action across the theme. */ .earthen-cta { background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); border-radius: 0.75rem; transition: box-shadow 200ms ease, transform 120ms ease; } .earthen-cta:hover, .earthen-cta:focus-visible { box-shadow: 0 6px 0 -2px hsl(var(--accent) / 0.35); transform: translateY(-1px); } .earthen-cta:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; } /* Sage link — dotted botanical underline that fills on hover. */ .earthen-link { color: hsl(var(--primary)); text-decoration: none; border-bottom: 1px dotted hsl(var(--primary) / 0.6); transition: color 150ms ease, border-color 150ms ease; } .earthen-link:hover, .earthen-link:focus-visible { color: hsl(var(--accent)); border-bottom-color: hsl(var(--accent)); } /* Leaf line-draw — a hairline that draws in on scroll where motion is allowed. */ @media (prefers-reduced-motion: no-preference) { .earthen-draw { stroke-dasharray: 240; stroke-dashoffset: 240; animation: earthen-draw-in 1.4s ease forwards; } @keyframes earthen-draw-in { to { stroke-dashoffset: 0; } } .earthen-blob-morph { animation: earthen-blob-morph 18s ease-in-out infinite; } @keyframes earthen-blob-morph { 0%, 100% { border-radius: 42% 58% 62% 38% / 42% 44% 56% 58%; } 50% { border-radius: 58% 42% 38% 62% / 56% 58% 42% 44%; } } } /* ── Responsive layout primitives ────────────────────────────────────────── These are shipped as compiled CSS (not Tailwind utilities) on purpose: the host Tailwind JIT does not scan a theme's page/layout, override or master-page templates, so responsive grid utilities that live only in those files (e.g. sm:grid-cols-3, md:grid-cols-[2fr_1fr]) are silently dropped and never collapse or expand. Compiling them here guarantees the layout works on both mobile and desktop. Layout-only — no colour tokens. */ /* Donation CTA — preset amount tiles: 1-up on mobile, 3-up from 640px. */ .earthen-amount-grid { display: grid; grid-template-columns: 1fr; gap: 0.75rem; } @media (min-width: 640px) { .earthen-amount-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } /* Donation CTA — custom amount + submit: stack on mobile, inline from 640px. */ .earthen-amount-row { display: flex; flex-direction: column; gap: 0.75rem; align-items: stretch; } @media (min-width: 640px) { .earthen-amount-row { flex-direction: row; align-items: center; } } /* Field Journal — post cards: 1-up mobile, 2-up >=640px, 3-up >=1024px. */ .earthen-post-grid { display: grid; grid-template-columns: 1fr; gap: 2rem; } @media (min-width: 640px) { .earthen-post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { .earthen-post-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } /* Contact — form + aside: stacked on mobile, 2fr/1fr from 768px. */ .earthen-contact-grid { display: grid; grid-template-columns: 1fr; gap: 3rem; } @media (min-width: 768px) { .earthen-contact-grid { grid-template-columns: 2fr 1fr; } } /* Article — body + byline rail: stacked on mobile, main + 260px rail >=1024px. */ .earthen-article-grid { display: grid; grid-template-columns: 1fr; gap: 3rem; } @media (min-width: 1024px) { .earthen-article-grid { grid-template-columns: minmax(0, 1fr) 260px; } } /* Hero — comfortable padded band. A text-only (image-less) hero uses padding only, so it never balloons into a tall empty band. When a background image IS present the taller band is applied via the --media modifier. */ .earthen-hero { padding-top: 4rem; padding-bottom: 4rem; } @media (min-width: 768px) { .earthen-hero { padding-top: 6rem; padding-bottom: 6rem; } } .earthen-hero.earthen-hero--media { min-height: 60vh; padding-top: 3rem; padding-bottom: 3rem; } @media (min-width: 768px) { .earthen-hero.earthen-hero--media { min-height: 72vh; } } /* Split hero — the media column needs a floor so its absolutely-positioned image has height to fill. Only rendered when an image is present. */ .earthen-hero-split-media { position: relative; min-height: 320px; }