/* The theme's constants, faces and shared primitives — the one source every
   entry that dresses itself in this theme reads (the app shell through
   main.css, the rankings page directly). Layout geometry lives here too, so a
   rail resize cannot strand a panel: every rule downstream reads these
   variables. */

:root {
  --white: #fff;
  /* The glossy button edge, one shade under --white. */
  --white-dim: #f2f2f2;
  --black-trans-md: rgba(0, 0, 0, 0.5);
  --mainColor: #202327;
  --mainColor-dark: #16181c;
  --mainColor-darker: #0c0d0f;
  --mainColor-light: #33373d;
  --mainColor-lighter: #8b949d;
  --mainColor-lightest: #e8eaed;
  --mainColor-lightest-trans-hi: rgba(232, 234, 237, 0.7);
  --mainColor-lightest-trans-md: rgba(232, 234, 237, 0.5);
  /* The hover edge the channel toolbar's outlined buttons (Replays,
   * Rankings, Test game, My card) and the game card's actions brighten to.
   * It was used at three sites and defined nowhere; 0.4 is the lowest alpha
   * that clears WCAG 1.4.11's 3:1 on the plates it lands on — 3.29:1 on
   * --mainColor, 3.38:1 on --mainColor-dark (tools/contrast_check.py). */
  --mainColor-lightest-trans-lo: rgba(232, 234, 237, 0.4);
  --mainColor-dark-trans-lo: rgba(22, 24, 28, 0.3);
  --mainColor-darker-trans-hi: rgba(12, 13, 15, 0.7);
  --mainColor-darker-trans-lo: rgba(12, 13, 15, 0.3);
  /* The theme's metal: one value the accent and the online state both wear,
   * written once. The two names stay separate because they answer different
   * questions — `--accentColor` is the theme's highlight ink, `--state-online`
   * is a status — and a status that borrows the highlight's literal would be
   * edited by whoever edits the highlight. \#121 U8 found the pair spelled
   * twice and folded the value, not the names. */
  --silver: #c9d1d9;
  --accentColor: var(--silver);
  /* The mention/turbo warm: one value that is both an ink over the chat's
   * gradient and a plate under a badge's digit, so it has to clear the bar from
   * either side.  The fork's #ef5a36 was 3.53:1 as an ink at the gradient's
   * lightest stop (--mainColor-light) and 2.82:1 as a plate under the inherited
   * --mainColor-lightest digit; this clears both (4.74 as that ink, 7.70 under
   * --mainColor-darker), and it separates from --errorColor, which it nearly
   * duplicated before (#121 U8). */
  --accentColor2: #ff7d55;
  /* The accent's soft plate — the turbo badge's fill, which spelled the accent's
   * own rgb() a second time and stayed behind when this round moved the accent.
   * That is the argument for naming it (#121 U8). */
  --accentColor2-trans-lo: rgba(255, 125, 85, 0.14);
  --errorColor: #e94c3a;
  /* The fork's SOCD plate: the dark red its input display draws the
     clear-opposites badge on, with the word in white. A fact of the fork, not
     a choice of the theme - the lobby badge wears the plate the emulator
     wears. */
  --badgeSocdPlate: #781e14;
  --successColor: #8ce62f;
  --state-online: var(--silver);
  --state-away: #e8b73a;
  --text-dim: #9aa0a6;
  /* Nickname tiers (global roles): admin red, operator green, vip yellow.
   * All clear 4.5:1 on --mainColor-dark (#16181c): 6.40 / 8.82 / 10.41. */
  --roleAdmin: #ff6b6b;
  --roleOperator: #7bc96f;
  --roleVip: #e8c339;
  /* ---- the type ladder ------------------------------------------------
   * Nine steps, one spelling each. The tree drew these in 29 distinct sizes
   * before they existed (tools/ui_scale_census.py), the same step written in
   * `rem` in one rule and `px` in the next, and 0.78/0.8/0.82/0.85/0.88/0.9
   * are six spellings of two sizes a reader cannot tell apart.
   *
   * The steps are in `rem`. The theme sets no root size anywhere — `html`
   * carries height and margin and nothing else — so one `rem` is the browser's
   * default 16, which is the number every comment here is measured against.
   * The ladder stays relative on purpose: a player who raises their minimum
   * text size scales all nine steps together, and pinning the root would
   * spend that to make the comments exact. */
  --text-1: 0.625rem; /* 10px  a circle's own word, a chip's letter */
  --text-2: 0.6875rem; /* 11px  a counter, a timestamp, a ribbon */
  --text-3: 0.75rem; /* 12px  dense meta: a row's second line */
  --text-4: 0.8125rem; /* 13px  secondary prose, a rail label */
  --text-5: 0.875rem; /* 14px  body — the size prose is written at */
  --text-6: 1rem; /* 16px  a row's subject, an input's own text */
  --text-7: 1.25rem; /* 20px  a panel or dialog heading */
  --text-8: 1.5rem; /* 24px  a page heading, a glyph that is the control */
  --text-display: 2.5rem; /* 40px  the landing title */
  /* The roles prose and controls reach for, so a callsite names its job
   * rather than counting pixels. */
  --text-body: var(--text-5);
  --text-control: var(--text-6);
  /* ---- leading --------------------------------------------------------
   * Three steps. A line-height is the other half of every fixed-height box's
   * arithmetic: a box that names its own height owes its text at least
   * `font-size * leading`, and the two clipped boxes this round found were
   * both a height that had not been told what its line measured.
   * `--leading-body` is what every rule that names no line-height already
   * inherits from `body`. `line-height: 0` is not a step and is not folded:
   * fourteen rules use it to suppress a box's own line, which is a layout
   * device, not a size. */
  --leading-none: 1; /* a glyph, a badge, a counter in a plate */
  --leading-tight: 1.1; /* a control's label, a rail column's one-line rows */
  --leading-body: 1.45; /* prose */
  /* ---- the radius ladder ----------------------------------------------
   * Five steps, a pill and a circle. The tree spelled 16 of them (the same
   * census), and three of those were corner shorthands that named a step for
   * two corners and 0 for the other two. */
  --radius-1: 2px; /* a badge plate, a flag */
  --radius-2: 4px; /* the control corner: every button, every input */
  --radius-3: 6px; /* a chip, a tile, a row */
  --radius-4: 8px; /* a popover, a panel's inner card */
  --radius-5: 10px; /* the big panel */
  --radius-pill: 999px;
  --radius-circle: 50%; /* `100%` is the same shape on every box, spelled twice */
  /* ---- the control scale ----------------------------------------------
   * One scale, three steps, two faces. The face says how loud the act is —
   * `gloss` (.button-generic: the one act a screen wants the eye on) and
   * `flat` (.appButton and every bordered control beside an input) — and the
   * step says how big. A variant (is-primary, is-danger, cardClose, a
   * secondary label) changes ink and never geometry, and a callsite that
   * wants a bigger control names a step instead of writing a padding.
   *
   * The heights are min-heights: a wrapped label grows the box, and 44 is the
   * smallest target this theme will hand to a pointer for the act that
   * matters. Each step carries its own font size, so the four things the
   * tree used to set per-callsite (height, pad, font, radius) move together. */
  --control-h-sm: 26px; /* a dense row: the rail's retry, a match's handoff.
                         * WCAG 2.5.8's 24px floor plus the 1px border each
                         * side, so the drawn box is not the target's size. */
  --control-h-md: 32px; /* the default: a control level with a 32px input */
  --control-h-lg: 44px; /* the slab, and WCAG 2.5.5's enlarged-target number */
  --control-font-sm: var(--text-3);
  --control-font-md: var(--text-5);
  --control-font-lg: var(--text-6);
  --control-pad-x-sm: 0.5rem;
  --control-pad-x-md: 0.875rem;
  --control-pad-x-lg: 1rem;
  --control-gap: 0.35rem; /* an icon inside a control */
  /* Layout geometry (single source — the panels that hang on the rail read
   * these, so a rail resize cannot strand one anymore). */
  --rail-w: 120px;
  /* The rail's own account circle.  The state popover is centred in the rail
   * and so is offset from this circle, not from a number measured off it:
   * \#121 U8 found `left: -15px` and a bare `width: 160px` two rules apart,
   * which is a layout that moves only when both are remembered. */
  --rail-avatar: 50px;
  /* A popover opens *from* the rail; it is not sized by it. 160 is the width
   * the state menu's own labels need, and the menu lands over the channel
   * column, which is wider than the rail by design. */
  --popover-w: 160px;
  /* The chat column's own floor. It is a framed flex row with a fixed roster,
   * so a chat that shrinks without a stated minimum lets a long word in one
   * message decide the whole shell's width: measured at \#122 U9, the column's
   * own content asked for 334px and pushed the roster 30px past the window's
   * edge at a 784px page. 20rem holds the composer's inset and a text line
   * and is the number the window floor (shared/window.ts) is held against. */
  --chat-w-min: 20rem;
  --chatbar-h: 58px;
  /* Clearance above the chat bar for the log and popups. Coupled to
   * --chatbar-h by constraint, not equality: must stay >= it. */
  --chatbar-clear: 75px;
}

/* The one hidden-label rule: table captions and aria references across the
   app and the public pages share it, so it lives in the sheet every entry
   reads (F-174). */
.visuallyHidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Adobe Source Sans Pro (open license), the theme's face. */
@font-face {
  font-family: 'Source Sans Pro';
  font-style: normal;
  font-weight: 400;
  src: url('./source-sans-pro-regular-DlNrLNKj.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Sans Pro';
  font-style: italic;
  font-weight: 400;
  src: url('./source-sans-pro-italic-DvQ_kjcu.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Sans Pro';
  font-style: normal;
  font-weight: 600;
  src: url('./source-sans-pro-600-CVFS1ax3.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Sans Pro';
  font-style: normal;
  font-weight: 700;
  src: url('./source-sans-pro-700-4xXxtyX1.woff2') format('woff2');
}

@font-face {
  font-family: 'Source Sans Pro';
  font-style: italic;
  font-weight: 700;
  src: url('./source-sans-pro-700italic-CoIzS47E.woff2') format('woff2');
}
/* The frame every page beside the app stands on. tokens.css holds the theme's
   constants, face and shared primitives; this holds the document they dress —
   body, column, title, note — so src/ranks and src/replays read from one
   source instead of each keeping a private copy to drift. */

html,
body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--mainColor-darker);
  color: var(--mainColor-lightest);
  font-family: 'Source Sans Pro', 'Segoe UI', system-ui, sans-serif;
  /* The same two properties the app's own body declares, read from the same
   * ladder: a public page that spelled its body size `14px` kept a second type
   * scale alive outside the one the tokens name (\#121 U8). */
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.publicPage {
  max-width: 40rem;
  margin: 0 auto;
  padding: 2rem 1rem;
}

.publicPage .publicTitle {
  margin: 0 0 0.25rem;
  text-align: center;
}

