Reverts PR #297's column reorder (owner override): URL returns to position 6 in both list tables (Paste, Type, Size, Views, Created, URL, ID; /mine without Views), data-sort attrs and td cells move back together. Keeps #297's non-position improvements: /mine URL uses the shared .col-url class instead of reusing col-e, and mine's ID column returns to .col-f (100px). Widens .col-url 150px -> 340px so a ~20-char slug displays fully at 1400x900; genuinely long custom slugs keep text ellipsis. No mobile media query needed: <=640px already scrolls the table horizontally (min-width 720px), verified at 375x812. Verified via CDP probe at 1400x900 and 375x812 on /history and /mine: column order, colgroup/header alignment, sort arrow right of label, no other column clipped, no CSP changes (no inline styles added).
945 lines
45 KiB
CSS
945 lines
45 KiB
CSS
/* Palette UI tokens (mirrors sketches/themes/tokens.css, midnight approved preset) */
|
||
:root {
|
||
--bg: #241B30; --surface: #2D2340; --surface-2: #3A2D52;
|
||
--muted: #7A6A9E; --muted-fg: #C0B2DE; --fg: #F2EDF8;
|
||
--accent: #C4A8F0; --border: #42355C;
|
||
--radius-lg: 20px; --radius: 10px; --radius-sm: 999px;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23C8C8D4' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: select chevron stroke (dark presets) */
|
||
--chevron-fg: #C8C8D4;
|
||
--font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||
--font-mono: ui-monospace, "JetBrains Mono", "Fira Code", monospace;
|
||
}
|
||
/* semantic status colors (dark preset values; light presets override below) */
|
||
:root {
|
||
--ok: #9CD49C; --warn: #E8C77B; --err: #F2A3B3;
|
||
--on-accent: #241B30; /* text placed on accent-colored backgrounds */
|
||
}
|
||
[data-preset="smooth"] {
|
||
--bg: #F6F5FA; --surface: #FFFFFF; --surface-2: #DAD7E6;
|
||
--muted: #B5B1C9; --muted-fg: #7A7796; --fg: #2A2A36;
|
||
--accent: #7A7796; --border: #DAD7E6;
|
||
--ok: #456F45; --warn: #7A5E1B; --err: #9E4054;
|
||
--on-accent: #F6F5FA;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555560' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: light presets use a dark stroke */
|
||
--chevron-fg: #555560;
|
||
}
|
||
[data-preset="pastel-lavender"] {
|
||
--bg: #e6e0f5; --surface: #f1edfa; --surface-2: #cbb8e7;
|
||
--muted: #a99cc9; --muted-fg: #5f5390; --fg: #3E3059;
|
||
--accent: #806bb8; --border: #c4b6e0;
|
||
--ok: #3E6B3E; --warn: #7A5E1B; --err: #9E4054;
|
||
--on-accent: #f1edfa;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555560' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: light presets use a dark stroke */
|
||
--chevron-fg: #555560;
|
||
}
|
||
[data-preset="pastel-peach"] {
|
||
--bg: #ffe0d6; --surface: #fff0ea; --surface-2: #ffc4a8;
|
||
--muted: #d9a08c; --muted-fg: #7a4632; --fg: #4F2318;
|
||
--accent: #f9826c; --border: #ffc9b5;
|
||
--ok: #3E6B3E; --warn: #7A5E1B; --err: #9E4054;
|
||
--on-accent: #4F2318;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555560' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: light presets use a dark stroke */
|
||
--chevron-fg: #555560;
|
||
}
|
||
[data-preset="pastel-cloud"] {
|
||
--bg: #fff0f6; --surface: #fff7fb; --surface-2: #ffc8dd;
|
||
--muted: #d9b9c9; --muted-fg: #7d5670; --fg: #4A3355;
|
||
--accent: #a2d2ff; --border: #ffccd9;
|
||
--ok: #3E6B3E; --warn: #7A5E1B; --err: #9E4054;
|
||
--on-accent: #274a6b;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555560' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: light presets use a dark stroke */
|
||
--chevron-fg: #555560;
|
||
}
|
||
/* matching light/dark counterparts: same hue family, flipped lightness roles */
|
||
/* Midnight Light: light counterpart of midnight (violet family) */
|
||
[data-preset="midnight-light"] {
|
||
--bg: #F3EFF9; --surface: #FAF8FD; --surface-2: #E1D9EF;
|
||
--muted: #A99CC9; --muted-fg: #5F5390; --fg: #2B2140;
|
||
--accent: #7B5FC0; --border: #D8CEEC;
|
||
--ok: #3E6B3E; --warn: #7A5E1B; --err: #9E4054;
|
||
--on-accent: #FAF8FD;
|
||
--chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555560' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* #136: light presets use a dark stroke */
|
||
--chevron-fg: #555560;
|
||
}
|
||
/* Smooth Dark: dark counterpart of smooth (muted slate-violet family) */
|
||
[data-preset="smooth-dark"] {
|
||
--bg: #23222E; --surface: #2C2B3A; --surface-2: #3B3A4D;
|
||
--muted: #7A7796; --muted-fg: #B5B1C9; --fg: #E8E7F0;
|
||
--accent: #A9A6C4; --border: #45435A;
|
||
--ok: #9CD49C; --warn: #E8C77B; --err: #F2A3B3;
|
||
--on-accent: #23222E;
|
||
}
|
||
/* Pastel Lavender Dark: dark counterpart (lavender family) */
|
||
[data-preset="pastel-lavender-dark"] {
|
||
--bg: #2A2340; --surface: #352C50; --surface-2: #4A3E6B;
|
||
--muted: #8F7FB8; --muted-fg: #CBBEE8; --fg: #EFEAF8;
|
||
--accent: #B39DE4; --border: #4E4272;
|
||
--ok: #9CD49C; --warn: #E8C77B; --err: #F2A3B3;
|
||
--on-accent: #2A2340;
|
||
}
|
||
/* Pastel Peach Dark: dark counterpart (peach family) */
|
||
[data-preset="pastel-peach-dark"] {
|
||
--bg: #3A241C; --surface: #4A2F24; --surface-2: #654234;
|
||
--muted: #B07A64; --muted-fg: #F0C4B0; --fg: #FBEBE2;
|
||
--accent: #F9826C; --border: #75503F;
|
||
--ok: #9CD49C; --warn: #E8C77B; --err: #F2A3B3;
|
||
--on-accent: #3A241C;
|
||
}
|
||
/* Pastel Cloud Dark: dark counterpart (pink cloud family, blue accent) */
|
||
[data-preset="pastel-cloud-dark"] {
|
||
--bg: #33222E; --surface: #402C3A; --surface-2: #583D50;
|
||
--muted: #A87E97; --muted-fg: #E5C2D6; --fg: #FAEEF5;
|
||
--accent: #A2D2FF; --border: #644759;
|
||
--ok: #9CD49C; --warn: #E8C77B; --err: #F2A3B3;
|
||
--on-accent: #33222E;
|
||
}
|
||
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body {
|
||
font-family: var(--font-body);
|
||
background: var(--bg);
|
||
color: var(--fg);
|
||
line-height: 1.45;
|
||
-webkit-font-smoothing: antialiased;
|
||
min-height: 100vh;
|
||
font-size: 24.2px;
|
||
}
|
||
.topbar {
|
||
display: flex; align-items: center; gap: 20px;
|
||
padding: 0 22px; height: 76px;
|
||
background: var(--surface); border-bottom: 1px solid var(--border);
|
||
}
|
||
.logo { font-weight: 700; font-size: 27.6px; letter-spacing: -0.02em; text-decoration: none; color: var(--fg); }
|
||
.logo em { font-style: normal; color: var(--muted-fg); font-weight: 400; }
|
||
.topbar nav { display: flex; gap: 4px; }
|
||
.topbar nav a { color: var(--muted-fg); text-decoration: none; padding: 6px 12px; border-radius: var(--radius); font-size: 23.2px; }
|
||
.topbar nav a:hover { background: var(--surface-2); color: var(--fg); }
|
||
.topbar nav a.on { background: var(--accent); color: var(--bg); }
|
||
.topbar .spacer { flex: 1; }
|
||
.kbd { font-family: var(--font-mono); font-size: 18.9px; border: 1px solid var(--border); border-radius: var(--radius); padding: 2px 6px; color: var(--muted-fg); }
|
||
|
||
.float {
|
||
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
|
||
box-shadow:
|
||
0 1px 2px rgba(0, 0, 0, .10),
|
||
0 2px 6px rgba(0, 0, 0, .08),
|
||
0 8px 24px rgba(0, 0, 0, .07);
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* new paste page */
|
||
.deck {
|
||
display: grid; grid-template-columns: 1fr 300px; gap: 16px;
|
||
padding: 16px 20px 20px; height: calc(100vh - 76px);
|
||
max-width: 1400px; margin: 0 auto;
|
||
}
|
||
.pane-r { display: flex; flex-direction: column; gap: 16px; overflow-y: auto; padding-bottom: 4px; }
|
||
.side-section { padding: 14px 16px; flex-shrink: 0; }
|
||
.side-section h3 { font-size: 18.9px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted-fg); margin-bottom: 10px; }
|
||
.pane-l-col { display: flex; flex-direction: column; gap: 14px; min-height: 0; }
|
||
.pane-l-head { flex-shrink: 0; }
|
||
.editor-head {
|
||
display: flex; align-items: stretch; gap: 12px; padding: 12px 16px;
|
||
}
|
||
/* #147: title lives in its own pill; select+refresh stay paired in a second pill */
|
||
.editor-head-title,
|
||
.editor-head-settings {
|
||
display: flex; align-items: center; gap: 8px;
|
||
background: var(--surface-2); border: 1px solid var(--border);
|
||
border-radius: var(--radius); padding: 6px 10px;
|
||
}
|
||
.editor-head-title { flex: 1; min-width: 0; }
|
||
.editor-head-settings { flex: 0 0 fit-content; }
|
||
.editor-head-title:focus-within { border-color: var(--accent); }
|
||
.editor-head input {
|
||
border: none; outline: none; background: transparent; color: var(--fg); font: inherit; font-size: 23.2px; flex: 1;
|
||
}
|
||
.editor-head select {
|
||
border: 1px solid var(--border); background-color: var(--surface-2); color: var(--muted-fg);
|
||
border-radius: var(--radius); padding: 4px 10px; font: inherit; font-size: 21.6px; cursor: pointer;
|
||
}
|
||
/* shared code line metrics (#50): gutter + code must share one line box */
|
||
:root { --code-lh: 1.7; --code-fs: 21.6px; }
|
||
|
||
.editor-wrap { flex: 1; display: flex; min-height: 0; }
|
||
.gutter {
|
||
padding: 14px 10px; text-align: right; color: var(--muted); font-family: var(--font-mono);
|
||
font-size: var(--code-fs); line-height: var(--code-lh); user-select: none; white-space: pre; overflow: hidden;
|
||
border-right: 1px solid var(--border);
|
||
}
|
||
.editor {
|
||
flex: 1; padding: 14px 16px; font-family: var(--font-mono); font-size: 21.6px; line-height: 1.7;
|
||
white-space: pre; outline: none; overflow: auto; border: none; background: transparent; color: var(--fg);
|
||
resize: none; width: 100%;
|
||
}
|
||
.editor::placeholder { color: var(--muted); }
|
||
.actionbar {
|
||
display: flex; align-items: center; gap: 14px;
|
||
padding: 10px 4px;
|
||
}
|
||
.actionbar .btn { padding: 10px 26px; }
|
||
.btn {
|
||
background: var(--accent); color: var(--bg); border: none; cursor: pointer;
|
||
padding: 8px 18px; border-radius: var(--radius); font: inherit; font-size: 22.4px; font-weight: 600;
|
||
}
|
||
.btn:hover { filter: brightness(1.08); }
|
||
.hint { font-size: 20.7px; color: var(--muted-fg); }
|
||
.hint b { color: var(--fg); font-weight: 550; }
|
||
.seg { display: flex; flex-direction: column; gap: 2px; }
|
||
.seg label { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: var(--radius); cursor: pointer; font-size: 22.4px; }
|
||
.seg label:hover { background: var(--surface-2); }
|
||
.seg input { accent-color: var(--accent); }
|
||
.toggle { display: flex; align-items: center; gap: 8px; font-size: 22.4px; cursor: pointer; padding: 5px 8px; border-radius: var(--radius); }
|
||
.toggle:hover { background: var(--surface-2); }
|
||
.toggle input { accent-color: var(--accent); }
|
||
.deck .row { display: flex; justify-content: space-between; align-items: center; font-size: 22.4px; padding: 4px 0; }
|
||
.row input[type="text"] {
|
||
border: 1px solid var(--border); border-radius: var(--radius); padding: 5px 8px; background: var(--bg);
|
||
color: var(--fg); font: inherit; font-size: 21.6px; width: 130px;
|
||
}
|
||
/* #168: compact side notification pill (paste-created feedback) */
|
||
.created-pill {
|
||
position: fixed; right: 12px; bottom: 12px; z-index: 200;
|
||
background: var(--surface-2); color: var(--ok); border: 1px solid var(--ok);
|
||
border-radius: var(--radius-sm); padding: 2px 8px; font-size: 11.5px;
|
||
opacity: 0; pointer-events: none; transform: translateY(6px);
|
||
transition: opacity .25s ease, transform .25s ease;
|
||
box-shadow: 0 4px 16px rgba(0,0,0,.25);
|
||
}
|
||
.created-pill.show { opacity: 1; transform: translateY(0); }
|
||
@media (max-width: 640px) { .created-pill { right: 12px; bottom: 12px; } }
|
||
|
||
/* paste view */
|
||
.meta-bar { display: flex; align-items: center; gap: 12px; padding: 12px 18px; flex-wrap: wrap; }
|
||
.meta-bar h1 { font-size: 29.2px; font-weight: 600; }
|
||
.slug { font-family: var(--font-mono); font-size: 21.6px; color: var(--muted-fg); background: var(--surface-2); padding: 3px 9px; border-radius: var(--radius-sm); }
|
||
.tag { font-size: 19.8px; color: var(--muted-fg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px 9px; }
|
||
.paste-title-bar { display: flex; align-items: center; gap: 12px; padding: 12px 18px; flex-wrap: wrap; }
|
||
.paste-title-bar h1 { font-size: 29.2px; font-weight: 600; margin: 0; word-break: normal; overflow-wrap: anywhere; }
|
||
/* #222: .float already draws the border + radius and clips corners; the pill's own
|
||
tighter border curve was getting clipped thin at the corners. Let .float be the
|
||
only border/paint surface for the details pill (collapsed and expanded). */
|
||
.stats-pill { border: 0; border-radius: 0; overflow: hidden; }
|
||
.stats-head { display: flex; align-items: center; gap: 16px; width: 100%; background: none; border: 0; border-bottom: 1px solid var(--border); color: var(--muted-fg); font: inherit; font-size: 21.6px; padding: 14px 18px; cursor: pointer; text-align: left; }
|
||
.stats-head:hover { color: var(--fg); background: var(--surface-2); }
|
||
.stats-chev { width: 18px; height: 18px; flex: none; transition: transform 0.15s ease; }
|
||
.stats-pill.open .stats-chev { transform: rotate(180deg); }
|
||
.stats-summary { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: .01em; }
|
||
@media (max-width: 640px) { .stats-summary { white-space: normal; word-break: break-word; } }
|
||
.stats-body { /* #169: divider under the dropdown title is the head's own persistent border-bottom */ }
|
||
.stats-grid { display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px; padding: 12px 16px; font-size: 20.7px; }
|
||
.stats-k { color: var(--muted-fg); }
|
||
.stats-v { color: var(--fg); word-break: break-all; }
|
||
.meta-bar .spacer { flex: 1; }
|
||
.iconbtn { border: 1px solid var(--border); background: var(--surface-2); color: var(--muted-fg); border-radius: var(--radius); padding: 5px 12px; font: inherit; font-size: 21.6px; cursor: pointer; text-decoration: none; }
|
||
.iconbtn.gear { display: inline-flex; align-items: center; padding: 5px 9px; }
|
||
.iconbtn.gear svg { width: 22px; height: 22px; }
|
||
/* #127: gear highlights like selected nav tabs; dark toggle button */
|
||
.iconbtn.gear.on { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
||
.iconbtn.dark-toggle { display: inline-flex; align-items: center; gap: 6px; padding: 5px 9px; }
|
||
.iconbtn.dark-toggle svg { width: 22px; height: 22px; }
|
||
.iconbtn.dark-toggle .icon-moon { display: none; }
|
||
.iconbtn.dark-toggle .icon-sun { display: inline-block; }
|
||
.dark .iconbtn.dark-toggle .icon-sun { display: none; }
|
||
.dark .iconbtn.dark-toggle .icon-moon { display: inline-block; }
|
||
/* #127: gear highlights like selected nav tabs; dark toggle button */
|
||
.iconbtn.gear.on { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
||
.iconbtn.dark-toggle { display: inline-flex; align-items: center; gap: 6px; padding: 5px 9px; }
|
||
.iconbtn.dark-toggle svg { width: 22px; height: 22px; }
|
||
.iconbtn.dark-toggle .icon-moon { display: none; }
|
||
.iconbtn.dark-toggle .icon-sun { display: inline-block; }
|
||
.dark .iconbtn.dark-toggle .icon-sun { display: none; }
|
||
.dark .iconbtn.dark-toggle .icon-moon { display: inline-block; }
|
||
.settings-head { padding: 12px 18px; border-bottom: 1px solid var(--border); }
|
||
.settings-head h1 { font-size: 29.2px; font-weight: 600; margin: 0; }
|
||
.settings-body { padding: 16px 18px; color: var(--muted-fg); font-size: 21.6px; }
|
||
.settings-section-title { color: var(--fg); font-size: 24px; margin-bottom: 6px; }
|
||
/* theme switcher cards (#100) */
|
||
.theme-grid { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 14px; }
|
||
|
||
/* #161: more breathing room between settings sections */
|
||
/* #207 r2: owner wants the toggle left aligned (revert #197 centering) */
|
||
#settings-dark-toggle { margin-bottom: 20px; }
|
||
.settings-body h3 { margin-top: 28px; }
|
||
.settings-body .theme-grid { margin-bottom: 8px; }
|
||
.theme-card {
|
||
display: flex; flex-direction: column; gap: 10px; align-items: flex-start;
|
||
padding: 14px 16px; min-width: 180px;
|
||
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
|
||
color: var(--fg); font: inherit; font-size: 20px; cursor: pointer;
|
||
}
|
||
.theme-card:hover { border-color: var(--muted); }
|
||
.theme-card[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
|
||
.theme-card .swatches { display: flex; gap: 4px; }
|
||
.theme-card .swatch { width: 26px; height: 26px; border-radius: 6px; border: 1px solid rgba(255,255,255,.15); }
|
||
.theme-name { font-weight: 600; }
|
||
.iconbtn:hover { color: var(--fg); border-color: var(--muted); }
|
||
/* #130: line wrap toggle, accent when active like other toggles */
|
||
/* #166: wrap toggle must show its state: neutral when off, accent when on.
|
||
The .btn base is accent filled, which made on and off look identical. */
|
||
.btn-icon.wrap-toggle { background: var(--surface-2); color: var(--muted-fg); font-size: 21.6px; font-weight: inherit; border: 1px solid var(--border); }
|
||
.btn-icon.wrap-toggle:hover { color: var(--fg); border-color: var(--muted-fg); filter: none; }
|
||
.iconbtn.wrap-toggle[aria-pressed="true"],
|
||
.btn-icon.wrap-toggle[aria-pressed="true"] { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
||
/* #152: wrap ON must break long unbroken tokens mid-word and allow no horizontal scrolling */
|
||
html[data-wrap] .codebody { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-all; overflow-x: hidden; }
|
||
/* #167: overflow:hidden zeroes the flex auto-minimum, so the codebody must
|
||
be told to fill the space left of the gutter or it collapses and the
|
||
gutter (flex-shrink:0) consumes the whole row */
|
||
html[data-wrap] .code .codebody { flex: 1 1 auto; min-width: 0; }
|
||
html[data-wrap] .editor { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-all; overflow-x: hidden; }
|
||
/* #152: with wrap on nothing may scroll horizontally, including the code container and mobile floats */
|
||
html[data-wrap] .code { overflow-x: hidden; }
|
||
html[data-wrap] .float { overflow-x: hidden; }
|
||
.iconbtn.danger:hover { color: #ff8fa3; border-color: #ff8fa3; }
|
||
.code-head {
|
||
display: flex; align-items: center; gap: 10px; padding: 8px 16px;
|
||
border-bottom: 1px solid var(--border); font-size: 21.6px; color: var(--muted-fg);
|
||
}
|
||
.code-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
|
||
.code {
|
||
font-family: var(--font-mono); font-size: var(--code-fs); line-height: var(--code-lh);
|
||
padding: 14px 0; display: flex; overflow-x: hidden;
|
||
}
|
||
/* #261: horizontal scroll must live on the codebody, not the .code flex
|
||
container — a container-level scroll takes the gutter with it when the
|
||
user scrolls long lines. The gutter sits OUTSIDE the scroll container and
|
||
stays visible; the codebody shrinks to the remaining space and scrolls
|
||
(min-width: 0 lets it shrink below its content width inside the flex row). */
|
||
.code .codebody { flex: 1 1 auto; min-width: 0; overflow-x: auto; }
|
||
/* #167: the gutter must not drive the flex layout — its content width
|
||
(row count × number width) shrinks the code column, which re-wraps lines,
|
||
which grows the gutter: a feedback loop. Pin the gutter with a fixed
|
||
basis, take its width out of the negotiation, and let the codebody take
|
||
the rest. */
|
||
.code .gutter { flex: 0 0 auto; width: 3ch; min-width: 3ch; overflow: visible; }
|
||
.code .gutter { flex-shrink: 0; }
|
||
/* gutter/code share line metrics; the editor gutter keeps its own padding (#50) */
|
||
.code .gutter { padding-top: 0; padding-bottom: 0; }
|
||
.codebody { padding: 0 18px; white-space: pre; overflow-x: auto; }
|
||
/* #167: each logical line is its own block so offsetTop identifies its first visual row */
|
||
.codeline { display: block; }
|
||
/* #167: gutter number spans must stack one per visual row (wrap on).
|
||
#274: the /new editor gutter uses the same .gutline blocks when its own
|
||
wrap toggle is on, so scope the rule to any gutter, not just .code. */
|
||
.code .gutter .gutline, .editor-wrap .gutter .gutline { display: block; }
|
||
/* #194: codeline blocks are adjacent (no '\n' text between them), so an
|
||
empty block (blank source line) needs its own line box to stay one row */
|
||
.codeline:empty::before { content: "\200B"; }
|
||
/* syntax highlight tokens (#1) */
|
||
.tok-kw { color: #c792ea; }
|
||
.tok-str { color: #a5e075; }
|
||
.tok-num { color: #f78c6c; }
|
||
.tok-com { color: #6a737d; font-style: italic; }
|
||
.footnote { display: flex; gap: 20px; padding: 10px 18px; font-size: 20.7px; color: var(--muted-fg); border-top: 1px solid var(--border); flex-wrap: wrap; }
|
||
|
||
/* history */
|
||
.page { max-width: 1200px; margin: 0 auto; padding: 20px 20px 28px; display: flex; flex-direction: column; gap: 16px; min-height: calc(100vh - 76px); }
|
||
.pager { position: sticky; bottom: 0; margin-top: auto; z-index: 5; }
|
||
.head-row { display: flex; align-items: baseline; gap: 14px; }
|
||
.head-row h1 { font-size: 34.5px; font-weight: 600; }
|
||
.search {
|
||
display: flex; align-items: center; gap: 8px; background: var(--surface);
|
||
border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 14px; width: 260px;
|
||
}
|
||
.search input { border: none; outline: none; background: transparent; color: var(--fg); font: inherit; font-size: 22.4px; width: 100%; }
|
||
table { width: 100%; border-collapse: collapse; font-size: 22.4px; table-layout: fixed; }
|
||
th {
|
||
text-align: left; font-size: 18.9px; text-transform: uppercase; letter-spacing: .08em;
|
||
color: var(--muted-fg); padding: 10px 16px; border-bottom: 1px solid var(--border); font-weight: 600;
|
||
}
|
||
td { padding: 10px 16px; border-bottom: 1px solid var(--border); overflow: clip; text-overflow: ellipsis; white-space: nowrap; }
|
||
td:has(> a.slug), td:has(> .slug) { overflow: visible; }
|
||
tr:last-child td { border-bottom: none; }
|
||
tr.row { cursor: pointer; }
|
||
tr.row:hover td { background: var(--surface-2); }
|
||
tr.row:hover td a.slug { color: var(--accent); }
|
||
/* #292: highlight the paste NAME uniformly on row hover, titled or not */
|
||
tr.row:hover td .paste-name { color: var(--accent); }
|
||
td a.slug { font-family: var(--font-mono); font-size: 21.6px; color: var(--fg); text-decoration: none; }
|
||
td a.slug:hover { color: var(--accent); }
|
||
/* PASTE column fallback for untitled pastes: plain text, identical to a titled paste. URL/ID chips keep .slug styling. */
|
||
td a.slug.paste-name { background: none; padding: 0; border-radius: 0; font-family: inherit; font-size: inherit; color: var(--fg); }
|
||
td a.paste-name { color: var(--fg); text-decoration: none; font-family: inherit; font-size: inherit; }
|
||
.badge { font-size: 18.9px; border: 1px solid var(--border); color: var(--muted-fg); border-radius: var(--radius-sm); padding: 1px 8px; }
|
||
.badge.lock { color: var(--accent); border-color: var(--accent); }
|
||
.dim { color: var(--muted-fg); white-space: nowrap; }
|
||
.pager { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; font-size: 21.6px; color: var(--muted-fg); }
|
||
.pager .pg { display: flex; gap: 6px; }
|
||
.pager button { border: 1px solid var(--border); background: var(--surface-2); color: var(--muted-fg); border-radius: var(--radius); padding: 4px 11px; font: inherit; font-size: 21.6px; cursor: pointer; }
|
||
.pager button:hover:not(:disabled) { color: var(--fg); border-color: var(--muted); }
|
||
.pager button.on { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
||
.pager button:disabled { opacity: .4; cursor: default; }
|
||
.empty { text-align: center; padding: 40px 16px; color: var(--muted-fg); font-size: 22.4px; }
|
||
|
||
/* unlock */
|
||
.center { display: flex; align-items: center; justify-content: center; padding: 20px; height: calc(100vh - 52px); }
|
||
.center .float { width: 400px; max-width: 100%; }
|
||
.inner { padding: 28px; text-align: center; }
|
||
.lockring {
|
||
width: 56px; height: 56px; margin: 0 auto 16px; border-radius: 50%;
|
||
background: var(--surface-2); display: flex; align-items: center; justify-content: center; font-size: 41.4px;
|
||
}
|
||
.inner h1 { font-size: 29.2px; font-weight: 600; margin-bottom: 6px; }
|
||
.inner .sub { font-size: 22.4px; color: var(--muted-fg); margin-bottom: 20px; }
|
||
/* #173: missing paste message box */
|
||
.notfound-err { color: var(--err); }
|
||
.notfound-card .btn { display: block; margin-top: 10px; }
|
||
.pwinput {
|
||
width: 100%; padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--radius);
|
||
background: var(--bg); color: var(--fg); font: inherit; font-size: 23.2px; outline: none; text-align: center;
|
||
letter-spacing: .12em;
|
||
}
|
||
.pwinput:focus { border-color: var(--accent); }
|
||
.center .btn { width: 100%; margin-top: 12px; }
|
||
.err { display: none; margin-top: 12px; font-size: 21.6px; color: #ff8fa3; }
|
||
.center .foot { font-size: 20.7px; color: var(--muted-fg); padding: 14px; border-top: 1px solid var(--border); }
|
||
|
||
.btn-icon {
|
||
padding: 4px 8px; font-size: 24.2px; line-height: 1; overflow: visible;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
min-width: 40px; height: 36px;
|
||
}
|
||
|
||
/* selection controls: pill-style selected states (#14) */
|
||
.seg label, .toggle {
|
||
border: 1px solid transparent;
|
||
transition: background .12s ease, border-color .12s ease, color .12s ease;
|
||
}
|
||
.seg label:hover, .toggle:hover {
|
||
background: var(--surface-2);
|
||
color: var(--fg);
|
||
}
|
||
.seg label:has(input:checked),
|
||
.toggle:has(input:checked) {
|
||
background: var(--surface-2);
|
||
border-color: var(--accent);
|
||
color: var(--fg);
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
.seg label:has(input:focus-visible),
|
||
.toggle:has(input:focus-visible) {
|
||
outline: 2px solid var(--accent);
|
||
outline-offset: 1px;
|
||
}
|
||
.seg input, .toggle input { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; }
|
||
|
||
/* toast (#19, #168): small pill anchored to the corner, out of content flow */
|
||
.toast {
|
||
position: fixed; right: 16px; bottom: 16px;
|
||
background: var(--surface-2); color: var(--fg); border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm); padding: 6px 12px; font-size: 13px;
|
||
opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease; z-index: 200;
|
||
box-shadow: 0 4px 16px rgba(0,0,0,.25);
|
||
}
|
||
.toast.show { opacity: 1; transform: translateY(0); }
|
||
/* status variants (#16) */
|
||
.toast.success { border-color: var(--ok); color: var(--ok); }
|
||
.toast.error { border-color: var(--err); color: var(--err); }
|
||
|
||
/* result box color-coding (#105): colored left border + text tint per status */
|
||
.result-ok, .result-err, .result-warn { border-left: 4px solid transparent; padding-left: 10px; }
|
||
.result-ok { border-left-color: var(--ok); color: var(--ok); }
|
||
.result-err { border-left-color: var(--err); color: var(--err); }
|
||
.result-warn { border-left-color: var(--warn); color: var(--warn); }
|
||
.result-ok a { color: var(--ok); }
|
||
|
||
/* protection section rhythm (#20) */
|
||
.protect { display: flex; flex-direction: column; gap: 2px; }
|
||
.protect .pw-row:not(.submenu) { padding: 2px 8px 4px; }
|
||
|
||
/* submenu number boxes (#157): styled number inputs + unit selects,
|
||
padded + indented to line up with parent option labels */
|
||
.submenu {
|
||
/* #240: indent the box under the parent option LABEL text (8px row padding
|
||
+ 16px control + 8px gap = 32px), and match the row control padding rhythm */
|
||
margin: 4px 0 4px 32px;
|
||
padding: 6px 10px;
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
}
|
||
.exp-group { display: flex; align-items: center; gap: 8px; }
|
||
.num-input {
|
||
width: 72px;
|
||
border: 1px solid var(--border); border-radius: var(--radius);
|
||
background: var(--surface-2); color: var(--fg);
|
||
font: inherit; font-size: 21.6px; padding: 6px 10px; outline: none;
|
||
-moz-appearance: textfield; appearance: textfield;
|
||
}
|
||
.num-input::-webkit-outer-spin-button,
|
||
.num-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
||
.num-input:focus { border-color: var(--accent); }
|
||
.unit-select {
|
||
border: 1px solid var(--border); border-radius: var(--radius);
|
||
background-color: var(--surface-2); color: var(--muted-fg);
|
||
font: inherit; font-size: 21.6px; padding: 6px 28px 6px 10px;
|
||
cursor: pointer; outline: none;
|
||
appearance: none; -webkit-appearance: none;
|
||
background-image: var(--chevron);
|
||
background-repeat: no-repeat; background-position: right 10px center;
|
||
}
|
||
.unit-select:focus { border-color: var(--accent); }
|
||
.readable-group { gap: 8px; }
|
||
.readable-label { font-size: 19px; color: var(--muted-fg); white-space: nowrap; }
|
||
.pw-field {
|
||
display: flex; align-items: center; gap: 2px; width: 100%;
|
||
border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg);
|
||
}
|
||
.pw-field:focus-within { border-color: var(--accent); }
|
||
.pw-field input {
|
||
flex: 1; min-width: 0; border: none; outline: none; background: transparent; color: var(--fg);
|
||
font: inherit; font-size: 21.6px; padding: 7px 12px; letter-spacing: .08em;
|
||
}
|
||
.pw-field input::placeholder { color: var(--muted); letter-spacing: normal; }
|
||
.pw-field .reveal {
|
||
background: none; border: none; color: var(--muted-fg); cursor: pointer;
|
||
display: flex; align-items: center; justify-content: center; padding: 0 10px; height: 100%;
|
||
flex-shrink: 0;
|
||
}
|
||
.pw-field .reveal:hover { color: var(--fg); }
|
||
.pw-field .reveal .eye-slash { display: none; }
|
||
.pw-field .reveal.off .eye-slash { display: block; }
|
||
.pw-field svg { width: 20px; height: 20px; display: block; }
|
||
|
||
/* custom URL input (#22) */
|
||
.deck .row input[type="text"] { width: 100%; }
|
||
.custom-input {
|
||
display: block; width: 100%;
|
||
border: 1px solid var(--border); border-radius: var(--radius); padding: 7px 12px;
|
||
background: var(--bg); color: var(--fg); font: inherit; font-size: 21.6px; outline: none;
|
||
}
|
||
.custom-input:focus { border-color: var(--accent); }
|
||
.custom-input::placeholder { color: var(--muted); }
|
||
|
||
/* btn-icon svg (#24) */
|
||
.btn-icon svg { width: 20px; height: 20px; display: block; }
|
||
|
||
/* search spinner (#32) */
|
||
.search-spinner {
|
||
width: 16px; height: 16px; flex-shrink: 0;
|
||
border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%;
|
||
animation: spin .8s linear infinite; visibility: hidden;
|
||
}
|
||
@keyframes spin { to { transform: rotate(360deg); } }
|
||
|
||
/* unlock redesign (#27) */
|
||
.unlock-card .pw-field { margin: 18px 0 4px; text-align: left; }
|
||
.unlock-card .pw-field input { text-align: left; }
|
||
.unlock-err { margin-top: 10px; font-size: 20.7px; color: #ff8fa3; }
|
||
|
||
/* paste name under slug pill in Paste column (#43) */
|
||
.paste-sub { font-size: 19.8px; color: var(--muted-fg); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.paste-sub.dim { color: var(--muted); }
|
||
td a.slug.url-link { max-width: 100%; display: inline-block; vertical-align: middle; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; box-sizing: border-box; }
|
||
td .id-link { color: var(--muted-fg); text-decoration: none; font-family: var(--font-mono); font-size: 19.8px; }
|
||
td .id-link:hover { color: var(--accent); }
|
||
|
||
/* sortable column headers (#42) */
|
||
th.sortable { cursor: pointer; user-select: none; }
|
||
th.sortable:hover { color: var(--fg); }
|
||
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
|
||
/* #209: arrow sits RIGHT of the label, vertically centered, and absolutely
|
||
positioned so it never shifts the label text; label aligns with column contents. */
|
||
th.sortable .sort-ind {
|
||
/* #209 r2: inline right after the label text with a fixed gap, not pinned to the column edge */
|
||
display: inline-block; width: 0; height: 0; margin-left: 6px; vertical-align: middle;
|
||
border-left: 5px solid transparent; border-right: 5px solid transparent;
|
||
}
|
||
th.sorted.asc .sort-ind { border-bottom: 6px solid var(--accent); }
|
||
th.sorted.desc .sort-ind { border-top: 6px solid var(--accent); }
|
||
|
||
/* #102: small unobtrusive admin link on the settings page */
|
||
a.admin-link { color: var(--muted-fg); font-size: 15px; text-decoration: none; }
|
||
a.admin-link:hover { color: var(--fg); text-decoration: underline; }
|
||
|
||
/* ============================================================
|
||
Consistency audit (#18) — shared tokens across inputs, buttons,
|
||
headings. Visual-only, no behavior change.
|
||
============================================================ */
|
||
|
||
/* shared text-input treatment: .search input, .pw-field input, #title, #custom */
|
||
.search input,
|
||
.pw-field input,
|
||
.editor-head input#title,
|
||
.custom-input,
|
||
.row input[type="text"] {
|
||
font-size: 21.6px;
|
||
color: var(--fg);
|
||
}
|
||
.search input::placeholder,
|
||
.pw-field input::placeholder,
|
||
.editor-head input#title::placeholder,
|
||
.custom-input::placeholder {
|
||
color: var(--muted);
|
||
}
|
||
.custom-input { border-radius: var(--radius); }
|
||
|
||
/* buttons (incl. icon-only variants) share one radius + focus ring */
|
||
.btn-icon, .iconbtn {
|
||
border-radius: var(--radius);
|
||
transition: color .12s ease, border-color .12s ease, background .12s ease;
|
||
}
|
||
.iconbtn:focus-visible, .btn:focus-visible, .btn-icon:focus-visible, .pager button:focus-visible {
|
||
outline: 2px solid var(--accent);
|
||
outline-offset: 1px;
|
||
}
|
||
|
||
/* in-place copy success feedback (#53) */
|
||
.iconbtn.ok, .btn.ok {
|
||
color: var(--ok);
|
||
border-color: var(--ok);
|
||
}
|
||
|
||
/* #260: static-width success feedback. Label and checkmark stack in one
|
||
grid cell, so the button is always as wide as the wider of the two and
|
||
never shifts on click. Feedback is a pure .ok class toggle. */
|
||
.swapbtn {
|
||
display: inline-grid;
|
||
}
|
||
.swapbtn > * {
|
||
grid-area: 1 / 1;
|
||
justify-self: center;
|
||
}
|
||
.swapbtn .swap-check { visibility: hidden; }
|
||
.swapbtn.ok .swap-check { visibility: visible; }
|
||
.swapbtn.ok .swap-label { visibility: hidden; }
|
||
|
||
/* headings: unified treatment (mirrors .side-section h3) */
|
||
.settings-head h1, .paste-title-bar h1, .head-row h1, .inner h1 {
|
||
letter-spacing: -0.01em;
|
||
}
|
||
|
||
/* consistent card padding scale: 12px 18px for wide card heads/bodies */
|
||
.settings-head { padding: 12px 18px; }
|
||
.settings-body { padding: 16px 18px; }
|
||
|
||
/* topbar: Git external-link arrow (#56) */
|
||
.topbar nav a .ext { width: 14px; height: 14px; margin-left: 4px; opacity: .55; vertical-align: -1px; }
|
||
|
||
@media (max-width: 640px) {
|
||
body { font-size: 16px; }
|
||
|
||
/* topbar: tighten so logo + nav + gear fit */
|
||
.topbar { gap: 6px; padding: 0 10px; height: 56px; }
|
||
.logo { font-size: 17px; white-space: nowrap; }
|
||
.logo em { display: none; }
|
||
.topbar nav { gap: 2px; flex-shrink: 0; }
|
||
.topbar nav a { padding: 4px 6px; font-size: 15px; }
|
||
.iconbtn.gear { padding: 4px 7px; flex-shrink: 0; }
|
||
.iconbtn.gear svg { width: 18px; height: 18px; }
|
||
.iconbtn.dark-toggle { padding: 4px 7px; flex-shrink: 0; }
|
||
.iconbtn.dark-toggle svg { width: 18px; height: 18px; }
|
||
.iconbtn.dark-toggle span { display: none; }
|
||
.iconbtn.dark-toggle { padding: 4px 7px; flex-shrink: 0; }
|
||
.iconbtn.dark-toggle svg { width: 18px; height: 18px; }
|
||
.iconbtn.dark-toggle span { display: none; }
|
||
|
||
/* new paste: stack editor above sidebar, natural page height */
|
||
.deck {
|
||
display: flex; flex-direction: column;
|
||
height: auto; min-height: calc(100vh - 56px);
|
||
padding: 12px; gap: 12px;
|
||
}
|
||
.pane-l-col { order: 0; }
|
||
.pane-r { order: 1; overflow-y: visible; }
|
||
.editor-wrap { min-height: 45vh; }
|
||
.editor { font-size: 15px; }
|
||
.gutter { font-size: 15px; }
|
||
.editor-head { flex-wrap: wrap; }
|
||
.editor-head-title { flex: 1 1 100%; }
|
||
.editor-head input { min-width: 0; font-size: 16px; }
|
||
.editor-head select { max-width: 120px; font-size: 14px; }
|
||
.editor-head-title, .editor-head-settings { padding: 4px 8px; }
|
||
.actionbar { flex-wrap: wrap; }
|
||
.actionbar .btn { padding: 12px 22px; }
|
||
.hint { font-size: 13px; }
|
||
|
||
/* history: horizontal-scroll table inside its card */
|
||
.page { padding: 12px; }
|
||
.head-row { flex-wrap: wrap; }
|
||
.head-row h1 { font-size: 22px; }
|
||
.search { width: 100%; }
|
||
.search input { font-size: 16px; }
|
||
.float { overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
||
table { min-width: 720px; }
|
||
th { padding: 8px 10px; font-size: 12px; white-space: nowrap; }
|
||
td { padding: 8px 10px; font-size: 14px; }
|
||
.pager { flex-wrap: wrap; gap: 8px; font-size: 13px; }
|
||
|
||
/* paste view */
|
||
.paste-title-bar { padding: 10px 12px; gap: 8px; }
|
||
.paste-title-bar h1 { font-size: 18px; }
|
||
.slug { font-size: 13px; word-break: break-all; }
|
||
.stats-head { font-size: 13px; }
|
||
.stats-grid { font-size: 13px; padding: 10px 12px; }
|
||
.code { font-size: 13px; }
|
||
/* #167: gutter and code must share one line box at mobile width too — a
|
||
taller gutter font stacks its rows taller than the code rows and every
|
||
number drifts off its line start */
|
||
.code .gutter { font-size: 13px; }
|
||
.codebody { padding: 0 12px; }
|
||
.footnote { font-size: 12px; padding: 8px 12px; gap: 10px; }
|
||
.iconbtn { font-size: 13px; padding: 6px 10px; }
|
||
|
||
/* unlock card */
|
||
.center { height: auto; min-height: calc(100vh - 56px); padding: 16px; }
|
||
.center .float { width: 100%; }
|
||
.inner { padding: 20px 16px; }
|
||
.inner h1 { font-size: 20px; }
|
||
.inner .sub { font-size: 14px; }
|
||
.unlock-err { font-size: 13px; }
|
||
.center .foot { font-size: 13px; }
|
||
}
|
||
|
||
/* #4: can view page + can builder */
|
||
.can-page h1 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
||
.can-items { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
|
||
.can-item { padding: 12px 14px; }
|
||
.can-item-head { display: flex; align-items: center; gap: 10px; }
|
||
.can-item-head strong { flex: 1; word-break: break-all; }
|
||
.can-item-body { margin-top: 8px; }
|
||
.can-item-body summary { cursor: pointer; font-size: 19px; color: var(--muted, #888); }
|
||
/* #169: divider between the dropdown title and body must be persistent
|
||
(not hover dependent) and extend the full width of the card left and right */
|
||
.can-item-body[open] summary {
|
||
border-bottom: 1px solid var(--border);
|
||
margin: 0 -14px 8px;
|
||
padding: 0 14px 8px;
|
||
}
|
||
.can-item-body pre.code { margin: 8px 0 0; overflow-x: auto; }
|
||
.can-item-row { margin-top: 8px; }
|
||
.can-item-row .can-item-title { width: 100%; margin-bottom: 6px; }
|
||
.can-item-row .can-item-content { width: 100%; font-family: var(--mono, monospace); resize: vertical; }
|
||
|
||
/* ============================================================
|
||
Styled controls (#123) — buttons, selects, checkboxes, radios
|
||
match the custom URL box house pattern: 1px var(--border) on
|
||
var(--bg), var(--radius) corners, accent border on focus, no
|
||
default browser chrome (appearance: none).
|
||
============================================================ */
|
||
|
||
/* selects: replace native chrome with a house-styled pill */
|
||
select {
|
||
appearance: none;
|
||
-webkit-appearance: none;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
background: var(--bg) var(--chevron) no-repeat right 10px center; /* #136: themed chevron */
|
||
color: var(--fg);
|
||
font: inherit;
|
||
padding: 4px 30px 4px 12px;
|
||
cursor: pointer;
|
||
outline: none;
|
||
transition: border-color .12s ease, background-color .12s ease;
|
||
}
|
||
select:hover { border-color: var(--muted-fg); background-color: var(--surface-2); }
|
||
select:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 1px; }
|
||
.editor-head select { padding: 4px 30px 4px 10px; }
|
||
|
||
/* checkboxes and radios: custom drawn, accent when checked */
|
||
input[type="checkbox"],
|
||
input[type="radio"] {
|
||
appearance: none;
|
||
-webkit-appearance: none;
|
||
width: 16px; height: 16px; margin: 0; flex-shrink: 0;
|
||
border: 1px solid var(--border);
|
||
background: var(--bg);
|
||
cursor: pointer;
|
||
position: relative;
|
||
transition: border-color .12s ease, background-color .12s ease;
|
||
}
|
||
input[type="checkbox"] { border-radius: 4px; }
|
||
input[type="radio"] { border-radius: 50%; }
|
||
input[type="checkbox"]:hover,
|
||
input[type="radio"]:hover { border-color: var(--muted-fg); }
|
||
input[type="checkbox"]:checked,
|
||
input[type="radio"]:checked { background: var(--accent); border-color: var(--accent); }
|
||
input[type="checkbox"]:checked::after {
|
||
content: "";
|
||
position: absolute; inset: 0;
|
||
background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10'%3E%3Cpath d='M1 5l4 4 6-8' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 11px no-repeat;
|
||
}
|
||
input[type="radio"]:checked::after {
|
||
content: "";
|
||
position: absolute; inset: 3px;
|
||
border-radius: 50%;
|
||
background: var(--bg);
|
||
}
|
||
input[type="checkbox"]:focus-visible,
|
||
input[type="radio"]:focus-visible {
|
||
outline: 2px solid var(--accent);
|
||
outline-offset: 1px;
|
||
}
|
||
|
||
/* buttons: every submit-style button gets the .btn treatment,
|
||
and .btn itself gains the house surface/border/hover pattern */
|
||
button[type="submit"] {
|
||
background: var(--accent); color: var(--bg); border: 1px solid var(--accent);
|
||
border-radius: var(--radius); font: inherit; font-weight: 600;
|
||
padding: 8px 18px; cursor: pointer;
|
||
transition: filter .12s ease;
|
||
}
|
||
button[type="submit"]:hover { filter: brightness(1.08); }
|
||
button[type="submit"]:focus-visible,
|
||
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
||
.btn {
|
||
border: 1px solid var(--accent);
|
||
}
|
||
.btn:hover { filter: brightness(1.08); }
|
||
|
||
/* settings: give the Admin link clear separation from the theme grid */
|
||
.admin-link-row {
|
||
margin-top: 32px;
|
||
padding-top: 20px;
|
||
border-top: 1px solid var(--border);
|
||
}
|
||
|
||
/* #38: attachment upload on /new + attachment display on paste view */
|
||
.side-section .file-input { display: none; }
|
||
.dropzone {
|
||
border: 1px dashed var(--border);
|
||
border-radius: var(--radius-lg);
|
||
padding: 14px 12px;
|
||
text-align: center;
|
||
color: var(--muted-fg);
|
||
cursor: pointer;
|
||
font-size: 20.7px;
|
||
transition: border-color .15s, background .15s;
|
||
background: var(--surface-2, transparent);
|
||
}
|
||
.dropzone:hover, .dropzone.dragover {
|
||
border-color: var(--accent);
|
||
background: var(--surface-2);
|
||
}
|
||
.dropzone.dragover { border-width: 2px; }
|
||
/* #171: uploaded-file preview replaces the editor area; image fitted inside */
|
||
.file-preview {
|
||
flex: 1;
|
||
min-width: 0;
|
||
min-height: 0;
|
||
max-width: 100%;
|
||
max-height: 100%;
|
||
object-fit: contain;
|
||
border-radius: 8px;
|
||
}
|
||
.editor-wrap.previewing .editor,
|
||
.editor-wrap.previewing .gutter { display: none; }
|
||
|
||
.file-chip {
|
||
display: flex; align-items: center; gap: 10px;
|
||
border: 1px solid var(--border); border-radius: var(--radius);
|
||
padding: 8px 14px; margin-top: 8px; background: var(--surface);
|
||
font-size: 21.6px;
|
||
}
|
||
.file-chip .file-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
|
||
.file-chip .file-chip-size { color: var(--muted-fg); font-size: 19px; }
|
||
.file-chip .file-chip-remove {
|
||
border: none; background: none; color: var(--muted-fg); cursor: pointer;
|
||
font-size: 22px; padding: 0 4px; border-radius: var(--radius-sm);
|
||
}
|
||
.file-chip .file-chip-remove:hover { color: var(--danger, #c0392b); }
|
||
.attachment-bar { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
|
||
/* #221: the link pill under an image preview stays a small inline chip,
|
||
left-aligned under the image, not stretched above it. */
|
||
.attachment-bar .attachment-chip {
|
||
display: inline-flex; align-items: center; gap: 12px; align-self: flex-start;
|
||
border: 1px solid var(--border); border-radius: var(--radius);
|
||
padding: 6px 14px; text-decoration: none; color: var(--fg);
|
||
background: var(--surface-2); font-size: 19px;
|
||
}
|
||
.attachment-bar .attachment-chip:hover { border-color: var(--accent); }
|
||
.attachment-bar .attachment-chip .attachment-name {
|
||
min-width: 0;
|
||
flex: 1;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
/* #232: long filenames are truncated but the pill stays a reasonable
|
||
width; on narrow viewports it shrinks to the container instead of
|
||
overflowing the card. */
|
||
.attachment-bar .attachment-chip {
|
||
max-width: 100%;
|
||
}
|
||
.attachment-bar .attachment-chip .attachment-name:hover {
|
||
white-space: normal;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
/* #221: images scale to fit the viewer box, aspect ratio preserved. */
|
||
.attachment-preview {
|
||
max-width: 100%;
|
||
align-self: flex-start;
|
||
/* #229: no inner border/radius of its own; the .float wrapper already
|
||
frames the pill (inner borders get corner-clipped by overflow:hidden).
|
||
Padding on .attachment-bar gives the image breathing room from the
|
||
pill border. */
|
||
border: 0;
|
||
border-radius: 0;
|
||
background: var(--surface-2);
|
||
overflow: hidden;
|
||
}
|
||
.attachment-preview img {
|
||
display: block;
|
||
max-width: 100%;
|
||
max-height: 70vh;
|
||
width: auto;
|
||
height: auto;
|
||
object-fit: contain;
|
||
}
|
||
|
||
/* #139: CSP-safe replacements for inline style attributes (style-src 'self') */
|
||
.hidden { display: none; }
|
||
.can-page { max-width: 900px; width: 100%; }
|
||
.col-a { width: 260px; } .col-b { width: 140px; } .col-c { width: 120px; }
|
||
.col-d { width: 96px; } .col-d2 { width: 150px; } .col-e { width: 190px; }
|
||
.col-f { width: 100px; } .col-g { width: 190px; }
|
||
/* #255: history's URL column had its own narrow width (col-f doubles as
|
||
/mine's ID column); give it a dedicated class. */
|
||
.col-url { width: 340px; }
|
||
/* #210: /mine rows render a delete button cell that had no declared column,
|
||
so under table-layout:fixed it overlapped the ID column. */
|
||
.col-del { width: 64px; }
|
||
.spacer-flex { flex: 1; }
|
||
.input-num { width: 80px; }
|
||
.input-num-sm { width: 64px; }
|
||
.danger-hint { color: var(--danger, #c0392b); margin-top: 6px; }
|
||
.hint-lg { font-size: 19px; }
|
||
.mt6 { margin-top: 6px; }
|
||
.mt18 { margin-top: 18px; }
|
||
.toggle-inline { display: inline-flex; }
|
||
.wrap-normal { word-break: normal; overflow-wrap: break-word; }
|
||
.created-banner { display: block; }
|
||
/* #167: gutter rows for wrapped paste view — one row per visual code line */
|
||
.gutline { display: block; }
|
||
|
||
/* #267: jump to top/bottom pills for long pastes and the editor.
|
||
Hidden unless JS (jump.js) detects content more than 2x the viewport. */
|
||
.jumpnav {
|
||
position: fixed;
|
||
right: 18px;
|
||
bottom: 18px;
|
||
z-index: 50;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
.jumpnav.hidden { display: none; }
|
||
.jump-btn { box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25); }
|
||
|
||
/* #273: theme-aware scrollbars. Standard properties first (Firefox, and
|
||
Chromium >= 121 honors scrollbar-color), then ::-webkit rules for finer
|
||
Chromium styling. Colors come from CSS vars so they track the preset. */
|
||
* {
|
||
scrollbar-width: thin;
|
||
scrollbar-color: var(--border) transparent;
|
||
}
|
||
::-webkit-scrollbar { width: 10px; height: 10px; }
|
||
::-webkit-scrollbar-track { background: transparent; }
|
||
::-webkit-scrollbar-thumb {
|
||
background: var(--border);
|
||
border-radius: 5px;
|
||
}
|
||
::-webkit-scrollbar-thumb:hover { background: var(--muted-fg); }
|
||
::-webkit-scrollbar-corner { background: transparent; }
|