Files
industries/app/globals.css
zeekay d8fd557f2b Navbar solid white + kill TopBanner rainbow shift animation
Navbar: drop frosted blur + opacity (bg-white/55 -> bg-white). The
40-45% transparency let the iridescent hero gradient bleed through
and the bar didn't read as 'white' on first paint.

TopBanner: drop the 30s linear pill-rainbow-shift animation. The
slow horizontal slide read as distracting 'moving across' motion
at the very top of the page. Gradient stays, pinned.
2026-05-22 20:03:43 -07:00

342 lines
12 KiB
CSS

@import "tailwindcss";
@plugin "tailwindcss-animate";
/* Tailwind v4 defaults the ``dark:`` variant to ``@media (prefers-color-
scheme: dark)``, which means OS-level dark mode triggers it regardless
of what next-themes sets on <html>. Rebind it to a class-based variant
so ``forcedTheme="light"`` in the layout actually wins — without this,
the navbar's ``dark:bg-black/70`` activated whenever the visitor's OS
was in dark mode and the bar rendered as a dark overlay on production. */
@custom-variant dark (&:where(.dark, .dark *));
:root {
/* Iridescent pastel gradient — applied via body background-image. The
token is transparent so sections using bg-background let the gradient
show through; the body itself paints the flat fallback below the image. */
--background: transparent;
--background-fallback: #f5e8c8;
--foreground: #000000;
--card: rgba(255, 255, 255, 0.65);
--card-foreground: #000000;
--popover: #ffffff;
--popover-foreground: #000000;
/* Brand accents — pulled directly from the Zoo logo (the CMYK Venn
diagram in app/icon.svg). Buttons, banner, gradient, and any spot
accent should reach for these so the whole site reads as the
same family as the mark. */
--primary: #ea018e; /* magenta */
--primary-foreground: #000000;
--secondary: rgba(255, 255, 255, 0.5);
--secondary-foreground: #000000;
--accent: rgba(255, 255, 255, 0.45);
--accent-foreground: #000000;
--muted: rgba(255, 255, 255, 0.55);
--muted-foreground: #1a1a1a;
--brand-magenta: #ea018e;
--brand-pink: #ea018e; /* alias */
--brand-green: #00a652;
--brand-blue: #2e3192;
--brand-cyan: #01acf1;
--brand-yellow: #fcf006;
--brand-red: #ed1c24;
--destructive: #ed1c24;
--destructive-foreground: #ffffff;
--border: #000000;
--input: rgba(255, 255, 255, 0.7);
--ring: #000000;
}
.dark {
/* Dark variant keeps the iridescent motif but darker, with light text. */
--background: #0a0a0a;
--foreground: #f5f5f5;
--card: rgba(20, 20, 20, 0.7);
--card-foreground: #f5f5f5;
--popover: #0a0a0a;
--popover-foreground: #f5f5f5;
--primary: #ff4fa3;
--primary-foreground: #000000;
--secondary: #4ad48a;
--secondary-foreground: #000000;
--accent: #8a8aff;
--accent-foreground: #000000;
--muted: rgba(40, 40, 40, 0.7);
--muted-foreground: #cfcfcf;
--destructive: #ff5560;
--destructive-foreground: #000000;
--border: #ffffff;
--input: rgba(20, 20, 20, 0.7);
--ring: #ffffff;
}
@theme {
--font-sans: var(--font-geist-sans), system-ui, -apple-system, sans-serif;
--font-mono: var(--font-geist-mono), ui-monospace, monospace;
--radius: 0.25rem;
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
}
html {
scrollbar-gutter: stable;
}
html.dark {
color-scheme: dark;
}
html:not(.dark) {
color-scheme: light;
}
body {
color: var(--foreground);
font-family: var(--font-sans);
background-color: var(--background-fallback, #f5e8c8);
/* Layered radial pastels produce the iridescent rainbow wash. */
/* Iridescent wash — soft tints of the Zoo logo's CMYK palette
(magenta #ea018e, green #00a652, blue #2e3192, cyan #01acf1,
yellow #fcf006). Same hues as the mark, dialed down to ~15%
saturation so the page reads as the same family as the logo
and CTAs without competing with them. */
background-image:
radial-gradient(at 14% 16%, #fff3b8 0%, transparent 38%),
radial-gradient(at 86% 12%, #ffc6e6 0%, transparent 40%),
radial-gradient(at 92% 62%, #b8dff8 0%, transparent 42%),
radial-gradient(at 28% 82%, #b8e8c8 0%, transparent 44%),
radial-gradient(at 62% 50%, #c4c8ec 0%, transparent 44%),
radial-gradient(at 8% 92%, #ffc6e6 0%, transparent 40%),
linear-gradient(135deg, #fff3d8 0%, #ffd9ec 28%, #d8dcef 55%, #cfeede 80%, #d6ecf8 100%);
background-attachment: fixed;
background-size: cover;
}
html.dark body {
background-image:
radial-gradient(at 12% 18%, #2a1a3a 0%, transparent 40%),
radial-gradient(at 82% 8%, #1a2a3a 0%, transparent 40%),
radial-gradient(at 92% 58%, #1a1a3a 0%, transparent 45%),
radial-gradient(at 32% 82%, #3a1a2a 0%, transparent 45%),
radial-gradient(at 60% 50%, #1a3a2a 0%, transparent 50%),
linear-gradient(135deg, #100018 0%, #001020 50%, #200020 100%);
}
* {
border-color: var(--border);
--tw-ring-color: var(--ring);
}
/* Brutalist: every box is a hard rectangle. The only escapes are
``rounded-full`` (circle avatars — team photos, mascot heads) and
the ``[data-circle]`` opt-in for anything else that genuinely needs
to be a disc. Every other ``rounded-*`` utility is overridden. */
*:not(.rounded-full):not([data-circle]),
*::before,
*::after {
border-radius: 0 !important;
}
/* Headings adopt the screenshot's heavy black bold treatment. */
h1, h2, h3, h4, h5, h6 {
font-weight: 800;
letter-spacing: -0.01em;
}
/* Neobrutalist pill — bright color block with a hard offset black shadow.
Wrap a heading or label to match the FOUNDATION / $ZOO NETWORK / ZOO
INDUSTRIES / ZOO LABS treatment. Sharp corners, heavy black border,
chunky offset shadow, black uppercase type. */
.pill {
display: inline-block;
padding: 0.625rem 1.25rem;
font-weight: 800;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0.04em;
color: #000;
background-color: var(--pill-color, var(--secondary));
border: 2px solid #000;
border-radius: 0;
box-shadow: 6px 6px 0 0 #000;
transition: transform 0.1s ease-out, box-shadow 0.1s ease-out;
}
@media (min-width: 768px) {
.pill {
padding: 0.875rem 2rem;
box-shadow: 10px 10px 0 0 #000;
}
}
.pill-green { --pill-color: var(--brand-green); }
.pill-pink { --pill-color: var(--brand-magenta); }
.pill-blue { --pill-color: var(--brand-blue); color: #fff; }
.pill-cyan { --pill-color: var(--brand-cyan); }
.pill-yellow { --pill-color: var(--brand-yellow); }
.pill-red { --pill-color: var(--brand-red); }
.pill-rainbow {
/* Repeat the spectrum twice so the gradient can shift left forever
without ever revealing an end. ``background-size: 200% 100%`` plus
a linear 8 s animation gives a continuous color ribbon underneath
the FOUNDATION wordmark. */
background-image: linear-gradient(
90deg,
var(--brand-yellow) 0%, var(--brand-green) 8.33%,
var(--brand-cyan) 16.66%, var(--brand-blue) 25%,
var(--brand-magenta) 33.33%, var(--brand-red) 41.66%,
var(--brand-yellow) 50%, var(--brand-green) 58.33%,
var(--brand-cyan) 66.66%, var(--brand-blue) 75%,
var(--brand-magenta) 83.33%, var(--brand-red) 100%
);
background-size: 200% 100%;
background-position: 0% 50%;
/* Animation removed 2026-05-23 — the continuous left-shift read as a
distracting "moving across" motion at the very top of the page.
The colorful gradient stays, pinned. Hover-driven .button-rainbow
variant below still animates as expected. */
}
@keyframes pill-rainbow-shift {
0% { background-position: 0% 50%; }
100% { background-position: 200% 50%; }
}
/* Brutalist button — same vibe as .pill but interactive: presses into
its own shadow on hover/active. Use on <button>/<a>. */
.btn-brutalist {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.875rem 1.75rem;
font-weight: 800;
font-size: 1rem;
line-height: 1;
text-transform: uppercase;
letter-spacing: 0.04em;
color: #000;
background-color: var(--pill-color, var(--secondary));
border: 2px solid #000;
border-radius: 0;
box-shadow: 8px 8px 0 0 #000;
cursor: pointer;
transition: transform 0.1s ease-out, box-shadow 0.1s ease-out;
}
/* The blue variant gets a continuously cycling rainbow instead of a
solid fill. Other .btn-brutalist colors keep their solid pill color.
Text is forced white so it stays legible through the dark-blue trough
of the rainbow cycle. */
.btn-brutalist.pill-blue {
color: #fff;
background-color: var(--brand-blue); /* fallback for prefers-reduced-motion */
background-image: linear-gradient(
90deg,
var(--brand-red) 0%,
var(--brand-yellow) 16.66%,
var(--brand-green) 33.33%,
var(--brand-cyan) 50%,
var(--brand-blue) 66.66%,
var(--brand-magenta) 83.33%,
var(--brand-red) 100%
);
background-size: 300% 100%;
background-position: 0% 50%;
animation: btn-brutalist-rainbow 6s linear infinite;
}
@keyframes btn-brutalist-rainbow {
0% { background-position: 0% 50%; }
100% { background-position: 300% 50%; }
}
@media (prefers-reduced-motion: reduce) {
.btn-brutalist.pill-blue { animation: none; background-image: none; }
}
.btn-brutalist:hover {
transform: translate(2px, 2px);
box-shadow: 6px 6px 0 0 #000;
}
.btn-brutalist:active {
transform: translate(8px, 8px);
box-shadow: 0 0 0 0 #000;
}
.btn-brutalist:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
box-shadow: 8px 8px 0 0 #000;
}
/* Card panels — solid color block with the same hard offset shadow,
used for the side info boxes in the diagram. */
.panel {
background-color: var(--panel-color, rgba(255, 255, 255, 0.9));
color: #000;
border: 2px solid #000;
border-radius: 0;
box-shadow: 6px 6px 0 0 #000;
padding: 1rem 1.125rem;
}
@media (min-width: 768px) {
.panel {
box-shadow: 10px 10px 0 0 #000;
padding: 1.25rem 1.5rem;
}
}
.panel-green { --panel-color: var(--brand-green); }
.panel-pink { --panel-color: var(--brand-magenta); }
.panel-blue { --panel-color: var(--brand-blue); }
.panel-cyan { --panel-color: var(--brand-cyan); }
.panel-yellow{ --panel-color: var(--brand-yellow); }
/* Card hover: swap a brutalist white card to the same rainbow ribbon
used on .pill-rainbow, but only while hovered. The gradient inherits
the 4 s shifting animation so the colors flow under the card. Text
stays black; black border + offset shadow stay intact. */
.card-rainbow-hover {
transition: background-color 0.2s ease;
background-image: none;
}
.card-rainbow-hover:hover {
background-image: linear-gradient(
90deg,
var(--brand-yellow) 0%, var(--brand-green) 8.33%,
var(--brand-cyan) 16.66%, var(--brand-blue) 25%,
var(--brand-magenta) 33.33%, var(--brand-red) 41.66%,
var(--brand-yellow) 50%, var(--brand-green) 58.33%,
var(--brand-cyan) 66.66%, var(--brand-blue) 75%,
var(--brand-magenta) 83.33%, var(--brand-red) 100%
);
background-size: 200% 100%;
animation: pill-rainbow-shift 24s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.card-rainbow-hover:hover { animation: none; }
}
/* Continuous slow rotation for the brand mark in the navbar. */
.logo-spin {
animation: logo-spin 14s linear infinite;
transform-origin: 50% 50%;
}
@keyframes logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
.logo-spin { animation: none; }
}