forked from Mike/freno-dev
[gpt-6.1-sol] The meetings, mixer and charging previews had drifted from the current app, while slogans obscured what the modules do. Match the shipped controls and behavior, reuse the existing demo machinery, and explain the landing-page features plainly without changing routing or purchase flows. Tests: bun test src/routes/nook src/components/nook (36 passed) NOOK-1037
878 lines
19 KiB
CSS
878 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;
|
|
}
|
|
|
|
/* Directional dashes in the power-flow preview. */
|
|
.nook-power-flow {
|
|
animation: nook-power-flow 1.6s linear infinite;
|
|
}
|
|
@keyframes nook-power-flow {
|
|
to { stroke-dashoffset: -21; }
|
|
}
|
|
|
|
/* 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-power-flow,
|
|
.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;
|
|
}
|
|
}
|