/* Sibling of schůzky.online: the same warm paper brand on the outside, a
   dark surface inside the call.

   The deviation is deliberate. Everywhere else the brand is light, but a
   call is a room whose content is other people's faces — a pale page around
   them lifts the black level of every tile and puts a lamp behind whoever is
   sitting in a dim office in February. Dark chrome is the one place where
   the product's own colour has to give way to what is on screen.

   Tokens are named as in schuzky's app.css so the two read as one system. */

:root {
  --paper: #faf7f0;
  --paper-deep: #f2edde;
  --card: #ffffff;
  --ink: #2a241a;
  --muted: #7b7263;
  --line: #e2dbc9;
  --accent: #5f7434;         /* lipová zeleň */
  --accent-soft: #8fa14f;
  --accent-ink: #fdfcf7;
  --warn: #a44b35;
  --ok: #4c8a5c;
  --radius: 14px;
  --radius-lg: 22px;
  --shadow: 0 1px 2px rgba(42, 36, 26, 0.05), 0 12px 34px rgba(42, 36, 26, 0.09);
  --font-body: system-ui, -apple-system, "Segoe UI", sans-serif;

  /* The call's own surface. */
  --stage: #171512;
  --tile: #221f1a;
  --stage-ink: #f4f0e6;
  --stage-muted: #a49b8a;
  --stage-line: #35302a;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

body {
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

/* ----------------------------------------------------------- landing */

.wrap { max-width: 46rem; margin: 0 auto; padding: 4rem 1.25rem; }

.brand {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent);
}

h1 {
  font-size: clamp(2rem, 6vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 1.5rem 0 1rem;
}

.lede { font-size: 1.15rem; color: var(--muted); max-width: 32rem; line-height: 1.6; }

.actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 2rem; }

.points { margin-top: 3rem; display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.points div { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.2rem; }
.points h2 { font-size: .95rem; margin-bottom: .35rem; }
.points p { font-size: .9rem; color: var(--muted); line-height: 1.55; }

footer { margin-top: 4rem; font-size: .85rem; color: var(--muted); }

/* ------------------------------------------------------------- forms */

.btn {
  font: inherit;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: .7rem 1.4rem;
  cursor: pointer;
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
}
.btn:hover { background: var(--accent-soft); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.ghost { background: transparent; border-color: var(--line); color: var(--ink); }
.btn.danger { background: var(--warn); }

input[type="text"] {
  font: inherit;
  padding: .7rem .9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  width: 100%;
}
input[type="text"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --------------------------------------------------------- the call */

body.room {
  background: var(--stage);
  color: var(--stage-ink);
  height: 100dvh;
  display: flex;
  flex-direction: column;
  /* The page itself never scrolls. Three tiles used to overflow the
     viewport and push the toolbar off the bottom of the screen — leaving
     no way to mute or hang up without scrolling for it. */
  overflow: hidden;
}

/* Lobby: permission is asked here, before anyone is waiting on the far end. */
.lobby {
  margin: auto;
  width: min(30rem, calc(100vw - 2rem));
  background: var(--tile);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  text-align: center;
}
.lobby h1 { font-size: 1.4rem; margin: 0 0 .35rem; }
.lobby p { color: var(--stage-muted); font-size: .92rem; line-height: 1.5; }
.lobby .preview {
  width: 100%;
  aspect-ratio: 4 / 3;
  background: #000;
  border-radius: var(--radius);
  margin: 1.1rem 0;
  object-fit: cover;
  transform: scaleX(-1);
}
.lobby label { display: block; text-align: left; font-size: .85rem; color: var(--stage-muted); margin-bottom: .35rem; }
.lobby input[type="text"] { background: #100e0c; border-color: var(--stage-line); color: var(--stage-ink); }
.lobby .btn { width: 100%; justify-content: center; margin-top: .9rem; }
.lobby .btn.ghost { color: var(--stage-ink); border-color: var(--stage-line); }
.lobby .btn.small { font-size: .88rem; padding: .5rem 1rem; margin-top: .5rem; }
.lobby .who { font-size: .88rem; color: var(--accent-soft); margin-top: 1rem; }

/* Alone in a room you just made: the next step is sending the link, so the
   link is the thing on screen. */
.alone {
  margin: auto;
  width: min(32rem, calc(100vw - 2rem));
  text-align: center;
  padding: 1.25rem;
  border: 1px dashed var(--stage-line);
  border-radius: var(--radius-lg);
  color: var(--stage-muted);
}
.alone p { font-size: .95rem; }
.alone code {
  display: block;
  margin: .8rem 0;
  padding: .6rem .8rem;
  background: #100e0c;
  border-radius: var(--radius);
  color: var(--stage-ink);
  font-size: .88rem;
  word-break: break-all;
}

.stage {
  flex: 1;
  display: grid;
  gap: .6rem;
  padding: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  align-content: center;
  /* A tile on its way out is pinned in place while the rest reflow past it. */
  position: relative;
  /* `min-height: 0` is what lets a flex child actually shrink; without it
     the grid claims its full content height and shoves the toolbar out of
     the viewport instead of scrolling. */
  min-height: 0;
  overflow-y: auto;
}

.tile {
  position: relative;
  background: var(--tile);
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.tile video { width: 100%; height: 100%; object-fit: cover; background: #000; display: block; }
/* Only your own camera is mirrored — that is the image you are used to. */
.tile.self video { transform: scaleX(-1); }
/* A shared screen is letterboxed, never cropped: the parts a 16:9 crop cuts
   off are the toolbars and window edges people are pointing at. */
.tile.presenting video { object-fit: contain; }
/* Your own screen is not a mirror image of you — never flip it. */
.tile.own-screen video { transform: none; }

/* While anything is being shared, that is what the meeting is about. The
   screen takes the stage and everyone's face drops to a thumbnail under it:
   a spreadsheet in a tile the size of somebody's forehead is unreadable,
   which defeats the entire point of having shared it. */
.stage.focus {
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  align-content: start;
}
.stage.focus .tile.presenting {
  order: -1;
  grid-column: 1 / -1;
  height: min(66dvh, 100%);
  aspect-ratio: auto;
  background: #000;
}
.stage.focus .tile:not(.presenting) {
  max-width: 12rem;
  align-self: start;
}
.stage.focus .tile:not(.presenting) .label { font-size: .72rem; padding: .12rem .45rem; }
/* On a phone the thumbnails would leave the screen no room at all. */
@media (max-width: 34rem) {
  .stage.focus .tile:not(.presenting) { max-width: 6.5rem; }
  .stage.focus .tile.presenting { height: min(52dvh, 100%); }
}

.tile .label {
  position: absolute;
  left: .5rem;
  bottom: .5rem;
  background: rgba(0, 0, 0, .55);
  padding: .2rem .6rem;
  border-radius: 999px;
  font-size: .8rem;
  display: flex;
  align-items: center;
  gap: .35rem;
  max-width: calc(100% - 1rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Whoever is talking. An outline rather than a border, so the ring costs no
   layout and cannot nudge the grid every time somebody starts a sentence. */
.tile.speaking {
  outline: 3px solid var(--accent-soft);
  outline-offset: -3px;
}
.tile.speaking .label { background: var(--accent); }

.tile .label .mic-off { color: var(--warn); font-weight: 700; }
.tile .label .share-on { color: var(--accent-soft); font-weight: 700; }

/* Sharing banner. Top of the page, because the browser's own sharing bar
   covers the bottom of the screen — including the toolbar this would
   otherwise sit next to. */
.sharing-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .6rem 1rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  font-size: .95rem;
}
.sharing-bar .btn {
  background: rgba(0, 0, 0, .25);
  color: var(--accent-ink);
  border-color: rgba(255, 255, 255, .35);
  padding: .35rem 1rem;
}
.sharing-bar .btn:hover { background: rgba(0, 0, 0, .4); }

/* Until media arrives there is a black rectangle and no explanation; say
   which of the two slow things is happening. */
.tile .waiting {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--stage-muted);
  font-size: .9rem;
}

/* Covers the frozen last frame left behind when a camera is released. */
.tile .off {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--tile);
  color: var(--stage-muted);
  font-size: .9rem;
}
.stage.focus .tile:not(.presenting) .off { font-size: .7rem; }

/* Device pickers. The same block is styled for both homes — inside the
   lobby card, and in the popover above the toolbar. */
.devices { display: grid; gap: .3rem; text-align: left; margin: .9rem 0; }
.devices label { font-size: .85rem; color: var(--stage-muted); }
.devices select {
  font: inherit;
  width: 100%;
  padding: .5rem .6rem;
  background: #100e0c;
  color: var(--stage-ink);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
}
.devices select:disabled { opacity: .55; }
.devices select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.panel {
  margin: 0 auto;
  width: min(26rem, calc(100vw - 2rem));
  background: var(--tile);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
  padding: .25rem 1rem 1rem;
}

.bar {
  display: flex;
  gap: .5rem;
  justify-content: center;
  padding: .75rem;
  border-top: 1px solid var(--stage-line);
  flex-wrap: wrap;
}
.bar .btn {
  background: #2c2822;
  color: var(--stage-ink);
  border-color: var(--stage-line);
  padding: .6rem 1.1rem;
}
/* Line-drawn icons, inheriting the button's colour so they follow every
   state (pressed, danger) without a second set of rules. */
.bar .btn svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}
.bar #mic svg path:first-child { fill: currentColor; stroke: none; }

/* On a phone the words go and the icons stay: six labelled buttons wrapped
   onto three rows and took 168px — a fifth of a 844px screen — leaving the
   call itself squeezed into what was left. The label remains in the DOM as
   the accessible name, so this costs a screen reader nothing. */
@media (max-width: 34rem) {
  .bar { gap: .4rem; padding: .6rem .4rem; flex-wrap: nowrap; }
  .bar .btn {
    padding: 0;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    justify-content: center;
  }
  .bar .btn svg { width: 1.35rem; height: 1.35rem; }
  .bar .btn .lbl {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
.bar .btn:hover { background: #3a352d; }
/* Red in the toolbar means one thing: something of yours is off, or is
   about to end — a muted microphone, a stopped camera, hanging up. Things
   that are actively ON take the accent instead, so the two never have to be
   told apart by reading. */
.bar .btn[aria-pressed="true"] { background: var(--warn); border-color: transparent; }
.bar #gear[aria-pressed="true"],
.bar #chat-btn[aria-pressed="true"],
.bar #share[aria-pressed="true"] { background: var(--accent); border-color: transparent; }
.bar .btn.leave { background: var(--warn); }

/* Out of flow on purpose: this line comes and goes, and in flow it nudged
   the whole toolbar down every time it did. */
.note {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 4.6rem;
  text-align: center;
  padding: .3rem 1rem;
  font-size: .9rem;
  color: var(--stage-muted);
  pointer-events: none;
}
.note.bad { color: #e9a08c; }

/* Arrivals and departures. Bottom-left, clear of the sharing banner at the
   top, and never touching the layout. */
.toasts {
  position: fixed;
  left: .75rem;
  bottom: 5.2rem;
  display: flex;
  flex-direction: column;
  gap: .4rem;
  z-index: 20;
  pointer-events: none;
}
.toast {
  background: rgba(34, 31, 26, .96);
  border: 1px solid var(--stage-line);
  color: var(--stage-ink);
  padding: .45rem 1rem;
  border-radius: 999px;
  font-size: .9rem;
  box-shadow: var(--shadow);
  animation: toast-in .22s ease-out;
}
.toast.out { animation: toast-out .3s ease-in forwards; }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(.6rem); }
  to { opacity: 1; transform: none; }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(.4rem); }
}

/* Tiles fade in and out instead of the grid snapping around them. */
.tile { animation: tile-in .28s ease-out; }
.tile.leaving { animation: tile-out .25s ease-in forwards; }
@keyframes tile-in {
  from { opacity: 0; transform: scale(.94); }
  to { opacity: 1; transform: none; }
}
@keyframes tile-out {
  to { opacity: 0; transform: scale(.94); }
}

/* The end of a call is a place you can leave from, not a dead page. */
.ended {
  margin: auto;
  width: min(28rem, calc(100vw - 2rem));
  background: var(--tile);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius-lg);
  padding: 2rem 1.5rem;
  text-align: center;
  animation: tile-in .3s ease-out;
}
.ended h1 { font-size: 1.35rem; margin-bottom: .4rem; }
.ended p { color: var(--stage-muted); font-size: .93rem; line-height: 1.55; }
.ended > .btn { margin-top: 1.2rem; }
.ways-out {
  display: flex;
  gap: .5rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--stage-line);
}
.ways-out .btn {
  font-size: .88rem;
  padding: .45rem 1rem;
  color: var(--stage-ink);
  border-color: var(--stage-line);
}
.ways-out .btn:hover { background: #2c2822; }

/* Someone who asked for less movement gets less movement. The tile still
   has to disappear, so the exit keeps a duration — just an imperceptible
   one, since `animationend` is what removes it from the DOM. */
@media (prefers-reduced-motion: reduce) {
  .tile, .ended, .toast { animation: none; }
  .tile.leaving { animation: tile-out .01s linear forwards; }
}

.gone {
  margin: auto;
  max-width: 28rem;
  text-align: center;
  padding: 2rem 1.25rem;
  color: var(--stage-ink);
  font-size: 1.05rem;
  line-height: 1.6;
}

/* A link that is struggling says so on the tile it belongs to. Amber for
   wobbling, red for genuinely bad — and nothing at all when it is fine,
   because a permanent indicator is just decoration people stop reading. */
.tile .label .net { color: var(--honey); font-weight: 700; }
.tile.link-bad .label .net { color: var(--warn); }
.tile.link-bad { outline: 2px solid var(--warn); outline-offset: -2px; }

/* ------------------------------------------------------------------ chat */

/* A column beside the call on a desktop, a sheet over it on a phone. Either
   way the video keeps its place — chat that shoves the faces around is
   chat nobody opens twice. */
.chat {
  position: fixed;
  right: 0;
  top: 0;
  bottom: 4.6rem;
  width: min(22rem, 100vw);
  background: var(--tile);
  border-left: 1px solid var(--stage-line);
  display: flex;
  flex-direction: column;
  z-index: 30;
}
.chat header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .8rem 1rem;
  border-bottom: 1px solid var(--stage-line);
  font-weight: 700;
}
.chat header .btn {
  padding: .2rem .6rem;
  color: var(--stage-ink);
  border-color: transparent;
  background: transparent;
}
.chat-log {
  flex: 1;
  overflow-y: auto;
  padding: .8rem 1rem;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  min-height: 0;
}
.chat .msg { display: flex; flex-direction: column; gap: .1rem; font-size: .9rem; }
.chat .msg .who { color: var(--accent-soft); font-weight: 700; font-size: .78rem; }
.chat .msg .text { color: var(--stage-ink); overflow-wrap: anywhere; }
.chat .msg.mine .who { color: var(--stage-muted); }
.chat .msg.system .text { color: var(--warn); font-size: .82rem; }
.chat-form { display: flex; gap: .4rem; padding: .7rem; border-top: 1px solid var(--stage-line); }
.chat-form input {
  flex: 1;
  font: inherit;
  padding: .55rem .7rem;
  background: #100e0c;
  color: var(--stage-ink);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
  min-width: 0;
}
.chat-form input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.chat-note {
  padding: 0 .7rem .7rem;
  font-size: .72rem;
  color: var(--stage-muted);
  text-align: center;
}

/* Unread count on the toolbar button. */
.bar .btn { position: relative; }
.bar .badge {
  position: absolute;
  top: -.15rem;
  right: -.15rem;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 .25rem;
  border-radius: 999px;
  background: var(--warn);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}

@media (max-width: 34rem) {
  .chat { width: 100vw; bottom: 4.4rem; }
}

/* With chat open the stage gives up the width rather than being covered:
   a panel laid over the faces hides the person you are talking to, which
   is a strange thing for a video call to do. On a phone there is no width
   to give, so there the chat is a sheet over the top — one thing at a
   time is the right answer on a small screen anyway. */
@media (min-width: 34.01rem) {
  body.room.chatting .stage,
  body.room.chatting .alone,
  body.room.chatting .note,
  body.room.chatting .toasts { margin-right: min(22rem, 100vw); }
  /* The bar is not indented: the chat panel stops above it, so there is
     nothing to make room for — and indenting it wrapped the controls onto
     a second row for no reason at all. */
}

.chat-tools { display: flex; gap: .2rem; align-items: center; }
.chat-tools .btn { font-size: .82rem; }
/* A line that came from someone else's copy of the conversation, not from
   the person who said it. Quieter, and marked, because it is hearsay. */
.chat .msg.replayed .text { color: var(--stage-muted); }
.chat .msg.replayed .who::after { content: " · z historie"; font-weight: 400; opacity: .7; }

/* ------------------------------------------------------- the door */

.knocking {
  margin: auto;
  width: min(28rem, calc(100vw - 2rem));
  text-align: center;
  padding: 2rem 1.5rem;
  background: var(--tile);
  border: 1px solid var(--stage-line);
  border-radius: var(--radius-lg);
}
.knocking h1 { font-size: 1.3rem; margin-bottom: .4rem; }
.knocking p { color: var(--stage-muted); font-size: .93rem; line-height: 1.55; }

/* The host's prompt sits top-centre, where the sharing banner does: it is
   the one thing that should interrupt, and it must not be mistaken for a
   toast that will go away on its own. */
.door {
  position: fixed;
  top: .75rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  width: min(26rem, calc(100vw - 1.5rem));
}
.door .knock {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  background: var(--tile);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: .7rem .9rem;
  box-shadow: var(--shadow);
}
.door .knock .who { flex: 1; min-width: 8rem; font-size: .93rem; }
.door .knock .who b { font-weight: 700; }
.door .knock .btn { padding: .4rem .9rem; font-size: .88rem; }
.door .knock .btn.no {
  background: transparent;
  border-color: var(--stage-line);
  color: var(--stage-ink);
}
