Pithos: fill wide windows, one row for the host buttons

On a 1920px screen Pithos used about 60% of the window: the content
stopped at 1100px and the text stayed small, so it took 150% zoom to
fill the screen. Sizes are now in rem and the root size grows past
1440px wide (about 1.25x at 1920), and the content takes the full width.
The narrow sidebar panel is unchanged.

Open in browser floated in the middle of the sidebar because it and
Back to sidebar each pushed themselves to the bottom. The host's buttons
now share one row above the s3d status.
This commit is contained in:
Local Dev 2026-10-07 22:23:54 +02:00
parent 527bfee4d4
commit 4fb8e83712
2 changed files with 207 additions and 199 deletions

View file

@ -13,7 +13,7 @@
--warn: #b7791f;
--warn-soft: #fdf3e1;
--mono: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, monospace;
--radius: 10px;
--radius: 0.625rem;
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
@ -37,75 +37,79 @@
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
/* Sizes are in rem, so the whole app grows with wide windows instead of
sitting small in a corner: 16px up to 1440px wide, about 20px at 1920. */
html { font-size: 16px; }
@media (min-width: 1440px) { html { font-size: clamp(16px, 0.85vw + 3.75px, 24px); } }
body {
background: var(--bg); color: var(--text);
font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
font: 0.875rem/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
[hidden] { display: none !important; }
a { color: var(--accent); }
h1 { font-size: 22px; margin: 0 0 4px; font-weight: 650; }
h2 { font-size: 16px; margin: 0 0 12px; font-weight: 600; }
h3 { font-size: 14px; margin: 0 0 8px; font-weight: 600; }
code, .mono { font-family: var(--mono); font-size: 12.5px; }
h1 { font-size: 1.375rem; margin: 0 0 0.25rem; font-weight: 650; }
h2 { font-size: 1rem; margin: 0 0 0.75rem; font-weight: 600; }
h3 { font-size: 0.875rem; margin: 0 0 0.5rem; font-weight: 600; }
code, .mono { font-family: var(--mono); font-size: 0.7813rem; }
.muted { color: var(--muted); }
.error { color: var(--danger); }
.small { font-size: 12.5px; }
.small { font-size: 0.7813rem; }
/* layout */
.app { display: grid; grid-template-columns: 220px 1fr; min-height: 100%; }
.app { display: grid; grid-template-columns: 13.75rem 1fr; min-height: 100%; }
.sidebar {
background: var(--surface); border-right: 1px solid var(--border);
display: flex; flex-direction: column; padding: 16px 12px; gap: 16px;
display: flex; flex-direction: column; padding: 1rem 0.75rem; gap: 1rem;
position: sticky; top: 0; height: 100vh;
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 17px; padding: 0 8px; }
.brand { display: flex; align-items: center; gap: 0.625rem; font-weight: 700; font-size: 1.0625rem; padding: 0 0.5rem; }
nav { display: flex; flex-direction: column; gap: 2px; }
nav a {
color: var(--text); text-decoration: none; padding: 8px 10px; border-radius: 8px;
color: var(--text); text-decoration: none; padding: 0.5rem 0.625rem; border-radius: 0.5rem;
}
nav a:hover { background: var(--surface-2); }
nav a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.daemon-pill {
margin-top: auto; display: flex; align-items: center; gap: 8px;
padding: 8px 10px; border-radius: 8px; background: var(--surface-2); font-size: 13px;
margin-top: auto; display: flex; align-items: center; gap: 0.5rem;
padding: 0.5rem 0.625rem; border-radius: 0.5rem; background: var(--surface-2); font-size: 0.8125rem;
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; }
.dot.running { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--muted); flex: none; }
.dot.running { background: var(--accent); box-shadow: 0 0 0 0.1875rem var(--accent-soft); }
.dot.starting, .dot.stopping { background: var(--warn); }
.dot.crashed { background: var(--danger); }
main { padding: 28px 32px 48px; max-width: 1100px; width: 100%; min-width: 0; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
main { padding: 1.75rem 2rem 3rem; width: 100%; min-width: 0; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.page-head p { margin: 0; }
.grid { display: grid; gap: 16px; }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.grid { display: grid; gap: 1rem; }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); }
.card {
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
padding: 18px 20px;
padding: 1.125rem 1.25rem;
}
.card + .card { margin-top: 16px; }
.card + .card { margin-top: 1rem; }
.grid > .card + .card { margin-top: 0; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.row.spread { justify-content: space-between; }
.stack { display: flex; flex-direction: column; gap: 10px; }
.stack { display: flex; flex-direction: column; gap: 0.625rem; }
dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0; }
dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: 0.375rem 1rem; margin: 0; }
dl.kv dt { color: var(--muted); }
dl.kv dd { margin: 0; overflow-wrap: anywhere; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: 12px; }
.stat { background: var(--surface-2); border-radius: 8px; padding: 12px 14px; }
.stat .v { font-size: 22px; font-weight: 650; font-variant-numeric: tabular-nums; }
.stat .l { color: var(--muted); font-size: 12.5px; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9.375rem, 100%), 1fr)); gap: 0.75rem; }
.stat { background: var(--surface-2); border-radius: 0.5rem; padding: 0.75rem 0.875rem; }
.stat .v { font-size: 1.375rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.stat .l { color: var(--muted); font-size: 0.7813rem; }
.stat.bad .v { color: var(--danger); }
/* controls */
.btn {
appearance: none; border: 1px solid var(--border); background: var(--surface);
color: var(--text); padding: 7px 14px; border-radius: 8px; font: inherit; cursor: pointer;
display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
color: var(--text); padding: 0.4375rem 0.875rem; border-radius: 0.5rem; font: inherit; cursor: pointer;
display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap;
}
.btn:hover:not(:disabled) { background: var(--surface-2); }
.btn:disabled { opacity: .5; cursor: default; }
@ -113,42 +117,42 @@ dl.kv dd { margin: 0; overflow-wrap: anywhere; }
.btn.primary:hover:not(:disabled) { filter: brightness(1.06); background: var(--accent); }
.btn.danger { color: var(--danger); }
.btn.danger:hover:not(:disabled) { background: var(--danger-soft); }
.btn.small { padding: 3px 9px; font-size: 12.5px; }
.btn.small { padding: 0.1875rem 0.5625rem; font-size: 0.7813rem; }
.btn.link { border: none; background: none; color: var(--accent); padding: 0; }
input[type=text], input[type=password], input[type=number], input[type=url], select, textarea {
font: inherit; color: var(--text); background: var(--surface); border: 1px solid var(--border);
border-radius: 8px; padding: 7px 10px; width: 100%;
border-radius: 0.5rem; padding: 0.4375rem 0.625rem; width: 100%;
}
textarea { resize: vertical; min-height: 70px; }
textarea { resize: vertical; min-height: 4.375rem; }
input:focus, select:focus, textarea:focus, .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
label.field { display: flex; flex-direction: column; gap: 4px; }
label.field > span { font-weight: 550; font-size: 13px; }
label.field { display: flex; flex-direction: column; gap: 0.25rem; }
label.field > span { font-weight: 550; font-size: 0.8125rem; }
label.field > small { color: var(--muted); }
label.check { display: flex; align-items: center; gap: 8px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 14px; }
label.check { display: flex; align-items: center; gap: 0.5rem; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: 0.875rem; }
/* tables */
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
th { color: var(--muted); font-weight: 550; font-size: 12.5px; }
th, td { text-align: left; padding: 0.5rem 0.625rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
th { color: var(--muted); font-weight: 550; font-size: 0.7813rem; }
tr:last-child td { border-bottom: none; }
td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.actions { text-align: right; white-space: nowrap; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--surface-2); }
.empty { text-align: center; color: var(--muted); padding: 28px 10px; }
.empty { text-align: center; color: var(--muted); padding: 1.75rem 0.625rem; }
.badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 12px; background: var(--surface-2); color: var(--muted); }
.badge { display: inline-block; padding: 1px 0.5rem; border-radius: 62.4375rem; font-size: 0.75rem; background: var(--surface-2); color: var(--muted); }
.badge.ok { background: var(--accent-soft); color: var(--accent); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.banner { border-radius: var(--radius); padding: 12px 16px; margin-bottom: 16px; display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.banner { border-radius: var(--radius); padding: 0.75rem 1rem; margin-bottom: 1rem; display: flex; gap: 0.75rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.banner.warn { background: var(--warn-soft); color: var(--text); border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent); }
.banner.info { background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: 15px; }
.crumbs button { border: none; background: none; color: var(--accent); cursor: pointer; font: inherit; padding: 2px 4px; border-radius: 4px; }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; font-size: 0.9375rem; }
.crumbs button { border: none; background: none; color: var(--accent); cursor: pointer; font: inherit; padding: 2px 0.25rem; border-radius: 0.25rem; }
.crumbs button:hover { background: var(--surface-2); }
.crumbs .sep { color: var(--muted); }
@ -159,45 +163,45 @@ tr.clickable:hover td { background: var(--surface-2); }
border-radius: var(--radius); font-weight: 600; color: var(--accent);
}
.uploads { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.upload { display: grid; grid-template-columns: 1fr 160px 70px; gap: 10px; align-items: center; font-size: 13px; }
.bar { height: 6px; background: var(--surface-2); border-radius: 3px; overflow: hidden; }
.uploads { display: flex; flex-direction: column; gap: 0.375rem; margin-bottom: 0.75rem; }
.upload { display: grid; grid-template-columns: 1fr 10rem 4.375rem; gap: 0.625rem; align-items: center; font-size: 0.8125rem; }
.bar { height: 0.375rem; background: var(--surface-2); border-radius: 0.1875rem; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent); width: 0; transition: width .2s; }
.logs {
font-family: var(--mono); font-size: 12px; background: var(--surface); border: 1px solid var(--border);
border-radius: var(--radius); padding: 12px; height: calc(100vh - 170px); overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere;
font-family: var(--mono); font-size: 0.75rem; background: var(--surface); border: 1px solid var(--border);
border-radius: var(--radius); padding: 0.75rem; height: calc(100vh - 10.625rem); overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere;
}
.logs .err { color: var(--danger); }
.logs .sys { color: var(--muted); font-style: italic; }
.secret { display: flex; gap: 6px; align-items: center; }
.secret code { background: var(--surface-2); padding: 3px 8px; border-radius: 6px; overflow-wrap: anywhere; }
pre.snippet { background: var(--surface-2); padding: 10px 12px; border-radius: 8px; overflow: auto; margin: 0; font-family: var(--mono); font-size: 12px; }
.secret { display: flex; gap: 0.375rem; align-items: center; }
.secret code { background: var(--surface-2); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; overflow-wrap: anywhere; }
pre.snippet { background: var(--surface-2); padding: 0.625rem 0.75rem; border-radius: 0.5rem; overflow: auto; margin: 0; font-family: var(--mono); font-size: 0.75rem; }
.phrase { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; counter-reset: w; }
.phrase span { background: var(--surface-2); padding: 6px 8px; border-radius: 6px; font-family: var(--mono); counter-increment: w; }
.phrase { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.375rem; counter-reset: w; }
.phrase span { background: var(--surface-2); padding: 0.375rem 0.5rem; border-radius: 0.375rem; font-family: var(--mono); counter-increment: w; }
.phrase span::before { content: counter(w) ". "; color: var(--muted); }
.steps { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.steps span { padding: 3px 10px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 12.5px; }
.steps { display: flex; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; }
.steps span { padding: 0.1875rem 0.625rem; border-radius: 62.4375rem; background: var(--surface-2); color: var(--muted); font-size: 0.7813rem; }
.steps span.on { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
/* modal + toasts */
.modal-backdrop { position: fixed; inset: 0; background: rgb(0 0 0 / .45); display: grid; place-items: center; padding: 16px; z-index: 25; }
.modal { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 22px; width: min(560px, 100%); max-height: 90vh; overflow: auto; }
.modal h2 { margin-bottom: 14px; }
.modal .foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.modal-backdrop { position: fixed; inset: 0; background: rgb(0 0 0 / .45); display: grid; place-items: center; padding: 1rem; z-index: 25; }
.modal { background: var(--surface); border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.375rem; width: min(35rem, 100%); max-height: 90vh; overflow: auto; }
.modal h2 { margin-bottom: 0.875rem; }
.modal .foot { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.125rem; }
.toasts { position: fixed; right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 8px; z-index: 20; }
.toast { background: var(--text); color: var(--bg); padding: 10px 14px; border-radius: 8px; max-width: 380px; box-shadow: 0 6px 20px rgb(0 0 0 / .2); }
.toasts { position: fixed; right: 1rem; bottom: 1rem; display: flex; flex-direction: column; gap: 0.5rem; z-index: 20; }
.toast { background: var(--text); color: var(--bg); padding: 0.625rem 0.875rem; border-radius: 0.5rem; max-width: 23.75rem; box-shadow: 0 0.375rem 1.25rem rgb(0 0 0 / .2); }
.toast.error { background: var(--danger); color: #fff; }
.signin { display: grid; place-items: center; min-height: 100%; padding: 16px; }
.signin-card { width: min(340px, 100%); display: flex; flex-direction: column; gap: 12px; align-items: stretch; text-align: center; }
.signin { display: grid; place-items: center; min-height: 100%; padding: 1rem; }
.signin-card { width: min(21.25rem, 100%); display: flex; flex-direction: column; gap: 0.75rem; align-items: stretch; text-align: center; }
.signin-card img { align-self: center; }
.spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .8s linear infinite; display: inline-block; }
.spinner { width: 0.875rem; height: 0.875rem; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .8s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }
.nav-toggle, .brand .here { display: none; }
@ -207,90 +211,90 @@ pre.snippet { background: var(--surface-2); padding: 10px 12px; border-radius: 8
@media (max-width: 760px) {
.app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
.sidebar { position: sticky; top: 0; z-index: 5; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center;
padding: 8px 12px; gap: 8px; border-right: none; border-bottom: 1px solid var(--border); }
.brand { flex: 1; min-width: 0; padding: 0; font-size: 15px; gap: 8px; }
.brand img { width: 22px; height: 22px; }
padding: 0.5rem 0.75rem; gap: 0.5rem; border-right: none; border-bottom: 1px solid var(--border); }
.brand { flex: 1; min-width: 0; padding: 0; font-size: 0.9375rem; gap: 0.5rem; }
.brand img { width: 1.375rem; height: 1.375rem; }
.brand .here { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-weight: 500; }
.brand .here:not(:empty)::before { content: "· "; }
.nav-toggle { display: inline-grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: 8px;
background: var(--surface); color: var(--text); font: inherit; font-size: 17px; cursor: pointer; }
.nav-toggle { display: inline-grid; place-items: center; width: 2.125rem; height: 2.125rem; border: 1px solid var(--border); border-radius: 0.5rem;
background: var(--surface); color: var(--text); font: inherit; font-size: 1.0625rem; cursor: pointer; }
/* ☰ opens the menu over the page, from the top-right corner. */
nav { display: none; position: absolute; top: calc(100% + 4px); right: 10px; z-index: 30; width: min(240px, calc(100vw - 20px));
flex-direction: column; padding: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
box-shadow: 0 10px 28px rgb(0 0 0 / .22); }
nav { display: none; position: absolute; top: calc(100% + 0.25rem); right: 0.625rem; z-index: 30; width: min(15rem, calc(100vw - 1.25rem));
flex-direction: column; padding: 0.375rem; background: var(--surface); border: 1px solid var(--border); border-radius: 0.625rem;
box-shadow: 0 0.625rem 1.75rem rgb(0 0 0 / .22); }
.sidebar.nav-open nav { display: flex; }
.sidebar.nav-open .nav-toggle { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
nav .nav-sep { display: block; height: 1px; background: var(--border); margin: 6px 4px; }
nav .nav-sep { display: block; height: 1px; background: var(--border); margin: 0.375rem 0.25rem; }
nav a.nav-action { display: block; color: var(--muted); }
.host-controls { display: none; }
.daemon-pill { margin: 0; padding: 5px 9px; font-size: 12px; }
main { padding: 16px 14px 40px; }
.upload { grid-template-columns: 1fr 80px 50px; }
.daemon-pill { margin: 0; padding: 0.3125rem 0.5625rem; font-size: 0.75rem; }
main { padding: 1rem 0.875rem 2.5rem; }
.upload { grid-template-columns: 1fr 5rem 3.125rem; }
.hide-sm, .wide-only { display: none; }
.page-head { margin-bottom: 14px; }
.page-head { margin-bottom: 0.875rem; }
.page-head > .row { width: 100%; }
.page-head > .row > label { flex: 1 1 100%; min-width: 0; }
.page-head h1:only-child, .page-head > div > h1 { display: none; }
.tiles { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.tiles { grid-template-columns: repeat(auto-fill, minmax(8.75rem, 1fr)); }
.page-head > .row > label > span[style] { width: auto !important; flex: 1; min-width: 0; }
.card { padding: 14px; }
h1 { font-size: 19px; }
th, td { padding: 7px 6px; }
.modal { padding: 16px; }
.modal-backdrop { padding: 8px; }
.card { padding: 0.875rem; }
h1 { font-size: 1.1875rem; }
th, td { padding: 0.4375rem 0.375rem; }
.modal { padding: 1rem; }
.modal-backdrop { padding: 0.5rem; }
}
@media (max-width: 420px) {
.daemon-pill .label { display: none; }
.daemon-pill { padding: 8px; }
.daemon-pill { padding: 0.5rem; }
}
/* Theseus sidebar: widen / open-in-tab controls */
.host-controls { display: flex; gap: 6px; flex-wrap: wrap; margin-top: auto; }
.host-controls { display: flex; gap: 0.375rem; flex-wrap: wrap; margin-top: auto; }
.host-controls + .daemon-pill { margin-top: 0; }
@media (max-width: 760px) { .host-controls { display: none; } }
@media (max-width: 420px) { .host-controls .btn { padding: 3px 7px; } }
@media (max-width: 420px) { .host-controls .btn { padding: 0.1875rem 0.4375rem; } }
/* Narrow hosts (Theseus sidebar): never scroll sideways. */
html, body { overflow-x: hidden; }
.card { min-width: 0; }
/* Get started wizard */
.wizard { max-width: 720px; }
.wizard h2 { margin-top: 6px; }
.wizard-progress { margin-bottom: 18px; }
.wizard-progress .bar { margin-top: 6px; }
.wizard-nav { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border); }
.wizard-list { margin: 0 0 8px 1.2em; padding: 0; display: grid; gap: 4px; }
.wizard { max-width: 45rem; }
.wizard h2 { margin-top: 0.375rem; }
.wizard-progress { margin-bottom: 1.125rem; }
.wizard-progress .bar { margin-top: 0.375rem; }
.wizard-nav { margin-top: 1.375rem; padding-top: 0.875rem; border-top: 1px solid var(--border); }
.wizard-list { margin: 0 0 0.5rem 1.2em; padding: 0; display: grid; gap: 0.25rem; }
.account-line { margin-top: 4px; }
.account-line { margin-top: 0.25rem; }
.account-line a { color: var(--accent); }
/* Buckets as folder tiles */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(170px, 100%), 1fr)); gap: 12px; }
.tile { border: 1px solid var(--border); border-radius: 10px; padding: 14px; cursor: pointer; display: flex; flex-direction: column; gap: 6px; background: var(--surface-2); }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(10.625rem, 100%), 1fr)); gap: 0.75rem; }
.tile { border: 1px solid var(--border); border-radius: 0.625rem; padding: 0.875rem; cursor: pointer; display: flex; flex-direction: column; gap: 0.375rem; background: var(--surface-2); }
.tile:hover, .tile:focus-visible { border-color: var(--accent); outline: none; }
.tile-icon { font-size: 34px; line-height: 1; }
.tile-icon { font-size: 2.125rem; line-height: 1; }
.tile-name { font-weight: 600; overflow-wrap: anywhere; }
.tile-actions { display: flex; gap: 6px; margin-top: 4px; }
.tile-actions { display: flex; gap: 0.375rem; margin-top: 0.25rem; }
/* Viewer */
.modal:has(.viewer) { width: min(920px, 100%); }
.viewer-media { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; border-radius: 8px; background: var(--surface-2); }
.modal:has(.viewer) { width: min(57.5rem, 100%); }
.viewer-media { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; border-radius: 0.5rem; background: var(--surface-2); }
.viewer-audio { width: 100%; }
.viewer-text { max-height: 60vh; white-space: pre-wrap; overflow-wrap: anywhere; }
/* Drive icon (a bucket): a small disk with a status light */
.drive-icon { width: 46px; height: 30px; border-radius: 7px; position: relative;
.drive-icon { width: 2.875rem; height: 1.875rem; border-radius: 0.4375rem; position: relative;
background: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
border: 2px solid var(--muted); box-shadow: inset 0 -7px 0 color-mix(in srgb, var(--muted) 25%, transparent); }
.drive-icon::after { content: ""; position: absolute; right: 7px; bottom: 3px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.drive-icon::after { content: ""; position: absolute; right: 0.4375rem; bottom: 0.1875rem; width: 0.375rem; height: 0.375rem; border-radius: 50%; background: var(--accent); }
.tile:hover .drive-icon { border-color: var(--accent); }
/* View types: Icons / List / Details */
.view-bar { display: flex; justify-content: flex-end; margin: -6px 0 8px; }
.view-bar { display: flex; justify-content: flex-end; margin: -6px 0 0.5rem; }
.view-bar:empty { display: none; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--surface); }
.seg button { appearance: none; border: none; background: none; color: var(--muted); font: inherit; font-size: 15px; line-height: 1; padding: 6px 10px; cursor: pointer; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 0.5rem; overflow: hidden; background: var(--surface); }
.seg button { appearance: none; border: none; background: none; color: var(--muted); font: inherit; font-size: 0.9375rem; line-height: 1; padding: 0.375rem 0.625rem; cursor: pointer; }
.seg button + button { border-left: 1px solid var(--border); }
.seg button:hover { background: var(--surface-2); color: var(--text); }
.seg button.on { background: var(--accent-soft); color: var(--accent); }
@ -298,100 +302,100 @@ html, body { overflow-x: hidden; }
table.files td.name { max-width: 0; width: 100%; white-space: normal; }
table.files td, table.files th { white-space: nowrap; }
table.files td.name > * { vertical-align: middle; }
table.files td.name > .drive-icon { display: inline-block; margin-right: 8px; }
.cell-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
table.files td.name > .drive-icon { display: inline-block; margin-right: 0.5rem; }
.cell-name { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
/* File names wrap to two lines at most, then end in "…" */
.cell-name .label, ul.rows .label { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
overflow-wrap: anywhere; line-height: 1.35; min-width: 0; }
.ficon { flex: none; width: 1.4em; text-align: center; }
.drive-icon.sm { width: 26px; height: 17px; border-radius: 4px; border-width: 1.5px; box-shadow: inset 0 -4px 0 color-mix(in srgb, var(--muted) 25%, transparent); flex: none; }
.drive-icon.sm::after { width: 4px; height: 4px; right: 4px; bottom: 2px; }
.drive-icon.sm { width: 1.625rem; height: 1.0625rem; border-radius: 0.25rem; border-width: 1.5px; box-shadow: inset 0 -4px 0 color-mix(in srgb, var(--muted) 25%, transparent); flex: none; }
.drive-icon.sm::after { width: 0.25rem; height: 0.25rem; right: 0.25rem; bottom: 2px; }
ul.rows { list-style: none; margin: 0; padding: 0; }
ul.rows li { display: flex; align-items: center; gap: 10px; padding: 6px 6px; border-radius: 6px; min-width: 0; }
ul.rows li { display: flex; align-items: center; gap: 0.625rem; padding: 0.375rem 0.375rem; border-radius: 0.375rem; min-width: 0; }
ul.rows li + li { border-top: 1px solid var(--border); }
ul.rows li:hover, ul.rows li:focus-visible { background: var(--surface-2); outline: none; }
ul.rows .label { flex: 1; }
ul.rows .meta { color: var(--muted); font-size: 12.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
ul.rows .meta { color: var(--muted); font-size: 0.7813rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.clickable { cursor: pointer; }
tr.clickable:focus-visible td { background: var(--surface-2); }
tr.clickable:focus-visible { outline: none; }
.tile { position: relative; }
.tile-more { position: absolute; top: 6px; right: 6px; }
.tile-more { position: absolute; top: 0.375rem; right: 0.375rem; }
.tile .tile-more .more { opacity: .55; }
.tile:hover .tile-more .more, .tile:focus-within .tile-more .more { opacity: 1; }
.tiles.files { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.tiles.files .tile { padding: 8px; gap: 4px; align-items: stretch; text-align: center; }
.tiles.files .tile-name { font-weight: 500; font-size: 13px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.thumb { aspect-ratio: 4 / 3; border-radius: 6px; background: var(--surface); display: grid; place-items: center; overflow: hidden; }
.tiles.files { grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr)); gap: 0.5rem; }
.tiles.files .tile { padding: 0.5rem; gap: 0.25rem; align-items: stretch; text-align: center; }
.tiles.files .tile-name { font-weight: 500; font-size: 0.8125rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.thumb { aspect-ratio: 4 / 3; border-radius: 0.375rem; background: var(--surface); display: grid; place-items: center; overflow: hidden; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.big-icon { font-size: 38px; line-height: 1; }
.big-icon { font-size: 2.375rem; line-height: 1; }
.usage { display: block; white-space: nowrap; }
.more { padding: 1px 8px; font-size: 15px; line-height: 1.2; }
.menu { position: fixed; z-index: 30; min-width: 150px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 8px 24px rgb(0 0 0 / .18); padding: 4px; display: flex; flex-direction: column; }
.menu button { appearance: none; border: none; background: none; color: var(--text); font: inherit; text-align: left; padding: 7px 10px; border-radius: 6px; cursor: pointer; }
.more { padding: 1px 0.5rem; font-size: 0.9375rem; line-height: 1.2; }
.menu { position: fixed; z-index: 30; min-width: 9.375rem; background: var(--surface); border: 1px solid var(--border); border-radius: 0.5rem;
box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / .18); padding: 0.25rem; display: flex; flex-direction: column; }
.menu button { appearance: none; border: none; background: none; color: var(--text); font: inherit; text-align: left; padding: 0.4375rem 0.625rem; border-radius: 0.375rem; cursor: pointer; }
.menu button:hover, .menu button:focus-visible { background: var(--surface-2); outline: none; }
.menu button.danger { color: var(--danger); }
/* Music player, docked at the bottom; stays while you browse */
.player { position: fixed; left: 0; right: 0; bottom: 0; z-index: 15; display: flex; align-items: center; gap: 12px;
padding: 8px 14px; background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -4px 16px rgb(0 0 0 / .12); }
@media (min-width: 761px) { .player { left: 220px; } }
body.has-player main { padding-bottom: 96px; }
body.has-player .toasts { bottom: 84px; }
.player { position: fixed; left: 0; right: 0; bottom: 0; z-index: 15; display: flex; align-items: center; gap: 0.75rem;
padding: 0.5rem 0.875rem; background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -4px 1rem rgb(0 0 0 / .12); }
@media (min-width: 761px) { .player { left: 13.75rem; } }
body.has-player main { padding-bottom: 6rem; }
body.has-player .toasts { bottom: 5.25rem; }
.pl-controls { display: flex; align-items: center; gap: 2px; flex: none; }
.pl-btn { appearance: none; border: none; background: none; color: var(--text); font: inherit; font-size: 16px; width: 32px; height: 32px;
.pl-btn { appearance: none; border: none; background: none; color: var(--text); font: inherit; font-size: 1rem; width: 2rem; height: 2rem;
border-radius: 50%; cursor: pointer; display: grid; place-items: center; }
.pl-btn:hover:not(:disabled) { background: var(--surface-2); }
.pl-btn:disabled { opacity: .35; cursor: default; }
.pl-main { width: 38px; height: 38px; background: var(--accent); color: var(--accent-ink); font-size: 15px; }
.pl-main { width: 2.375rem; height: 2.375rem; background: var(--accent); color: var(--accent-ink); font-size: 0.9375rem; }
.pl-main:hover:not(:disabled) { background: var(--accent); filter: brightness(1.08); }
.pl-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-head { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.pl-head { display: flex; align-items: baseline; gap: 0.5rem; min-width: 0; }
.pl-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.pl-where { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 0; min-width: 0; }
.pl-seek { display: flex; align-items: center; gap: 8px; }
.pl-seek { display: flex; align-items: center; gap: 0.5rem; }
.pl-seek input { flex: 1; min-width: 0; accent-color: var(--accent); margin: 0; }
.pl-time { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 2.6em; text-align: center; }
.pl-time { font-size: 0.7188rem; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 2.6em; text-align: center; }
@media (max-width: 420px) {
.player { gap: 6px; padding: 6px 8px; }
.player { gap: 0.375rem; padding: 0.375rem 0.5rem; }
.pl-where { display: none; }
.pl-btn { width: 28px; height: 28px; font-size: 14px; }
.pl-main { width: 34px; height: 34px; }
.pl-btn { width: 1.75rem; height: 1.75rem; font-size: 0.875rem; }
.pl-main { width: 2.125rem; height: 2.125rem; }
}
/* Footer: pithos.sia, the version and the updater (like Aegis's) */
.brandfoot { position: fixed; left: 0; right: 0; bottom: 0; z-index: 14; height: 28px; display: flex; align-items: center;
justify-content: space-between; padding: 0 12px; background: var(--surface); border-top: 1px solid var(--border);
font-size: 11.5px; color: var(--muted); }
@media (min-width: 761px) { .brandfoot { left: 220px; } }
.brandlink { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); text-decoration: none; padding: 2px 4px; border-radius: 4px; }
.brandfoot { position: fixed; left: 0; right: 0; bottom: 0; z-index: 14; height: 1.75rem; display: flex; align-items: center;
justify-content: space-between; padding: 0 0.75rem; background: var(--surface); border-top: 1px solid var(--border);
font-size: 0.7188rem; color: var(--muted); }
@media (min-width: 761px) { .brandfoot { left: 13.75rem; } }
.brandlink { display: inline-flex; align-items: center; gap: 0.3125rem; color: var(--muted); text-decoration: none; padding: 2px 0.25rem; border-radius: 0.25rem; }
.brandlink:hover { color: var(--accent); }
.brandfoot-right { display: inline-flex; align-items: center; gap: 8px; }
.brandfoot-right { display: inline-flex; align-items: center; gap: 0.5rem; }
.brandver { font-variant-numeric: tabular-nums; letter-spacing: .3px; }
.brandcheck { appearance: none; background: none; border: 0; color: var(--muted); cursor: pointer; padding: 0 2px; font: inherit;
font-size: 13px; line-height: 1; opacity: .75; }
font-size: 0.8125rem; line-height: 1; opacity: .75; }
.brandcheck:hover { color: var(--accent); opacity: 1; }
.brandcheck.spin { animation: spin 1s linear infinite; }
.brandupd { appearance: none; border: 0; font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 9px; border-radius: 999px;
.brandupd { appearance: none; border: 0; font: inherit; font-size: 0.7188rem; font-weight: 600; padding: 2px 0.5625rem; border-radius: 62.4375rem;
background: var(--accent-soft); color: var(--accent); cursor: pointer; white-space: nowrap; }
.brandupd:disabled { cursor: default; }
.brandupd.ok, .brandupd.wait { background: var(--surface-2); color: var(--muted); font-weight: 500; }
.brandupd.err { background: var(--danger-soft); color: var(--danger); font-weight: 500; }
body.has-foot main { padding-bottom: 64px; }
body.has-foot .player { bottom: 28px; }
body.has-foot .toasts { bottom: 44px; }
body.has-foot.has-player main { padding-bottom: 124px; }
body.has-foot.has-player .toasts { bottom: 112px; }
body.has-foot main { padding-bottom: 4rem; }
body.has-foot .player { bottom: 1.75rem; }
body.has-foot .toasts { bottom: 2.75rem; }
body.has-foot.has-player main { padding-bottom: 7.75rem; }
body.has-foot.has-player .toasts { bottom: 7rem; }
/* Download / Share as icons on narrow screens */
.nav-sep, .nav-action { display: none; }
.narrow-only { display: none; }
.icon-row { gap: 2px; }
.btn.icon { padding: 4px 6px; color: var(--muted); }
.btn.icon { padding: 0.25rem 0.375rem; color: var(--muted); }
.btn.icon:hover:not(:disabled) { color: var(--accent); }
.btn.icon svg { display: block; }
.row-actions { display: inline-flex; align-items: center; gap: 2px; flex: none; }
@ -401,87 +405,87 @@ body.has-foot.has-player .toasts { bottom: 112px; }
}
/* Player volume */
.pl-volume { position: relative; display: flex; align-items: center; gap: 4px; flex: none; }
.pl-volume { position: relative; display: flex; align-items: center; gap: 0.25rem; flex: none; }
.pl-volpop { display: flex; align-items: center; }
.pl-volpop > .pl-btn { display: none; }
.pl-vol { width: 90px; accent-color: var(--accent); margin: 0; }
.pl-volbtn { font-size: 15px; }
.pl-vol { width: 5.625rem; accent-color: var(--accent); margin: 0; }
.pl-volbtn { font-size: 0.9375rem; }
@media (max-width: 760px) {
.pl-volpop { display: none; position: absolute; bottom: calc(100% + 10px); right: -6px; padding: 8px 10px; gap: 6px;
background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgb(0 0 0 / .2); }
.pl-volpop { display: none; position: absolute; bottom: calc(100% + 0.625rem); right: -6px; padding: 0.5rem 0.625rem; gap: 0.375rem;
background: var(--surface); border: 1px solid var(--border); border-radius: 0.625rem; box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / .2); }
.pl-volume.open .pl-volpop { display: flex; }
.pl-volpop > .pl-btn { display: grid; }
.pl-vol { width: 120px; }
.pl-vol { width: 7.5rem; }
}
/* "More options" disclosure in dialogs */
details.more-opts > summary { cursor: pointer; color: var(--muted); font-size: 13px; }
details.more-opts > summary { cursor: pointer; color: var(--muted); font-size: 0.8125rem; }
details.more-opts > summary:hover { color: var(--text); }
/* Free space on the Sia account */
.space { margin-top: 6px; max-width: 420px; }
.space-bar { margin-top: 4px; height: 6px; }
.space { margin-top: 0.375rem; max-width: 26.25rem; }
.space-bar { margin-top: 0.25rem; height: 0.375rem; }
.space-bar.full > i { background: var(--warn); }
/* Navigation: the Accounts card first, then pages, then the s3d group */
nav a.nav-account { display: flex; flex-direction: column; gap: 2px; padding: 9px 10px; margin-bottom: 6px;
border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); min-width: 0; }
nav a.nav-account { display: flex; flex-direction: column; gap: 2px; padding: 0.5625rem 0.625rem; margin-bottom: 0.375rem;
border: 1px solid var(--border); border-radius: 0.625rem; background: var(--surface-2); min-width: 0; }
nav a.nav-account:hover { border-color: var(--accent); background: var(--surface-2); }
nav a.nav-account.active { border-color: var(--accent); background: var(--accent-soft); color: var(--text); font-weight: 400; }
.na-label { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.na-label { font-size: 0.6875rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
nav a.nav-account.active .na-label { color: var(--accent); }
.na-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.na-space { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); margin-top: 2px; }
.na-space .bar { height: 4px; }
.na-space { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.75rem; color: var(--muted); margin-top: 2px; }
.na-space .bar { height: 0.25rem; }
.na-space .bar.full > i { background: var(--warn); }
.nav-group { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 12px 10px 4px; }
.nav-group { font-size: 0.6875rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 0.75rem 0.625rem 0.25rem; }
/* Full page / Back to sidebar as an icon beside the menu button (compact bar) */
.bar-btn { display: none; }
@media (max-width: 760px) {
.bar-btn { display: inline-grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: 8px;
background: var(--surface); color: var(--text); font: inherit; font-size: 16px; cursor: pointer; }
.bar-btn { display: inline-grid; place-items: center; width: 2.125rem; height: 2.125rem; border: 1px solid var(--border); border-radius: 0.5rem;
background: var(--surface); color: var(--text); font: inherit; font-size: 1rem; cursor: pointer; }
.bar-btn:hover { border-color: var(--accent); color: var(--accent); }
}
/* Account switcher on the Accounts page */
.acct-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: 10px; }
.acct-tile { display: flex; flex-direction: column; gap: 4px; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); min-width: 0; align-items: flex-start; }
.acct-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(13.75rem, 100%), 1fr)); gap: 0.625rem; }
.acct-tile { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: 0.625rem; background: var(--surface-2); min-width: 0; align-items: flex-start; }
.acct-tile .row.spread { width: 100%; }
.acct-tile.current { border-color: var(--accent); background: var(--accent-soft); }
.acct-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.acct-tile .btn { margin-top: auto; }
.acct-tile.add { appearance: none; font: inherit; color: var(--text); cursor: pointer; border-style: dashed; background: transparent; text-align: left; justify-content: center; }
.acct-tile.add:hover { border-color: var(--accent); }
.acct-plus { font-size: 20px; line-height: 1; color: var(--accent); }
.acct-plus { font-size: 1.25rem; line-height: 1; color: var(--accent); }
/* The Pithos name is a link to Overview */
a.brand { color: inherit; text-decoration: none; }
a.brand:hover > span:first-of-type { color: var(--accent); }
/* Drive header: who can read it, and Share, beside the path */
.crumb-row { gap: 8px; align-items: center; }
.chip { border: 1px solid var(--border); background: var(--surface-2); color: inherit; font: inherit; font-size: 12.5px; padding: 3px 10px; border-radius: 999px; cursor: pointer; white-space: nowrap; }
.crumb-row { gap: 0.5rem; align-items: center; }
.chip { border: 1px solid var(--border); background: var(--surface-2); color: inherit; font: inherit; font-size: 0.7813rem; padding: 0.1875rem 0.625rem; border-radius: 62.4375rem; cursor: pointer; white-space: nowrap; }
.chip:hover { border-color: var(--accent); }
.access-chip.private { color: var(--muted); }
.access-chip.public { color: var(--accent); border-color: var(--accent); }
@media (max-width: 760px) { .crumb-row { row-gap: 6px; } .chip { font-size: 12px; padding: 2px 8px; } }
@media (max-width: 760px) { .crumb-row { row-gap: 0.375rem; } .chip { font-size: 0.75rem; padding: 2px 0.5rem; } }
/* Public links in the Share dialogs */
.link-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; background: var(--surface-2); }
.link-card { border: 1px solid var(--border); border-radius: 0.625rem; padding: 0.625rem 0.75rem; display: flex; flex-direction: column; gap: 0.375rem; background: var(--surface-2); }
.link-card.fresh { border-color: var(--accent); }
.link-card .link-url { color: var(--accent); font-family: ui-monospace, Consolas, monospace; font-size: 13px; word-break: break-all; text-decoration: none; }
.link-card .link-url { color: var(--accent); font-family: ui-monospace, Consolas, monospace; font-size: 0.8125rem; word-break: break-all; text-decoration: none; }
.link-card .link-url:hover { text-decoration: underline; }
.link-card code { font-size: 12px; word-break: break-all; }
.link-card .row { gap: 6px; flex-wrap: wrap; }
.link-make { gap: 10px; align-items: center; flex-wrap: wrap; }
.link-card code { font-size: 0.75rem; word-break: break-all; }
.link-card .row { gap: 0.375rem; flex-wrap: wrap; }
.link-make { gap: 0.625rem; align-items: center; flex-wrap: wrap; }
.link-card a.btn { text-decoration: none; }
/* Waiting files that lost their copy (stuck uploads) */
.banner.stuck .stack { gap: 8px; width: 100%; }
.stuck-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.stuck-list li { display: flex; gap: 8px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.stuck-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 220px; }
.banner.stuck .stack { gap: 0.5rem; width: 100%; }
.stuck-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.375rem; }
.stuck-list li { display: flex; gap: 0.5rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.stuck-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 13.75rem; }
/* Toasts with actions (Share: Open / Manage) */
.toast.action { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.toast.action { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.toast.action > span { flex: 1 1 auto; }

View file

@ -261,12 +261,18 @@ function addOpenInBrowser() {
const run = async () => {
try { await api('POST', '/api/open-in-browser', { route: shareableRoute() }); toast('Opened in your browser'); } catch (e) { fail(e); }
};
const row = h('div', { class: 'host-controls' },
h('button', { class: 'btn small', title: 'Open this page of Pithos in your default browser', onclick: run }, '↗ Open in browser'));
$('.sidebar').insertBefore(row, $('#daemon-pill'));
hostControls().append(h('button', { class: 'btn small', title: 'Open this page of Pithos in your default browser', onclick: run }, '↗ Open in browser'));
addMenuAction('↗ Open in browser', run);
}
// The host's buttons (Full page, Back to sidebar, Open in browser) share
// one row at the foot of the sidebar, just above the s3d status.
function hostControls() {
let row = $('.sidebar .host-controls');
if (!row) { row = h('div', { class: 'host-controls' }); $('.sidebar').insertBefore(row, $('#daemon-pill')); }
return row;
}
// Go to a page given as '#/page/parts', whichever kind of address this host uses.
function navTo(hash) {
if (!PATH_MODE) { location.hash = hash; return; }
@ -2715,13 +2721,12 @@ function logs(main) {
function addSidebarControls() {
// The panel may have been widened by an earlier Pithos; start narrow.
bridge.sidebar?.isMax?.().then((max) => { if (max) bridge.sidebar.restore?.() ?? bridge.sidebar.toggleMax?.(); }).catch(() => {});
const row = h('div', { class: 'host-controls' },
h('button', { class: 'btn small', title: 'Open Pithos in a tab and close this panel', onclick: async () => {
try { await bridge.invoke('open-in-tab', { path: hashToPath(location.hash || '#/overview') }); await bridge.sidebar?.close?.(); } catch (e) { fail(e); }
} }, '⤢ Full page'));
$('.sidebar').insertBefore(row, $('#daemon-pill'));
addMenuAction('⤢ Open as full page', () => row.querySelector('button').click());
addBarButton('⤢', 'Open as full page', () => row.querySelector('button').click());
const btn = h('button', { class: 'btn small', title: 'Open Pithos in a tab and close this panel', onclick: async () => {
try { await bridge.invoke('open-in-tab', { path: hashToPath(location.hash || '#/overview') }); await bridge.sidebar?.close?.(); } catch (e) { fail(e); }
} }, '⤢ Full page');
hostControls().prepend(btn);
addMenuAction('⤢ Open as full page', () => btn.click());
addBarButton('⤢', 'Open as full page', () => btn.click());
}
// A one-click icon in the compact top bar, beside ☰ (narrow layouts only).
@ -2917,14 +2922,13 @@ function setupFooter() {
// The full-page tab opened from the Theseus panel: one button back.
function addBackToSidebar() {
const row = h('div', { class: 'host-controls' },
h('button', { class: 'btn small', title: 'Show Pithos in the sidebar again and close this page', onclick: async () => {
try { await api('POST', '/api/host/show-panel'); } catch (e) { return fail(e); }
window.close(); // works for tabs the add-on opened; harmless otherwise
} }, '⇤ Back to sidebar'));
$('.sidebar').insertBefore(row, $('#daemon-pill'));
addMenuAction('⇤ Back to sidebar', () => row.querySelector('button').click());
addBarButton('⇤', 'Back to sidebar', () => row.querySelector('button').click());
const btn = h('button', { class: 'btn small', title: 'Show Pithos in the sidebar again and close this page', onclick: async () => {
try { await api('POST', '/api/host/show-panel'); } catch (e) { return fail(e); }
window.close(); // works for tabs the add-on opened; harmless otherwise
} }, '⇤ Back to sidebar');
hostControls().prepend(btn);
addMenuAction('⇤ Back to sidebar', () => btn.click());
addBarButton('⇤', 'Back to sidebar', () => btn.click());
}
function showSignin() {