Files
uncensored-send/web/static/style.css
T

297 lines
8.4 KiB
CSS

/* Hand-written, no build step, no framework. */
:root {
--bg: #f6f6f4;
--fg: #1b1b18;
--muted: #6b6b63;
--card: #ffffff;
--line: #dcdcd5;
--accent: #2f6f4f;
--accent-fg: #ffffff;
--danger: #9b2c2c;
--warn-bg: #fdf6e3;
--radius: 10px;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #16161a;
--fg: #e8e8e3;
--muted: #9a9a92;
--card: #1f1f25;
--line: #33333c;
--accent: #5fae86;
--accent-fg: #10241a;
--danger: #e07070;
--warn-bg: #2a2418;
}
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 0 1rem 3rem;
background: var(--bg);
color: var(--fg);
font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}
header, main, footer { max-width: 42rem; margin: 0 auto; }
header { padding: 1.5rem 0; }
footer { padding-top: 2rem; color: var(--muted); font-size: .875rem; }
.brand {
font-weight: 600;
font-size: 1.125rem;
color: var(--fg);
text-decoration: none;
}
h1 { font-size: 1.375rem; margin: 0 0 .75rem; }
h2 { font-size: 1rem; margin: 0 0 .5rem; }
a { color: var(--accent); }
.card, .limits, .cli {
background: var(--card);
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 1.25rem;
margin-bottom: 1.25rem;
}
.field { display: block; margin-bottom: 1rem; }
.field > span { display: block; font-size: .8125rem; color: var(--muted); margin-bottom: .25rem; }
.field em { font-style: normal; opacity: .7; }
input[type=text], input[type=password] {
width: 100%;
padding: .5rem .625rem;
font: inherit;
color: var(--fg);
background: var(--bg);
border: 1px solid var(--line);
border-radius: 6px;
}
.row { display: flex; gap: 1rem; flex-wrap: wrap; }
.row > .field { flex: 1 1 12rem; }
/* The file input has to be the last part in the submitted body, so it sits at
the bottom of the form's markup and is lifted back to the top here. Only the
painting order moves; the submission order, which the server depends on, is
the markup's. */
#upload { display: flex; flex-direction: column; }
#upload > .drop { order: -1; }
#upload > button { align-self: flex-start; }
/* An author `display` beats the browser's own [hidden] rule, so anything given
a display here has to say what hidden means for it. */
#upload[hidden] { display: none; }
.drop {
border: 2px dashed var(--line);
border-radius: var(--radius);
padding: 1.5rem;
text-align: center;
margin-bottom: 1rem;
transition: border-color .15s, background .15s;
}
.drop.over { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.drop input[type=file] { max-width: 100%; }
button, .button {
display: inline-block;
padding: .5rem 1rem;
font: inherit;
font-weight: 500;
color: var(--accent-fg);
background: var(--accent);
border: 0;
border-radius: 6px;
cursor: pointer;
text-decoration: none;
}
button:disabled { opacity: .55; cursor: default; }
button.danger { background: var(--danger); color: #fff; }
.progress .bar {
height: .5rem;
background: var(--line);
border-radius: 999px;
overflow: hidden;
margin-bottom: .375rem;
}
.progress .fill { height: 100%; width: 0; background: var(--accent); transition: width .1s linear; }
.hint { color: var(--muted); font-size: .875rem; margin: .25rem 0 0; }
#error:not([hidden]) { color: var(--danger); }
dl { display: grid; grid-template-columns: auto 1fr; gap: .25rem 1rem; margin: 0; }
dt { color: var(--muted); font-size: .875rem; }
dd { margin: 0; }
.mono, pre, code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8125rem; }
.wrap { overflow-wrap: anywhere; }
.filename { overflow-wrap: anywhere; }
pre {
margin: 0;
padding: .75rem;
background: var(--bg);
border: 1px solid var(--line);
border-radius: 6px;
overflow-x: auto;
}
.warn {
margin: 1.25rem 0;
padding: 1rem;
background: var(--warn-bg);
border: 1px solid var(--line);
border-radius: var(--radius);
}
.warn p { margin: .25rem 0 .75rem; font-size: .875rem; }
.result .field { margin-top: 1rem; }
.check { display: flex; align-items: center; gap: .5rem; margin-bottom: 1rem; font-size: .875rem; }
.check input { margin: 0; }
.notice {
margin: 0 0 1rem;
padding: .625rem .875rem;
background: var(--card);
border: 1px solid var(--line);
border-left: 3px solid var(--accent);
border-radius: 6px;
font-size: .875rem;
}
.notice .forget-form, .notice form { display: inline; }
button.link {
padding: 0;
background: none;
border: 0;
color: var(--accent);
font: inherit;
text-decoration: underline;
cursor: pointer;
}
/* Result card ------------------------------------------------------------ */
.result .links { margin: 1.25rem 0 0; }
.result .links .field { margin-bottom: 1rem; }
/* A read-only URL with its copy button alongside. */
.copyrow { display: flex; gap: .5rem; align-items: stretch; }
.copyrow input { flex: 1 1 auto; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8125rem; }
.copyrow .copy { flex: 0 0 auto; }
/* Keep the detail list clear of the copy buttons above it. */
.result dl { margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.result dl dd { margin-bottom: .25rem; }
.result .actions { margin: 1.5rem 0 0; }
@media (max-width: 26rem) {
.copyrow { flex-wrap: wrap; }
.copyrow input { flex-basis: 100%; }
}
/* Administration --------------------------------------------------------- */
header { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
header nav {
margin-left: auto;
display: flex;
align-items: baseline;
gap: .875rem;
font-size: .875rem;
}
header nav form { display: inline; }
header nav .who { color: var(--muted); }
header nav .who::before { content: "\1F511\00a0"; }
/* A listing needs far more room than the reading measure a form wants. */
body.wide header,
body.wide main,
body.wide footer { max-width: 72rem; }
dl.stats { grid-template-columns: auto 1fr; }
dl.stats em { font-style: normal; color: var(--muted); }
table.admin { border-collapse: collapse; width: 100%; font-size: .8125rem; }
table.admin th,
table.admin td {
padding: .45rem .5rem;
text-align: left;
vertical-align: top;
border-bottom: 1px solid var(--line);
}
table.admin th { color: var(--muted); font-weight: 500; white-space: nowrap; }
table.admin th a { color: inherit; text-decoration: none; }
table.admin th a:hover { color: var(--accent); text-decoration: underline; }
table.admin tr:last-child td { border-bottom: 0; }
table.admin .num { text-align: right; }
table.admin .nowrap { white-space: nowrap; }
table.admin form { margin: 0; }
table.admin .actions-cell { text-align: right; width: 1%; }
/* The filename carries the link and the identifier sits under it, which saves
a whole column of UUID. */
table.admin .filecell a { overflow-wrap: anywhere; font-weight: 500; }
table.admin .filecell .id {
display: block;
font-size: .6875rem;
color: var(--muted);
overflow-wrap: anywhere;
}
button.small { padding: .2rem .5rem; font-size: .75rem; }
.visually-hidden {
position: absolute;
width: 1px; height: 1px;
margin: -1px; padding: 0; border: 0;
clip-path: inset(50%);
overflow: hidden;
}
/* Narrow screens get one card per row rather than a horizontal scrollbar,
which is unusable for picking a row and pressing a button in it. */
@media (max-width: 46rem) {
table.admin,
table.admin tbody,
table.admin tr,
table.admin td { display: block; width: 100%; }
table.admin thead { display: none; }
table.admin tr {
padding: .625rem 0;
border-bottom: 1px solid var(--line);
}
table.admin td { border: 0; padding: .1rem 0; }
table.admin td[data-label]::before {
content: attr(data-label) ": ";
color: var(--muted);
}
table.admin .num,
table.admin .actions-cell { text-align: left; width: auto; }
table.admin .actions-cell { padding-top: .5rem; }
table.admin .filecell::before { content: none; }
}
.cli code, .hint code { background: var(--bg); padding: .1rem .3rem; border-radius: 4px; }
/* One-off token, tucked away so the common path stays a single button. */
.onceoff { margin-bottom: 1rem; }
.onceoff summary { font-weight: 400; font-size: .875rem; color: var(--muted); }
.onceoff .field { max-width: 24rem; }
.limits .hint { margin-top: .75rem; }
.limits dl, .card dl { row-gap: .375rem; }
/* Actions that mix a link-button with a form-button. */
.actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.actions form { margin: 0; }