484 lines
14 KiB
CSS
484 lines
14 KiB
CSS
/* app.css — global styles for humor-units */
|
|
|
|
/* CSS custom properties (set dynamically via inline style from ConverterCard) */
|
|
:root {
|
|
--grid-gap: 1rem;
|
|
--card-font-size: 1rem; /* overridden per-grid by uniformFontSize action */
|
|
|
|
/* Shadow for card elevation (theme-neutral) */
|
|
--shadow-color: 30deg 8% 20%;
|
|
--shadow-low:
|
|
0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.06),
|
|
0.6px 1px 1.4px hsl(var(--shadow-color) / 0.06),
|
|
1.2px 2px 2.8px hsl(var(--shadow-color) / 0.07);
|
|
--shadow-medium:
|
|
0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.07),
|
|
1.2px 2px 2.8px hsl(var(--shadow-color) / 0.08),
|
|
3px 5px 7px hsl(var(--shadow-color) / 0.09);
|
|
}
|
|
|
|
/* Warm neutral palette — light mode only.
|
|
Applied when: (a) OS is light and no data-theme override, or (b) explicit light override.
|
|
Dark mode (OS or explicit) falls back entirely to Pico's own dark tokens. */
|
|
@media (prefers-color-scheme: light) {
|
|
:root:not([data-theme]) {
|
|
--pico-background-color: #F7F5F2;
|
|
--pico-card-background-color: #FDFCFB;
|
|
--pico-card-border-color: #E8E4DF;
|
|
--pico-color: #2C2C2C;
|
|
--pico-muted-color: #888880;
|
|
--color-label: #555550;
|
|
--pico-muted-border-color: #E0DCD7;
|
|
--pico-primary: #5B7FA6;
|
|
--pico-primary-background: rgba(91, 127, 166, 0.08);
|
|
--pico-secondary-background: rgba(0, 0, 0, 0.03);
|
|
}
|
|
}
|
|
|
|
[data-theme=light] {
|
|
--pico-background-color: #F7F5F2;
|
|
--pico-card-background-color: #FDFCFB;
|
|
--pico-card-border-color: #E8E4DF;
|
|
--pico-color: #2C2C2C;
|
|
--pico-muted-color: #888880;
|
|
--color-label: #555550;
|
|
--pico-muted-border-color: #E0DCD7;
|
|
--pico-primary: #5B7FA6;
|
|
--pico-primary-background: rgba(91, 127, 166, 0.08);
|
|
--pico-secondary-background: rgba(0, 0, 0, 0.03);
|
|
}
|
|
|
|
/* --color-label: Pico doesn't define this var, so we must set it for dark too */
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not([data-theme]) { --color-label: #a0a09a; }
|
|
}
|
|
[data-theme=dark] { --color-label: #a0a09a; }
|
|
|
|
/* ── DAN MODE ──────────────────────────────────────────────────────────────── */
|
|
/* Screaming bright colors. Offensive to the eyes by design. */
|
|
[data-theme=dan] {
|
|
color-scheme: light;
|
|
|
|
/* Base */
|
|
--pico-background-color: #ffffff;
|
|
--pico-color: #0000ff;
|
|
--pico-muted-color: #ff6600;
|
|
--pico-muted-border-color: #ff00ff;
|
|
--pico-border-radius: 0; /* sharp corners — brutalist */
|
|
|
|
/* Pico's default box-shadow has grey in it — nuke it */
|
|
--pico-box-shadow: 0 0 0 2px #ff00ff, 0 0 12px 2px #ffff00;
|
|
|
|
/* Cards / article */
|
|
--pico-card-background-color: #ffffff;
|
|
--pico-card-border-color: #ff00ff;
|
|
--pico-card-box-shadow: 0 0 0 2px #ff00ff, 0 0 12px 4px #ffff00;
|
|
--pico-card-sectioning-background-color: #ffff00;
|
|
|
|
/* Primary — nuclear yellow */
|
|
--pico-primary: #cccc00;
|
|
--pico-primary-background: #ffff00;
|
|
--pico-primary-border: #ff0000;
|
|
--pico-primary-hover: #ff0000;
|
|
--pico-primary-hover-background: #ff0000;
|
|
--pico-primary-hover-border: #ff0000;
|
|
--pico-primary-focus: rgba(255, 0, 0, 0.6);
|
|
--pico-primary-inverse: #000000;
|
|
|
|
/* Secondary — hot magenta */
|
|
--pico-secondary: #ff00ff;
|
|
--pico-secondary-background: #ff00ff;
|
|
--pico-secondary-border: #ff00ff;
|
|
--pico-secondary-hover: #ff44ff;
|
|
--pico-secondary-hover-background: #cc00cc;
|
|
--pico-secondary-hover-border: #cc00cc;
|
|
--pico-secondary-inverse: #ffff00;
|
|
--pico-secondary-focus: rgba(255, 0, 255, 0.5);
|
|
|
|
/* Contrast */
|
|
--pico-contrast: #000000;
|
|
--pico-contrast-background: #000000;
|
|
--pico-contrast-inverse: #ffff00;
|
|
|
|
/* Form elements — bright yellow bg, magenta borders, blue text */
|
|
--pico-form-element-background-color: #ffff00;
|
|
--pico-form-element-selected-background-color: #ffcc00;
|
|
--pico-form-element-border-color: #ff00ff;
|
|
--pico-form-element-color: #0000ff;
|
|
--pico-form-element-placeholder-color: #0000cc;
|
|
--pico-form-element-active-background-color: #ffff00;
|
|
--pico-form-element-active-border-color: #ff0000;
|
|
--pico-form-element-focus-color: rgba(255, 0, 0, 0.7);
|
|
|
|
/* Dropdown */
|
|
--pico-dropdown-background-color: #ffff00;
|
|
--pico-dropdown-border-color: #ff00ff;
|
|
--pico-dropdown-color: #0000ff;
|
|
--pico-dropdown-hover-background-color: #ff00ff;
|
|
|
|
/* App-specific */
|
|
--color-label: #ff0000;
|
|
}
|
|
|
|
/* Body background */
|
|
[data-theme=dan] body {
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
/* Article (ConverterCard wrapper) — override Pico's grey box-shadow */
|
|
[data-theme=dan] article {
|
|
background: #ffffff;
|
|
border: 2px solid #ff00ff;
|
|
box-shadow: 0 0 0 2px #ffff00, 0 0 20px 4px #ff00ff;
|
|
}
|
|
|
|
/* Input + select — yellow bg, magenta border, blue text */
|
|
[data-theme=dan] input,
|
|
[data-theme=dan] select {
|
|
background-color: #ffff00 !important;
|
|
border-color: #ff00ff !important;
|
|
color: #0000ff !important;
|
|
}
|
|
|
|
[data-theme=dan] input:focus,
|
|
[data-theme=dan] select:focus {
|
|
border-color: #ff0000 !important;
|
|
box-shadow: 0 0 0 3px rgba(255, 0, 0, 0.5) !important;
|
|
}
|
|
|
|
/* Dan Mode: result tile */
|
|
[data-theme=dan] .result-tile {
|
|
--pico-color: initial;
|
|
color: #0000ff;
|
|
background-color: #ffffff;
|
|
border: 2px solid #ff00ff;
|
|
box-shadow: 0 0 6px 1px #ffff00;
|
|
}
|
|
|
|
[data-theme=dan] .result-tile:hover,
|
|
[data-theme=dan] .result-tile.highlighted {
|
|
background-color: #ffff00;
|
|
border-color: #ff0000;
|
|
color: #000000;
|
|
box-shadow: 0 0 16px 4px #ff00ff, 0 0 4px 1px #ff0000;
|
|
}
|
|
|
|
[data-theme=dan] .result-label {
|
|
color: #ff0000;
|
|
}
|
|
|
|
/* Dan Mode: highlight bar */
|
|
[data-theme=dan] .highlighted-result {
|
|
background-color: #ffff00;
|
|
border-color: #ff0000 !important;
|
|
box-shadow: 0 0 0 2px #ff00ff, 0 0 20px 6px #ff0000;
|
|
}
|
|
|
|
[data-theme=dan] .highlighted-placeholder {
|
|
color: #ff0000;
|
|
}
|
|
|
|
[data-theme=dan] .highlighted-eq-from,
|
|
[data-theme=dan] .highlighted-eq-to {
|
|
color: #000000;
|
|
}
|
|
|
|
[data-theme=dan] .highlighted-eq-sep {
|
|
color: #ff0000;
|
|
}
|
|
|
|
/* Dan Mode: nav / header */
|
|
[data-theme=dan] header {
|
|
background-color: #ffff00;
|
|
border-bottom: 3px solid #ff00ff;
|
|
box-shadow: 0 4px 0 #ff0000;
|
|
}
|
|
|
|
[data-theme=dan] header strong {
|
|
color: #ff0000;
|
|
}
|
|
|
|
[data-theme=dan] header nav a {
|
|
color: #0000ff !important;
|
|
font-weight: 700;
|
|
}
|
|
|
|
[data-theme=dan] header nav a:hover {
|
|
color: #ff0000 !important;
|
|
}
|
|
|
|
/* Hotkey hint */
|
|
[data-theme=dan] .hotkey-hint {
|
|
color: #ff00ff;
|
|
}
|
|
|
|
/* Footer */
|
|
[data-theme=dan] footer {
|
|
background-color: #ffff00;
|
|
border-top: 3px solid #ff00ff;
|
|
color: #ff0000;
|
|
}
|
|
|
|
/* ── Dan Mode banner ───────────────────────────────────────────────────────── */
|
|
.dan-banner {
|
|
background-color: #ff0000;
|
|
color: #ffff00;
|
|
text-align: center;
|
|
font-weight: 900;
|
|
font-size: 1.2rem;
|
|
letter-spacing: 0.2em;
|
|
padding: 0.5rem 1rem;
|
|
border-bottom: 3px solid #ffff00;
|
|
animation: dan-blink 1.2s step-start infinite;
|
|
}
|
|
|
|
@keyframes dan-blink {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0; }
|
|
}
|
|
|
|
/* ── Results grid ──────────────────────────────────────────────────────────── */
|
|
/* Responsive column count: minimum 1 col mobile, 2 col tablet, 3 col desktop.
|
|
Uses auto-fill + minmax so extra columns appear automatically when there's
|
|
room — floor(availableWidth / minCardWidth) columns at any given width.
|
|
minmax values chosen so the minimum column count is enforced at each breakpoint:
|
|
<480px → 1 col min (cards can be full-width)
|
|
≥480px → 2 col min (minmax(220px) → ⌊480/220⌋ = 2)
|
|
≥900px → 3 col min (minmax(280px) → ⌊900/280⌋ = 3) */
|
|
.results-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: var(--grid-gap);
|
|
margin-top: 1.5rem;
|
|
}
|
|
|
|
@media (min-width: 480px) {
|
|
.results-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (min-width: 900px) {
|
|
.results-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
}
|
|
}
|
|
|
|
/* ── Result tile ───────────────────────────────────────────────────────────── */
|
|
.result-tile {
|
|
cursor: pointer;
|
|
padding: 0.75rem 1rem;
|
|
background-color: var(--pico-card-background-color);
|
|
border: 1px solid var(--pico-card-border-color);
|
|
border-radius: var(--pico-border-radius, 0.25rem);
|
|
box-shadow: var(--shadow-low);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.2rem;
|
|
/* Fixed two-line height so all cards are the same size */
|
|
min-height: 4.5rem;
|
|
justify-content: center;
|
|
transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
|
user-select: none;
|
|
/* Pico's [role=button] rule sets --pico-color: var(--pico-primary-inverse)
|
|
which is #fff in light mode — making text invisible on white cards.
|
|
Override it back to the body text color on the tile itself so children inherit correctly. */
|
|
--pico-color: initial;
|
|
color: var(--pico-contrast, #181c25);
|
|
}
|
|
|
|
.result-tile:hover,
|
|
.result-tile.highlighted {
|
|
border-color: var(--pico-primary);
|
|
box-shadow: var(--shadow-medium);
|
|
}
|
|
|
|
.result-value {
|
|
font-size: var(--card-font-size, 1rem);
|
|
font-weight: 600;
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
/* color inherits from .result-tile which has already corrected for Pico's button reset */
|
|
}
|
|
|
|
.result-label {
|
|
font-size: var(--card-font-size, 0.85rem);
|
|
color: var(--color-label);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
/* .result-symbol removed — symbol is now rendered inline in the label */
|
|
|
|
/* ── Highlighted result (above grid) ──────────────────────────────────────── */
|
|
.highlighted-result {
|
|
/* Fixed height that never changes whether populated or empty */
|
|
height: 5rem;
|
|
margin-bottom: 1.5rem;
|
|
border-radius: var(--pico-border-radius, 0.25rem);
|
|
background-color: var(--pico-card-background-color);
|
|
border: 2px solid transparent; /* always present, color changes */
|
|
box-shadow: var(--shadow-medium);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.3rem;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: border-color 0.2s ease;
|
|
text-align: center;
|
|
container-type: inline-size;
|
|
}
|
|
|
|
.highlighted-result.has-highlight {
|
|
border-color: var(--pico-primary);
|
|
}
|
|
|
|
/* Equation row: inline on wide screens, over-under on narrow */
|
|
.highlighted-equation {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-wrap: nowrap;
|
|
gap: 0.4em;
|
|
font-size: clamp(1rem, 2.5cqi, 1.5rem);
|
|
font-weight: 600;
|
|
font-variant-numeric: tabular-nums;
|
|
color: var(--pico-color);
|
|
word-break: break-all;
|
|
text-align: center;
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* Switch to stacked layout when the container gets tight */
|
|
@container (max-width: 420px) {
|
|
.highlighted-equation {
|
|
flex-direction: column;
|
|
gap: 0.15em;
|
|
}
|
|
|
|
.highlighted-eq-sep {
|
|
display: none;
|
|
}
|
|
|
|
.highlighted-eq-to::before {
|
|
content: '= ';
|
|
color: var(--pico-muted-color, #888880);
|
|
font-weight: 400;
|
|
}
|
|
}
|
|
|
|
.highlighted-eq-from,
|
|
.highlighted-eq-to {
|
|
/* same size, same color — both use the container-relative font above */
|
|
}
|
|
|
|
.highlighted-eq-sep {
|
|
color: var(--pico-muted-color, #888880);
|
|
font-weight: 400;
|
|
}
|
|
|
|
.highlighted-placeholder {
|
|
font-size: 0.9rem;
|
|
color: var(--pico-muted-color, #888880);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* ── Converter controls ────────────────────────────────────────────────────── */
|
|
.converter-controls {
|
|
display: flex;
|
|
gap: 1rem;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.converter-controls input[type='number'] {
|
|
flex: 1 1 200px;
|
|
min-width: 120px;
|
|
}
|
|
|
|
.converter-controls select {
|
|
flex: 0 1 auto;
|
|
min-width: 160px;
|
|
}
|
|
|
|
/* ── Input unit tile indicator ─────────────────────────────────────────────── */
|
|
.result-tile.is-input-unit {
|
|
border-style: dashed;
|
|
border-color: var(--pico-primary);
|
|
opacity: 0.85;
|
|
}
|
|
|
|
/* ── Highlight dismiss button ──────────────────────────────────────────────── */
|
|
.highlight-dismiss {
|
|
position: absolute;
|
|
top: 0.4rem;
|
|
right: 0.6rem;
|
|
background: none;
|
|
border: none;
|
|
font-size: 1.1rem;
|
|
color: var(--pico-muted-color, #888880);
|
|
cursor: pointer;
|
|
padding: 0.2rem 0.4rem;
|
|
line-height: 1;
|
|
}
|
|
.highlight-dismiss:hover {
|
|
color: var(--pico-color, #2C2C2C);
|
|
}
|
|
|
|
/* ── Hotkey hint ───────────────────────────────────────────────────────────── */
|
|
.hotkey-hint {
|
|
margin-top: 1rem;
|
|
margin-bottom: 0;
|
|
color: var(--pico-muted-color, #666);
|
|
text-align: center;
|
|
}
|
|
|
|
/* ── Theme toggle button ───────────────────────────────────────────────────── */
|
|
.theme-toggle {
|
|
width: auto;
|
|
padding: 0.25rem 0.5rem;
|
|
margin-bottom: 0;
|
|
font-size: 1rem;
|
|
line-height: 1;
|
|
border-radius: var(--pico-border-radius);
|
|
}
|
|
|
|
/* ── Custom tooltip ────────────────────────────────────────────────────────── */
|
|
.hu-tooltip {
|
|
position: fixed;
|
|
z-index: 9999;
|
|
max-width: 280px;
|
|
padding: 0.4rem 0.6rem;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
line-height: 1.4;
|
|
background: #1a1a2e;
|
|
color: #f0f0f0;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.35);
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: opacity 0.15s ease;
|
|
white-space: pre-wrap;
|
|
}
|
|
.hu-tooltip--visible {
|
|
opacity: 1;
|
|
}
|
|
[data-theme=dan] .hu-tooltip {
|
|
background: #000;
|
|
color: #ffff00;
|
|
border: 1px solid #ff00ff;
|
|
box-shadow: 0 0 8px #ff00ff;
|
|
}
|
|
|
|
/* ── Description indicator (ⓘ) ────────────────────────────────────────────── */
|
|
[data-theme=dan] .desc-indicator {
|
|
color: #ff00ff;
|
|
opacity: 1;
|
|
}
|