:root {
  --bg: #f6f6f8; --fg: #16161a; --mute: #6b6b76; --card: #fff; --line: #e4e4ea; --acc: #0a7c6c; --acc-fg: #fff;
  --user: #e8f4f1; --tool: #f0f0f4; --danger: #b3261e;
  --sat: env(safe-area-inset-top, 0px); --sab: env(safe-area-inset-bottom, 0px);
}
/* Theme: html[data-theme] = light | dark; absent = follow the system. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --bg: #111114; --fg: #ececf1; --mute: #9a9aa6; --card: #1b1b20; --line: #2a2a31; --acc: #35b39d; --acc-fg: #06110f; --user: #17302b; --tool: #202026; color-scheme: dark; }
}
:root[data-theme="dark"] { --bg: #111114; --fg: #ececf1; --mute: #9a9aa6; --card: #1b1b20; --line: #2a2a31; --acc: #35b39d; --acc-fg: #06110f; --user: #17302b; --tool: #202026; color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
* { box-sizing: border-box; }
/* App shell: the document never scrolls — only `main` does. 100% (not 100vh/dvh) is the visible area on every mobile browser. */
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; }
/* iOS: the keyboard does not resize the layout viewport, it scrolls the page and often leaves it scrolled
   when it closes (a blank band at the bottom). The shell is pinned and sized to the visual viewport instead. */
body { position: fixed; inset: 0; top: var(--vvtop, 0px); width: 100%; height: var(--vvh, 100%); }
body { margin: 0; background: var(--bg); color: var(--fg); font: 16px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; display: flex; flex-direction: column; -webkit-tap-highlight-color: transparent; }
button, input, select, textarea { font: inherit; color: inherit; }
button { border: 0; border-radius: 12px; padding: 10px 14px; background: var(--acc); color: var(--acc-fg); cursor: pointer; }
button.ghost { background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); }
button.danger { color: var(--danger); }
button:disabled { opacity: .5; cursor: default; }
input, select, textarea { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; min-width: 0; }
code, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
a { color: var(--acc); }
[hidden] { display: none !important; }

#top { display: flex; align-items: center; justify-content: space-between; padding: calc(10px + var(--sat)) 16px 10px; }
.brand { font-size: 18px; white-space: nowrap; display: flex; align-items: center; gap: 8px; color: inherit; text-decoration: none; } .logo { width: 26px; height: 26px; border-radius: 6px; }
#top .pill { white-space: nowrap; }
.pill { background: var(--card); color: var(--mute); box-shadow: inset 0 0 0 1px var(--line); padding: 6px 12px; border-radius: 999px; font-size: 13px; }
.pill.ok { color: var(--acc); } .pill.bad { color: var(--danger); }

main { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0 16px; }   /* the tab bar is a flex row below it, not an overlay */
.tab { min-height: 100%; display: flex; flex-direction: column; }
.hint { color: var(--mute); font-size: 14px; } .center { text-align: center; }
.notice { background: var(--user); border-radius: 12px; padding: 12px 14px; margin: 8px 0; }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 14px; padding: 8px 0 20px; }
.tile { background: var(--card); border-radius: 18px; padding: 14px 8px 10px; text-align: center; box-shadow: inset 0 0 0 1px var(--line); cursor: pointer; user-select: none; }
.tile:active { transform: scale(.97); }
.group.local .group-h { margin-top: 6px; }
.group.local > .hint { margin: -2px 0 8px; }
.tile.localapp .localmark { position: absolute; bottom: 6px; right: 7px; font-style: normal; font-size: 11px; opacity: .65; }
.tile.running { box-shadow: inset 0 0 0 2px var(--acc); }
.tile.running::after { content: ''; position: absolute; top: 8px; right: 8px; width: 7px; height: 7px; border-radius: 50%; background: var(--acc); }
.tile { position: relative; }
.tile.newapp .icon { color: var(--acc); font-weight: 300; }
.tile .icon { font-size: 36px; line-height: 1; } .tile .name { font-size: 13px; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* App tiles, small (the default since 2026-10-24): four across a phone like its own home screen, the icon on a rounded
   square with the name under it on up to two lines; wider windows simply fit more. html[data-tiles="big"] (Settings →
   Appearance) keeps the earlier three-across cards. */
html:not([data-tiles="big"]) .grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 16px 6px; }
html:not([data-tiles="big"]) .tile { background: none; box-shadow: none; padding: 2px 2px 0; border-radius: 14px; }
html:not([data-tiles="big"]) .tile .icon { width: 60px; height: 60px; margin: 0 auto; border-radius: 16px; background: var(--card); box-shadow: inset 0 0 0 1px var(--line); display: flex; align-items: center; justify-content: center; font-size: 32px; }
html:not([data-tiles="big"]) .tile .name { font-size: 12px; line-height: 1.25; margin-top: 6px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
html:not([data-tiles="big"]) .tile.running { box-shadow: none; }
html:not([data-tiles="big"]) .tile.running .icon { box-shadow: inset 0 0 0 2px var(--acc); }
html:not([data-tiles="big"]) .tile.running::after { top: 2px; right: calc(50% - 32px); }
html:not([data-tiles="big"]) .tile.localapp .localmark { bottom: auto; top: 44px; right: calc(50% - 30px); }

.chips { display: flex; gap: 8px; overflow-x: auto; padding: 6px 0 10px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip { flex: 0 0 auto; background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); padding: 7px 12px; border-radius: 999px; font-size: 14px; }
.chip.on { background: var(--acc); color: var(--acc-fg); box-shadow: none; }

.transcript { flex: 1; display: flex; flex-direction: column; gap: 8px; padding-bottom: 8px; }
.msg { max-width: 92%; padding: 10px 14px; border-radius: 16px; white-space: pre-wrap; word-break: break-word; }
.msg.user { align-self: flex-end; background: var(--user); }
.msg.assistant { align-self: flex-start; background: var(--card); box-shadow: inset 0 0 0 1px var(--line); }
.msg.tool { align-self: flex-start; background: none; color: var(--mute); font-size: 13px; padding: 2px 6px; }
.msg.error { align-self: stretch; background: var(--card); color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }
.hint.held { color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); border-radius: 10px; padding: 8px 10px; }

/* the pattern picker, shown in "+ New" before the first message */
.new-ask { margin: 4px 2px 10px; font-size: 17px; font-weight: 600; color: var(--fg); }
.new-examples { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 0 0 14px; }
.new-ex { text-align: left; background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line);
  padding: 9px 13px; border-radius: 14px; font-size: 14px; line-height: 1.35; }
.new-ex::before { content: "“"; color: var(--mute); }
.new-ex::after { content: "”"; color: var(--mute); }
.pat-more { margin: 0 0 6px; }
.pat-more > summary { cursor: pointer; color: var(--mute); font-size: 14px; padding: 4px 2px 10px; }
.pat-more > summary .pat-picked { color: var(--fg); }
.patterns { align-self: stretch; margin: 2px 0 6px; }
.patterns .hint { margin: 0 2px 8px; }
.pat-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
.pat-row.three { grid-template-columns: repeat(3, 1fr); }
/* chips are small enough to pair up, rather than stacking three deep */
@media (max-width: 420px) { .pat-row.three { grid-template-columns: 1fr 1fr; } }
.patterns .hint { margin: 2px 2px 8px; }
/* A phone gets chips — icon and name, two across — because seven cards with a line of
   explanation each is a wall of text in front of the box you came here to type in. The
   full cards are for a window that has room for them. */
.pat { display: flex; align-items: center; gap: 8px; text-align: left;
  background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); padding: 9px 11px; border-radius: 12px; }
.pat small { display: none; }
.patterns .hint .long { display: none; }
html[data-layout="wide"] .patterns .hint .long { display: inline; }
html[data-layout="wide"] .patterns .hint .short { display: none; }
html[data-layout="wide"] .pat { flex-direction: column; align-items: flex-start; gap: 2px; padding: 10px 12px; border-radius: 14px; }
html[data-layout="wide"] .pat small { display: block; }
.pat.on { box-shadow: inset 0 0 0 2px var(--acc); }
.pat .pat-icon { font-size: 18px; line-height: 1.2; }
html[data-layout="wide"] .pat .pat-icon { font-size: 20px; }
.pat b { font-size: 14px; }
.pat small { color: var(--mute); font-size: 12px; line-height: 1.35; }
.pat.on small { color: var(--fg); }

.transcript, .msg { user-select: text; -webkit-user-select: text; -webkit-touch-callout: default; }   /* copy/paste from the build window */
.msg .md { white-space: normal; }
.msg .md > :first-child { margin-top: 0; } .msg .md > :last-child { margin-bottom: 0; }
.msg .md p { margin: 0 0 8px; white-space: pre-wrap; }
.msg .md h3, .msg .md h4, .msg .md h5, .msg .md h6 { margin: 12px 0 6px; font-size: 1.02em; line-height: 1.3; }
.msg .md ul, .msg .md ol { margin: 0 0 8px; padding-left: 22px; }
.msg .md li { margin: 2px 0; white-space: pre-wrap; }
.msg .md code { font: 0.9em ui-monospace, Menlo, Consolas, monospace; background: var(--line); padding: 1px 4px; border-radius: 5px; }
.msg .md pre { margin: 0 0 8px; padding: 8px 10px; background: var(--line); border-radius: 8px; overflow-x: auto; white-space: pre; }
.msg .md pre code { background: none; padding: 0; }
.msg .copy { display: block; margin: 4px -8px -6px auto; background: none; color: var(--mute); padding: 2px 8px; font-size: 15px; line-height: 1; border-radius: 8px; user-select: none; -webkit-user-select: none; }
.msg .copy:active { color: var(--acc); }
.msg.busy::after { content: ''; display: inline-block; width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: var(--acc); animation: blink 1s infinite; }
@keyframes blink { 50% { opacity: .2; } }

.composer { position: sticky; bottom: 0; display: flex; gap: 8px; align-items: flex-end; padding: 8px 0 10px; background: var(--bg); }
.composer textarea { flex: 1; resize: none; max-height: 160px; }
.composer button { width: 44px; height: 44px; border-radius: 50%; padding: 0; font-size: 20px; }

.card { background: var(--card); border-radius: 16px; padding: 14px 16px; margin: 10px 0; box-shadow: inset 0 0 0 1px var(--line); }
.card h2 { font-size: 15px; margin: 0 0 10px; color: var(--mute); text-transform: uppercase; letter-spacing: .04em; }
.row { display: flex; gap: 8px; align-items: center; margin: 8px 0; flex-wrap: wrap; }
.row input { flex: 1; }
.kv { font-size: 14px; } .kv div { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; } .kv span:last-child { color: var(--mute); text-align: right; word-break: break-all; }
#log { max-height: 240px; overflow: auto; white-space: pre-wrap; margin: 0; color: var(--mute); }

#tabs { flex: none; display: flex; background: var(--card); border-top: 1px solid var(--line); padding-bottom: var(--sab); }
html[data-keyboard]:not([data-layout="wide"]) #tabs { display: none; }
html[data-keyboard] #composer { padding-bottom: 8px; }
#tabs button { flex: 1; background: none; color: var(--mute); border-radius: 0; padding: 8px 0 6px; font-size: 20px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
#tabs button span { font-size: 11px; } #tabs button.on { color: var(--acc); }

#runner { position: fixed; inset: 0; background: var(--bg); display: flex; flex-direction: column; z-index: 10; }
.runbar { position: relative; display: flex; align-items: center; gap: 6px; padding: calc(2px + var(--sat)) 6px 2px; background: var(--card); border-bottom: 1px solid var(--line); }
.runbar > span { flex: 1; text-align: center; font-weight: 500; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.runbar > button { background: none; color: var(--fg); font-size: 19px; width: 40px; height: 32px; padding: 0; }
.runmenu { position: absolute; right: 6px; top: calc(100% + 4px); z-index: 30; min-width: 220px; background: var(--card); border-radius: 14px; padding: 6px; box-shadow: 0 10px 30px rgba(0,0,0,.22), 0 0 0 1px var(--line); display: flex; flex-direction: column; }
.runmenu[hidden] { display: none; }
.runmenu button { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: none; color: var(--fg); font: inherit; font-size: 15px; font-weight: 400; padding: 10px 12px; min-height: 44px; border-radius: 10px; }
.runmenu button:hover, .runmenu button:focus-visible { background: var(--soft); }
.runmenu button i { font-style: normal; width: 22px; text-align: center; font-size: 17px; }
/* The frame paints Palmtop's own background while the app loads — never white on a dark Palmtop. */
#run-frame { flex: 1; border: 0; width: 100%; background: var(--bg); }

/* WeChat: a shared app runs here, and this is the way out to install Palmtop (it goes back to the share page with ?stay) */
#wx-bar { position: fixed; left: 12px; right: 12px; bottom: calc(12px + var(--sab)); z-index: 25; display: flex; gap: 8px; }
#wx-bar[hidden] { display: none; }
#wx-get { flex: 1; padding: 14px 16px; font-size: 16px; font-weight: 600; border-radius: 14px; box-shadow: 0 6px 24px rgba(0,0,0,.35); }
#wx-close { flex: none; width: 48px; border-radius: 14px; background: var(--card); }
#toast { position: fixed; left: 50%; bottom: calc(84px + var(--sab)); transform: translateX(-50%); background: #333; color: #fff; padding: 10px 16px; border-radius: 20px; font-size: 14px; z-index: 20; box-shadow: 0 4px 20px rgba(0,0,0,.4); }

dialog.sheet { border: 0; padding: 0; background: transparent; color: var(--fg); max-width: 420px; width: calc(100% - 32px); }
dialog.sheet::backdrop { background: rgba(0,0,0,.5); }
dialog.sheet .card { margin: 0; }
/* "Send the link" (app.js sendLinkSheet): a bottom sheet on a phone, a centred dialog in the desk layout */
dialog.sendlink { max-height: calc(100dvh - 16px); }
html:not([data-layout="wide"]) dialog.sendlink { margin: auto auto 0; width: 100%; max-width: 560px; }
html:not([data-layout="wide"]) dialog.sendlink .card { border-radius: 18px 18px 0 0; padding-bottom: calc(16px + var(--sab, 0px)); }
html[data-layout="wide"] dialog.sendlink { max-width: 480px; }
dialog.sendlink .card { max-height: calc(100dvh - 16px); overflow-y: auto; }
dialog.sendlink h2 { margin: 0 0 4px; font-size: 20px; color: var(--fg); text-transform: none; letter-spacing: 0; }
.sendlink .sl-what { margin: 0 0 4px; color: var(--mute); font-weight: 600; overflow-wrap: anywhere; }
.sendlink textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 116px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg); overflow-wrap: anywhere; }
.sendlink .sl-main { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 10px 0 6px; }
.sendlink .sl-main > * { display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 52px; font-size: 16px; font-weight: 600; border-radius: 14px; text-decoration: none; }
.sendlink .sl-go { background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); }
.sendlink .sl-qr { margin: 10px 0 4px; text-align: center; }
.sendlink .sl-qr svg { width: 168px; height: 168px; display: block; margin: 0 auto; border-radius: 8px; }
.sendlink .sl-qr figcaption { font-size: 13px; color: var(--mute); margin-top: 4px; }
.sendlink .sl-foot { align-items: center; margin-top: 6px; }
.scanbox { position: relative; width: 100%; aspect-ratio: 1; background: #000; border-radius: 12px; overflow: hidden; }
.scanbox video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scanframe { position: absolute; inset: 14%; border: 3px solid rgba(255,255,255,.9); border-radius: 14px; box-shadow: 0 0 0 999px rgba(0,0,0,.3); pointer-events: none; }
.scanbox { touch-action: none; }
.scanbox video { transform-origin: 50% 50%; }
.scanzoom { display: flex; align-items: center; gap: 10px; margin: 10px 2px 0; font-size: 14px; }
.scanzoom[hidden] { display: none; }
.scanzoom input { flex: 1; min-height: 32px; }
.scanzoom b { min-width: 3.2em; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.scanmsg { min-height: 2.6em; text-align: center; }
.scanmsg.warn { color: var(--danger, #e5534b); }
.app-head { display: flex; gap: 12px; align-items: center; margin: 6px 0 10px; } .app-head .icon { font-size: 40px; line-height: 1; }
.linkbox { word-break: break-all; user-select: all; -webkit-user-select: all; }
.cardprev { display: block; width: 100%; border-radius: 10px; margin: 6px 0 8px; box-shadow: inset 0 0 0 1px var(--line); }

.intro { position: relative; padding-right: 40px; } .intro p { margin: 0; } .intro .row { margin: 10px 0 0; }
.intro .x { position: absolute; top: 4px; right: 4px; background: none; color: var(--mute); padding: 6px 10px; font-size: 18px; line-height: 1; }
.bar { display: flex; align-items: center; gap: 8px; padding: 8px 0 0; } .grow { flex: 1; }
button.small { padding: 6px 12px; font-size: 13px; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.group-h { display: flex; justify-content: space-between; align-items: baseline; margin: 10px 0 0; font-size: 14px; color: var(--mute); }
.gname { font-weight: 600; color: var(--fg); } .gname.edit { text-decoration: underline dotted; cursor: pointer; }
.tile { position: relative; }
#tab-apps { touch-action: pan-y pinch-zoom; }
.arrange .tile { touch-action: none; cursor: grab; }
.tile { -webkit-touch-callout: none; -webkit-user-select: none; }     /* iOS: the hold lifts the tile, no callout or text selection */
.tile.lifted { transform: scale(1.06); box-shadow: inset 0 0 0 2px var(--acc), 0 6px 20px rgba(0,0,0,.2); z-index: 2; animation: wiggle .3s ease-in-out infinite alternate; }
@keyframes wiggle { from { transform: scale(1.06) rotate(-1.5deg); } to { transform: scale(1.06) rotate(1.5deg); } }
@media (prefers-reduced-motion: reduce) { .tile.lifted { animation: none; } }
.tile.drag { opacity: .75; transform: scale(1.06); box-shadow: 0 6px 20px rgba(0,0,0,.25); z-index: 2; animation: none; }
.tile .del { position: absolute; top: -7px; left: -7px; width: 24px; height: 24px; border-radius: 50%; padding: 0; font-size: 12px; line-height: 24px; background: var(--danger); color: #fff; }
.arrange .grid:empty, .dragging .grid:empty { min-height: 60px; border: 1px dashed var(--line); border-radius: 14px; }
.row.check { gap: 10px; font-weight: 600; } .row.check input { flex: none; width: 22px; height: 22px; margin: 0; accent-color: var(--acc); }
.dtoast { margin-top: 10px; background: #333; color: #fff; padding: 8px 12px; border-radius: 12px; font-size: 14px; text-align: center; }
#inst-link { width: 100%; font-size: 12px; margin-top: 8px; }

.badge { position: absolute; top: 6px; right: 22%; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--danger); color: #fff; font-size: 11px; font-style: normal; line-height: 16px; text-align: center; }
#tabs button { position: relative; }
.ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccard { display: flex; align-items: center; gap: 12px; cursor: pointer; } .ccard .cicon { font-size: 28px; } .ccard .cname { font-weight: 600; } .ccard .cmeta { font-size: 13px; color: var(--mute); }
.ccard .unread { margin-left: auto; background: var(--acc); color: var(--acc-fg); border-radius: 999px; padding: 2px 9px; font-size: 12px; }
.feed { flex: 1; display: flex; flex-direction: column; gap: 10px; padding: 8px 0; }
.post { background: var(--card); border-radius: 14px; padding: 10px 12px; box-shadow: inset 0 0 0 1px var(--line); user-select: text; -webkit-user-select: text; }
.post.mine { background: var(--user); }
.post .who { font-size: 12px; color: var(--mute); margin-bottom: 4px; display: flex; gap: 8px; } .post .who span:nth-child(2) { flex: 1; }
.post .who .rm { margin-left: 8px; background: none; color: var(--mute); padding: 0 4px; font-size: 12px; }
.post.app .body { display: flex; gap: 12px; align-items: center; } .post.app .icon { font-size: 34px; line-height: 1; } .post.app .body > div { flex: 1; min-width: 0; }
.post.app .desc { font-size: 13px; color: var(--mute); } .post.app button.get { padding: 8px 12px; font-size: 14px; }
.post.note .text { white-space: pre-wrap; word-break: break-word; }
.round { width: 44px; height: 44px; border-radius: 50%; padding: 0; font-size: 22px; }
#circle-view { display: flex; flex-direction: column; min-height: 100%; }

.reply .sender { background: none; color: var(--mute); box-shadow: inset 0 0 0 1px var(--line); font-size: 11px; padding: 2px 8px; border-radius: 999px; margin-left: 6px; }
.reply .sender:active { color: var(--fg); }
.reply .vemail { color: var(--acc); font-weight: 600; } .reply .noemail { color: var(--danger, #c0392b); }
label.row.check { gap: 8px; align-items: center; font-size: 14px; } label.row.check input { width: auto; }
.iblist { max-height: 45vh; overflow: auto; display: flex; flex-direction: column; gap: 8px; margin: 6px 0; }
.reply { background: var(--bg); border-radius: 12px; padding: 8px 10px; font-size: 14px; }
.reply .who { font-size: 12px; color: var(--mute); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; } .reply .who .rm { margin-left: auto; background: none; color: var(--mute); padding: 0 4px; font-size: 12px; }
.reply .kv div { display: flex; gap: 10px; } .reply .kv span:first-child { color: var(--mute); min-width: 30%; }

.galgroup { padding: 6px 2px 0; }
.galgroup b { display: block; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--mute); }
.galgroup small { color: var(--mute); font-size: 12.5px; }
.galgroup:first-child { padding-top: 0; }
.gitem { display: flex; gap: 12px; align-items: center; background: var(--bg); border-radius: 12px; padding: 10px; } .gitem .icon { font-size: 32px; line-height: 1; } .gitem > div { flex: 1; min-width: 0; } .gitem .desc { font-size: 13px; color: var(--mute); } .gitem .tags { font-size: 11px; color: var(--mute); } .gitem button { padding: 8px 12px; font-size: 14px; }
#log { user-select: text; -webkit-user-select: text; }

.pick { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.pick .opt { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 12px; background: var(--bg); box-shadow: inset 0 0 0 1px var(--line); cursor: pointer; }
.pick .opt input { width: 20px; height: 20px; margin: 0; accent-color: var(--acc); flex: none; }
.pick .opt span { flex: 1; display: flex; flex-direction: column; } .pick .opt small { color: var(--mute); font-size: 12px; }
.pick .opt.on { box-shadow: inset 0 0 0 2px var(--acc); } .pick .opt.off { opacity: .6; } .pick .chev { color: var(--mute); font-style: normal; }
.row select { flex: 1; min-width: 0; } #gmodels-refresh { flex: none; padding: 6px 10px; }

.seg { display: flex; background: var(--bg); border-radius: 12px; padding: 3px; box-shadow: inset 0 0 0 1px var(--line); margin-top: 6px; }
.seg button { flex: 1; background: none; color: var(--mute); border-radius: 9px; padding: 8px 0; font-size: 14px; }
.seg button.on { background: var(--card); color: var(--fg); box-shadow: 0 1px 3px rgba(0,0,0,.15); }

/* Laptop / desktop: the layout is a phone's, so on a wide screen the shell becomes a phone-width column in the middle of the
   page instead of stretching across it. body keeps its fixed positioning; the transform also makes the fixed overlays
   (#runner, #toast) position against the column rather than the whole window. */
@media (min-width: 760px) and (min-height: 480px) {
  html:not([data-layout="wide"]) { background: #e6e6eb; }
  html:not([data-layout="wide"]) body { width: 560px; left: 50%; right: auto; transform: translateX(-50%); box-shadow: 0 0 0 1px var(--line), 0 24px 60px -32px rgba(0, 0, 0, .55); }
}
@media (min-width: 760px) and (min-height: 480px) and (prefers-color-scheme: dark) { html:not([data-layout="wide"]):not([data-theme="light"]) { background: #08080a; } }
@media (min-width: 760px) and (min-height: 480px) { html[data-theme="dark"]:not([data-layout="wide"]) { background: #08080a; } html[data-theme="light"]:not([data-layout="wide"]) { background: #e6e6eb; } }

/* ── Wide window: the whole window, with the tabs as a left rail. The choice lives in
   Settings → Appearance; app.js resolves Automatic against the window width and sets
   html[data-layout], the way it sets html[data-theme], so there is no media query here. */
html[data-layout="wide"] body {
  width: 100%; left: 0; right: 0; transform: none; box-shadow: none;
  display: grid; grid-template-columns: 240px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "head head" "rail main";
}
html[data-layout="wide"] #top { grid-area: head; background: var(--card); border-bottom: 1px solid var(--line); padding-left: 20px; padding-right: 20px; }
html[data-layout="wide"] main { grid-area: main; padding: 0 28px; }
html[data-layout="wide"] .tab { max-width: 1000px; margin: 0 auto; width: 100%; }
html[data-layout="wide"] #tabs {
  grid-area: rail; flex-direction: column; justify-content: flex-start; gap: 4px;
  border-top: 0; border-right: 1px solid var(--line); padding: 14px 10px calc(14px + var(--sab));
}
html[data-layout="wide"] #tabs button {
  flex: none; width: 100%; flex-direction: row; justify-content: flex-start; align-items: center;
  gap: 12px; padding: 11px 13px; border-radius: 12px; font-size: 19px;
}
html[data-layout="wide"] #tabs button span { font-size: 15px; }
html[data-layout="wide"] #tabs button.on { background: var(--bg); }
html[data-layout="wide"] #tabs .badge { position: static; margin-left: auto; }
/* the app that is still running, kept in the rail below the four tabs */
html[data-layout="wide"] #tab-app { margin-top: auto; border-top: 1px solid var(--line); border-radius: 12px; padding-top: 12px; }
html[data-layout="wide"] #tab-app span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html[data-layout="wide"] #tab-app .railx { margin-left: auto; font-style: normal; font-size: 13px; color: var(--mute); padding: 0 2px; }
html[data-layout="wide"] #tab-app .railx:hover { color: var(--fg); }
#run-close { display: none; }                       /* on a phone ⌂ is the way out */
html[data-layout="wide"] #run-close { display: flex; }

/* A sheet is phone-width because a phone is narrow. The Gallery is a catalogue,
   so on a desk it gets room to be one: wider, two or three across, and taller
   before it starts scrolling. */
html[data-layout="wide"] dialog#gallery { max-width: 960px; }
html[data-layout="wide"] #gal-list { max-height: 72vh; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }
html[data-layout="wide"] #gal-list .gitem { align-items: flex-start; padding: 12px; }
html[data-layout="wide"] #gal-list .galgroup { grid-column: 1 / -1; }
html[data-layout="wide"] #gal-list .gitem button { align-self: center; }
/* the Inbox is a list of replies, and reads better with the same room */
html[data-layout="wide"] dialog#inboxdlg { max-width: 760px; }
html[data-layout="wide"] dialog#inboxdlg .iblist { max-height: 60vh; }
/* A mini-app is written for a phone, so it keeps a phone's width in the middle of the pane
   rather than being stretched across a monitor. The rail stays visible beside it. */
html[data-layout="wide"] #runner { position: static; grid-area: main; padding-bottom: 20px; }
html[data-layout="wide"] .grid { grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); }
html[data-layout="wide"] .runbar { border-radius: 14px 14px 0 0; max-width: 480px; width: 100%; margin: 14px auto 0; box-shadow: 0 0 0 1px var(--line); }
html[data-layout="wide"] #run-frame { max-width: 480px; width: 100%; margin: 0 auto; border-radius: 0 0 18px 18px; box-shadow: 0 0 0 1px var(--line), 0 24px 60px -34px rgba(0,0,0,.55); }
/* An app built for a desk — a table, a rota, a board — takes the pane instead.
   plugin.json "wide": true, or the ⤢ button, which the person's choice remembers. */
html[data-layout="wide"] #runner[data-wide="1"] { padding-bottom: 0; }
html[data-layout="wide"] #runner[data-wide="1"] .runbar { max-width: none; margin: 0; border-radius: 0; box-shadow: none; border-bottom: 1px solid var(--line); }
html[data-layout="wide"] #runner[data-wide="1"] #run-frame { max-width: none; margin: 0; border-radius: 0; box-shadow: none; }
/* On a phone the runner is full-bleed either way, so the toggle has nothing to offer. */
#run-wide { display: none; }
html[data-layout="wide"] #run-wide { display: flex; }

/* what is attached to the next request */
.attach-chips { display: flex; gap: 6px; flex-wrap: wrap; padding: 4px 0 6px; }
.attach-chips .achip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; background: var(--card); box-shadow: inset 0 0 0 1px var(--line); border-radius: 999px; padding: 4px 6px 4px 10px; font-size: 13px; }
.attach-chips .achip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-chips .achip img { width: 22px; height: 22px; border-radius: 6px; object-fit: cover; }
.attach-chips .achip button { width: 22px; height: 22px; border-radius: 50%; padding: 0; font-size: 13px; line-height: 1; background: transparent; box-shadow: none; }
.composer button.ghost { background: var(--card); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); font-size: 18px; }
/* one small attach button on the left; on the right the mic gives way to send as soon as there is text */
.composer button#attach { width: 36px; height: 36px; font-size: 16px; margin-bottom: 4px; }
.composer button#mic { background: var(--acc); color: var(--acc-fg); box-shadow: none; }
.composer button#mic.on { background: #d33; color: #fff; box-shadow: none; animation: micpulse 1.2s ease-in-out infinite; }
@keyframes micpulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

/* a published page: the app alone, a thin line at the bottom saying what made it. Keyed on the html
   attribute the inline script sets before first paint, so the tab bar, header and rail never show. */
html[data-page] #tabs, html[data-page] #top, html[data-page] #run-home, html[data-page] #run-back, html[data-page] #run-close, html[data-page] #run-share, html[data-page] #run-bug, html[data-page] #run-wide { display: none !important; }
html[data-page] body { display: block; width: 100%; left: 0; right: 0; transform: none; box-shadow: none; }
html[data-page] main { display: none; }
html[data-page] #runner { position: fixed; inset: 0 0 28px 0; padding-bottom: 0; }
#page-foot { position: fixed; left: 0; right: 0; bottom: 0; height: 28px; z-index: 11; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; font-size: 12px; color: var(--mute); background: var(--card); border-top: 1px solid var(--line); }
#page-foot a { color: var(--acc); text-decoration: none; margin-left: 12px; }
#page-foot #page-report { color: var(--mute); }
#acct-page-list { list-style: none; padding: 0; margin: 6px 0 0; } #acct-page-list li { margin: 4px 0; word-break: break-all; } #acct-page-list a.right { color: var(--mute); }
.row.rem { justify-content: space-between; flex-wrap: nowrap; } .row.rem small { color: var(--mute); }
/* feedback on a Gallery app: what the person chooses to send */
#feedback .actions button.on { box-shadow: inset 0 0 0 2px var(--acc); background: var(--soft, rgba(0,0,0,.04)); }
#feedback label { display: block; margin: 6px 0; }
#feedback textarea { display: block; width: 100%; box-sizing: border-box; margin-top: 6px; font: inherit; }

/* versions (2026-10-23): lineage, History, updates offered to customized Gallery apps */
.lineage { font-size: 12px; margin-top: 2px; }
.reads { margin: 8px 0 4px; } .reads .row.check { margin: 4px 0; font-weight: 500; }
.update-b { width: 100%; margin: 8px 0 0; }
.tile .updmark { position: absolute; top: 4px; right: 6px; width: 10px; height: 10px; border-radius: 50%; background: var(--acc, #0a7c6c); box-shadow: 0 0 0 2px var(--bg, #fff); }
.tile .updmark.sec { background: #c62828; }
#vd-body .ver { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line, #e4e4ea); }
#vd-body .ver .mid { flex: 1; min-width: 0; }
#vd-body .ver .mid small { display: block; color: var(--mute, #6b6b76); }
#vd-body .choice { display: block; width: 100%; text-align: left; margin: 8px 0; padding: 12px 14px; }
#vd-body .choice small { display: block; font-weight: 400; opacity: .8; margin-top: 2px; }
#vd-body .listen-words { min-height: 72px; font-size: 18px; line-height: 1.4; padding: 10px 12px; border-radius: 12px; box-shadow: inset 0 0 0 1px var(--line); }   /* forge.dictate's words as they are heard */
#vd-body .sec { background: #fdecea; color: #8a1c14; border-radius: 10px; padding: 10px 12px; margin: 8px 0; font-size: 14px; }
/* spaces (2026-10-27): the picker at the top of the home screen, its list, and the space chips in the app sheet */
.space-pick { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 60%; font-weight: 600; }
.space-pick .sname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.space-pick .caret { color: var(--mute); font-size: 11px; }
#vd-body .space-row { cursor: pointer; } #vd-body .space-row .tick { color: var(--acc); font-weight: 700; }
#vd-body .space-row.ordering { cursor: default; }
.space-order { display: flex; gap: 4px; }
.space-order button { min-width: 44px; min-height: 44px; }
.sh-spaces { gap: 6px; } .sh-spaces .chip { padding: 5px 10px; font-size: 13px; }
.space-line { margin: 6px 0 0; font-size: 13px; } .space-line .linkish, .linkish { background: none; color: var(--acc); padding: 0; border-radius: 0; font-size: inherit; text-decoration: underline; }
.space-note { margin: 8px 0 0; }
.group.gone .gone-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.group.gone .gone-row .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.intro .packs { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; } .intro .packs .chip { padding: 5px 10px; font-size: 13px; }
.intro .intro-sp { margin: 10px 0 0; font-size: 13px; }
/* ready-made spaces in sections (Your business / You and your family / Groups and work): a heading, then compact rows */
#vd-body .pack-sec { margin: 16px 0 2px; font-size: 13px; font-weight: 600; letter-spacing: .02em; color: var(--mute, #6b6b76); text-transform: uppercase; }
#vd-body .choice.pack-choice { margin: 6px 0; padding: 9px 12px; }
#vd-body .choice.pack-choice small { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.intro .packs .pack-sec { flex-basis: 100%; margin: 6px 0 0; font-size: 12px; font-weight: 600; color: var(--mute, #6b6b76); }
.intro .packs .chip.pack-more { background: transparent; color: var(--acc); box-shadow: inset 0 0 0 1px var(--line); }
.intro .packs .pack-break { flex-basis: 100%; height: 4px; }
#vd-body .pack-apps { margin: 4px 0 8px; padding-left: 18px; } #vd-body .pack-apps li { margin: 2px 0; }
/* The Team area (teamarea.js): a team's apps and its library, apart from the person's own */
.group.team .team-lib { margin: 4px 0 14px; }
.group.team .team-name { font-weight: 600; margin: 4px 0 6px; }
.group.team .team-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.group.team .team-row { background: var(--card); box-shadow: inset 0 0 0 1px var(--line); border-radius: 12px; padding: 10px 12px; overflow-wrap: anywhere; }
.group.team .team-row-h { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; }
.group.team .team-ver, .group.team .team-can, .group.team .team-notes { font-size: 13px; opacity: .75; }
.group.team .team-req { font-size: 12px; padding: 1px 8px; border-radius: 999px; background: var(--acc); color: var(--acc-fg); }
.group.team .team-act { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.group.team .team-act button { padding: 6px 12px; }
#team-disconnect { margin-top: 4px; font-size: 13px; }

/* the team space (teamarea.teamOnly): team apps only; no tabs, no builder status, no personal bars */
body.team-only #tabs, body.team-only #status, body.team-only #tab-apps > .bar, body.team-only #intro, body.team-only #grid-empty,
body.team-only #update-notice { display: none !important; }
body.team-only .team-space-empty { margin: 24px 4px; }
