:root {
  --bg:#0d1117; --panel:#161b22; --panel2:#0f141b; --border:#30363d;
  --text:#c9d1d9; --dim:#8b949e; --accent:#39d0c8; --accent-text:#06231f;
  --mono:'SF Mono',ui-monospace,Menlo,Consolas,monospace;
}
* { box-sizing:border-box; }
body {
  margin:0; height:100vh; background:var(--bg); color:var(--text);
  font-family:-apple-system,Segoe UI,Roboto,sans-serif;
}
.hidden { display:none !important; }

/* gate */
#gate { height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; }
.tally { margin-top:18px; color:var(--dim); font-size:12.5px; text-align:center; min-height:1em; }
.tally-app { margin:0; padding:6px 10px; border-top:1px solid var(--border);
  background:var(--panel2); font-size:11.5px; }

/* Scan (camera/OCR) button + full-screen camera overlay */
.scanbtn, .micbtn {
  background:var(--panel2); color:var(--accent); border:1px solid var(--border);
  border-radius:8px; cursor:pointer; padding:0 14px; display:flex;
  align-items:center; justify-content:center;
}
.scanbtn:hover, .micbtn:hover { border-color:var(--accent); }
.micbtn.listening { color:#fff; background:#c0392b; border-color:#c0392b;
  animation:micpulse 1s infinite; }
@keyframes micpulse { 0%,100%{ opacity:1 } 50%{ opacity:.55 } }

.camera { position:fixed; inset:0; z-index:50; background:#000;
  display:flex; flex-direction:column; }
.cam-view { position:relative; flex:1; min-height:0; overflow:hidden; }
#cam-video, #cam-still { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; background:#000; }
/* Only the inside of this box is read; the box-shadow dims everything outside. */
.crop-frame { position:absolute; border:2px solid var(--accent); border-radius:8px;
  box-shadow:0 0 0 9999px rgba(0,0,0,.45); pointer-events:none; }
.cam-bar { background:var(--panel2); border-top:1px solid var(--border);
  padding:12px; display:flex; flex-direction:column; gap:10px; }
#cam-status { color:var(--dim); font-size:13px; text-align:center; }
.cam-buttons { display:flex; gap:10px; justify-content:center; }
.cam-buttons button { padding:12px 24px; border-radius:8px; font-size:15px;
  font-weight:600; cursor:pointer; border:0; }
#capture { background:var(--accent); color:var(--accent-text); }
#capture:disabled { opacity:.5; cursor:default; }
#cam-cancel { background:var(--panel); color:var(--text); border:1px solid var(--border); }
.gatebox {
  width:min(340px, 90vw); padding:28px; background:var(--panel);
  border:1px solid var(--border); border-radius:14px; text-align:center;
}
.gatebox h1 { margin:0 0 6px; font-size:20px; }
.gatebox .hint { color:var(--dim); font-size:13px; margin:0 0 18px; }
.gatebox .hint.error { color:#f7796b; }
#passphrase, #machine-name {
  width:100%; padding:10px; background:#0a0e14; border:1px solid var(--border);
  border-radius:8px; color:var(--text); font-size:14px; margin-bottom:12px;
}
.field { position:relative; }
#passphrase { padding-right:40px; }
.peek {
  position:absolute; right:6px; top:7px; width:32px; height:32px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:0; cursor:pointer; color:var(--accent); opacity:.85;
  -webkit-user-select:none; user-select:none; -webkit-tap-highlight-color:transparent;
}
.peek:hover { opacity:1; }
#connect, .sendbtn {
  background:var(--accent); color:var(--accent-text); border:0; border-radius:8px;
  font-weight:700; cursor:pointer; padding:10px 18px; font-size:14px;
}
#connect { width:100%; }
.ghostbtn { width:100%; margin-top:10px; background:none; color:var(--accent);
  border:1px solid var(--border); border-radius:8px; padding:9px; font-size:13px; cursor:pointer; }
.ghostbtn:hover { border-color:var(--accent); }
/* Invited via a join link: hide the passphrase + quick-join, just ask for a name. */
body.invited .field, body.invited #quickjoin { display:none; }

.invitebtn { background:var(--panel); color:var(--accent); border:1px solid var(--border);
  border-radius:6px; padding:3px 10px; font-size:12px; cursor:pointer; }
.invitebtn:hover { border-color:var(--accent); }

.invite { position:fixed; inset:0; z-index:60; background:rgba(0,0,0,.6);
  display:flex; align-items:center; justify-content:center; padding:16px; }
.invite-card { background:var(--panel); border:1px solid var(--border); border-radius:14px;
  padding:22px; width:min(360px,92vw); text-align:center; }
.invite-card h2 { color:var(--accent); margin:0 0 6px; font-size:18px; }
.invite-qr { display:flex; align-items:center; justify-content:center; margin:14px 0; min-height:160px; }
.invite-qr img { width:210px; height:210px; image-rendering:pixelated;
  background:#fff; padding:8px; border-radius:8px; }
.invite-link { font-family:var(--mono); font-size:11px; color:var(--dim); word-break:break-all;
  background:#0a0e14; border:1px solid var(--border); border-radius:8px; padding:8px; margin-bottom:12px; }
.invite-actions { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; }
.invite-actions button { padding:9px 16px; border-radius:8px; font-size:14px; cursor:pointer; }
#invite-close { background:var(--panel2); color:var(--text); border:1px solid var(--border); }
.invite-warn { color:#f7796b; font-size:11.5px; margin:14px 0 0; }

/* app */
#app { height:100vh; display:flex; flex-direction:column; }
.topbar {
  display:flex; align-items:center; gap:12px; padding:10px 16px;
  /* In an installed PWA, keep the bar clear of the phone's status bar / notch. */
  padding-top:calc(10px + env(safe-area-inset-top, 0px));
  background:var(--panel2); border-bottom:1px solid var(--border); font-size:13px;
}
.brand { font-weight:600; letter-spacing:.4px; color:var(--accent); }
.machine { color:var(--dim); }
.dot { width:9px; height:9px; border-radius:50%; background:#3a3f47; }
.dot.on { background:var(--accent); box-shadow:0 0 8px var(--accent); }
#presence { margin-left:auto; color:var(--dim); }
#presence.on { color:var(--accent); }
.lock { color:var(--dim); }
.mute { cursor:pointer; user-select:none; }
.themebtn { background:none; border:0; cursor:pointer; font-size:15px; padding:0; line-height:1; }
.theme-pop { position:fixed; top:46px; right:10px; z-index:45; background:var(--panel);
  border:1px solid var(--border); border-radius:10px; padding:11px; display:flex; gap:9px;
  flex-wrap:wrap; width:168px; box-shadow:0 8px 24px rgba(0,0,0,.45); }
.swatch { width:26px; height:26px; border-radius:50%; border:2px solid var(--border);
  cursor:pointer; padding:0; transition:transform .1s; }
.swatch:hover { transform:scale(1.12); border-color:#fff; }

.two { flex:1; display:grid; grid-template-columns:1fr 1fr; min-height:0; }
.col { display:flex; flex-direction:column; min-width:0; min-height:0; }
.col:first-child { border-right:1px solid var(--border); }
.colhead {
  font-size:11px; text-transform:uppercase; letter-spacing:.6px; color:var(--dim);
  padding:9px 14px; border-bottom:1px solid var(--border); background:var(--panel2);
}
.arrow { color:var(--accent); font-weight:700; }
.body { flex:1; overflow:auto; padding:10px 12px; }

.snip { border:1px solid var(--border); border-radius:8px; background:var(--panel2);
  margin:0 0 10px; overflow:hidden; }
.snip.you { box-shadow:inset 3px 0 0 var(--accent); }
.snip .sh { display:flex; align-items:center; gap:8px; padding:5px 10px;
  font-size:11px; color:var(--dim); border-bottom:1px solid var(--border); }
.snip .copy { margin-left:auto; color:var(--accent); cursor:pointer; }
/* Group mode (group.clipferry.com): one unified chat stream instead of columns. */
#chat { display:none; flex:1; min-height:0; overflow-y:auto;
  padding:12px; flex-direction:column; gap:8px; }
body.group .two { display:none; }
body.group #chat { display:flex; }
.msg { display:flex; }
.msg.mine { justify-content:flex-end; }
.msg .bubble { max-width:82%; border:1px solid var(--border); border-radius:10px;
  background:var(--panel2); overflow:hidden; }
.msg.mine .bubble { background:#0f2a28; border-color:var(--accent); }
.msg .mh { display:flex; align-items:center; gap:8px; padding:5px 10px;
  font-size:11px; color:var(--dim); border-bottom:1px solid var(--border); }
.msg .mh .who { color:var(--accent); font-weight:600; }
.msg .mh .copy { margin-left:auto; color:var(--accent); cursor:pointer; }
.msg pre { margin:0; padding:9px 11px; font-family:var(--mono); font-size:12.5px;
  color:#d6dde6; white-space:pre-wrap; word-break:break-word; line-height:1.45; }

/* File mode (file.clipferry.com): a drop zone replaces the text compose, and
   each transfer shows as a card with a progress bar (+ preview for images). */
#filebar { display:none; }
body.file .compose { display:none; }
body.file #filebar { display:block; }
.dropzone { margin:10px 12px; padding:18px; text-align:center;
  border:2px dashed var(--border); border-radius:12px; background:var(--panel2); }
.dropzone.drag { border-color:var(--accent); background:#0f2a28; }
.dropzone .dz-main { margin:0 0 12px; color:var(--text); font-size:14px; }
.dropzone .dz-hint { margin:12px 0 0; color:var(--dim); font-size:12px; }

.filecard { border:1px solid var(--border); border-radius:8px; background:var(--panel2);
  margin:0 0 10px; padding:10px; }
.filecard .fname { font-size:13px; color:var(--text); word-break:break-all; }
.filecard .fmeta { font-size:11px; color:var(--dim); margin-top:2px; }
.filecard .fbar { height:6px; border-radius:4px; background:#0a0e14; overflow:hidden; margin-top:8px; }
.filecard .fbar > i { display:block; height:100%; width:0; background:var(--accent); transition:width .15s; }
.filecard img.fthumb { max-width:100%; max-height:200px; border-radius:6px; margin-top:8px; display:block; }
.filecard .fdl { display:inline-block; margin-top:8px; color:var(--accent-text);
  background:var(--accent); border-radius:6px; padding:6px 12px; font-size:13px;
  font-weight:600; text-decoration:none; cursor:pointer; }
.filecard .fnote { font-size:11px; color:#e0b341; margin-top:6px; }
.snip .remove { color:var(--dim); cursor:pointer; }
.snip .remove:hover { color:#f7796b; }
.snip pre { margin:0; padding:9px 11px; font-family:var(--mono); font-size:12.5px;
  color:#d6dde6; white-space:pre-wrap; word-break:break-word; line-height:1.45; }
.snip pre a, .msg pre a { color:var(--accent); }

/* Secret mode (secret.clipferry.com): masked compose + self-destructing cards. */
#secretbar { display:none; padding:10px 12px; border-top:1px solid var(--border);
  background:var(--panel2); }
body.secret .compose { display:none; }
body.secret #secretbar { display:block; }
#secretbar .field { margin-bottom:10px; }
#secretinput { width:100%; padding:10px 40px 10px 10px; background:#0a0e14;
  border:1px solid var(--border); border-radius:8px; color:var(--text); font-size:14px; }
#secretsend { width:100%; }
.snip.secret { box-shadow:inset 3px 0 0 #e0b341; }
.secretbody { padding:8px 11px; }
.revealbtn { background:var(--panel); color:#e0b341; border:1px solid var(--border);
  border-radius:8px; padding:8px 14px; cursor:pointer; font-size:13px; }
.revealbtn:hover { border-color:#e0b341; }

/* Call mode (call.clipferry.com): a centered voice-call screen. */
#callbar { display:none; }
body.call .two, body.call .compose { display:none; }
body.call #callbar { display:flex; flex:1; flex-direction:column;
  align-items:center; justify-content:center; gap:22px; padding:24px; text-align:center; }
.call-status { color:var(--text); font-size:16px; min-height:1.4em; max-width:90%; }
.call-buttons { display:flex; gap:12px; flex-wrap:wrap; justify-content:center; }
.call-buttons button { padding:12px 22px; border-radius:10px; font-size:15px; cursor:pointer;
  border:1px solid var(--border); background:var(--panel2); color:var(--text); }
#call-start, #call-answer { background:var(--accent); color:var(--accent-text); border:0; font-weight:700; }
.callend { background:#c0392b !important; color:#fff !important; border:0 !important; }
/* Video call (video.clipferry.com) reuses the call screen + adds video tiles. */
.call-videos { display:none; position:relative; width:min(560px,92vw); }
body.video .call-videos { display:block; }
#remote-video { width:100%; max-height:60vh; background:#000; border-radius:12px; object-fit:cover; }
#local-video { position:absolute; right:10px; bottom:10px; width:28%; max-width:140px;
  border-radius:8px; border:1px solid var(--border); background:#000; object-fit:cover; }

/* list.clipferry.com — the launcher grid of doors. */
#launcher { display:none; min-height:100vh; flex-direction:column; align-items:center;
  justify-content:center; padding:24px 16px; }
body.list #launcher { display:flex; }
body.list #gate, body.list #app { display:none !important; }
.launch-head { text-align:center; }
.launch-head h1 { color:var(--accent); margin:0 0 6px; font-size:26px; }
.launch-head p { color:var(--dim); margin:0; font-size:13px; }
.launch-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:12px;
  width:min(560px,94vw); margin-top:16px; }
.door { display:flex; flex-direction:column; align-items:center; gap:4px;
  background:var(--panel); border:1px solid var(--border); border-radius:14px;
  padding:16px 8px; text-decoration:none; color:var(--text);
  transition:border-color .15s, transform .1s; text-align:center; }
.door:hover { border-color:var(--accent); transform:translateY(-2px); }
.door .d-ic { color:var(--accent); line-height:0; }
.door .d-ic svg { width:30px; height:30px; display:block; }
.door .d-nm { font-weight:600; font-size:13px; }
.door .d-ds { color:var(--dim); font-size:11px; }
@media (max-width:480px){ .launch-grid { grid-template-columns:repeat(2,1fr); } }

/* matrix.clipferry.com — code-locked, garbled message. */
#matrixbar { display:none; padding:10px 12px; border-top:1px solid var(--border); background:var(--panel2); }
body.matrix .compose { display:none; }
body.matrix #matrixbar { display:block; }
#matrix-input { width:100%; height:54px; resize:vertical; background:#0a0e14;
  border:1px solid var(--border); border-radius:8px; color:var(--text); font-size:14px;
  padding:9px; margin-bottom:8px; }
#matrix-code { width:100%; padding:10px; background:#0a0e14; border:1px solid var(--border);
  border-radius:8px; color:var(--text); font-size:14px; margin-bottom:8px; }
#matrix-send { width:100%; }
.snip.matrix { box-shadow:inset 3px 0 0 #2ecc71; }
.matrixbody { padding:8px 11px; }
.matrix-canvas { width:100%; height:120px; display:block; border-radius:6px; background:#000; }
.matrix-unlock { display:flex; gap:8px; margin-top:8px; }
.matrix-unlock input { flex:1; min-width:0; padding:8px; background:#0a0e14; border:1px solid var(--border);
  border-radius:6px; color:#2ecc71; font-family:var(--mono); font-size:13px; }
.matrix-unlock button { padding:8px 14px; border-radius:6px; border:0;
  background:#2ecc71; color:#06231f; font-weight:700; cursor:pointer; }
.matrix-reveal { color:#2ecc71; font-family:var(--mono); white-space:pre-wrap;
  word-break:break-word; margin-top:8px; line-height:1.5; }

.compose { display:flex; gap:8px; padding:10px 12px;
  border-top:1px solid var(--border); background:var(--panel2); }
#input { flex:1; height:60px; resize:vertical; background:#0a0e14;
  border:1px solid var(--border); border-radius:8px; color:var(--text);
  font-family:var(--mono); font-size:12.5px; padding:9px; }

.flash {
  position:fixed; bottom:18px; left:50%; transform:translateX(-50%);
  background:#1c2230; border:1px solid var(--border); color:var(--text);
  padding:9px 14px; border-radius:8px; font-size:13px; opacity:0;
  transition:opacity .2s; pointer-events:none;
}
.flash.show { opacity:1; }

/* A little ferry sails across when you send — a playful "on its way" flourish. */
.ferry-anim { position:fixed; left:0; top:60%; z-index:40; pointer-events:none;
  color:var(--accent); filter:drop-shadow(0 2px 5px rgba(0,0,0,.45));
  animation:ferry-sail 1.5s ease-in-out forwards; }
@keyframes ferry-sail {
  0%   { transform:translateX(-60px) translateY(0); opacity:0; }
  12%  { opacity:1; }
  25%  { transform:translateX(25vw) translateY(-7px); }
  50%  { transform:translateX(50vw) translateY(0); }
  75%  { transform:translateX(75vw) translateY(-7px); }
  90%  { opacity:1; }
  100% { transform:translateX(calc(100vw + 60px)) translateY(0); opacity:0; }
}
@media (prefers-reduced-motion: reduce) { .ferry-anim { display:none; } }

/* Use dynamic viewport height on mobile so the layout fills the screen
   correctly under the browser's address bar. */
@supports (height: 100dvh) {
  body, #app, #gate { height: 100dvh; }
}

/* Phone / narrow screens: stack the two columns vertically (You sent on top,
   Received below) instead of side-by-side. */
@media (max-width: 640px) {
  .two { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .col:first-child { border-right: none; border-bottom: 1px solid var(--border); }
  .topbar { flex-wrap: wrap; gap: 6px 10px; }
  /* 16px input text stops iOS Safari from auto-zooming when a field is tapped. */
  #passphrase, #machine-name, #input { font-size: 16px; }
}
