/* xi-chrome.css v1 — the furniture every game in the family wears.
 *
 * WHY THIS FILE EXISTS. Two games grew two chromes. The crossword had a solid
 * green bar with game navigation and no way home; the word search had a paper
 * bar with family navigation and no game navigation. Each had the half the
 * other was missing, and once you were on a board the crossword swapped to a
 * third header with no navigation at all — which is why a player could get
 * stranded mid-puzzle with no route back to the hub or the other game.
 *
 * ON THE GREEN. The crossword's masthead was --pitch, the same green that marks
 * a correct answer. Spending the one colour that means something on furniture
 * is why a correct answer had to shout to be heard. The bar is paper; green
 * appears when you get something right, and otherwise it does not appear.
 *
 * ON THE SHAPE. Bar, then the game's own tools row, then the board. The bar is
 * identical in every game — that is what makes it read as a squad rather than
 * as two sites that share a host. The tools row is where the games differ, and
 * keeping the difference on its own row is what lets the bar stay identical.
 *
 * THE CLOCK IS NOT IN HERE. Both games already pair the clock with the score
 * (.match-clock beside 114, .scoreCluster holding both). That pairing is a
 * family pattern that already existed; moving the clock up here to fill the
 * bar would have broken it to satisfy a sketch.
 *
 * NO COLOURS ARE DEFINED IN THIS FILE. Every value comes from xi-tokens.css.
 * A palette restated in a second place is the fault this project keeps paying
 * for, and the gate asserts it.
 */

/* A DOUBLE TAP IS PLAY, NOT A ZOOM (the owner, 30 Sep 2026, on Scrambled in
   the app: "if I double click in the app it zooms in"). Two quick taps are
   ordinary on every board -- a tile, then the same tile, a key twice -- and
   iOS read them as zoom. `manipulation` turns off only the double-tap zoom:
   pinch still zooms, for anyone who needs it, and an element that handles its
   own touches (the crossword's frame, the word search grid, Ballpark's track)
   keeps its stricter touch-action:none, which still wins there. The crossword
   had this alone; every page loads this file. */
body { touch-action: manipulation; }

/* ---- the bar ---------------------------------------------------------- */

.xic-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 16px;
  /* UNDER THE SYSTEM BARS. A page with viewport-fit=cover (ten of them: it is
     what lets interactive-widget and the keyboard behave) is drawn edge to
     edge, and the browser -- or the app's WebView, before app 0.1.3 -- expects
     the page to keep clear of the status bar and the notch itself. It did not,
     and the bar sat under Android's clock (found in the app, 25 Sep 2026).
     env() is 0 wherever nothing is in the way, so this costs nothing there. */
  padding-top: calc(6px + env(safe-area-inset-top));
  padding-left: calc(16px + env(safe-area-inset-left));
  padding-right: calc(16px + env(safe-area-inset-right));
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  /* Not sticky. A sticky bar on a phone eats the board's height for something
     nobody looks at while solving, and the board is already scaled to fit. */
}

.xic-burger {
  display: grid;
  place-items: center;
  /* THE BOX IS THE TARGET. This was a 34px button with a --tap pseudo-element
     stretched over it, on the theory that the hit area is what matters. It is
     not what render_test measures, and render_test is right: a pseudo-element
     is invisible to assistive tech and to anything reasoning about the control
     itself. Reported as "xic-burger:34" across every viewport. The button is
     the size of the target. */
  width: var(--tap);
  height: var(--tap);
  margin-left: -10px;             /* optical: the icon reads inset otherwise */
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.xic-burger:hover { background: var(--tint); }
.xic-burger:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.xic-burger svg { width: 20px; height: 20px; display: block; }

/* The wordmark goes home. Every game, every view, including mid-board — this
   is the actual fix for being stranded on a puzzle. */
.xic-home {
  font-family: var(--disp);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.xic-home:hover { text-decoration: underline; text-underline-offset: 3px; }
.xic-home .xic-xi { color: var(--xi-ink); }
/* "The XI Games - Football": the theme beside the wordmark, in its face and a
   step quieter, so the site reads first and the theme second. */
.xic-sep { margin: 0 6px; color: var(--ink-faint); font-family: var(--disp); }
.xic-theme {
  font-family: var(--disp);
  font-size: 16px;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
}
.xic-theme:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

.xic-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

.xic-ghost {
  font: inherit;
  font-size: 13px;
  /* THE BOX IS THE TARGET, as for the burger: render_test measured the
     Settings button at 36px on every viewport the day it reached the
     in-game bar. The bar is already the burger's --tap tall, so this costs
     no height. */
  min-height: var(--tap);
  color: var(--ink-soft);
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 7px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.xic-ghost:hover { color: var(--ink); background: var(--tint); }
.xic-ghost:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* The signed-in name is the Account button's face. A long one is cut, not
   allowed to squeeze the wordmark off a phone. */
.xic-account { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }

/* Under about 430px the bar keeps the way out and drops the rest. The
   hamburger holds everything it drops, which is the whole reason it exists. */
@media (max-width: 430px) {
  .xic-ghost[data-optional] { display: none; }
}

/* SHORT SCREENS. The bar keeps its --tap control and loses its padding: the
   button IS the bar's height. Every pixel here comes off the board — with the
   padding in, render_test measured the board frame down to 119px on a 320x568
   phone, "the board has nowhere to go".

   This lived in the crossword's own stylesheet for one build, which the gate
   caught: a game defining .xic- rules has started a second chrome, and a
   second chrome is the fault this file exists to end. Nothing about a short
   screen is specific to one game. */
@media (max-height: 620px) {
  .xic-bar { padding: 0 12px; }
}

/* ---- the drawer ------------------------------------------------------- */

.xic-scrim {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / .38);
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s ease;
  z-index: 200;
}
.xic-scrim.open { opacity: 1; pointer-events: auto; }

.xic-drawer {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: min(300px, 86vw);
  background: var(--card);
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
  transition: transform .2s ease;
  z-index: 201;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.xic-drawer.open { transform: none; }

/* A player who has asked for no animation gets none — the drawer still opens,
   it simply arrives. */
@media (prefers-reduced-motion: reduce) {
  .xic-scrim, .xic-drawer { transition: none; }
}

.xic-dhead {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.xic-dhead .xic-home { font-size: 17px; }
.xic-close {
  margin-left: auto;
  width: var(--tap); height: var(--tap);
  display: grid; place-items: center;
  border: 0; border-radius: 8px;
  background: none; color: var(--ink-soft);
  font-size: 20px; line-height: 1; cursor: pointer;
}
.xic-close:hover { background: var(--tint); color: var(--ink); }
.xic-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.xic-dlabel {
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 14px 16px 6px;
}

.xic-squad { list-style: none; margin: 0; padding: 0 8px; }

.xic-slot {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 8px;
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
  font-size: 14px;
  min-height: var(--tap);         /* a tap target, not a line of text */
  box-sizing: border-box;
}
a.xic-slot:hover { background: var(--tint); }
a.xic-slot:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.xic-slot[aria-current="page"] { background: var(--tint); font-weight: 600; }

/* The shirt number. Filled for a released game, outlined for one that is not —
   so the drawer reads as a team sheet filling up rather than a list of dead
   links. */
.xic-shirt {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 5px;
  font-family: var(--disp);
  font-size: 12px;
  background: var(--pitch);
  color: var(--paper);
}
.xic-slot.soon { color: var(--ink-soft); }
.xic-slot.soon .xic-shirt {
  background: none;
  border: 1px dashed var(--line);
  color: var(--ink-soft);
}
/* An unreleased game is never named — live_check asserts the site names none
   of them, and the status is all there is to say about it anyway. */
.xic-status { font-size: 12px; color: var(--ink-soft); }

.xic-dfoot {
  margin-top: auto;
  border-top: 1px solid var(--line);
  padding: 8px;
  display: flex;
  flex-direction: column;
}
.xic-dfoot .xic-slot { font-size: 14px; }

/* ---- the footer ------------------------------------------------------- */

/* THE COMMUNITY LINE ON A RESULTS CARD. Quiet on purpose: it sits under a
   score the player has just earned and must not compete with it, so it takes
   the soft ink and the body face rather than the display one. Centred because
   every results card it lands in is centred. */
.xic-community { margin: 14px 0 2px }
.xic-community-in { display: flex; flex-wrap: wrap; gap: 6px;
  align-items: baseline; justify-content: center;
  font-family: var(--body); font-size: 14px; color: var(--ink-soft) }
.xic-community-link { color: var(--ink); text-decoration: underline;
  text-underline-offset: 2px }
.xic-community-link:hover { text-decoration-thickness: 2px }

.xic-foot {
  border-top: 1px solid var(--line);
  background: var(--paper);
  padding: 26px 16px 30px;
  font-size: 13px;
  color: var(--ink-soft);
}
.xic-foot-in {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  gap: 22px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.xic-foot h2 {
  font: inherit;
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 9px;
}
.xic-foot ul { list-style: none; margin: 0; padding: 0; }
.xic-foot li { margin: 0 0 7px; }
.xic-foot a { color: var(--ink); text-decoration: none; }
.xic-foot a:hover { text-decoration: underline; text-underline-offset: 3px; }
.xic-foot .xic-note {
  grid-column: 1 / -1;
  border-top: 1px solid var(--line);
  padding-top: 16px;
  line-height: 1.6;
}

/* The line somebody gets when they arrive at an old board from a link. Quiet
   — it is a fact about the board, not a warning about a mistake — and it sits
   directly under the bar so it is read before the board is. */
.xic-aged {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 16px; font-size: 13.5px; line-height: 1.45;
  background: var(--tint); color: var(--ink-soft);
  border-bottom: 1px solid var(--line);
}
.xic-aged-go {
  color: var(--pitch-ink, var(--pitch)); font-weight: 600; text-decoration: none;
  white-space: nowrap;
}
.xic-aged-go:hover { text-decoration: underline; text-underline-offset: 3px; }
.xic-aged-x {
  margin-left: auto; font: inherit; font-size: 17px; line-height: 1;
  min-height: var(--tap); min-width: var(--tap);
  border: 0; background: none; color: var(--ink-soft); cursor: pointer;
}
.xic-aged-x:hover { color: var(--ink); }
/* On a locked play screen the banner is one line: every pixel it takes is a
   pixel the board does not get (measured on a 412x860 phone: 114px as a
   sentence, 45px as a line, and the cards 54px tall against 64). The long
   wording is for pages that scroll. body.locked is the family's class for a
   play screen fitted to the viewport; see tools/lock_test.mjs. The crossword's
   play screen is body.flex-layout (it was fitted before the family's class
   existed), and its home screen is .home-showing, which scrolls. */
.xic-aged-short { display: none; }
/* The bottom of a locked play screen keeps clear of the gesture bar and the
   home indicator, for the reason the bar keeps clear of the status bar above.
   Not where the family's keyboard is on the page: it pads itself
   (shared/xi-keys.css), and twice would be a strip of nothing under the keys. */
body.locked:not(:has(.osk)) { box-sizing: border-box; padding-bottom: env(safe-area-inset-bottom); }
body.locked .xic-aged,
body.flex-layout:not(.home-showing) .xic-aged { flex-wrap: nowrap; gap: 10px; padding: 0 4px 0 14px; font-size: 13px; }
body.locked .xic-aged-long,
body.flex-layout:not(.home-showing) .xic-aged-long { display: none; }
body.locked .xic-aged-short,
body.flex-layout:not(.home-showing) .xic-aged-short {
  display: inline; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}

/* ---- the account and the settings ----------------------------------------
   The crossword's sheet and menu, moved here so every game has them. The
   sheet is a card over a scrim; the menu is a small card under the button
   that opened it, or in the middle when opened from the drawer. Every
   value comes from the tokens. */

/* The drawer's account row. Quiet: a utility row, not a call to action. */
.xic-acct { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; border-top: 1px solid var(--line); font-size: 14px; }
/* display:flex beats the browser's [hidden] rule, so a hidden row still
   rendered — and its button was measured at 36px in a drawer nobody had
   opened. Said explicitly, as the sheet and the menu already say it. */
.xic-acct[hidden] { display: none; }
.xic-acct-state { opacity: .8; flex: 1 1 auto; }
.xic-acct-btn { font: inherit; font-size: 13px; cursor: pointer;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  min-height: var(--tap); padding: 0 12px; color: var(--ink); }
.xic-acct-btn:hover { background: var(--tint); }
.xic-dsettings { font: inherit; border: 0; background: none; cursor: pointer;
  width: 100%; text-align: left; }
.xic-dsettings:hover { background: var(--tint); }

/* Buttons the chrome draws in its own sheets. */
.xic-btn {
  font-family: var(--disp); font-weight: 700; font-size: 14px; letter-spacing: .08em;
  text-transform: uppercase; min-height: var(--tap); padding: 0 18px;
  border-radius: var(--r-pill); border: 2px solid var(--pitch);
  background: var(--pitch); color: var(--on-pitch); cursor: pointer;
}
.xic-btn:hover { filter: brightness(1.06); }
.xic-btn.outline { background: transparent; color: var(--pitch-ink); }
.xic-btn.outline:hover { background: var(--tint); }
.xic-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* The account sheet. */
.xic-sheet {
  position: fixed; inset: 0; z-index: 210;
  background: rgb(0 0 0 / .45);
  display: flex; align-items: center; justify-content: center; padding: 18px;
}
.xic-sheet[hidden] { display: none; }
.xic-sheet-card {
  background: var(--card); color: var(--ink); border-radius: var(--r-lg);
  max-width: 480px; width: 100%; max-height: 92vh; overflow: auto;
  padding: 22px 22px 20px; border-top: 6px solid var(--pitch);
  box-shadow: var(--shadow-2); text-align: center; font-family: var(--body);
}
.xic-sheet-card h3 {
  font-family: var(--disp); font-weight: 700; font-size: 15px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--pitch-ink); text-align: left;
  border-bottom: 2px solid var(--pitch); padding-bottom: 4px; margin: 0 0 8px;
}
.xic-sub { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 16px; text-align: left; }
.xic-why { font-size: 14.5px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 16px; }
.xic-gsi { display: flex; flex-direction: column; align-items: center; gap: 8px; min-height: 44px; margin-bottom: 10px; }
/* The app's own Google button (xi-chrome.js nativeGoogle): shaped like the one
   Google's library draws on the web, so the sheet looks the same either way. */
.xic-gbtn { display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 0 22px 0 14px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font: inherit; font-weight: 600; cursor: pointer; }
.xic-gmark { width: 18px; height: 18px; flex: none; }
/* SIGN IN WITH APPLE, in the iOS app only (xi-chrome.js nativeApple). Black
   with the Apple mark and Apple's own words, as its guidelines require, and
   the same width as Google's beside it so neither is the lesser choice. The
   colours are Apple's (--brand-apple in xi-tokens.css), not the theme's. */
.xic-abtn, .xic-gsi .xic-gbtn { min-width: 240px; justify-content: center; }
.xic-abtn { display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 0 22px 0 14px; border-radius: var(--r-pill);
  border: 1px solid var(--brand-apple); background: var(--brand-apple); color: var(--brand-apple-ink);
  font: inherit; font-weight: 600; cursor: pointer; }
.xic-amark { width: 16px; height: 19px; flex: none; }
.xic-small { font-size: 12.5px; color: var(--ink-faint); margin: 12px 0 0; line-height: 1.45; }
.xic-small a { color: var(--pitch-ink); }
.xic-msg:empty { display: none; }
.xic-code { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); text-align: left; }
.xic-code-or { font-size: 12px; letter-spacing: .09em; color: var(--ink-faint);
  text-align: center; margin-bottom: 14px; text-transform: uppercase; }
.xic-code-lbl { font-size: 13px; font-weight: 700; color: var(--ink); margin: 14px 0 6px; }
.xic-code-lbl:first-of-type { margin-top: 0; }
.xic-code-row { display: flex; gap: 8px; align-items: stretch; }
.xic-code-row code, .xic-code-row input {
  flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 16px; letter-spacing: .06em; padding: 11px 12px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-md);
}
.xic-code-row code { display: flex; align-items: center; overflow: auto; }
.xic-code-row input { text-transform: uppercase; }
.xic-code-row .xic-btn { flex: none; padding: 0 14px; }
.xic-code-note { font-size: 12.5px; color: var(--ink-soft); margin-top: 6px; line-height: 1.45; }
.xic-code-msg:empty { display: none; }
.xic-field { display: block; text-align: left; margin-bottom: 14px; }
.xic-field span {
  display: block; font-family: var(--disp); font-weight: 600; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 5px;
}
.xic-field input {
  width: 100%; box-sizing: border-box; font-family: var(--body); font-size: 15px; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); padding: 9px 10px;
}
.xic-actions { display: flex; gap: 8px; justify-content: center; margin-bottom: 12px; flex-wrap: wrap; }
/* Deleting the account: set apart by a rule, the confirm button in the
   danger colour, and the device box a plain checkbox with its words. */
.xic-del { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 12px; }
.xic-del-what { text-align: left; }
.xic-del-dev { display: flex; gap: 8px; align-items: center; justify-content: center; margin: 0 0 12px; font-size: 14px; color: var(--ink); }
.xic-del-dev input { width: 20px; height: 20px; }
.xic-del-go:not([disabled]) { background: var(--danger); border-color: var(--danger); color: var(--on-pitch); }
.xic-del-go[disabled] { opacity: .5; cursor: not-allowed; }
.xic-sheet-close { width: 100%; margin-top: 14px; }

/* The settings menu. */
.xic-pop {
  position: fixed; z-index: 205; min-width: 230px; max-width: calc(100vw - 16px);
  background: var(--card); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-2); padding: 4px;
  font-family: var(--body);
}
.xic-pop[hidden] { display: none; }
.xic-pop.as-sheet {
  top: 50%; left: 50%; right: auto; transform: translate(-50%, -50%);
  width: min(320px, calc(100vw - 32px));
}
.xic-row {
  display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
  text-align: left; border: 0; background: none; color: var(--ink); font: inherit;
  font-size: 14px; padding: 9px 10px; border-radius: var(--r-sm); min-height: 40px;
  text-decoration: none; cursor: pointer;
}
.xic-row:hover, .xic-row:focus-visible { background: var(--tint); outline: none; }
.xic-pc { margin-left: auto; font-size: 12px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; text-transform: lowercase; }
.xic-set-build {
  padding: 8px 10px 2px; margin-top: 4px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--ink-faint); letter-spacing: .04em;
}
@media (prefers-reduced-motion: no-preference) {
  .xic-pop:not([hidden]) { animation: xic-pop-in .12s ease-out; }
}
@keyframes xic-pop-in { from { opacity: 0; transform: translateY(-4px); } }
.xic-pop.as-sheet:not([hidden]) { animation: none; }

/* ---- form chips ---------------------------------------------------------
   Drawn by XIChrome.formChips() and styled here, so the two games cannot
   disagree about what a win looks like any more than about what one is.
   Separated by lightness as well as hue: a colour-blind player reads the
   letter and the weight, not the green. */
.xic-form { display: flex; gap: 6px; }
.xic-rc {
  width: 23px; height: 23px; border-radius: 5px;
  font-size: 11.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.xic-rc.xic-w { background: var(--form-w); color: var(--form-w-ink); }
.xic-rc.xic-d { background: var(--form-d); color: var(--form-d-ink); }
.xic-rc.xic-l { background: var(--form-l); color: var(--form-l-ink); }
/* The unplayed slot: the chip shape as an outline. A place for a result,
   rather than a result nobody can name. */
.xic-rc.xic-none {
  background: transparent; border: 1.5px dashed var(--line); box-shadow: none;
}

/* ==========================================================================
   THE SHEET, AND THE MONTH GRID INSIDE IT
   ==========================================================================

   WHY THESE ARE HERE NOW. The crossword and Scrambled each carried this
   component in their own stylesheet — the same overlay, the same card, the
   same seven-column calendar — and Vowels carried a third copy because it is
   generated from Scrambled's. Byte for byte the two sources were the same
   rules: 28 of 33 identical once whitespace was normalised, and four of the
   five differences were ".85" against "0.85". That is not two designs, it is
   one design written down twice, which is the drift this project pays for
   everywhere else. Recorded as debt in scrambled/css/style.css on the day it
   was written; this is the lift it asked for.

   AND THE CROSSWORD HELD A THIRD COPY OF ITS OWN. Thirty-three lines of it
   sat inside `@media (prefers-reduced-motion:reduce)`, where a paste had
   dropped them in front of the one rule that belonged there
   (`.toast{transition:none}`). Identical values, so nothing was visibly wrong
   for anyone — and it would have become visibly wrong the moment this lift
   removed the copy above it and left that one behind, for players with
   reduced motion only.

   THE PREFIX IS NOT DECORATION. HiLo uses `.sheet` for something else
   entirely — the list of calls at full time — and every game loads this file.
   An unprefixed `.sheet` here would have made HiLo's results list a fixed
   full-screen overlay. `xic-` is what marks a class the shared layer owns,
   and the gates already refuse a game that defines one.

   AND IT IS A PANEL, NOT A SHEET, BECAUSE .xic-sheet IS ALREADY TAKEN — fifty
   lines above, by the account sheet the chrome builds. The two look alike and
   are not the same component: the account sheet sits at z-index 210 above
   everything, dims with a neutral black, centres its text and hides by the
   hidden attribute; this one is the game's own layer at 55, dims with the
   pitch, reads left and hides by the absence of .show. Lifting this in under
   the same name redefined the chrome's and broke the mechanism that opens it.
   frontend_test caught it, because it looks for the account sheet by that
   class and suddenly found three of the crossword's. Whether the family should
   have one overlay rather than two is a real question and a separate one:
   answering it here would change how a component on every page looks, in a
   commit meant to be a move and nothing else.

   ONE DELIBERATE CHANGE OF VALUE: `.xic-panel-empty` takes the crossword's
   top padding of 6px. Scrambled's said 10px; it is drift rather than a
   decision, and one of the two had to win. */

.xic-panel {
  position: fixed; inset: 0; background: var(--scrim); z-index: 55;
  display: none; align-items: center; justify-content: center; padding: 18px;
}
.xic-panel.show { display: flex; }
.xic-panel-card {
  background: var(--card); border-radius: var(--r-lg); max-width: 520px; width: 100%;
  max-height: 92vh; overflow: auto; padding: 22px 22px 20px; border-top: 6px solid var(--pitch);
}
.xic-panel-card h2 {
  font-family: var(--disp); font-weight: 700; font-size: 26px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pitch-ink); margin-bottom: 2px;
}
.xic-panel-card h3 {
  font-family: var(--disp); font-weight: 700; font-size: 15px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--pitch-ink);
  border-bottom: 2px solid var(--pitch-deep); padding-bottom: 4px; margin: 0 0 8px;
}
.xic-panel-sub { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 16px; }
.xic-panel-empty { color: var(--ink-soft); font-size: 13.5px; padding: 6px 0 14px; }
.xic-panel-note { font-size: 11.5px; color: var(--ink-faint); margin-top: 14px; line-height: 1.45; }
.xic-panel-close { width: 100%; margin-top: 14px; }

/* THE MONTH GRID. A board's only identity is its date, so a date is how you
   choose one. Three states rather than two: played, still to play, and not
   yet released — plus locked, for a day behind the free window. */
.xic-cal-head { display: flex; align-items: center; gap: 10px; margin: 14px 0 10px; }
.xic-cal-head button {
  width: 44px; height: 44px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); font-size: 19px; line-height: 1; color: var(--ink-soft);
}
.xic-cal-head button[disabled] { opacity: .35; }
.xic-cal-month {
  flex: 1; text-align: center; font-family: var(--disp); font-size: 19px; font-weight: 700;
}
.xic-cal-dow {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px;
  font-size: 11px; color: var(--ink-faint); text-align: center; margin-bottom: 6px;
}
.xic-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.xic-cal-cell {
  position: relative;
  aspect-ratio: 1; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 13px; color: var(--ink); min-height: 40px; padding: 0;
}
.xic-cal-cell.empty { border: 0; background: none; }
/* Not released. A dot rather than a number: there is nothing there to choose,
   and an empty square with a date on it reads as something you failed to do. */
.xic-cal-cell.none { border: 0; background: none; color: var(--ink-faint); }
.xic-cal-cell.none::after { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--line); }
.xic-cal-cell.none span { display: none; }
.xic-cal-cell.open { border-color: var(--pitch); color: var(--pitch); font-weight: 700; }
.xic-cal-cell.done { background: var(--pitch); border-color: var(--pitch); color: var(--on-pitch); font-weight: 700; }
.xic-cal-cell.today { box-shadow: 0 0 0 2px var(--sel); }
/* A DAY BEHIND THE FREE WINDOW. Shown rather than hidden: what is behind the
   lock is the reason to register, and a day that vanished would say nothing. */
.xic-cal-cell.locked { border-style: dashed; border-color: var(--line); color: var(--ink-faint); }
.xic-cal-cell.locked::after { content: "\1F512"; font-size: 8px; line-height: 1; margin-top: 2px; opacity: .75; }
.xic-cal-cell b { font-size: 9px; font-weight: 700; letter-spacing: .04em; opacity: .85; }
/* The date and the score are separate lines. Inline, "24" and a score of 97
   rendered as "2497". */
.xic-cal-cell span { display: block; line-height: 1.1; }
.xic-cal-cell .xic-cal-score { display: block; line-height: 1.1; margin-top: 1px; }
/* The open-book marker: a board whose answers page is published. Bottom
   corner, small and muted — information, not decoration. */
.xic-cal-cell .xic-cal-ans {
  position: absolute; right: 4px; bottom: 3px; font-style: normal;
  font: 700 9px/1 "Barlow Condensed", "Arial Narrow", Arial, sans-serif;
  letter-spacing: .05em; color: var(--ink-soft); opacity: .75;
}
.xic-cal-cell.done .xic-cal-ans { color: var(--on-pitch); opacity: .8; }
.xic-cal-key {
  display: flex; gap: 14px; justify-content: center; margin: 14px 0 4px;
  font-size: 12px; color: var(--ink-soft); flex-wrap: wrap;
}
.xic-cal-key span { display: flex; align-items: center; gap: 6px; }
.xic-cal-key .k { width: 13px; height: 13px; border-radius: var(--r-xs); border: 1px solid var(--line); display: inline-block; }
.xic-cal-key .k.done { background: var(--pitch); border-color: var(--pitch); }
.xic-cal-key .k.open { border-color: var(--pitch); }
.xic-cal-key .k.none { border: 0; background: var(--line); }
.xic-cal-key .k.locked { border-style: dashed; background: none; }

/* ---- THE CHALLENGE PANEL -------------------------------------------------
   Built by shared/xi-challenge.js, poured into the .xic-panel above. Every
   game that has a challenge draws the same one — the invitation, the name
   before the board opens, and the standings after Full Time — so this is
   where it is styled and there is nowhere else it can be styled differently. */
.xic-ch-card { text-align: left; }
.xic-ch-who {
  font-family: var(--disp); font-weight: 700; font-size: 24px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--pitch-ink); margin: 0 0 2px;
}
.xic-ch-board { margin-bottom: 6px; }
.xic-ch-count { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 16px; }
.xic-ch-msg { font-size: 13px; color: var(--danger); margin: 6px 0 0; min-height: 1em; }
.xic-ch-msg:empty { display: none; }
.xic-ch-make, .xic-ch-copy { width: 100%; }
/* The link is shown as well as copied: a clipboard that silently fails on a
   locked-down browser would otherwise leave nothing to send. */
.xic-ch-link {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
  word-break: break-all; background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 9px 10px; margin: 0 0 8px; color: var(--ink);
}
.xic-ch-table { width: 100%; border-collapse: collapse; font-size: 14px; margin: 6px 0 4px; }
.xic-ch-table th {
  text-align: left; font-family: var(--disp); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); padding: 6px 6px; font-weight: 600;
}
.xic-ch-table td {
  padding: 7px 6px; border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.xic-ch-table tr.me td { font-weight: 700; color: var(--pitch-ink); }
.xic-ch-standings h3 {
  font-family: var(--disp); font-weight: 700; font-size: 15px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--pitch-ink);
  border-bottom: 2px solid var(--pitch-deep); padding-bottom: 4px; margin: 4px 0 8px;
}
