/* augh yahh! -- round twelve, the new look (2026-08-20).
   Black ground, charcoal cards, one pink-to-violet fade, 16px corners.
   Martin's spec, saved verbatim at
   businesses/chat-app/sources/look spec 2026-08-20.md.
   Single theme on purpose. Every colour painted explicitly. */

:root {
  /* The ground. Pure black, and no wash over it: round nine had two coloured
     radial fades behind every page and round twelve takes them off. */
  --void:    #000000;
  --panel:   #151518;   /* every card, sheet and incoming chat bubble */
  --panel-2: #1C1C20;   /* a box sitting on a card */
  --line:    #2A2A30;   /* hairlines */

  /* The fade. Both ends came off Martin's spec, not sampled and not guessed.
     Every value here was measured against the black ground before it went in;
     the number is the contrast, and a small line of text needs 4.5. */
  --brand:     #F0296C;   /* 5.2 -- the mark, the lit tab, what you press, you */
  --brand-mid: #BD2AA7;   /* the step between pink and violet */
  --brand-2:   #8A2BE2;   /* 3.5 -- NEVER small text. Fades, borders, glows,
                             the lit icon in the bottom bar. Round nine found
                             the same thing about the old violet. */
  --gold:      #FFD700;   /* 15  -- coins, wins, the premium tier of gifts */
  --red:       #E12D2D;   /* 4.6 -- SPIN and bet buttons, and a mistake or a
                             report. NOT delete: deleting your account is
                             irreversible, and irreversible is amber
                             (.gone in profile.css). */
  --green:     #2ECC71;   /* 10  -- done, proven, online right now. Sparingly. */

  /* Two colours the spec has no replacement for, kept because they carry a
     meaning nothing else can: amber is the only word for irreversible, and
     lime is friends. Martin's rule, 2026-08-16: more colours are fine as long
     as they keep the look and stay easy to read. */
  --amber:  #FF9A3C;   /* 9.9 -- a gate, anything you cannot take back */
  --lime:   #C6FF3D;   /* 17.8 - friends, and open to anyone */

  /* Somebody up on the stage, and the word LIVE under the mark. It is a
     lighter member of the fade's family on purpose: --brand-2 reads 3.5
     against black, which is under the 4.5 a line needs, and nine places on
     this site put this colour on actual words. This one reads 5.1. The rule
     stands either way: --brand-2 is never text, --violet always is. */
  --violet: #9D5BF5;

  /* Retired round twelve, kept only so an old rule still resolves. */
  --cyan:   #F0296C;
  --pink:   #F0296C;

  --text:   #FFFFFF;   /* 21  -- every main line and icon */
  --text-2: #8B8B93;   /* 6.2 -- quiet second lines, unlit icons */
  --text-3: #75757D;   /* 4.6 -- the quietest line on a screen, still over 4.5 */

  /* One corner radius everywhere: cards, buttons, sheets, bubbles, boxes.
     A pill stays a pill (999px) and a face stays a circle (50%). */
  --r:    16px;
  --r-sm: 10px;   /* only for something smaller than about 28px tall */

  /* The typewriter face. NOTHING IN THE APP USES THIS ANY MORE (round
     twelve, 2026-08-20): it was the old look and 152 rules were still
     asking for it by name, which is why repainted screens still read as
     the old app. It stays declared for one reason only: the People page
     at /crm, which is a dashboard and where lining up emails and numbers
     in a column is the right thing. Do not bring it back into the app. */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* Headings and big numbers. Poppins ExtraBold, downloaded into the app so
     it comes from our own address and never from Google. */
  --round: "Poppins", ui-rounded, "SF Pro Rounded", "Arial Rounded MT Bold", var(--sans);
}

/* The two faces, latin only, from our own /fonts. 56 KB the first time and
   then kept on the phone. swap so words are readable while they load. */
@font-face {
  font-family: "Inter";
  src: url(/fonts/inter.woff2) format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url(/fonts/poppins-800.woff2) format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

/* Hold the page still: no double-tap zoom, no rubber-banding past the edges,
   and no sideways drift. Pinching is turned away in fixed.js, because Safari
   ignores the viewport tag that asks it not to. */
html {
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overscroll-behavior: none;
}

html { background: var(--void); }

body {
  margin: 0;
  overscroll-behavior: none;
  overflow-x: hidden;
  /* Round twelve: pure black, no wash. Round nine had two coloured fades
     behind every page; the spec asks for the ground to be black and it is. */
  background: var(--void);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ---- the mark ---- */
.mark {
  font-family: var(--round);
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1;
  margin: 0;
  color: #FFFFFF;
  /* The logo's look: white letters, a thin pink outline, a soft pink glow.
     The glow is in em, not px, so it shrinks with the mark: the same three
     shadows at 32 px looked like a pink smear at the 15 px the privacy and
     rules pages use (my own look on the preview, 2026-08-19). */
  text-shadow: 0 0 .06em rgba(240,41,108,.95), 0 0 .3em rgba(240,41,108,.8), 0 0 .8em rgba(240,41,108,.45);
}
.mark i { font-style: normal; color: inherit; text-shadow: inherit; }
/* .page p paints every paragraph grey, and the mark is a paragraph. Before
   round nine that left "augh" grey and "yahh!" cyan on the privacy and rules
   pages; the whole word is white now, so it has to win here too. */
.page .mark, .page .mark i { color: #FFFFFF; }

/* ---- round twelve: what Poppins ExtraBold is for ----
   Headings and big numbers only. Everything else is Inter, which is what
   --sans now is, so the rest of the app needs no rule. Poppins is one weight
   (800) on purpose: one file, 8 KB, and nothing to fall back through. */
h1, h2, h3, h1.big, .k2, .stat3 b, .lvbox .lv-n b, .win-n, .p-head h1 {
  font-family: var(--round);
  font-weight: 800;
  letter-spacing: -.01em;
}

/* ---- a middle-of-the-screen card ---- */
.stage {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 1.05rem 2rem;
}

.card {
  width: 100%;
  max-width: 26rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  text-align: center;
}

.kick {
  font-family: var(--sans);
  font-size: .66rem;
  letter-spacing: .01em;
  color: var(--text-3);
  margin: 0;
}

h1.big {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.025em;
  color: #FFFFFF;
  margin: 0;
  text-wrap: balance;
}

p.sub { margin: 0; font-size: .92rem; color: var(--text-2); }

/* ---- buttons ---- */
.btn {
  display: block;
  width: 100%;
  min-height: 2.75rem;               /* 44px, thumb sized */
  padding: .8rem 1.1rem;
  border-radius: 999px;              /* the standard: every button is a pill */
  text-align: center;
  font-family: var(--round);
  font-size: 1.2rem;
  letter-spacing: 0;
  font-weight: 800;
  cursor: pointer;
  border: 0;
  /* White words on the fade, which is what the spec asks for. The number:
     white on the hot pink end is 4.04, under the 4.5 a small line needs, but
     at 1.2rem (19.2px) bold this is LARGE text, where 3 is the bar, and it
     clears that everywhere along the fade (4.04 at the pink end, 6.0 at the
     violet). That size is not decoration: it is what makes white legal here.
     Round nine used dark words for the same reason at a smaller size; if a
     button ever needs to be smaller than this, it goes back to dark words. */
  color: #FFFFFF;
  background: linear-gradient(90deg, var(--brand), var(--brand-2));
  box-shadow: 0 0 22px -6px rgba(240,41,108,.75);
  text-decoration: none;
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: default; filter: none; }

.btn.ghost {
  background: transparent;
  color: var(--brand);
  border-color: rgba(240,41,108,.45);
  box-shadow: none;
  font-weight: 500;
}
.btn.ghost:hover { background: rgba(240,41,108,.07); filter: none; }

.btn.done {
  /* Round seventeen: the house green, flat. The old two-green fade broke the
     one-gradient rule (the brand fade is the only fade). Black words on it:
     white on this green cannot be read. */
  background: var(--green);
  color: #000000;
  border-color: rgba(46,204,113,.6);
  box-shadow: 0 0 20px -4px rgba(46,204,113,.75);
}

/* ---- the link box ---- */
.linkbox {
  width: 100%;
  border: 1px solid rgba(46,204,113,.4);
  border-radius: var(--r);
  background: rgba(46,204,113,.05);
  box-shadow: 0 0 18px -6px rgba(46,204,113,.5);
  padding: .75rem .8rem;
  font-family: var(--sans);
  font-size: .82rem;
  color: var(--green);
  text-shadow: 0 0 10px rgba(46,204,113,.4);
  word-break: break-all;
  text-align: left;
}

/* ---- name field ---- */
.field {
  width: 100%;
  border: 1px solid rgba(240,41,108,.38);
  border-radius: var(--r);
  background: rgba(240,41,108,.04);
  padding: .75rem .8rem;
  font-family: var(--sans);
  /* Never below 16px. Safari on the iPhone zooms the whole page in the moment
     you tap a smaller box, and does not zoom back out afterwards. That was
     the "zooming on the phone" Martin saw, 2026-08-18. */
  font-size: 16px;
  color: var(--text);
  text-align: left;
}
.field::placeholder { color: var(--text-3); }
.field:focus { outline: 2px solid rgba(240,41,108,.55); outline-offset: 1px; }

/* ---- your own camera, before you go in ---- */
.preview {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--r);
  border: 1px solid var(--line);
  background: linear-gradient(150deg, #2A2A30, #151518);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.preview video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
.preview .placeholder { font-family: var(--sans); font-size: .72rem; color: var(--text-3); padding: 1rem; }

.note {
  font-family: var(--sans);
  font-size: .68rem;
  letter-spacing: .04em;
  color: var(--text-3);
  margin: 0;
}
.note a { color: var(--text-3); }

/* an amber line: something you should read before you press on */
.warn {
  font-family: var(--sans);
  font-size: .72rem;
  line-height: 1.6;
  color: var(--amber);
  text-shadow: 0 0 12px rgba(255,154,60,.35);
  margin: 0;
  text-align: left;
  border: 1px solid rgba(255,154,60,.35);
  border-radius: var(--r);
  background: rgba(255,154,60,.05);
  padding: .6rem .7rem;
}

.bad {
  font-family: var(--sans);
  font-size: .72rem;
  line-height: 1.6;
  color: var(--red);
  text-shadow: 0 0 12px rgba(225,45,45,.4);
  margin: 0;
  text-align: left;
  border: 1px solid rgba(225,45,45,.4);
  border-radius: var(--r);
  background: rgba(225,45,45,.05);
  padding: .6rem .7rem;
}

.hidden { display: none !important; }

/* ============================ in the room ============================ */

.room {
  height: 100dvh;
  height: calc(100dvh - 3.1rem - env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  padding: .7rem;
  gap: .55rem;
}

.roomtop {
  flex: 0 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .75rem;
  font-family: var(--sans);
  font-size: .68rem;
  letter-spacing: .1em;
  color: var(--text-3);
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--line);
}
.roomtop .cnt { color: var(--text); }
.roomtop button, .roomtop a.out, .roomtop a.lnk {
  font: inherit;
  text-decoration: none;
  letter-spacing: .1em;
  color: var(--green);
  text-shadow: 0 0 10px rgba(46,204,113,.5);
  background: none;
  border: 1px solid rgba(46,204,113,.35);
  border-radius: var(--r-sm);
  padding: .3rem .55rem;
  cursor: pointer;
}
.roomtop button:hover, .roomtop a.out:hover, .roomtop a.lnk:hover { background: rgba(46,204,113,.08); }

.grid {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  gap: .4rem;
  grid-template-columns: 1fr;
}
.grid[data-n="2"], .grid[data-n="3"], .grid[data-n="4"] { grid-template-columns: 1fr 1fr; }
.grid[data-n="5"], .grid[data-n="6"] { grid-template-columns: 1fr 1fr; }

@media (min-width: 700px) {
  .grid[data-n="3"], .grid[data-n="4"] { grid-template-columns: 1fr 1fr; }
  .grid[data-n="5"], .grid[data-n="6"] { grid-template-columns: 1fr 1fr 1fr; }
}

.tile {
  position: relative;
  min-height: 0;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background: linear-gradient(150deg, #2A2A30, #151518);
  display: flex;
  align-items: center;
  justify-content: center;
}
.tile.me { border-color: rgba(240,41,108,.55); box-shadow: 0 0 16px -6px rgba(240,41,108,.65); }
.tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile.me video { transform: scaleX(-1); }
.tile.camoff video { display: none; }

/* The first letter of a name, shown in place of the video when the camera
   is off. Hidden the rest of the time. */
.tile .initial {
  display: none;
  font-family: var(--sans);
  font-size: 1.6rem;
  color: var(--text-3);
}
.tile.camoff .initial { display: block; }

.tile .nm {
  position: absolute;
  left: .35rem;
  bottom: .3rem;
  font-family: var(--sans);
  font-size: .62rem;
  color: var(--text-2);
  background: rgba(0,0,0,.72);
  padding: .1rem .32rem;
  border-radius: var(--r-sm);
  max-width: calc(100% - 4.5rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tile .mic {
  position: absolute;
  right: .35rem;
  bottom: .3rem;
  font-family: var(--sans);
  font-size: .62rem;
  color: var(--text-2);
  text-shadow: none;
  background: rgba(0,0,0,.72);
  padding: .1rem .32rem;
  border-radius: var(--r-sm);
}
.tile .connecting {
  position: absolute;
  font-family: var(--sans);
  font-size: .62rem;
  color: var(--text-3);
}

.ctrls { flex: 0 0 auto; display: flex; gap: .4rem; }
.ctrl {
  flex: 1;
  padding: .7rem .3rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  font-family: var(--sans);
  font-size: .64rem;
  letter-spacing: .06em;
  color: var(--text-2);
  text-align: center;
  background: rgba(255,255,255,.02);
  cursor: pointer;
}
.ctrl:hover { background: rgba(255,255,255,.05); }
.ctrl[aria-pressed="true"] {
  border-color: rgba(240,41,108,.55);
  color: var(--brand);
  text-shadow: 0 0 10px rgba(240,41,108,.5);
}
/* .ctrl.leave was the room's amber Leave button. Round sixteen replaced it
   with the back arrow (leaving a room is not irreversible: you still have the
   link), and nothing in the app carries the class any more. Removed here
   rather than left behind, because dead CSS has misled a plan, a done list
   and a tester on three separate rounds of this app. */

/* a line that slides in over the room: copied, someone left, connection lost */
.toast {
  position: fixed;
  left: 50%;
  /* The CENTRE of the screen, not the bottom (Martin's call 2026-08-21: a
     warning at the bottom hid behind sheets and thumbs). Above the card
     overlay (40) and the gold notes (45): a toast answering a tap on the
     card was drawn under it and nobody saw it (tester 2026-08-19). */
  top: 42%;
  transform: translate(-50%, -50%);
  font-family: var(--sans);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: .7rem 1rem;
  z-index: 60;
  max-width: calc(100vw - 3rem);
  text-align: center;
  box-shadow: 0 12px 40px -12px rgba(0,0,0,.9);
}
.toast.warnish { color: var(--amber); border-color: rgba(255,154,60,.45); }

/* ---- a plain page of words (privacy) ---- */
.page { max-width: 34rem; margin: 0 auto; padding: 2rem 1.05rem 4rem; }
.page h1 { font-size: 1.6rem; letter-spacing: -.025em; color: #FFFFFF; margin: .4rem 0 1rem; }
.page h2 {
  font-family: var(--round); font-size: .72rem; letter-spacing: .01em; color: var(--text-3);
  margin: 2rem 0 .6rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line);
}
.page p { color: var(--text-2); font-size: .92rem; }
.page a { color: var(--brand); }
.page footer {
  margin-top: 2.5rem; border-top: 1px solid var(--line); padding-top: 1rem;
  font-family: var(--sans); font-size: .68rem; line-height: 1.75; color: var(--text-3);
}

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ======================= home: the two choices ======================= */

.choice {
  border: 1px solid rgba(240,41,108,.3);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  box-shadow: 0 0 22px -8px rgba(240,41,108,.5);
  padding: .95rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  text-align: left;
}
/* The lobby is the public one, so it does not share the colour of the
   private room. Lime means "this one is open to anyone". */
.choice.lobbyish {
  border-color: rgba(198,255,61,.3);
  box-shadow: 0 0 22px -8px rgba(198,255,61,.45);
}
.choice-kick {
  margin: 0;
  font-family: var(--sans);
  font-size: .68rem;
  letter-spacing: .01em;
  color: var(--brand);
  text-shadow: 0 0 12px rgba(240,41,108,.5);
}
.choice.lobbyish .choice-kick { color: var(--lime); text-shadow: 0 0 12px rgba(198,255,61,.5); }
.choice-sub { margin: 0; font-size: .82rem; color: var(--text-2); }

.btn.lime {
  color: var(--lime);
  border-color: rgba(198,255,61,.4);
}
.btn.lime:hover { background: rgba(198,255,61,.08); }
.btn.lime span { color: var(--text-3); letter-spacing: .04em; text-transform: none; }

/* The private video room is the quiet one on Home now: no glow. */
.choice.quiet { border-color: var(--line); box-shadow: none; }
.choice.quiet .choice-kick { color: var(--text-2); text-shadow: none; }

/* ============================ bottom tabs ============================ */

.tabs {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  display: flex;
  border-top: 1px solid var(--line);
  background: rgba(0,0,0,.94);
  backdrop-filter: blur(8px);
  z-index: 30;
  padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  flex: 1;
  padding: .85rem .5rem;
  text-align: center;
  text-decoration: none;
  font-family: var(--sans);
  font-size: .68rem;
  letter-spacing: .01em;
  color: var(--text-3);
}
.tab.on { color: var(--brand); text-shadow: 0 0 12px rgba(240,41,108,.7); }
/* Four tabs since 2026-08-18: a touch smaller so Profile fits at 390 px. */
.tab { font-size: .64rem; letter-spacing: .1em; padding: .85rem .25rem; }
.tab .tab-n { color: var(--lime); letter-spacing: 0; text-transform: none; }
.tab.on .tab-n { color: var(--lime); }

/* Room the tabs need at the bottom of the page. */
body.has-nav .stage { padding-bottom: 5.5rem; }

/* ============================== the lobby ============================== */

.lobby {
  position: fixed;
  inset: 0;
  height: auto;
  max-height: 100dvh;
  bottom: calc(3.1rem + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  padding: .7rem .7rem .4rem;
  gap: .5rem;
}

.who {
  flex: 0 0 auto;
  max-height: 8rem;
  overflow-y: auto;
  border: 1px solid rgba(198,255,61,.28);
  border-radius: var(--r);
  background: rgba(198,255,61,.04);
  padding: .5rem .6rem;
}
.who ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.who li {
  font-family: var(--sans);
  font-size: .66rem;
  color: var(--lime);
  border: 1px solid rgba(198,255,61,.3);
  border-radius: 999px;
  padding: .12rem .5rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lines {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
  margin: 0;
  padding: .2rem .1rem;
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
/* The lines sit at the bottom and grow upward: a new one lands at the
   bottom and pushes the older ones up, like the live-stream apps. Done with
   margin-top:auto on the first line rather than justify-content, which
   would clip the older lines from scrolling. Martin's ask 2026-08-18 from his
   phone, for the chat under the stage; the Chat tab is the same piece. */
.lines > li:first-child { margin-top: auto; }

.line { max-width: 100%; }
.line-head { display: flex; align-items: center; gap: .45rem; }
/* The badge is a box now (round four), and a photo inside it has no text
   baseline, so baseline alignment sat it a line above the name (Martin's
   phone 2026-08-18: "my profile by my chat is crooked"). Centre it. */
.line-head .badge { align-self: center; vertical-align: middle; }
.line-who {
  font-family: var(--sans);
  font-size: .68rem;
  color: var(--text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
}
.line.mine .line-who { color: var(--green); text-shadow: 0 0 10px rgba(46,204,113,.45); }
.line-when { font-family: var(--sans); font-size: .6rem; color: var(--text-3); }
.line-text {
  margin: .1rem 0 0;
  font-size: .9rem;
  color: var(--text);
  overflow-wrap: anywhere;   /* a 500-character word must not widen the page */
  white-space: pre-wrap;
}

.line.note-line {
  font-family: var(--sans);
  font-size: .66rem;
  color: var(--text-3);
  text-align: center;
  padding: .1rem 0;
}

/* The send bar (round twelve, 2026-08-20), the shape in the reference
   pictures: the gift on the left, a dark rounded pill to type in, and a round
   gradient send on the right. The word "Send" is gone: at 44px round it is
   the arrow that reads, and the word was the last typewriter thing on the
   bar. */
.say { flex: 0 0 auto; display: flex; align-items: center; gap: .4rem; }
.say .field { flex: 1; min-width: 0; border-radius: 999px; padding: .7rem 1.05rem; }
/* Send is narrower since 2026-08-19 (Martin: "make send message smaller"),
   but no shorter: 44 px is what a thumb needs. The room it gives up goes to
   the Dragon Tiger coin, which now sits at the end of this row instead of
   floating over the last thing anyone said. */
.say .btn {
  width: 2.75rem; height: 2.75rem; flex: 0 0 auto;    /* 44px, thumb sized */
  padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0;                                        /* the word is hidden, the arrow is the button */
}
.say .btn::after {
  content: ''; width: 1.15rem; height: 1.15rem; display: block;
  background: #FFFFFF;
  -webkit-mask: no-repeat center / contain url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.5 2.8 2.9 10.6l7 2.8 2.8 7z"/><path d="M21.5 2.8 9.9 13.4"/></svg>');
  mask: no-repeat center / contain url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.5 2.8 2.9 10.6l7 2.8 2.8 7z"/><path d="M21.5 2.8 9.9 13.4"/></svg>');
}

.lobby-note { text-align: center; margin: .1rem 0 0; font-size: .62rem; }
.lobby-note a { color: var(--text-3); }

/* Built for a phone, but on a laptop a full-width column of chat is a lot of
   empty space with a few words floating in it. Keep it a readable column. */
@media (min-width: 46rem) {
  .lobby { max-width: 42rem; margin: 0 auto; }
  .room  { max-width: 60rem; margin: 0 auto; }
}

/* Who you are, and how long the name is yours for. */
.me-chip {
  font-family: var(--sans);
  font-size: .62rem;
  letter-spacing: .04em;
  text-transform: none;
  color: var(--green);
  text-shadow: 0 0 10px rgba(46,204,113,.45);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
}
.me-chip .fading { color: var(--amber); text-shadow: 0 0 10px rgba(255,154,60,.5); }

/* Logging out gives the name up, so it is amber like everything you cannot
   take back. */
.roomtop button.out, .roomtop a.out {
  color: var(--amber);
  border-color: rgba(255,154,60,.4);
  text-shadow: 0 0 10px rgba(255,154,60,.5);
}
.roomtop button.out:hover, .roomtop a.out:hover { background: rgba(255,154,60,.08); }
.roomtop { gap: .4rem; }
.roomtop button, .roomtop a.out, .roomtop a.lnk { flex: 0 0 auto; }

/* ============================ live, holding ============================ */
.soonbox {
  width: 100%;
  border: 1px dashed rgba(138,43,226,.45);
  border-radius: var(--r);
  padding: 1rem .8rem;
  font-family: var(--sans); font-size: .72rem; letter-spacing: .01em;
  color: var(--violet); text-shadow: 0 0 12px rgba(138,43,226,.5);
}
.soonbox small {
  display: block; margin-top: .45rem;
  font-family: var(--sans); font-size: .85rem; letter-spacing: 0; text-transform: none;
  color: var(--text-2); text-shadow: none; line-height: 1.5;
}
.spots { width: 100%; display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.spot {
  aspect-ratio: 1; border: 1px dashed rgba(138,43,226,.3); border-radius: var(--r);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--sans); font-size: .62rem; letter-spacing: .1em; color: var(--text-3);
}

/* ============================== profile ============================== */
.profile { width: 100%; display: flex; flex-direction: column; gap: .6rem; align-items: center; }
.profile-name {
  margin: 0; font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; color: #FFFFFF;
  text-shadow: 0 0 18px rgba(198,255,61,.45); overflow-wrap: anywhere;
}
.profile-left { margin: 0; font-family: var(--sans); font-size: .8rem; color: var(--lime); }

/* ============================ chat, extras ============================ */
/* Not logged in: the box says so and takes you to Profile. */
.login-bar {
  display: block; text-align: center; text-decoration: none;
  border: 1px solid rgba(198,255,61,.35); border-radius: var(--r);
  padding: .55rem .7rem; font-family: var(--sans); font-size: .68rem; letter-spacing: .06em;
  color: var(--lime); text-shadow: 0 0 10px rgba(198,255,61,.45); background: rgba(198,255,61,.04);
}
.say .field.locked { color: var(--text-3); border-color: var(--line); background: rgba(255,255,255,.02); cursor: pointer; }

/* ============================ live, holding ============================ */
.live-page {
  position: fixed; inset: 0;
  bottom: calc(3.1rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: .5rem;
  padding: .7rem .7rem .4rem;
}
.stage-box {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: .55rem; align-items: center; text-align: center;
  border: 1px solid var(--line); border-radius: var(--r); padding: .8rem .8rem .9rem;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
}
.stage-box .kick { margin: 0; }
.chatbox {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: .45rem;
  border: 1px solid rgba(198,255,61,.25); border-radius: var(--r); padding: .55rem .6rem .5rem;
  box-shadow: 0 0 20px -10px rgba(198,255,61,.5);
}
.chatbox .lines { flex: 1 1 auto; min-height: 0; }
@media (min-width: 700px) { .live-page { max-width: 42rem; margin: 0 auto; } }

/* ============================== profile ============================== */
.profile { width: 100%; display: flex; flex-direction: column; gap: .6rem; align-items: center; }
.profile-name {
  margin: 0; font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; color: #FFFFFF;
  text-shadow: 0 0 18px rgba(198,255,61,.45); overflow-wrap: anywhere;
}
.switch { width: 100%; display: flex; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.sw {
  flex: 1; font: inherit; font-family: var(--sans); font-size: .68rem; letter-spacing: .01em;
  padding: .6rem; background: none; border: 0; color: var(--text-3); cursor: pointer;
}
.sw.on { color: var(--brand); text-shadow: 0 0 10px rgba(240,41,108,.5); background: rgba(240,41,108,.07); }
.pform { width: 100%; display: flex; flex-direction: column; gap: .55rem; }
.pform .field { width: 100%; }
.pform .btn { width: 100%; }
.lbl { margin: .2rem 0 0; font-size: .8rem; color: var(--text-2); text-align: left; }
select.field {
  appearance: none; -webkit-appearance: none; padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--brand) 50%), linear-gradient(135deg, var(--brand) 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 50%, calc(100% - .75rem) 50%;
  background-size: .35rem .35rem, .35rem .35rem; background-repeat: no-repeat;
}
.fg-q { margin: 0; font-size: .95rem; color: var(--text); text-align: left; }

/* ============================ profile: the photo slot ============================ */
/* Martin's call 2026-08-18: a photo behind the log in, fading to dark, the form
   in a glass card at the bottom. Until a photo he has the rights to lands in
   public/icons/login-bg.jpg, an abstract neon wash stands in. Swap the picture
   by replacing that file; nothing else changes. */
body.login-page {
  background:
    linear-gradient(180deg, rgba(0,0,0,.25) 0%, rgba(0,0,0,.55) 45%, rgba(0,0,0,.94) 78%, var(--void) 100%),
    url('/icons/login-bg.jpg') center 20% / cover no-repeat,
    radial-gradient(70% 45% at 50% 22%, rgba(240,41,108,.30), transparent 70%),
    radial-gradient(45% 35% at 20% 55%, rgba(138,43,226,.26), transparent 70%),
    radial-gradient(50% 35% at 80% 65%, rgba(198,255,61,.14), transparent 70%),
    var(--void);
  background-attachment: fixed;
}
.login-stage { justify-content: flex-end; }
.card.glass {
  background: rgba(0,0,0,.72);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.08); border-radius: var(--r);
  padding: 1.1rem 1rem 1rem;
}

/* ============================ profile, step three ============================ */
.p-face { margin: .2rem 0 0; }
.swatches { display: flex; gap: .45rem; justify-content: center; flex-wrap: wrap; }
.swatch { width: 1.7rem; height: 1.7rem; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; box-shadow: 0 0 10px -2px currentColor; }
.swatch.on { border-color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.p-about { width: 100%; display: flex; gap: .4rem; }
.p-about .field { flex: 1; min-width: 0; }
.p-about .btn { width: auto; flex: 0 0 auto; padding: .75rem .9rem; }
.p-photo-row { width: 100%; display: flex; gap: .4rem; }
.p-photo-row .btn { flex: 1; text-align: center; cursor: pointer; }
.p-more { width: 100%; border: 1px solid var(--line); border-radius: var(--r); padding: 0 .8rem; text-align: left; }
.p-more summary { cursor: pointer; padding: .7rem 0; font-family: var(--sans); font-size: .72rem; letter-spacing: .01em; color: var(--text-2); list-style: none; display: flex; justify-content: space-between; }
.p-more summary::after { content: '›'; color: var(--text-3); }
.p-more[open] summary::after { content: '⌄'; }
.p-more .pform { padding: .2rem 0 .8rem; }
.p-count { color: var(--lime); letter-spacing: 0; }
.p-list { list-style: none; margin: 0; padding: .2rem 0 .7rem; display: flex; flex-direction: column; gap: .5rem; }
.p-list li { display: flex; align-items: center; gap: .5rem; font-size: .92rem; color: var(--text); }
.p-list li.note { font-size: .8rem; }
.p-where { margin-left: auto; font-family: var(--sans); font-size: .62rem; letter-spacing: .1em; color: var(--text-3); }
.lnk-btn { margin-left: auto; font: inherit; font-family: var(--round); font-size: .66rem; letter-spacing: .1em; color: var(--lime); background: none; border: 1px solid rgba(198,255,61,.4); border-radius: var(--r-sm); padding: .3rem .5rem; cursor: pointer; }
.note.ok { color: var(--green); }


/* ---- round four: level box, stats, shop, leaderboard (profile) ---- */
.lvbox { width: 100%; display: flex; align-items: center; gap: .7rem; border: 1px solid rgba(255,215,0,.35); border-radius: var(--r); padding: .6rem .75rem; background: #1C1C20; box-shadow: 0 0 22px -8px rgba(255,215,0,.5); text-align: left; }
.lvbox .lv-n b { display: block; font-family: var(--round); font-size: 1.6rem; font-weight: 800; color: var(--gold, #FFD700); text-shadow: 0 0 14px rgba(255,215,0,.7); line-height: 1; }
.lvbox .lv-n small { display: block; font-family: var(--sans); font-size: .5rem; letter-spacing: .01em; color: var(--text-3); margin-bottom: .15rem; }
.lvbox .lv-r { flex: 1; display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.lvbox .bar { height: 7px; border-radius: 99px; background: rgba(255,255,255,.06); overflow: hidden; }
.lvbox .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #FFD700, #FF9A3C); box-shadow: 0 0 8px rgba(255,215,0,.8); transition: width .5s ease; }
.lvbox .lv-r small { font-family: var(--sans); font-size: .62rem; color: var(--text-2); }
.stat3 { width: 100%; display: flex; gap: .4rem; }
.stat3 > div { flex: 1; border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .3rem; text-align: center; background: #151518; }
.stat3 b { display: block; font-family: var(--round); font-size: 1.05rem; font-weight: 700; }
.stat3 span { font-family: var(--sans); font-size: .5rem; letter-spacing: .01em; color: var(--text-3); }
.stat3 .coin b { color: #FFD700; text-shadow: 0 0 8px rgba(255,215,0,.6); }
.stat3 .strk b { color: #FF9A3C; text-shadow: 0 0 8px rgba(255,154,60,.6); }
.stat3 .rank b { color: var(--text); }
.p-list.shop li { justify-content: space-between; border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .6rem; background: #151518; }
.p-list.shop .sample { font-weight: 700; font-size: 1rem; }
.p-list.shop .lab { font-family: var(--sans); font-size: .6rem; color: var(--text-3); margin-left: .4rem; }
/* Round twenty-three (2026-08-21): the frame rows in the same shop list. A
   look's row has the big coloured name AS the sample, so .lab is its quiet
   second word. A frame's sample is a picture, which left the frame's NAME in
   .lab -- the quietest style on the screen -- as the only text in the row.
   The frame rows get their own two-line block instead. */
.p-list.shop .fr-txt { display: flex; flex-direction: column; gap: .1rem; min-width: 0; margin-left: .55rem; }
.p-list.shop .fr-txt b { font-size: .95rem; font-weight: 700; color: var(--text); line-height: 1.2; }
.p-list.shop .fr-txt small { font-family: var(--sans); font-size: .62rem; color: var(--text-3); }
.p-list.shop li .fr-left { display: flex; align-items: center; min-width: 0; }
.p-list.shop .pr { font: inherit; font-family: var(--sans); font-size: .66rem; color: #FFD700; border: 1px solid rgba(255,215,0,.45); border-radius: 99px; padding: .2rem .6rem; background: none; cursor: pointer; }
.p-list.shop .pr.own { color: var(--green); border-color: rgba(46,204,113,.45); }
.p-list.shop .pr.on { color: #000000; background: var(--green); border-color: var(--green); }
.p-list.shop .pr.poor { color: var(--text-3); border-color: var(--line); }
.p-list.board li { border-bottom: 1px solid var(--line); padding: .35rem .2rem; }
.p-list.board .pos { font-family: var(--sans); font-size: .62rem; color: var(--text-3); width: 1.2rem; }
.p-list.board .pts { margin-left: auto; font-family: var(--sans); font-size: .66rem; color: var(--gold); }
.p-list.board li.me { background: rgba(198,255,61,.06); border-radius: var(--r); }
.p-list.rules li { justify-content: space-between; font-size: .84rem; }
.p-list.rules b { font-family: var(--sans); color: var(--lime); font-weight: 600; white-space: nowrap; margin-left: auto; padding-left: .5rem; }
.p-list.rules .p-where { margin-left: .5rem; }
.profile-name { display: inline-flex; align-items: center; }
.board-box .p-list.board { padding: .2rem 0 .4rem; }
.board-box .p-list.board li { font-size: .9rem; }
.choice-sub-inline { font-family: var(--sans); font-size: .58rem; letter-spacing: .1em; color: var(--text-3); margin-left: .5rem; }

/* Keyboard up on a phone (fixed.js sets html.kb and the two measures): the
   Chat and Live pages fit the visible part exactly, the tab bar steps aside. */
html.kb .lobby, html.kb .live-page { top: var(--vvt, 0px); height: var(--vvh, 100dvh); max-height: none; bottom: auto; }
html.kb .tabs { display: none; }

/* ============ round eight (2026-08-19): Home's top row, the coin's lane,
   the video door and the rules page ============ */

/* Four chips beside the mark (CHAT, LIVE, FRIENDS, VIDEO) on one row at
   390 px: the mark a touch smaller and the chips a touch tighter, so the mark
   is never cut. The chips' colours keep their meaning; VIDEO is white. */
/* content from the top, even when a list fails to load. The room at the end is
   for the Dragon Tiger coin: it floats over the bottom right corner, so
   without it the coin sits on the last row of member cards for good and their
   name and level cannot be read (the tester, 2026-08-19). Scrolled to the
   end, the coin now sits over empty ground instead of somebody's card. */
.home-members { justify-content: flex-start; padding-bottom: 4.6rem; }

/* Home's footer row: Privacy · Rules · Contact, the same line as Profile's. */
.home-foot { text-align: center; margin: .2rem 0 0; }
.home-foot a { color: var(--text-2); text-decoration: none; border-bottom: 1px solid rgba(139,139,147,.35); padding-bottom: 1px; }

/* The gold coin (game.css: 3.4rem wide, .85rem from the right edge, a 5 px ring)
   sits over the right end of Home's lines on a phone. Below 700 px, where it
   hugs the edge, the top 10 rows, the biggest-win line and the footer stop
   short of it, so no number or word is ever under it at any scroll position.
   From 700 px up the coin sits outside the card and nothing needs to move. */
@media (max-width: 699px) {
  .home-members .p-list.board li { margin-right: 3.8rem; }
  .home-members .big-win { width: auto; margin-right: 3.8rem; }
  .home-members .home-foot { margin-right: 3.8rem; }
  /* Round twelve: the friends rows on Following end in a Message button, and
     the coin was sitting on the last one's. The whole list stops short of it,
     not only the final row, because the list grows. */
  .home-members .frow { margin-right: 3.8rem; }
}

/* The video door and the rules page: content from the top, a way back as the
   first line, the tab bar under it. */
.door { min-height: 100dvh; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding: 1rem 1.05rem 2rem; }
body.has-nav .door { padding-bottom: 5.5rem; }
.door .card { gap: .9rem; }
/* The same back link as the Profile screens (profile.css .back). */
.door .back, .page .back { align-self: flex-start; font-family: var(--sans); font-size: .8rem; letter-spacing: .06em; color: var(--brand); text-decoration: none; padding: .2rem 0; }
.door .back small { font-size: inherit; color: var(--text-3); }
.door .mark { margin-top: .3rem; }
.door .door-foot { text-align: center; margin: .6rem 0 0; }
.door .door-foot a { color: var(--text-2); text-decoration: none; border-bottom: 1px solid rgba(139,139,147,.35); padding-bottom: 1px; }
.page .back { display: inline-block; margin: 0 0 .6rem; }
.page ol.rules-list { margin: 0; padding: 0 0 0 1.6rem; display: flex; flex-direction: column; gap: .7rem; color: var(--text-2); font-size: .95rem; line-height: 1.55; }
.page ol.rules-list li::marker { font-family: var(--sans); color: var(--green); }
.page ol.rules-list b { color: var(--text); font-weight: 600; }

.tab { position: relative; }
.tab .tab-dot {
  position: absolute; top: .55rem; right: calc(50% - 1.9rem); width: .42rem; height: .42rem; border-radius: 50%;
  background: var(--brand); box-shadow: 0 0 8px rgba(240,41,108,.9), 0 0 3px var(--brand); pointer-events: none;
}

/* ==================== the app is always a phone ====================
   Martin, 2026-08-19: on his Mac the site stretched the whole window.
   Past a phone's width the whole app sits in one phone-wide column in
   the middle, with the dark ground and a hairline either side. Turning
   a phone sideways then changes nothing but the space around it, which
   is the other half of what he asked for: a website cannot stop Safari
   rotating, but it can make rotating look like nothing happened.

   Everything pinned to the screen (the tab bar, the chat, the game, the
   toasts, the sheets) is positioned against the window, not the page, so
   each one has to be brought into the column by hand. Anything with both
   a left and a right set is centred with margin; anything held to one
   side is measured from the middle instead. Selectors are written with
   body in front so they beat the same class in a stylesheet that loads
   after this one. */
@media (min-width: 520px) {
  :root { --col: 27rem; }        /* 432 px, about a big phone */

  /* the page itself */
  body .stage,
  body .door,
  body .page,
  body .room { max-width: var(--col); margin-inline: auto; }

  /* pinned, and spanning both sides: centre them in the column */
  body .tabs,
  body .lobby,
  body .live-page,
  body .report-wrap,
  body .menu,
  body .dm,
  body .gpanel,
  body .gmini,
  body .g-banner,
  body .level-toast { max-width: var(--col); margin-inline: auto; }

  /* pinned to one side: measure from the middle, keeping the same gap */
  body .gcoin     { right: calc(50% - var(--col) / 2 + .85rem); }
  body .pts-float { right: calc(50% - var(--col) / 2 + 1.1rem); }
  /* on Chat and Live the coin sits in the send row, whose edge is .7rem in
     (game.css). Two classes there, so it needs two here to be brought into
     the column as well. */
  body .lobby ~ .gcoin,
  body .live-page ~ .gcoin { right: calc(50% - var(--col) / 2 + .7rem); }

  /* The toast centres itself on the window, which is the column's middle too,
     so a short one looked right and this was nearly missed. Its width is set
     from the WINDOW though, so a long one (a refused link, a report that is
     too old) stretched right past the column and its hairlines. Caught by the
     code reviewer, 2026-08-19. */
  body .toast { max-width: min(calc(100vw - 2rem), calc(var(--col) - 1.6rem)); }

  /* the two edges, so it reads as a phone and not as a page that failed
     to stretch. Fixed, thin, and never in the way of a tap. */
  body::before,
  body::after {
    content: '';
    position: fixed;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--line);
    z-index: 1;
    pointer-events: none;
  }
  body::before { left: calc(50% - var(--col) / 2 - 1px); }
  body::after  { right: calc(50% - var(--col) / 2 - 1px); }

  /* Everything below used to spread out once the window was wide, back when a
     wide window meant a wide app. In a phone-wide column it would spread past
     the edges or crowd, so each one is put back to what a phone shows. */

  /* the game's own wide-screen places, all wider than the column */
  body .gmini,
  body .gpanel,
  body .g-banner { left: 0; right: 0; }

  /* Home's members: two across, the way a phone shows them, not three */
  body .mgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* video room tiles: the phone's layout, or three across in 432 px is a strip */
  body .grid[data-n="3"], body .grid[data-n="4"] { grid-template-columns: 1fr; }
  body .grid[data-n="5"], body .grid[data-n="6"] { grid-template-columns: 1fr 1fr; }

  /* The Dragon Tiger coin used to sit outside the card past 700 px, so the room
     it needs was only made below that. It is inside the column at every width
     now, so the top ten, the big win and the footer keep their room here too,
     or the coin sits on top of them. */
  body .home-members .p-list.board li,
  body .home-members .big-win,
  body .home-members .frow,
  body .home-members .home-foot { margin-right: 3.8rem; }
}

/* ---- round eleven (2026-08-19): the email gate ----------------------------
   The accounts made before emails existed are stopped here on their next open.
   It covers the whole window, so it is measured against the window and brought
   into the phone column by the block above, the same as every other pinned
   thing. Content starts at the top of the card, not floating mid-screen
   (build lessons, round five). */
.emailgate {
  position: fixed;
  inset: 0;
  z-index: 900;                 /* over the tab bar, the chat and the game coin */
  background: var(--void);
  overflow-y: auto;
  display: flex;
  justify-content: center;
}
body.eg-open { overflow: hidden; }
.emailgate .eg-card {
  width: 100%;
  max-width: 27rem;
  padding: 3rem 1.05rem 2rem;
  display: flex;
  flex-direction: column;
  gap: .9rem;
  background:
    radial-gradient(120% 40% at 50% 0%, rgba(240,41,108,.14), transparent 65%);
}
.emailgate .eg-title {
  margin: 0;
  font-family: var(--round);
  font-weight: 800;
  font-size: 1.7rem;
  letter-spacing: -.02em;
  color: #FFF;
  text-align: center;
  text-shadow: 0 0 22px rgba(240,41,108,.55);
}
.emailgate .eg-sub {
  margin: 0;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--text-2);
  text-align: center;
}
.emailgate .eg-form { display: flex; flex-direction: column; gap: .7rem; margin-top: .4rem; }
.emailgate .eg-note {
  margin: 0;
  font-size: .78rem;
  color: var(--text-3);
  text-align: center;
}
.emailgate .eg-out { margin-top: 1.6rem; }

/* A real email address is long. Anywhere one is printed into a sentence it
   wraps inside its box rather than pushing the page sideways (the tester
   caught this on the code screen at 390 px, 2026-08-20). */
.pform .sub b, .emailgate .eg-sub b { overflow-wrap: anywhere; }
.pform .sub, .emailgate .eg-sub { overflow-wrap: anywhere; }

/* The six-digit code boxes (round eleven, 2026-08-20). Wide, spaced and
   centred, because a code is read off a phone screen and typed once. */
.field.code {
  font-size: 1.5rem;
  letter-spacing: .01em;
  text-align: center;
  padding-left: .35em;      /* the letter-spacing pushes the last digit right */
}
/* The placeholder is words, not digits, so it does not want the digit spacing:
   at 390 px "The 6-digit code" measured 366 px inside a 302 px box and read
   "The 6-digit co" (tester, 2026-08-20). */
.field.code::placeholder { letter-spacing: normal; font-size: .95rem; }


/* ==========================================================================
   Round fourteen (2026-08-20): the pieces Home's feed introduced that the
   Chat tab now uses too -- the round icon buttons with their waiting dot, the
   dashed empty state, and the person row. They lived in profile.css, which
   the Chat page does not load, so the icons came out as blank squares. They
   are shared chrome now and belong here.
   ========================================================================== */
.ficon {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem;                     /* 44px, thumb sized */
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--text);
  border-radius: 50%; text-decoration: none;
}
.ficon svg { width: 1.35rem; height: 1.35rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.ficon:active { background: #1C1C20; }
.ficon[aria-expanded="true"] { color: var(--brand); }
/* Something waiting behind Friends: the same count the Profile tab's dot uses. */
.fdot {
  position: absolute; top: .45rem; right: .4rem;
  min-width: .95rem; height: .95rem; padding: 0 .2rem;
  border-radius: 999px; background: var(--brand); color: #FFFFFF;
  font-family: var(--sans); font-size: .55rem; font-weight: 700; line-height: .95rem; text-align: center;
  border: 2px solid #000000;
}

/* ---- Following / Discover ---- */
.feedtabs { display: flex; gap: 1.2rem; width: 100%; margin: .5rem 0 0; border-bottom: 1px solid var(--line); }
.ftab {
  background: none; border: 0; padding: .5rem 0 .55rem; cursor: pointer;
  font-family: var(--sans); font-size: 1rem; font-weight: 600;
  color: var(--text-2); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.ftab.on { color: #FFFFFF; font-weight: 800; border-bottom-color: var(--brand); }

.fsearch { width: 100%; margin: .6rem 0 0; }
.fsearch input {
  width: 100%; padding: .7rem .9rem; border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
  font-family: var(--sans); font-size: .95rem;
}
.fsearch input::placeholder { color: var(--text-3); }
.fsearch input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(240,41,108,.22); }

/* ---- the sign on the door ---- */
.hero { width: 100%; text-align: center; padding: .7rem 0 .2rem; }
/* The mark in the fade rather than white-with-a-glow, the way the reference
   picture carries its lips. The glow stays in em so it shrinks with the type. */
.hero-mark {
  font-size: 2.3rem;
  background: linear-gradient(100deg, var(--brand) 8%, var(--brand-mid) 48%, var(--brand-2) 88%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 .18em rgba(240,41,108,.55));
}
.hero-lv {
  margin: .1rem 0 0; font-family: var(--round); font-weight: 800;
  font-size: .72rem; letter-spacing: .01em; text-indent: .55em;
  color: var(--violet);             /* 5.2. It is a word, and 11.5px bold is not large text, so it needs the readable violet, not the fade's. */
}

/* ---- a section heading with a See all ---- */
.sechead { display: flex; align-items: baseline; gap: .6rem; width: 100%; margin: 1rem 0 .45rem; }
.sechead .k2 { margin: 0; }
/* The spec's section headers are white and bold, not small grey capitals.
   Only Home's, so Profile's own labels keep the look they already have. */
.home-members .k2 {
  font-family: var(--round); font-weight: 800; font-size: 1.02rem;
  letter-spacing: -.01em; text-transform: none; color: #FFFFFF;
}
.home-members .k2 .p-count { font-family: var(--sans); font-size: .72rem; font-weight: 400; color: var(--text-2); letter-spacing: 0; }
.seeall { margin-left: auto; font-family: var(--sans); font-size: .82rem; font-weight: 700; color: var(--brand); text-decoration: none; padding: .35rem 0; }
.k2.mt { margin-top: 1.1rem; }

/* ---- Live now ---- */
.lrow { display: flex; gap: .55rem; width: 100%; overflow-x: auto; padding-bottom: .3rem; scrollbar-width: none; }
.lrow::-webkit-scrollbar { display: none; }
.lcard {
  position: relative; flex: 0 0 auto; width: 7.4rem; aspect-ratio: 3 / 4;
  border-radius: var(--r); overflow: hidden; cursor: pointer;
  border: 1px solid var(--line); background: #151518;
  text-align: left; padding: 0; font: inherit; color: inherit;
  text-decoration: none; display: block;
}
.lcard .lph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 2.4rem; color: #000000; }
.lcard .lph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lcard .ltop { position: absolute; top: .35rem; left: .35rem; right: .35rem; display: flex; gap: .25rem; z-index: 2; }
.lcard .lpill {
  border-radius: 999px; padding: .12rem .4rem;
  font-family: var(--sans); font-size: .5rem; font-weight: 700; letter-spacing: .08em;
  background: var(--brand); color: #FFFFFF;
}
.lcard .leye {
  margin-left: auto; display: inline-flex; align-items: center; gap: .2rem;
  border-radius: 999px; padding: .12rem .4rem;
  background: rgba(0,0,0,.6); border: 1px solid rgba(255,255,255,.18); color: #FFFFFF;
  font-family: var(--sans); font-size: .5rem; font-weight: 700;
}
.lcard .leye svg { width: .6rem; height: .6rem; fill: none; stroke: currentColor; stroke-width: 2; }
.lcard .lfoot {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 1.1rem .45rem .45rem;
  background: linear-gradient(transparent, rgba(0,0,0,.94));
}
.lcard .ln { display: block; font-size: .8rem; font-weight: 800; color: #FFFFFF; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lcard .lsub { display: block; font-size: .62rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* An empty state is an invitation, so it wears the brand pink. It must never
   wear the violet that means somebody IS up (round nine's tester catch). */
.fempty {
  width: 100%; border: 1px dashed rgba(240,41,108,.5); border-radius: var(--r);
  padding: 1.1rem .9rem; text-align: center;
}
.fempty b { display: block; color: var(--brand); font-size: .95rem; font-weight: 800; }
.fempty span { display: block; color: var(--text-2); font-size: .82rem; margin-top: .15rem; }
.fempty.quiet { border-color: rgba(255,255,255,.2); }
.fempty.quiet b { color: #FFFFFF; }

/* ---- Following: your friends, one row each ---- */
.frows { width: 100%; display: flex; flex-direction: column; gap: .5rem; }
/* a row can be a link now (the Chat tab's message list), so it must not
   wear a browser underline */
a.frow, a.frow:visited { text-decoration: none; color: inherit; }
a.rcard2, a.rcard2:visited { text-decoration: none; color: inherit; }

.frow {
  /* No width: 100% here. The Dragon Tiger coin's clearance is a margin-right
     in style.css, and a fixed width would let the row keep its size and slide
     under the coin instead of stopping short of it. */
  display: flex; align-items: center; gap: .65rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: .55rem .6rem; text-align: left; font: inherit; color: inherit; cursor: pointer;
}
.frow .fav {
  position: relative; flex: 0 0 auto; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  padding: 2px; background: linear-gradient(135deg, var(--brand), var(--brand-2));
}
.frow .fav > span {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  font-weight: 800; font-size: 1rem; color: #000000;
}
.frow .fav img { width: 100%; height: 100%; object-fit: cover; display: block; }
.frow .fwho { min-width: 0; flex: 1; }
.frow .fwho b { display: block; font-size: .95rem; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frow .fwho span { display: block; font-size: .74rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frow .fgo {
  flex: 0 0 auto; border: 0; border-radius: 999px; cursor: pointer;
  padding: .5rem 1rem; min-height: 2.2rem;
  background: linear-gradient(90deg, var(--brand), var(--brand-2));
  color: #FFFFFF; font-family: var(--sans); font-size: .78rem; font-weight: 800;
}
.frow .fgo.done { background: #1C1C20; color: var(--text-2); }
.frow .fdotr { flex: 0 0 auto; width: .55rem; height: .55rem; border-radius: 50%; background: var(--text-3); }
.frow .fdotr.on { background: var(--green); box-shadow: 0 0 8px var(--green); }


/* ==========================================================================
   Round seventeen (2026-08-20): shared page chrome. The title bar came out of
   lobby.css because the Games page wears it too, and the Games page itself.
   ========================================================================== */
/* ---- the title bar ---- */
.chattop {
  position: fixed; top: 0; left: 0; right: 0; z-index: 6;
  max-width: 27rem; margin-inline: auto;
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem .9rem .3rem;
  background: var(--void);
}
.chattitle { margin: 0; font-family: var(--round); font-weight: 800; font-size: 1.35rem; color: #FFFFFF; }
.chaticons { margin-left: auto; display: flex; align-items: center; gap: .1rem; }

/* ---- the Games page ---- */
.gamespage {
  max-width: 27rem; margin-inline: auto;
  padding: 3.6rem .9rem calc(4.6rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: .7rem;
}
.gpage-tile {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: .9rem; color: inherit; text-decoration: none; cursor: pointer; font: inherit;
}
.gpage-tile:active { background: var(--panel-2); }
.gpage-ic {
  flex: 0 0 auto; width: 4.6rem; height: 4.6rem; border-radius: var(--r);
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.04); border: 1px solid var(--line);
}
.gpage-ic img { width: 78%; height: 78%; object-fit: contain; display: block; filter: drop-shadow(0 2px 6px rgba(0,0,0,.65)); }
.gpage-tile.gold .gpage-ic { border-color: rgba(255,215,0,.4); box-shadow: inset 0 0 18px -8px var(--gold); }
.gpage-tile.red  .gpage-ic { border-color: rgba(225,45,45,.45); box-shadow: inset 0 0 18px -8px var(--red); }
.gpage-w { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .2rem; }
.gpage-w b { font-family: var(--round); font-weight: 800; font-size: 1rem; color: #FFFFFF; display: flex; align-items: center; gap: .4rem; }
.gpage-w span { font-size: .78rem; color: var(--text-2); line-height: 1.35; }
.gpage-go { flex: 0 0 auto; font-size: 1.4rem; color: var(--text-3); }
.gpage-note { margin: .3rem 0 0; text-align: center; font-size: .72rem; color: var(--text-3); }
/* This page is the door; the floating coin would be a second door to the same
   room on the same screen. The MINI BAR stays: a minimised table with a live
   bet must never vanish (reviewer catch, round seventeen). */
.games-page .gcoin { display: none !important; }

/* ==========================================================================
   The menu sheet: the person card and the host's menu. Round seventeen,
   Martin's catch 2026-08-20: "the tray doesnt align with the design, its
   still the old design". It came out of room.css (shared chrome; the card
   opens on Home, Chat, Live, Profile and in a room) and off the old neon
   look: a charcoal sheet with a handle, white words, quiet grey buttons,
   amber only on what cannot be taken back. One accent, not five.
   ========================================================================== */
.menu {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  background: rgba(0,0,0,.6);
}
.menu-card {
  width: 100%;
  max-width: 27rem;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  padding: .55rem .9rem calc(1rem + env(safe-area-inset-bottom));
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--r) var(--r) 0 0;
  background: var(--panel);
}
/* the sheet's handle, the same one every other sheet wears */
.menu-card::before {
  content: '';
  display: block;
  width: 2.4rem; height: .28rem;
  margin: .1rem auto .55rem;
  border-radius: 999px;
  background: rgba(255,255,255,.5);
}
.menu-name {
  margin: 0 0 .2rem;
  font-family: var(--round);
  font-weight: 800;
  font-size: .95rem;
  color: #FFFFFF;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.menu-btn {
  width: 100%;
  min-height: 44px;
  padding: .7rem 1rem;
  border-radius: var(--r);
  font-family: var(--sans);
  font-size: .85rem;
  font-weight: 600;
  /* Names are shown as typed, not shouted. */
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.menu-btn:hover { background: rgba(255,255,255,.06); }
.menu-btn.amber { color: var(--amber); border-color: rgba(255,154,60,.5); }
.menu-btn.amber:hover { background: rgba(255,154,60,.08); }
.menu-btn.plain { color: var(--text-2); background: transparent; }
.menu-note {
  margin: -.2rem 0 .3rem;
  font-family: var(--sans);
  font-size: .7rem;
  color: var(--text-3);
}

/* The .lines.caption style lived here for two hours on 2026-08-21 and was
   cut by Martin's option 2 the same sitting: ONE chat style everywhere, the
   Chat tab's bubbles, small. The live screens differ in one thing only:
   no timestamps (his standing call). */

/* 2026-08-22, Martin's call: "its only suppose to be the log in screen".
   Logged out, the bottom bar was still on the log in screen with four tabs
   you could tap. Every one of them bounced you straight back, so nothing
   leaked, but a log in screen with a nav bar on it looks like a door left
   open. The class is set by an inline script in the head of profile.html
   before anything is drawn, so the bar is never there to flash, and
   profile.js keeps it right when you log in or out without a reload.
   The padding goes with it, or the screen keeps a gap where the bar was. */
html.signed-out .tabs { display: none; }
html.signed-out body.has-nav .stage,
html.signed-out body.has-nav .door { padding-bottom: 0; }
