Files
webmail-client/frontend/src/index.css
T

274 lines
6.7 KiB
CSS
Raw Normal View History

2026-07-17 23:20:34 +02:00
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Lato (SIL OFL) — the UI font. Browsers only fetch the weights/styles actually
rendered, so declaring the full family is cheap. */
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Thin.ttf") format("truetype");
font-weight: 100;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-ThinItalic.ttf") format("truetype");
font-weight: 100;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-LightItalic.ttf") format("truetype");
font-weight: 300;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Italic.ttf") format("truetype");
font-weight: 400;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-BoldItalic.ttf") format("truetype");
font-weight: 700;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Lato";
src: url("../fonts/Lato-BlackItalic.ttf") format("truetype");
font-weight: 900;
font-style: italic;
font-display: swap;
}
2026-07-17 23:20:34 +02:00
/* Semantic theme tokens as "R G B" triplets (consumed by tailwind.config.js as
rgb(var(--x) / <alpha>)). Light is the default; .dark on <html> flips them. */
:root {
--app-bg: 243 244 246; /* app chrome behind panels */
--app-surface: 255 255 255; /* panels */
--app-elevated: 255 255 255; /* popovers, composer */
--app-border: 229 231 235;
--app-fg: 24 27 32;
--app-muted: 107 114 128;
--app-faint: 156 163 175;
--app-accent: 37 99 235;
--app-accent-fg: 255 255 255;
--app-hover: 243 244 246;
--app-active: 224 233 254; /* selected row */
color-scheme: light;
}
:root.dark {
--app-bg: 27 30 32; /* main background */
--app-surface: 33 36 39; /* panels (slightly elevated) */
--app-elevated: 39 42 46; /* popovers, composer */
2026-07-19 18:58:01 +02:00
--app-border: 58 62 68; /* dark dividers (brighter) */
2026-07-17 23:20:34 +02:00
--app-fg: 226 228 231;
--app-muted: 150 156 164;
--app-faint: 108 114 122;
--app-accent: 59 130 246;
--app-accent-fg: 255 255 255;
--app-hover: 42 46 50;
--app-active: 44 54 70;
color-scheme: dark;
}
html,
body,
#root {
height: 100%;
margin: 0;
}
body {
font-family: "Lato", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
2026-07-17 23:20:34 +02:00
background-color: rgb(var(--app-bg));
color: rgb(var(--app-fg));
-webkit-font-smoothing: antialiased;
}
/* Rich-text compose editor: quoted replies get depth-colored left borders
(blue → green → amber), matching a Fastmail-style nested quote. */
.wmc-editor {
line-height: 1.55;
}
.wmc-editor:empty::before {
content: "";
}
.wmc-editor a {
color: rgb(var(--app-accent));
text-decoration: underline;
}
.wmc-editor ul {
list-style: disc;
padding-left: 1.4em;
}
.wmc-editor ol {
list-style: decimal;
padding-left: 1.4em;
}
.wmc-editor img {
max-width: 100%;
height: auto;
}
.wmc-editor blockquote {
margin: 0.5em 0;
padding: 0.35em 0.9em;
border-left: 2px solid #5b7fb9;
border-radius: 2px;
background: rgba(120, 140, 170, 0.06);
}
.wmc-editor blockquote blockquote {
border-left-color: #6a9955;
background: rgba(120, 160, 120, 0.06);
}
.wmc-editor blockquote blockquote blockquote {
border-left-color: #c08a4a;
background: rgba(180, 150, 100, 0.06);
}
/* The reply's quoted original folds behind a "•••" pill, as in the reading
pane. Only a quote the pill directly precedes is hidden, so deleting the pill
can never leave a quote hidden with no way back to it. */
.wmc-editor .wmc-quote-toggle {
display: inline-block;
margin: 6px 0;
padding: 1px 9px;
border: none;
border-radius: 8px;
background: rgb(var(--app-hover));
color: rgb(var(--app-muted));
cursor: pointer;
font: inherit;
font-size: 15px;
line-height: 1.5;
user-select: none;
}
.wmc-editor .wmc-quote-toggle:hover {
color: rgb(var(--app-fg));
}
.wmc-editor.wmc-quote-collapsed .wmc-quote-toggle + blockquote {
display: none;
}
/* The text a new link will wrap, kept visible while the URL field has focus
(RichTextEditor registers the range; browsers without the Highlight API
simply show nothing extra). */
::highlight(wmc-link-target) {
background-color: rgb(var(--app-accent) / 0.25);
}
/* Spelling (red) and grammar/style (blue) marks from the compose editor's
LanguageTool check, drawn as CSS highlights over the text — never written
into the message (components/compose/spellcheck.ts). */
::highlight(wmc-spell) {
text-decoration: underline wavy #e5484d;
text-decoration-thickness: 1.5px;
text-underline-offset: 3px;
}
::highlight(wmc-grammar) {
text-decoration: underline wavy rgb(var(--app-accent));
text-decoration-thickness: 1.5px;
text-underline-offset: 3px;
}
2026-07-17 23:20:34 +02:00
/* Thin, unobtrusive scrollbars that match the theme. */
* {
scrollbar-width: thin;
scrollbar-color: rgb(var(--app-border)) transparent;
}
*::-webkit-scrollbar {
width: 10px;
height: 10px;
}
*::-webkit-scrollbar-thumb {
background-color: rgb(var(--app-border));
border-radius: 6px;
border: 2px solid transparent;
background-clip: content-box;
}
/* Offline (components/Offline.tsx): buttons that need the server look
unavailable, and their clicks are stopped with a "Not available offline". */
html[data-offline] .wm-online-only {
opacity: 0.4;
cursor: not-allowed;
}
html[data-offline] .wm-online-only:hover {
background-color: transparent;
}
.wm-offline-notice {
animation: wm-offline-in 180ms ease-out;
}
@keyframes wm-offline-in {
from {
opacity: 0;
transform: translate(-50%, 8px);
}
to {
opacity: 1;
transform: translate(-50%, 0);
}
}
/* Attachment tiles (thread/Attachments.tsx) shrink with the reading column so
three fit in a row; their name bar adapts to the tile's own width. */
.wm-tile {
container-type: inline-size;
}
@container (max-width: 160px) {
.wm-tile-icon,
.wm-tile-size {
display: none;
}
.wm-tile-bar {
height: 34px;
gap: 6px;
padding-inline: 6px;
}
}
@container (max-width: 80px) {
/* Too small for a name: the picture (or icon) alone; a click still opens it. */
.wm-tile-bar {
display: none;
}
.wm-tile-art {
bottom: 0;
}
}