WO-TF-013. Bring the coffee theme up to the frozen OVERRIDE-CONTRACT: - 49 mandatory builtin overrides in templates/overrides/coffee/ (chrome, marketing, primitives, commerce/local, blog family, auth surface, page-suggestions), each re-skinned in cafe/roastery chrome over the builtin data model. Legacy button/heading/image/text field reads updated to the new builtin contract (link/label/style, media/text). - Signature moves: chalkboard menu panel (menu-list), hand-drawn doodle dividers, torn-paper edges, kraft-tag stamped buttons, circular roast stamps, hours "today" highlight. Semantic tokens only; CSS-first motion with prefers-reduced-motion fallbacks. - 7 page templates: default, landing, article, full-width, blog-index, contact, auth. - Blocks rework: deleted the five builtin-duplicating theme blocks (menu_board, hours_strip, location_card, footer, doodle_divider) — now overrides. Kept/added 4 persona blocks: featured_pour, roast_profile, loyalty_card, brew_guide. - 5 dual-mode presets (mode "both"), all 19 tokens, light and dark tuned. - Bundled Fraunces / Work Sans / Caveat woff2 (OFL, latin subset, license recorded); fonts.json populated; all font-family via var(--font-*). Updated RECOMMENDED_FONTS.md, added RECOMMENDED_ICONS.md; required_icon_packs declared. - Themed email-safe wrapper retained (tables, inline styles). - Master pages rebuilt on builtin keys. Demo seed (demo:true): home, about, blog + 3 posts, contact (form + contact_submissions data table + row_inserted email-admins workflow), login. Cafe voice. make (codeless build + verify) and check-safety both exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
265 lines
9.7 KiB
CSS
265 lines
9.7 KiB
CSS
/* Coffee theme styles
|
|
*
|
|
* Dual-mode via the 19 shadcn-style HSL token CSS variables (--background,
|
|
* --foreground, --primary, --accent, --border, --muted, --card, ...) consumed
|
|
* as hsl(var(--token)). No literal colors. Font families resolve ONLY through
|
|
* the BlockNinja font variables (--font-heading, --font-body, --font-mono) with
|
|
* the fallback stacks below — never hardcoded, so the admin font picker works.
|
|
*/
|
|
|
|
:root {
|
|
--coffee-heading-fallback: "Fraunces", "Playfair Display", Georgia, "Times New Roman", serif;
|
|
--coffee-body-fallback: "Work Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
--coffee-hand-fallback: "Caveat", "Segoe Print", "Bradley Hand", cursive;
|
|
--coffee-mono-fallback: "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;
|
|
}
|
|
|
|
/* --- Paper grain background --------------------------------------------- */
|
|
body.coffee-paper {
|
|
background-color: hsl(var(--background));
|
|
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cfilter id='paper-grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.18 0 0 0 0 0.13 0 0 0 0 0.09 0 0 0 0.07 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23paper-grain)'/%3E%3C/svg%3E");
|
|
background-repeat: repeat;
|
|
}
|
|
|
|
/* --- Type roles --------------------------------------------------------- */
|
|
.coffee-display {
|
|
font-family: var(--font-heading, var(--coffee-heading-fallback));
|
|
font-feature-settings: "liga" 1, "dlig" 1;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
.coffee-body {
|
|
font-family: var(--font-body, var(--coffee-body-fallback));
|
|
line-height: 1.65;
|
|
}
|
|
.coffee-mono {
|
|
font-family: var(--font-mono, var(--coffee-mono-fallback));
|
|
}
|
|
/* Hand-drawn accents (badges, stamps, captions). Routed through --font-heading
|
|
* with a Caveat fallback: unassigned it renders Caveat; if the admin sets a
|
|
* heading font the accents follow it (the 3-slot model working as intended). */
|
|
.coffee-hand {
|
|
font-family: var(--font-heading, var(--coffee-hand-fallback));
|
|
letter-spacing: 0.01em;
|
|
line-height: 1.15;
|
|
}
|
|
|
|
/* --- Doodle underline --------------------------------------------------- */
|
|
.coffee-doodle-underline {
|
|
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8 Q 20 2 40 7 T 80 6 T 118 7' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' opacity='0.55'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: 0 100%;
|
|
background-size: 100% 0.5em;
|
|
padding-bottom: 0.18em;
|
|
}
|
|
|
|
/* --- Drop-cap ----------------------------------------------------------- */
|
|
.coffee-dropcap > p:first-of-type::first-letter {
|
|
font-family: var(--font-heading, var(--coffee-heading-fallback));
|
|
font-size: 4em;
|
|
line-height: 0.85;
|
|
float: left;
|
|
padding: 0.05em 0.12em 0 0;
|
|
color: hsl(var(--primary));
|
|
}
|
|
|
|
/* --- Kraft-tag button (stamp press on hover) ---------------------------- */
|
|
.kraft-tag {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.55rem 1.1rem;
|
|
background-color: hsl(var(--primary));
|
|
color: hsl(var(--primary-foreground));
|
|
border: 1px solid hsl(var(--border));
|
|
border-radius: 0.25rem;
|
|
font-family: var(--font-body, var(--coffee-body-fallback));
|
|
font-weight: 500;
|
|
letter-spacing: 0.02em;
|
|
box-shadow: 0 2px 0 hsl(var(--border));
|
|
transition: transform 120ms ease, box-shadow 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.kraft-tag:hover {
|
|
transform: translateY(1px) rotate(-1.2deg);
|
|
box-shadow: 0 1px 0 hsl(var(--border));
|
|
}
|
|
.kraft-tag:focus-visible {
|
|
outline: 2px solid hsl(var(--ring));
|
|
outline-offset: 3px;
|
|
}
|
|
.kraft-tag--ghost {
|
|
background-color: transparent;
|
|
color: hsl(var(--primary));
|
|
box-shadow: none;
|
|
border-style: dashed;
|
|
}
|
|
.kraft-tag--ghost:hover {
|
|
background-color: hsl(var(--muted));
|
|
}
|
|
|
|
/* --- Torn-paper edges --------------------------------------------------- */
|
|
.coffee-torn-top {
|
|
-webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0 12 L0 6 Q 5 2 10 5 T 20 4 T 30 6 T 40 3 T 50 5 T 60 4 T 70 5 T 80 3 T 90 5 T 100 4 L100 12 Z' fill='black'/%3E%3C/svg%3E");
|
|
mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0 12 L0 6 Q 5 2 10 5 T 20 4 T 30 6 T 40 3 T 50 5 T 60 4 T 70 5 T 80 3 T 90 5 T 100 4 L100 12 Z' fill='black'/%3E%3C/svg%3E");
|
|
-webkit-mask-repeat: no-repeat;
|
|
mask-repeat: no-repeat;
|
|
-webkit-mask-size: 100% 100%;
|
|
mask-size: 100% 100%;
|
|
}
|
|
.coffee-torn-bottom {
|
|
-webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0 0 L100 0 L100 6 Q 95 10 90 7 T 80 8 T 70 6 T 60 9 T 50 7 T 40 8 T 30 7 T 20 9 T 10 7 T 0 8 Z' fill='black'/%3E%3C/svg%3E");
|
|
mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 12' preserveAspectRatio='none'%3E%3Cpath d='M0 0 L100 0 L100 6 Q 95 10 90 7 T 80 8 T 70 6 T 60 9 T 50 7 T 40 8 T 30 7 T 20 9 T 10 7 T 0 8 Z' fill='black'/%3E%3C/svg%3E");
|
|
-webkit-mask-repeat: no-repeat;
|
|
mask-repeat: no-repeat;
|
|
-webkit-mask-size: 100% 100%;
|
|
mask-size: 100% 100%;
|
|
}
|
|
|
|
/* --- Surfaces ----------------------------------------------------------- */
|
|
.coffee-card {
|
|
background-color: hsl(var(--card));
|
|
color: hsl(var(--card-foreground));
|
|
border: 1px solid hsl(var(--border));
|
|
border-radius: 0.5rem;
|
|
}
|
|
.coffee-frame {
|
|
border: 1px solid hsl(var(--border));
|
|
background-color: hsl(var(--card));
|
|
}
|
|
.coffee-pencil-rule {
|
|
border-color: hsl(var(--border));
|
|
border-style: solid;
|
|
}
|
|
|
|
/* --- Chalkboard menu panel (inverts foreground/background for a hung board;
|
|
* light mode = dark board + cream chalk, dark mode = light menu paper) --- */
|
|
.coffee-chalkboard {
|
|
position: relative;
|
|
background-color: hsl(var(--foreground));
|
|
color: hsl(var(--background));
|
|
border-radius: 0.5rem;
|
|
box-shadow: inset 0 0 0 3px hsl(var(--background) / 0.12), inset 0 0 0 4px hsl(var(--foreground));
|
|
}
|
|
.coffee-chalk-rule {
|
|
border-color: hsl(var(--background) / 0.28);
|
|
border-style: solid;
|
|
}
|
|
.coffee-chalk-muted {
|
|
color: hsl(var(--background) / 0.72);
|
|
}
|
|
|
|
/* --- Hours: today highlight --------------------------------------------- */
|
|
.coffee-hours-today {
|
|
background-color: hsl(var(--accent) / 0.15);
|
|
color: hsl(var(--accent-foreground));
|
|
border-left: 3px solid hsl(var(--accent));
|
|
padding-left: 0.75rem;
|
|
}
|
|
|
|
/* --- Price + spec chips ------------------------------------------------- */
|
|
.coffee-price {
|
|
font-family: var(--font-mono, var(--coffee-mono-fallback));
|
|
font-variant-numeric: tabular-nums;
|
|
color: hsl(var(--accent));
|
|
}
|
|
.coffee-chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
padding: 0.3rem 0.7rem;
|
|
border: 1px dashed hsl(var(--border));
|
|
border-radius: 9999px;
|
|
background-color: hsl(var(--muted));
|
|
color: hsl(var(--foreground));
|
|
font-family: var(--font-body, var(--coffee-body-fallback));
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
/* --- Circular stamp / badge (press on hover) ---------------------------- */
|
|
.coffee-stamp {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 4.25rem;
|
|
height: 4.25rem;
|
|
border-radius: 9999px;
|
|
background-color: hsl(var(--accent));
|
|
color: hsl(var(--accent-foreground));
|
|
border: 2px solid hsl(var(--accent-foreground) / 0.35);
|
|
box-shadow: inset 0 0 0 3px hsl(var(--accent));
|
|
font-family: var(--font-heading, var(--coffee-hand-fallback));
|
|
font-size: 0.95rem;
|
|
text-align: center;
|
|
line-height: 1.05;
|
|
transform: rotate(-6deg);
|
|
transition: transform 140ms ease;
|
|
}
|
|
.coffee-stamp:hover {
|
|
transform: rotate(-6deg) scale(0.94);
|
|
}
|
|
.coffee-stamp-sm {
|
|
width: 2.25rem;
|
|
height: 2.25rem;
|
|
font-size: 1rem;
|
|
transform: rotate(-4deg);
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* --- Loyalty punch stamps ----------------------------------------------- */
|
|
.coffee-punch {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
aspect-ratio: 1 / 1;
|
|
border-radius: 9999px;
|
|
border: 2px dashed hsl(var(--border));
|
|
color: hsl(var(--muted-foreground));
|
|
}
|
|
.coffee-punch-on {
|
|
border-style: solid;
|
|
border-color: hsl(var(--accent));
|
|
background-color: hsl(var(--accent) / 0.15);
|
|
color: hsl(var(--accent));
|
|
transform: rotate(-5deg);
|
|
}
|
|
.coffee-punch-reward {
|
|
border-color: hsl(var(--primary));
|
|
background-color: hsl(var(--primary) / 0.12);
|
|
color: hsl(var(--primary));
|
|
}
|
|
|
|
/* --- Location pin ------------------------------------------------------- */
|
|
.coffee-pin {
|
|
color: hsl(var(--accent));
|
|
}
|
|
|
|
/* --- Doodle divider draw-in --------------------------------------------- */
|
|
.coffee-doodle-draw path,
|
|
.coffee-doodle-draw ellipse,
|
|
.coffee-doodle-draw circle {
|
|
stroke-dasharray: 240;
|
|
stroke-dashoffset: 240;
|
|
animation: coffee-draw 1.4s ease forwards;
|
|
}
|
|
|
|
@keyframes coffee-draw {
|
|
to { stroke-dashoffset: 0; }
|
|
}
|
|
|
|
/* --- Motion safety: static fallback ------------------------------------- */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.kraft-tag,
|
|
.coffee-stamp,
|
|
.coffee-punch-on { transition: none; }
|
|
.kraft-tag:hover,
|
|
.coffee-stamp:hover { transform: none; }
|
|
.coffee-doodle-draw path,
|
|
.coffee-doodle-draw ellipse,
|
|
.coffee-doodle-draw circle {
|
|
stroke-dasharray: none;
|
|
stroke-dashoffset: 0;
|
|
animation: none;
|
|
}
|
|
}
|