/* ---------- 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; }

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);
  /* The icon's glow: a teal halo over navy, fading into the darker page. */
  background-image:
    radial-gradient(900px 600px at 50% -10%, rgba(52, 182, 197, 0.13), transparent 70%),
    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 */

.site-header.banded {
  position: sticky; top: 0; z-index: 10;
  background: rgba(7, 12, 24, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.site-header .inner {
  display: flex; align-items: center; gap: 16px;
  max-width: 860px; margin: 0 auto; padding: 14px 16px;
}
.brand {
  display: flex; align-items: center; gap: 9px; margin-right: auto;
  color: var(--text); text-decoration: none;
  font-size: 1.05rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
}
.brand img { width: 30px; height: 30px; 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 15px;
  font-size: 0.9rem; 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); }

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

.site-footer { margin-top: 56px; }
.site-footer .inner {
  display: flex; gap: 20px 40px; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  max-width: 860px; margin: 0 auto; padding: 16px 16px 20px;
  border-top: 1px solid var(--border);
}
.site-footer strong { font-size: 0.82rem; 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: 18px; 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 and the join code */

.hero { text-align: center; padding: 9vh 0 4px; }
.hero h2 { position: relative; margin: 0 0 10px; font-size: clamp(2rem, 6.5vw, 2.9rem); }

/* 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;
}
.hero p { margin: 0 auto; max-width: 30em; color: var(--muted); }

/* 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 { max-width: 440px; margin: 22px auto 0; padding: 26px 30px 30px; }
#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.
   Header and footer follow, otherwise the brand would not line up with the content. */
.wide main,
.wide .site-header .inner,
.wide .site-footer .inner { 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; }
@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);
}

/* 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); */
}
