forked from Mike/freno-dev
The landing page sold eight features from around 0.6 and summed up the rest in one line, while 0.6–0.10 shipped most of the island's modules. It also said twelve agents (Muse made thirteen) and marked phone approvals "coming soon" although the iPhone companion is in TestFlight beta. Adds live demos for terminal replies, the volume mixer, Capture with its Wings, and floating actions; a bento of module tiles behind a two-way feature marquee; and an iPhone/Watch beta section whose request form posts the same email-only report the app's Settings > Phone card sends. The approval flow, remote sessions and setup, timer, temperatures and Capture mocks are rebuilt from the app's own views, so the site shows what the island actually draws. Tests: report.test.ts pins the landing page's beta request against the /report schema (red when the schema demands a machine snapshot); nook and subdomain suites pass. NOOK-334 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
869 lines
19 KiB
CSS
869 lines
19 KiB
CSS
@import "tailwindcss";
|
|
@plugin "@tailwindcss/typography";
|
|
|
|
/* Register --color-base as animatable color property */
|
|
@property --color-base {
|
|
syntax: "<color>";
|
|
inherits: true;
|
|
initial-value: #fbf1c7;
|
|
}
|
|
|
|
:root {
|
|
/* Comments indicate what they are used for in vim/term
|
|
/* Base Colors (Background/Text) */
|
|
--color-base: #fbf1c7; /* Main background color (lightest) */
|
|
--color-mantle: #f3eac1; /* Secondary background (slightly darker) */
|
|
--color-crust: #e7deb7; /* Lowest background layer (darkest) */
|
|
|
|
/* Text Colors */
|
|
--color-text: #654735; /* Primary text color */
|
|
--color-subtext1: #7b5d44; /* Secondary text (comments, less important) */
|
|
--color-subtext0: #8f6f56; /* Tertiary text (even less important) */
|
|
|
|
/* Surface Colors */
|
|
--color-surface0: #dfd6b1; /* Surface layer 0 (medium background) */
|
|
--color-surface1: #c9c19f; /* Surface layer 1 (darker surface) */
|
|
--color-surface2: #a79c86; /* Surface layer 2 (darkest surface) */
|
|
|
|
/* Overlay Colors */
|
|
--color-overlay0: #c9aa8c; /* Overlay layer 0 */
|
|
--color-overlay1: #b6977a; /* Overlay layer 1 */
|
|
--color-overlay2: #a28368; /* Overlay layer 2 */
|
|
|
|
/* Accent Colors (Syntax/Highlighting) */
|
|
--color-red: #c14a4a; /* Error messages, important keywords */
|
|
--color-maroon: #c14a4a; /* Error messages, critical elements */
|
|
--color-peach: #c35e0a; /* Warning messages, operators */
|
|
--color-yellow: #a96b2c; /* Variables, parameters, attributes */
|
|
--color-green: #6c782e; /* Strings, literals, constants */
|
|
--color-teal: #4c7a5d; /* Functions, methods, built-ins */
|
|
--color-sky: #4c7a5d; /* Functions, methods (alternative) */
|
|
--color-sapphire: #4c7a5d; /* Functions, methods (alternative) */
|
|
--color-blue: #45707a; /* Keywords, types, classes */
|
|
--color-lavender: #45707a; /* Comments, documentation strings */
|
|
--color-pink: #945e80; /* Special syntax elements, identifiers */
|
|
--color-mauve: #945e80; /* Special syntax elements (alternative) */
|
|
--color-flamingo: #c14a4a; /* Error messages, critical elements */
|
|
--color-rosewater: #c14a4a; /* Error messages, critical elements */
|
|
}
|
|
|
|
@theme {
|
|
--color-rosewater: #c14a4a;
|
|
--color-flamingo: #c14a4a;
|
|
--color-pink: #945e80;
|
|
--color-mauve: #945e80;
|
|
--color-red: #c14a4a;
|
|
--color-maroon: #c14a4a;
|
|
--color-peach: #c35e0a;
|
|
--color-yellow: #a96b2c;
|
|
--color-green: #6c782e;
|
|
--color-teal: #4c7a5d;
|
|
--color-sky: #4c7a5d;
|
|
--color-sapphire: #4c7a5d;
|
|
--color-blue: #45707a;
|
|
--color-lavender: #45707a;
|
|
--color-text: #654735;
|
|
--color-subtext1: #7b5d44;
|
|
--color-subtext0: #8f6f56;
|
|
--color-overlay2: #a28368;
|
|
--color-overlay1: #b6977a;
|
|
--color-overlay0: #c9aa8c;
|
|
--color-surface2: #a79c86;
|
|
--color-surface1: #c9c19f;
|
|
--color-surface0: #dfd6b1;
|
|
--color-base: #fbf1c7;
|
|
--color-mantle: #f3eac1;
|
|
--color-crust: #e7deb7;
|
|
|
|
/* Button text colors: white on dark bg variants (primary/danger),
|
|
theme text on light bg variants (secondary). */
|
|
--color-button-text: #ffffff;
|
|
--color-button-text-alt: var(--color-text);
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
:root {
|
|
--color-rosewater: #efc9c2;
|
|
--color-flamingo: #ebb2b2;
|
|
--color-pink: #f2a7de;
|
|
--color-mauve: #b889f4;
|
|
--color-red: #ea7183;
|
|
--color-maroon: #ea838c;
|
|
--color-peach: #f39967;
|
|
--color-yellow: #eaca89;
|
|
--color-green: #96d382;
|
|
--color-teal: #78cec1;
|
|
--color-sky: #91d7e3;
|
|
--color-sapphire: #68bae0;
|
|
--color-blue: #739df2;
|
|
--color-lavender: #a0a8f6;
|
|
--color-text: #b5c1f1;
|
|
--color-subtext1: #a6b0d8;
|
|
--color-subtext0: #959ec2;
|
|
--color-overlay2: #848cad;
|
|
--color-overlay1: #717997;
|
|
--color-overlay0: #63677f;
|
|
--color-surface2: #505469;
|
|
--color-surface1: #3e4255;
|
|
--color-surface0: #2c2f40;
|
|
--color-base: #1e1e2e;
|
|
--color-mantle: #141620;
|
|
--color-crust: #0e0f16;
|
|
|
|
/* Dark mode: dark text on lighter bg variants (primary/danger),
|
|
white text on dark bg variants (secondary). */
|
|
--color-button-text: var(--color-crust);
|
|
--color-button-text-alt: #ffffff;
|
|
}
|
|
@theme {
|
|
--color-rosewater: #efc9c2;
|
|
--color-flamingo: #ebb2b2;
|
|
--color-pink: #f2a7de;
|
|
--color-mauve: #b889f4;
|
|
--color-red: #ea7183;
|
|
--color-maroon: #ea838c;
|
|
--color-peach: #f39967;
|
|
--color-yellow: #eaca89;
|
|
--color-green: #96d382;
|
|
--color-teal: #78cec1;
|
|
--color-sky: #91d7e3;
|
|
--color-sapphire: #68bae0;
|
|
--color-blue: #739df2;
|
|
--color-lavender: #a0a8f6;
|
|
--color-text: #b5c1f1;
|
|
--color-subtext1: #a6b0d8;
|
|
--color-subtext0: #959ec2;
|
|
--color-overlay2: #848cad;
|
|
--color-overlay1: #717997;
|
|
--color-overlay0: #63677f;
|
|
--color-surface2: #505469;
|
|
--color-surface1: #3e4255;
|
|
--color-surface0: #2c2f40;
|
|
--color-base: #1e1e2e;
|
|
--color-mantle: #141620;
|
|
--color-crust: #0e0f16;
|
|
}
|
|
}
|
|
|
|
/* Manual theme override via classes (higher specificity than media query) */
|
|
:root.light {
|
|
--color-rosewater: #c14a4a;
|
|
--color-flamingo: #c14a4a;
|
|
--color-pink: #945e80;
|
|
--color-mauve: #945e80;
|
|
--color-red: #c14a4a;
|
|
--color-maroon: #c14a4a;
|
|
--color-peach: #c35e0a;
|
|
--color-yellow: #a96b2c;
|
|
--color-green: #6c782e;
|
|
--color-teal: #4c7a5d;
|
|
--color-sky: #4c7a5d;
|
|
--color-sapphire: #4c7a5d;
|
|
--color-blue: #45707a;
|
|
--color-lavender: #45707a;
|
|
--color-text: #654735;
|
|
--color-subtext1: #7b5d44;
|
|
--color-subtext0: #8f6f56;
|
|
--color-overlay2: #a28368;
|
|
--color-overlay1: #b6977a;
|
|
--color-overlay0: #c9aa8c;
|
|
--color-surface2: #a79c86;
|
|
--color-surface1: #c9c19f;
|
|
--color-surface0: #dfd6b1;
|
|
--color-base: #fbf1c7;
|
|
--color-mantle: #f3eac1;
|
|
--color-crust: #e7deb7;
|
|
--color-button-text: #ffffff;
|
|
--color-button-text-alt: var(--color-text);
|
|
}
|
|
|
|
:root.dark {
|
|
--color-rosewater: #efc9c2;
|
|
--color-flamingo: #ebb2b2;
|
|
--color-pink: #f2a7de;
|
|
--color-mauve: #b889f4;
|
|
--color-red: #ea7183;
|
|
--color-maroon: #ea838c;
|
|
--color-peach: #f39967;
|
|
--color-yellow: #eaca89;
|
|
--color-green: #96d382;
|
|
--color-teal: #78cec1;
|
|
--color-sky: #91d7e3;
|
|
--color-sapphire: #68bae0;
|
|
--color-blue: #739df2;
|
|
--color-lavender: #a0a8f6;
|
|
--color-text: #b5c1f1;
|
|
--color-subtext1: #a6b0d8;
|
|
--color-subtext0: #959ec2;
|
|
--color-overlay2: #848cad;
|
|
--color-overlay1: #717997;
|
|
--color-overlay0: #63677f;
|
|
--color-surface2: #505469;
|
|
--color-surface1: #3e4255;
|
|
--color-surface0: #2c2f40;
|
|
--color-base: #1e1e2e;
|
|
--color-mantle: #141620;
|
|
--color-crust: #0e0f16;
|
|
--color-button-text: var(--color-crust);
|
|
--color-button-text-alt: #ffffff;
|
|
}
|
|
|
|
:root {
|
|
font-family: "Source Code Pro", monospace;
|
|
background-color: var(--color-base);
|
|
transition-property: all;
|
|
transition-timing-function: var(
|
|
--tw-ease,
|
|
var(--default-transition-timing-function) /* cubic-bezier(0.4, 0, 0.2, 1) */
|
|
);
|
|
transition-duration: var(
|
|
--tw-duration,
|
|
var(--default-transition-duration) /* 150ms */
|
|
);
|
|
transition-duration: 500ms;
|
|
syntax: "*";
|
|
inherits: false;
|
|
}
|
|
|
|
::selection {
|
|
background-color: var(--color-text);
|
|
color: var(--color-crust);
|
|
}
|
|
::-moz-selection {
|
|
background-color: var(--color-text);
|
|
color: var(--color-crust);
|
|
}
|
|
::-webkit-selection {
|
|
background-color: var(--color-text);
|
|
color: var(--color-crust);
|
|
}
|
|
#rightbar-content {
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
body {
|
|
background: var(--color-base);
|
|
color: var(--color-text);
|
|
transition: background-color 500ms ease-in-out;
|
|
}
|
|
|
|
[data-typewriter="animated"] [data-char-index] {
|
|
opacity: 0;
|
|
}
|
|
|
|
[data-typewriter-ready="true"] [data-char-index] {
|
|
transition: opacity 0.05s ease-in;
|
|
}
|
|
|
|
.cursor-typing {
|
|
display: inline-block;
|
|
width: 2px;
|
|
background-color: var(--color-text);
|
|
vertical-align: text-bottom;
|
|
margin-left: 2px;
|
|
position: absolute;
|
|
}
|
|
|
|
/* Block cursor when done typing */
|
|
.cursor-block {
|
|
display: inline-block;
|
|
width: 1ch;
|
|
background-color: var(--color-text);
|
|
vertical-align: text-bottom;
|
|
animation: blink 1s infinite;
|
|
margin-left: 2px;
|
|
position: absolute;
|
|
}
|
|
|
|
@keyframes blink {
|
|
0%,
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
51%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.input-group,
|
|
.textarea-group {
|
|
position: relative;
|
|
margin-top: 30px;
|
|
}
|
|
|
|
input.underlinedInput,
|
|
textarea.underlinedInput {
|
|
font-size: 18px;
|
|
padding: 10px 10px 10px 5px;
|
|
display: block;
|
|
border: none;
|
|
}
|
|
input.underlinedInput,
|
|
textarea.underlinedInput {
|
|
border-bottom: 1px solid var(--color-surface2);
|
|
}
|
|
|
|
textarea.underlinedInput {
|
|
resize: none;
|
|
}
|
|
|
|
input.underlinedInput:focus,
|
|
textarea.underlinedInput:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.bar {
|
|
position: relative;
|
|
display: block;
|
|
}
|
|
|
|
.bar:before,
|
|
.bar:after {
|
|
content: "";
|
|
height: 2px;
|
|
width: 0;
|
|
bottom: 0px;
|
|
position: absolute;
|
|
transition: width 0.3s ease-out;
|
|
background: var(--color-blue);
|
|
}
|
|
|
|
.bar:before {
|
|
left: 50%;
|
|
}
|
|
|
|
.bar:after {
|
|
right: 50%;
|
|
}
|
|
|
|
input.underlinedInput:focus ~ .bar:before,
|
|
input.underlinedInput:focus ~ .bar:after,
|
|
textarea.underlinedInput:focus ~ .bar:before,
|
|
textarea.underlinedInput:focus ~ .bar:after {
|
|
width: 50%;
|
|
}
|
|
input.underlinedInput:focus ~ label,
|
|
input.underlinedInput:not(:placeholder-shown) ~ label,
|
|
textarea.underlinedInput:focus ~ label,
|
|
textarea.underlinedInput:not(:placeholder-shown) ~ label {
|
|
top: -20px;
|
|
font-size: 14px;
|
|
color: var(--color-blue);
|
|
}
|
|
|
|
.delete > input.underlinedInput:focus ~ label,
|
|
.delete > input.underlinedInput:not(:placeholder-shown) ~ label,
|
|
.delete > textarea.underlinedInput:focus ~ label,
|
|
.delete > textarea.underlinedInput:not(:placeholder-shown) ~ label {
|
|
color: var(--color-red);
|
|
}
|
|
|
|
label.underlinedInputLabel {
|
|
font-size: 18px;
|
|
font-weight: normal;
|
|
position: absolute;
|
|
pointer-events: none;
|
|
left: 5px;
|
|
top: 10px;
|
|
transition:
|
|
all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
|
|
color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
}
|
|
|
|
label.underlinedInputLabel {
|
|
color: var(--color-surface1);
|
|
}
|
|
|
|
.vertical-rule-around {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.vertical-rule-around:before,
|
|
.vertical-rule-around:after {
|
|
content: "";
|
|
flex: 1;
|
|
border-left: 1px solid var(--color-surface2);
|
|
margin: 10px 0;
|
|
}
|
|
.checkbox-container {
|
|
position: relative;
|
|
padding-left: 35px;
|
|
cursor: pointer;
|
|
font-size: 22px;
|
|
user-select: none;
|
|
}
|
|
|
|
.checkbox-container input {
|
|
position: absolute;
|
|
opacity: 0;
|
|
cursor: pointer;
|
|
height: 0;
|
|
width: 0;
|
|
}
|
|
|
|
.checkmark {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
height: 25px;
|
|
width: 25px;
|
|
background-color: #eee;
|
|
border-radius: 4px;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.checkbox-container:hover input ~ .checkmark {
|
|
background-color: #ccc;
|
|
}
|
|
|
|
.checkbox-container input:checked ~ .checkmark {
|
|
background-color: var(--color-text);
|
|
}
|
|
|
|
input[type="checkbox"] {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
background-color: var(--form-background);
|
|
margin: 0;
|
|
font: inherit;
|
|
width: 1.15em;
|
|
height: 1.15em;
|
|
border: 2px solid var(--color-blue);
|
|
border-radius: 0.15em;
|
|
transform: translateY(-0.075em);
|
|
|
|
display: grid;
|
|
place-content: center;
|
|
}
|
|
|
|
input[type="checkbox"]::before {
|
|
content: "";
|
|
width: 0.65em;
|
|
height: 0.65em;
|
|
clip-path: circle(25%);
|
|
transform: scale(0);
|
|
color: var(--color-blue);
|
|
transform-origin: center;
|
|
transition: 120ms transform ease-in-out;
|
|
/* Windows High Contrast Mode */
|
|
background-color: CanvasText;
|
|
box-shadow: inset 1em 1em var(--color-text);
|
|
}
|
|
|
|
input[type="checkbox"]:checked::before {
|
|
transform: scale(1);
|
|
}
|
|
.shaker:hover {
|
|
animation: shaker 0.5s ease;
|
|
}
|
|
.tooltip {
|
|
position: relative;
|
|
}
|
|
.tooltip .tooltip-text {
|
|
visibility: hidden;
|
|
min-width: fit-content;
|
|
background-color: var(--color-mantle);
|
|
color: var(--color-text);
|
|
text-align: center;
|
|
padding: 5px 0;
|
|
border-radius: 6px;
|
|
position: absolute;
|
|
z-index: 1;
|
|
top: 100%;
|
|
left: 50%;
|
|
opacity: 0;
|
|
transition: opacity 0.3s;
|
|
}
|
|
|
|
.tooltip:hover .tooltip-text {
|
|
visibility: visible;
|
|
opacity: 1;
|
|
}
|
|
.rule-around {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.rule-around:before,
|
|
.rule-around:after {
|
|
content: "";
|
|
flex: 1;
|
|
border-top: 1px solid var(--color-text);
|
|
margin: 0 10px;
|
|
}
|
|
.hover-underline-animation {
|
|
display: inline-block;
|
|
position: relative;
|
|
}
|
|
|
|
.hover-underline-animation::after {
|
|
content: "";
|
|
position: absolute;
|
|
width: 100%;
|
|
transform: scaleX(0);
|
|
height: 1px;
|
|
bottom: 0;
|
|
left: 0;
|
|
transform-origin: bottom right;
|
|
transition: transform 0.35s ease-out;
|
|
}
|
|
|
|
.hover-underline-animation:hover::after {
|
|
transform: scaleX(1);
|
|
transform-origin: bottom left;
|
|
background-color: var(--color-surface2);
|
|
}
|
|
a.hover-underline-animation:hover::after {
|
|
background-color: var(--color-blue) !important;
|
|
}
|
|
.image-overlay::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
.iframe-wrapper {
|
|
position: relative;
|
|
min-height: 300px;
|
|
width: 100%;
|
|
min-width: min(350px, 100%);
|
|
max-width: 100% !important;
|
|
background-color: black;
|
|
}
|
|
|
|
.iframe-wrapper iframe {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
/* Hamburger menu button - only show on non-touch devices under mobile breakpoint */
|
|
@media (max-width: 767px) {
|
|
.hamburger-menu-btn {
|
|
display: block !important;
|
|
}
|
|
}
|
|
|
|
@keyframes shaker {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
33% {
|
|
transform: rotate(15deg);
|
|
}
|
|
66% {
|
|
transform: rotate(-15deg);
|
|
}
|
|
100% {
|
|
transform: rotate(0deg);
|
|
}
|
|
}
|
|
.shaker:hover {
|
|
animation: shaker 0.5s ease;
|
|
}
|
|
|
|
/* ── Nook landing: campfire sprite frame cycling ──────────────────── */
|
|
/* Each frame layer is stacked; its animation holds opacity 1 during its
|
|
slot and 0 otherwise, so the stack reads as stop-motion at the app's
|
|
sprite cadence (frame time = total duration / frame count). The phase
|
|
lives inside the keyframes and every layer animates delay-free from the
|
|
same clock WebKit quantizes animation starts per cycle wrap, so
|
|
delay-offset layers can drop a wrap frame and show BOTH transparent
|
|
for a frame (the "blank frame" flicker). Complementary holds mean any
|
|
moment sums to exactly one opaque layer. Linear timing: steps()
|
|
holds mis-swap at boundary frames under WebKit. */
|
|
/* 2-frame sprites: layer i uses campfire-slot-2-{a,b}. */
|
|
@keyframes campfire-slot-2-a {
|
|
0%,
|
|
49.99% {
|
|
opacity: 1;
|
|
}
|
|
50%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes campfire-slot-2-b {
|
|
0%,
|
|
49.99% {
|
|
opacity: 0;
|
|
}
|
|
50%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
/* 6-frame sprites (question): six slot phases. */
|
|
@keyframes campfire-slot-6-a {
|
|
0%,
|
|
16.66% {
|
|
opacity: 1;
|
|
}
|
|
16.67%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes campfire-slot-6-b {
|
|
0%,
|
|
16.66% {
|
|
opacity: 0;
|
|
}
|
|
16.67%,
|
|
33.32% {
|
|
opacity: 1;
|
|
}
|
|
33.33%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes campfire-slot-6-c {
|
|
0%,
|
|
33.32% {
|
|
opacity: 0;
|
|
}
|
|
33.33%,
|
|
49.99% {
|
|
opacity: 1;
|
|
}
|
|
50%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes campfire-slot-6-d {
|
|
0%,
|
|
49.99% {
|
|
opacity: 0;
|
|
}
|
|
50%,
|
|
66.66% {
|
|
opacity: 1;
|
|
}
|
|
66.67%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes campfire-slot-6-e {
|
|
0%,
|
|
66.66% {
|
|
opacity: 0;
|
|
}
|
|
66.67%,
|
|
83.32% {
|
|
opacity: 1;
|
|
}
|
|
83.33%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes campfire-slot-6-f {
|
|
0%,
|
|
83.32% {
|
|
opacity: 0;
|
|
}
|
|
83.33%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.campfire-frame {
|
|
animation: var(--slot-kf, campfire-slot-2-a) var(--campfire-duration, 1s)
|
|
linear infinite;
|
|
opacity: 0;
|
|
}
|
|
|
|
/* ── Nook landing: breakdown section reveal ───────────────────────── */
|
|
.reveal {
|
|
opacity: 0;
|
|
transform: translateY(24px);
|
|
transition:
|
|
opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
|
|
transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
|
|
}
|
|
|
|
.reveal.in {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.reveal {
|
|
opacity: 1;
|
|
transform: none;
|
|
transition: none;
|
|
}
|
|
|
|
.campfire-frame {
|
|
animation: none;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.campfire-frame + .campfire-frame {
|
|
display: none;
|
|
}
|
|
}
|
|
/* ── Nook landing: fan card shake, builds with fan speed ───────── */
|
|
.fan-card-shake {
|
|
transform-origin: left center;
|
|
animation-name: fan-shake;
|
|
animation-duration: var(--fan-speed, 0.4s);
|
|
animation-iteration-count: infinite;
|
|
animation-timing-function: ease-in-out;
|
|
}
|
|
|
|
@keyframes fan-shake {
|
|
0%, 100% { transform: rotate(0deg); }
|
|
50% { transform: rotate(calc(var(--fan-amp, 0deg) * -1)); }
|
|
}
|
|
|
|
/* Sputtering sparks off the fan card at max speed */
|
|
.fan-spark {
|
|
position: absolute;
|
|
border-radius: 9999px;
|
|
background: #ffd23f;
|
|
box-shadow: 0 0 4px 1px rgba(255, 140, 0, 0.9);
|
|
animation: fan-spark-fly var(--sd, 0.5s) ease-out var(--sdel, 0s) infinite;
|
|
}
|
|
@keyframes fan-spark-fly {
|
|
0% { transform: translate(0, 0) scale(1); opacity: 0; }
|
|
10% { opacity: 1; }
|
|
100% { transform: translate(var(--sx, 20px), var(--sy, 30px)) scale(0.4); opacity: 0; }
|
|
}
|
|
|
|
/* Demo pulse: battery bolt */
|
|
@keyframes nook-pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.35; }
|
|
}
|
|
|
|
/* ── Nook landing: newer demos ─────────────────────────────────── */
|
|
.nook-caret {
|
|
animation: nook-pulse 0.8s steps(2, jump-none) infinite;
|
|
}
|
|
|
|
/* Live signal inside a mixer fader */
|
|
.nook-meter {
|
|
transform-origin: left center;
|
|
animation: nook-meter 0.6s ease-in-out infinite alternate;
|
|
}
|
|
@keyframes nook-meter {
|
|
0% { transform: scaleX(0.35); }
|
|
40% { transform: scaleX(0.8); }
|
|
100% { transform: scaleX(0.55); }
|
|
}
|
|
|
|
/* Waveform slot bars */
|
|
.nook-wave {
|
|
height: 100%;
|
|
transform-origin: center;
|
|
animation: nook-wave 0.8s ease-in-out infinite alternate;
|
|
}
|
|
@keyframes nook-wave {
|
|
0% { transform: scaleY(0.25); }
|
|
100% { transform: scaleY(1); }
|
|
}
|
|
|
|
/* Now Playing progress and artwork sheen */
|
|
.nook-progress {
|
|
animation: nook-progress 14s linear infinite;
|
|
}
|
|
@keyframes nook-progress {
|
|
from { width: 8%; }
|
|
to { width: 100%; }
|
|
}
|
|
.nook-art {
|
|
animation: nook-art 9s linear infinite;
|
|
}
|
|
@keyframes nook-art {
|
|
to { filter: hue-rotate(360deg); }
|
|
}
|
|
|
|
/* A ringing timer's tape breathes between 35 % and full */
|
|
.nook-tape-ring {
|
|
animation: nook-tape-ring 0.9s ease-in-out infinite alternate;
|
|
}
|
|
@keyframes nook-tape-ring {
|
|
from { opacity: 0.35; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
/* Keep Awake coffee steam */
|
|
.nook-steam path {
|
|
animation: nook-steam 1.8s ease-in-out infinite;
|
|
}
|
|
@keyframes nook-steam {
|
|
0% { transform: translateY(2px); opacity: 0; }
|
|
40% { opacity: 1; }
|
|
100% { transform: translateY(-4px); opacity: 0; }
|
|
}
|
|
|
|
/* Two-way feature marquee; edges fade, hover pauses */
|
|
.nook-marquee {
|
|
overflow: hidden;
|
|
mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
|
|
}
|
|
.nook-marquee-track {
|
|
display: flex;
|
|
gap: 0.625rem;
|
|
width: max-content;
|
|
padding-right: 0.625rem;
|
|
animation: nook-marquee 60s linear infinite;
|
|
}
|
|
.nook-marquee-track.reverse {
|
|
animation-direction: reverse;
|
|
}
|
|
.nook-marquee:hover .nook-marquee-track {
|
|
animation-play-state: paused;
|
|
}
|
|
@keyframes nook-marquee {
|
|
to { transform: translateX(-50%); }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.nook-meter,
|
|
.nook-wave,
|
|
.nook-progress,
|
|
.nook-art,
|
|
.nook-tape-ring,
|
|
.nook-steam path,
|
|
.nook-caret {
|
|
animation: none;
|
|
}
|
|
|
|
.nook-marquee {
|
|
mask-image: none;
|
|
}
|
|
|
|
.nook-marquee-track {
|
|
animation: none;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
width: auto;
|
|
padding: 0 1rem;
|
|
}
|
|
|
|
.nook-marquee-track > [aria-hidden="true"] {
|
|
display: none;
|
|
}
|
|
}
|