/* ---------- Fonts, served from here rather than Google, so no visit is reported to anyone.
   Both are variable fonts: one file carries every weight. Split in two like Google splits them,
   so a page without Polish letters never fetches the larger file. Licences in static/fonts. */

@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("../fonts/inter-latin-ext.1ad231aac0a8.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("../fonts/inter-latin.260c81a4759b.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono"; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext.bd4781a31b42.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono"; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.b636a65da4f0.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Palette (taken from the app icon: navy ground, teal rings, white devices) */

:root {
  --navy-900: #070c18;
  --navy-800: #0c1426;
  --navy-700: #121d36;
  --navy-600: #1a2747;
  --teal: #34b6c5;
  --teal-bright: #4ccbda; /* hover on teal surfaces */

  --bg: var(--navy-900);
  --surface: var(--navy-700);
  --surface-raised: var(--navy-600);
  --text: #f1f5fb;
  --muted: #94a5c4;
  --accent: var(--teal);
  --border: rgba(255, 255, 255, 0.09);
  --error: #ff7a7a;

  --radius: 14px;
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  color-scheme: dark;
}

/* ---------- Base */

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

/* The glow behind the join card is wider than a phone. Clipped here so it cannot scroll the page
   sideways; set on html as well, or body hands its overflow to the window and clips nothing. */
html, body { overflow-x: clip; }

body {
  margin: 0;
  /* Column layout so a short page still pushes the footer to the bottom. */
  display: flex; flex-direction: column;
  min-height: 100vh;
  color: var(--text);
  font: 16px/1.6 Inter, system-ui, sans-serif;
  background: var(--bg);
  background-image: linear-gradient(180deg, var(--navy-800), var(--bg) 45%);
  background-repeat: no-repeat;
  background-attachment: fixed;
}

h1, h2, h3 { line-height: 1.25; letter-spacing: -0.01em; }

a { color: var(--accent); overflow-wrap: anywhere; text-underline-offset: 3px; }
a:hover { color: var(--text); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

main { flex: 1; width: 100%; max-width: 860px; margin: 0 auto; padding: 28px 16px 0; }

.muted { color: var(--muted); }
.mono { font-family: "JetBrains Mono", ui-monospace, Consolas, monospace; }

/* ---------- Header */

/* See-through enough for the glow behind the join card to carry on under the bar, dimmed,
   instead of stopping at its edge. Still darker than the page, so it reads as a strip, and the
   blur turns anything scrolling under it into colour rather than text. */
.site-header {
  position: sticky; top: 0; z-index: 10;
  background: rgba(7, 12, 24, 0.55);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
/* The bands span the window and so does what is in them: brand and nav sit near the screen
   edges rather than lining up with the page, which on a wide screen left the bars looking cut short.
   On a phone the nav does not fit beside the brand, so it wraps onto its own line rather than
   squeezing every label until the words break letter by letter. */
.site-header .inner {
  display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap;
  padding: 13px clamp(16px, 2.5vw, 40px);
}
.brand {
  display: flex; align-items: center; gap: 9px; margin-right: auto; white-space: nowrap;
  color: var(--text); text-decoration: none;
  font-size: 1rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
}
.brand img { width: 28px; height: 28px; border-radius: 9px; }
/* Small enough to read as a note on the name rather than part of it. */
.brand .beta {
  padding: 2px 7px;
  font-size: 0.6rem; font-weight: 700; letter-spacing: 0.09em;
  color: var(--accent);
  background: rgba(52, 182, 197, 0.12);
  border: 1px solid rgba(52, 182, 197, 0.35);
  border-radius: 999px;
}

.site-header nav { display: flex; align-items: center; gap: 10px; }
/* Divides the language switch from everything to do with an account. */
.site-header nav .sep { width: 1px; height: 20px; background: rgba(255, 255, 255, 0.18); }
.site-header form { margin: 0; }

/* Nav items are pills, not underlined links, so the bar reads as controls. */
.site-header nav a,
.site-header nav button {
  padding: 6px 14px; white-space: nowrap;
  font-size: 0.85rem; font-weight: 600; text-decoration: none;
  color: var(--text); background: transparent;
  border: 1px solid var(--border); border-radius: 999px;
}
.site-header nav a:hover,
.site-header nav button:hover { color: var(--text); background: var(--surface-raised); border-color: var(--border); }
.site-header nav a.solid {
  color: var(--navy-900); background: var(--accent); border-color: var(--accent);
}
.site-header nav a.solid:hover { background: var(--teal-bright); border-color: var(--teal-bright); }
/* "Zarejestruj się" is the longest label: at 320px it only fits on its line with less padding. */
@media (max-width: 400px) {
  .site-header nav { gap: 8px; }
  .site-header nav a,
  .site-header nav button { padding: 6px 12px; }
}

/* ---------- Footer */

/* Edge to edge like the header. */
.site-footer { margin-top: 56px; border-top: 1px solid var(--border); }
.site-footer .inner {
  display: flex; gap: 20px 40px; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  padding: 17px clamp(16px, 2.5vw, 40px) 21px;
}
.site-footer strong { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
.site-footer p { margin: 1px 0 0; font-size: 0.9rem; max-width: 32em; }
.site-footer nav { display: flex; gap: 19px; align-items: center; }
.site-footer nav a,
.site-footer nav button { font-size: 0.9rem; text-decoration: none; }

/* A button that reads as a link (opens a dialog instead of navigating). */
button.as-link {
  padding: 0; font-weight: 400; color: var(--accent);
  background: none; border: none;
}
button.as-link:hover { color: var(--text); }

/* ---------- Dialogs */

dialog {
  width: min(560px, calc(100vw - 32px));
  padding: 26px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
dialog.narrow { width: min(360px, calc(100vw - 32px)); }
dialog::backdrop { background: rgba(4, 8, 16, 0.7); }
dialog h2 { margin: 22px 0 10px; font-size: 1.05rem; }
dialog h2:first-of-type { margin-top: 0; }
dialog p { margin: 0 0 10px; }
dialog .close {
  float: right; margin: -6px -6px 0 12px; padding: 2px 10px;
  font-size: 1.4rem; line-height: 1.2; color: var(--muted);
  background: none; border: none;
}
dialog .close:hover { color: var(--text); }

.contact-name { font-size: 1.05rem; font-weight: 600; }
dialog .mono { margin-bottom: 14px; color: var(--accent); }

/* The lists scroll with no bar drawn at all. Wheel, trackpad and keyboard still work.
   Textareas are left alone: a code snippet scrolling sideways has no other way of saying so.
   How much of a capped list shows is set by cap.js, counted in items. */
[data-cap] { overflow-y: auto; }
[data-cap],
.sheet .list { scrollbar-width: none; }
[data-cap]::-webkit-scrollbar,
.sheet .list::-webkit-scrollbar { display: none; }

/* ---------- Cards */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 18px;
  box-shadow: var(--shadow);
}
.card h2 {
  margin: 0 0 16px;
  font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--muted);
}

/* ---------- Forms */

label { display: block; margin-bottom: 16px; font-size: 0.92rem; font-weight: 600; }

input, textarea {
  display: block; width: 100%; margin-top: 7px; padding: 11px 13px;
  font: inherit; color: var(--text);
  background: var(--navy-800);
  border: 1px solid var(--border); border-radius: 10px;
}
/* Vertical only: dragging a textarea wider pulled it out past the edge of its panel.
   Taller is still allowed, which is the half of it that was worth having. */
textarea { resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--muted); }
input:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(52, 182, 197, 0.2);
}

select {
  padding: 10px 12px;
  font: inherit; color: var(--text);
  background: var(--navy-800);
  border: 1px solid var(--border); border-radius: 10px;
}
select:focus { outline: none; border-color: var(--accent); }

input[type="file"] { padding: 9px; }
input[type="file"]::file-selector-button {
  margin-right: 12px; padding: 7px 13px;
  font: inherit; color: var(--text); cursor: pointer;
  background: var(--surface-raised); border: 1px solid var(--border); border-radius: 8px;
}

button {
  font: inherit; font-weight: 600; cursor: pointer; padding: 11px 17px;
  color: var(--text); background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 10px;
}
button:hover { border-color: var(--accent); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

button.primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--navy-900); /* dark text: white on teal is hard to read */
  font-weight: 700;
}
button.primary:hover { background: var(--teal-bright); border-color: var(--teal-bright); }
button.big { width: 100%; font-size: 1.1rem; padding: 15px 24px; }
button.link { padding: 4px; color: var(--muted); background: none; border: none; }
button.link:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .room-tile { transition: none; }
}

.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.row form { margin: 0; }
.row .grow { flex: 1; min-width: 160px; margin: 0; }

/* ---------- Home: welcome, the join code and how it goes */

/* Wider than the rest of the app and centred top to bottom, so the page fills a big screen
   instead of sitting in a laptop-sized box. On screens past about 1600px it grows, up to a limit.
   Everything here is set about 15% smaller than the rest of the app: at full size the page
   looked zoomed in. */
.home main {
  display: flex; flex-direction: column; justify-content: center;
  max-width: clamp(990px, 62vw, 1180px); padding-top: 34px; padding-bottom: 34px;
}
/* On phones the page starts at the top, and the outer ring reaches about 41px above the heading. */
@media (max-width: 959px) {
  .home main { padding-top: 50px; }
}
/* The footer's usual gap would sit only under the content and push it off centre. */
.home .site-footer { margin-top: 0; }

/* Phone: heading, card, steps. Desktop: heading over steps, the card beside both. */
.home-split { display: grid; gap: 27px; grid-template-areas: "intro" "card" "steps"; }
@media (min-width: 960px) {
  .home-split {
    grid-template-columns: 1.15fr 1fr; gap: 30px 68px; align-items: center;
    grid-template-areas: "intro card" "steps card";
  }
}
.home-split .intro { grid-area: intro; align-self: end; }
.home-split .intro h2 { margin: 0 0 11px; font-size: clamp(1.9rem, 3.1vw, 3.8rem); letter-spacing: -0.02em; }
.home-split .intro p { margin: 0; max-width: 28em; font-size: clamp(0.95rem, 0.71vw + 0.35rem, 1.14rem); color: var(--muted); }
.home-split .join { grid-area: card; width: 100%; max-width: 400px; margin: 0 auto; }
/* Centred with the tip under it, the card itself sat high, its top level with the heading.
   Halfway down to the middle of the text looks settled and still keeps the page centred. */
@media (min-width: 960px) {
  .home-split .join { margin-top: 45px; }
}
.home-split .join-card { padding: 23px 26px 26px; }
.home-split .join-card label { font-size: 0.88rem; }
.home-split #join-code { padding: 11px; font-size: 2rem; }
.home-split button.big { padding: 12px 21px; font-size: 0.95rem; }

.how {
  grid-area: steps; align-self: start;
  display: grid; gap: 15px; margin: 0; padding: 0; list-style: none; counter-reset: step;
}
.how li { counter-increment: step; display: grid; grid-template-columns: 32px 1fr; gap: 0 12px; }
.how li::before {
  content: counter(step); grid-row: span 2;
  display: grid; place-items: center; width: 32px; height: 32px;
  font: 700 0.82rem "JetBrains Mono", ui-monospace, Consolas, monospace; color: var(--accent);
  background: rgba(52, 182, 197, 0.08); border: 1px solid rgba(52, 182, 197, 0.4); border-radius: 50%;
}
.how strong { padding-top: 4px; font-size: 0.87rem; }
.how span { font-size: 0.81rem; color: var(--muted); }

@media (min-width: 1600px) {
  .home-split { gap: 38px 103px; }
  .home-split .join { max-width: 447px; }
  .home-split .join-card { padding: 29px 32px 32px; }
  .home-split .join-card label { font-size: 0.95rem; }
  .home-split #join-code { padding: 15px; font-size: 2.38rem; }
  .home-split button.big { padding: 16px 21px; font-size: 1.03rem; }
  .how { gap: 19px; }
  .how li { grid-template-columns: 38px 1fr; gap: 0 13px; }
  .how li::before { width: 38px; height: 38px; font-size: 0.9rem; }
  .how strong { padding-top: 5px; font-size: 0.95rem; }
  .how span { font-size: 0.87rem; }
}

/* A footnote to the card, not a warning: outline only, muted text. */
.join-tip {
  display: flex; gap: 10px; margin: 12px 0 0; padding: 10px 13px;
  font-size: 0.76rem; line-height: 1.5; color: var(--muted); text-wrap: pretty;
  border: 1px solid var(--border); border-radius: 12px;
}
.join-tip svg { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--accent); }
.join-tip strong { color: var(--text); font-weight: 600; }
/* Invisible until join.js shows it, but its room is kept, so the card does not move when it
   appears and the page is centred with it in place. Phones never show it, so it takes no room there. */
.join-tip:not(.shown) { visibility: hidden; }
@media (max-width: 959px) {
  .join-tip:not(.shown) { display: none; }
}

/* The icon's rings, centred on the word. Sized in em, so they follow the heading's font size. */
.rings { position: relative; }
.rings::before,
.rings::after {
  content: "";
  position: absolute; left: 50%; top: 50%; z-index: -1;
  aspect-ratio: 1;
  border: 1px solid rgba(52, 182, 197, 0.35);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.rings::before { width: 2.4em; }
/* The third ring is the outline of the second one: outlines follow border-radius. */
.rings::after {
  width: 3.1em;
  border-color: rgba(52, 182, 197, 0.22);
  outline: 1px solid rgba(52, 182, 197, 0.12);
  outline-offset: 0.35em;
}

/* Roomier padding than a normal card, because there is very little in it: one field and a
   button. The height is whatever that comes to — propping it up only made it look empty. */
/* 26 on top, not 30: the first thing below it is text, whose line box carries about 4px of
   leading above the letters, while the last thing above the bottom edge is a button you see
   the edge of. Equal padding looks unequal. */
.join-card { position: relative; max-width: 440px; margin: 22px auto 0; padding: 26px 30px 30px; }
/* The icon's glow, kept faint and always centred behind the card wherever the card ends up. */
.join-card::before {
  content: ""; position: absolute; left: 50%; top: 50%; z-index: -1;
  width: 1100px; height: 800px; transform: translate(-50%, -50%); pointer-events: none;
  background: radial-gradient(closest-side, rgba(52, 182, 197, 0.065), transparent);
}
/* On the join page the card shares its width with the Edge tip under it. */
.join { max-width: 440px; margin: 22px auto 0; }
.join .join-card { max-width: none; margin: 0; }
#join-form label:last-of-type { margin-bottom: 6px; }
#join-form button { margin-top: 20px; }
#join-code {
  padding: 14px;
  font: 700 2.2rem/1.2 "JetBrains Mono", ui-monospace, Consolas, monospace;
  letter-spacing: 0.2em; text-align: center; text-indent: 0.2em; /* offsets the trailing letter-space */
  color: var(--accent);
}
/* The caret of an empty centred field lands mid-placeholder, so drop the zeros once focused. */
#join-code:focus::placeholder { color: transparent; }

/* ---------- Room page */

/* Send needs the room, so the page is wider than the rest of the app. */
.wide main { max-width: 1160px; }

.countdown {
  font-family: "JetBrains Mono", ui-monospace, Consolas, monospace;
  font-size: 0.92rem; color: var(--muted);
}
.countdown.big { margin-top: 0.4em; font-size: clamp(1.1rem, 3vw, 2rem); }

/* Devices that joined while the current code has been open. */
.list li.joined-now { border-left: 2px solid var(--accent); padding-left: 10px; }
.list li.joined-now .grow { color: var(--accent); }

/* Room, Joining and Devices: three panels, sized by how much each has to say.
   The floors are set by the longest label and controls across the languages, not by English:
   below them a head wraps and drops its control between the label and the figure. */
.room-top { display: grid; gap: 18px; grid-template-columns: 1fr; margin-bottom: 18px; }
@media (min-width: 1140px) {
  .room-top {
    grid-template-columns: minmax(255px, 1fr) minmax(500px, 1.6fr) minmax(295px, 1fr);
  }
  /* The real guarantee: with nowrap a column can never size below its one-line header,
     whatever the language does to the wording. The floors above only keep the three balanced. */
  .panel-head { flex-wrap: nowrap; }
}

/* One skeleton for all three: the label and its controls on one row, the figure below.
   Keeping the controls out of the body is what keeps the panels shallow. */
.panel { display: flex; flex-direction: column; gap: 8px; margin-bottom: 0; padding: 18px 20px; }
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px 14px; flex-wrap: wrap;
}
.panel h2 {
  margin: 0; white-space: nowrap;
  font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--muted);
}
.panel .value { font-size: 1.35rem; font-weight: 700; line-height: 1.2; }
.panel .value.code {
  font: 800 1.9rem/1 "JetBrains Mono", ui-monospace, Consolas, monospace;
  letter-spacing: 0.14em; color: var(--accent);
}
.panel .value.closed { color: var(--error); }
.panel .value-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.panel .controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }

/* One look for a panel control, whether it is a link or a button. */
.control {
  padding: 8px 14px; cursor: pointer;
  font-size: 0.9rem; font-weight: 600; text-decoration: none;
  color: var(--text); background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 8px;
}
.control:hover { color: var(--text); border-color: var(--accent); }

/* Header controls are secondary to the figure they sit above, so they stay small.
   A label never breaks across lines: its width is what the column floors are sized for. */
.panel-head .control,
.panel-head button,
.panel-head select {
  padding: 6px 12px; white-space: nowrap;
  font-size: 0.85rem;
  border-radius: 8px;
}

/* The roster as a sheet off the right edge: it scrolls on its own and moves nothing on the page. */
dialog.sheet {
  width: min(340px, calc(100vw - 32px));
  height: 100dvh; max-height: 100dvh;
  margin: 0 0 0 auto;
  padding: 0;
  border-radius: var(--radius) 0 0 var(--radius);
}
/* Only when open: a dialog is display:none until then, and flex would reveal it. */
dialog.sheet[open] { display: flex; flex-direction: column; }
.sheet-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 20px 22px 14px;
  border-bottom: 1px solid var(--border);
}
.sheet-head h2 { margin: 0; }
.sheet-head .close { float: none; margin: 0; }
.sheet .list { flex: 1; overflow-y: auto; margin: 0; padding: 14px 22px 22px; }

/* Send leads, Sent reads alongside it. */
.room-columns { display: grid; gap: 18px; grid-template-columns: 1fr; align-items: start; }
/* A grid column otherwise grows to its widest row, and one row too wide for a phone pushed
   both cards past the edge of the screen. */
.room-columns > * { min-width: 0; }
@media (min-width: 900px) {
  .room-columns { grid-template-columns: 1.6fr 1fr; }
}
.send-card { padding: 26px; }

/* One tab per kind of thing that can be sent. The open one is joined to the panel below it. */
.tabs { display: flex; gap: 4px; margin-bottom: 18px; border-bottom: 1px solid var(--border); }
.tab {
  padding: 9px 16px; margin-bottom: -1px;
  font-size: 0.95rem; color: var(--muted);
  background: none; border: 1px solid transparent; border-radius: 10px 10px 0 0;
}
.tab:hover { color: var(--text); border-color: transparent; }
.tab.open {
  color: var(--text); background: var(--surface-raised);
  border-color: var(--border); border-bottom-color: var(--surface-raised);
}
/* The four tabs need more width than a 320px phone leaves inside the full padding, so there
   they share the row equally instead of each taking its natural width. */
@media (max-width: 400px) {
  .send-card { padding: 22px 18px; }
  .tab { flex: 1; min-width: 0; padding: 9px 4px; }
}

/* Code is shown as it was written: fixed pitch, and long lines scroll instead of folding. */
textarea.code {
  font-family: "JetBrains Mono", ui-monospace, Consolas, monospace;
  font-size: 0.92rem; line-height: 1.5;
  white-space: pre; overflow-wrap: normal; overflow-x: auto;
  tab-size: 4;
}

/* The page a text or code notification opens. */
.message-view textarea {
  min-height: 46vh; margin-top: 14px;
  background: var(--navy-800);
}
.message-view .hint { color: var(--muted); }

/* Meta line over the content. The room page adds a second column for the resend control;
   the device page has no such control, so it stays one column and gains no dead gutter. */
.sent-list li { display: grid; gap: 5px 12px; }
.sent-list.with-resend li { grid-template-columns: minmax(0, 1fr) auto; }
.sent-list .meta { grid-column: 1; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sent-list .meta time { margin: 0; }
.sent-list .body { grid-column: 1; min-width: 0; }
.badge.kind { color: var(--accent); border-color: rgba(52, 182, 197, 0.4); }

/* One line, cut with an ellipsis. A link can be 2000 characters and would otherwise run the
   full width of the panel, leaving the resend button nowhere to sit. */
.sent-list .body > * {
  display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.sent-list .resend { grid-column: 2; grid-row: 1 / 3; align-self: center; margin: 0; }
/* Small, because there is one per entry and they add up. Width and height are both fixed so
   the button is the same size in either language: "Wyślij ponownie" wraps onto two lines and
   "Resend" sits on one, centred, in a box of the same shape. The width has to clear the
   longest single word — "ponownie" — or that word overruns the padding instead of wrapping. */
.sent-list .resend .control {
  display: inline-flex; align-items: center; justify-content: center;
  /* In rem, not em, so changing the text size below cannot change the box. */
  width: 5rem; min-height: 2.45rem;
  padding: 4px 8px;
  font-size: 0.72rem; line-height: 1.25; text-align: center;
  border-radius: 7px;
}
/* English is one word on one line in a box sized for two, so it has room for a larger face.
   Polish stays smaller: at this size "Wyślij ponownie" still wraps inside the same box. */
html[lang="en"] .sent-list .resend .control { font-size: 0.82rem; }

/* Two columns, kept for the device page. */
.columns { display: grid; gap: 18px; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 860px) {
  .columns { grid-template-columns: 1.35fr 1fr; }
}

/* ---------- Room settings */

.room-head { display: flex; align-items: center; gap: 12px 18px; flex-wrap: wrap; }
.room-head h2 { margin: 0; flex: 1; font-size: 1.5rem; }
.room-head a { font-size: 0.92rem; font-weight: 600; text-decoration: none; }

.card.danger { border-color: rgba(255, 122, 122, 0.3); }
.card.danger p { margin: 0 0 16px; }
.hint { margin: 0; font-size: 0.87rem; }

button.danger { color: var(--error); background: none; border-color: rgba(255, 122, 122, 0.5); }
button.danger:hover { color: var(--navy-900); background: var(--error); border-color: var(--error); }

/* ---------- Room list */

.room-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.room-tile {
  display: block; padding: 18px;
  color: var(--text); text-decoration: none;
  background: var(--navy-800);
  border: 1px solid var(--border); border-radius: var(--radius);
  transition: border-color 0.15s, transform 0.15s;
}
.room-tile:hover { border-color: var(--accent); transform: translateY(-2px); }
.room-tile strong { display: block; font-size: 1.1rem; }
.room-tile .meta { margin-top: 8px; font-size: 0.87rem; color: var(--muted); }
.room-tile .meta b { color: var(--accent); letter-spacing: 0.1em; }

/* ---------- Status texts and Django messages */

.status { min-height: 1.5em; margin: 14px 0 0; }
/* Until there is something to say it takes no room at all. It sits at the foot of the join
   card, where the reserved line plus its margin read as far too much padding. */
.status:empty { display: none; }
.status.ok { color: var(--accent); }
.status.error { color: var(--error); }

.flash {
  margin: 0 0 16px; padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border); border-left: 4px solid var(--accent);
  border-radius: 10px;
}
.flash.error { border-left-color: var(--error); }
.flash.warning { border-left-color: #ffd166; }
/* flash.js folds a success message away: it fades first, then gives its space back. */
.flash { transition: opacity 0.2s, height 0.25s 0.15s, margin 0.25s 0.15s, padding 0.25s 0.15s; }
.flash.leaving {
  opacity: 0; overflow: hidden;
  margin-bottom: 0; padding-top: 0; padding-bottom: 0; border-width: 0;
}
@media (prefers-reduced-motion: reduce) {
  .flash { transition: none; }
}

/* Shown by common.js while the browser's permission question goes unanswered. Pinned to the top
   right, under the address bar where a quiet browser keeps its bell, with an arrow pointing up. */
.permission-hint {
  position: fixed; top: 10px; right: 16px; z-index: 20;
  display: flex; gap: 12px; align-items: flex-start;
  max-width: min(360px, calc(100vw - 32px));
  padding: 14px 16px;
  background: var(--surface-raised);
  border: 1px solid var(--accent); border-radius: 12px;
  box-shadow: var(--shadow);
}
.permission-hint p { margin: 0; }
.permission-hint .arrow {
  font-size: 2rem; line-height: 1; color: var(--accent);
  animation: nudge 1.2s ease-in-out infinite;
}
@keyframes nudge {
  50% { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) {
  .permission-hint .arrow { animation: none; }
}

/* ---------- Lists (rooms, devices, messages) */

.list { list-style: none; margin: 0; padding: 0; }
.list li { padding: 13px 0; border-top: 1px solid var(--border); }
.list li:first-child { border-top: none; padding-top: 0; }
.list li:last-child { padding-bottom: 0; }
.list time { color: var(--muted); font-size: 0.84rem; margin-right: 8px; }
.list form { margin: 0; }
.list .from { font-weight: 600; }

.steps { margin: 0; padding-left: 1.3em; }
.steps li { margin-bottom: 8px; }

.badge {
  display: inline-block; padding: 2px 10px;
  font-size: 0.78rem; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px;
}
.badge.off { color: var(--error); border-color: rgba(255, 122, 122, 0.5); }

/* ---------- Projector mode */

.present { text-align: center; padding-top: 8vh; }
.present h2 { font-size: clamp(1.6rem, 5vw, 3rem); margin: 0 0 10px; }
.present .join-link { font-size: clamp(1.2rem, 4vw, 2.2rem); color: var(--text); }
.present .join-code {
  margin: 0.2em 0;
  font: 800 clamp(3.5rem, 17vw, 11rem)/1.1 "JetBrains Mono", ui-monospace, Consolas, monospace;
  letter-spacing: 0.12em;
  color: var(--accent);
  /* text-shadow: 0 0 50px rgba(52, 183, 197, 0.05); */
}
