/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!../../node_modules/.pnpm/@fontsource+kanit@5.3.0/node_modules/@fontsource/kanit/300.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* kanit-thai-300-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_next/static/media/kanit-thai-300-normal.e44b40ba.woff2) format('woff2'), url(/_next/static/media/kanit-thai-300-normal.1d2e7cd6.woff) format('woff');
  unicode-range: U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC;
}

/* kanit-vietnamese-300-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_next/static/media/kanit-vietnamese-300-normal.0ec2d223.woff2) format('woff2'), url(/_next/static/media/kanit-vietnamese-300-normal.59d48193.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* kanit-latin-ext-300-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_next/static/media/kanit-latin-ext-300-normal.244bb381.woff2) format('woff2'), url(/_next/static/media/kanit-latin-ext-300-normal.1db5e544.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* kanit-latin-300-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_next/static/media/kanit-latin-300-normal.9bd86e88.woff2) format('woff2'), url(/_next/static/media/kanit-latin-300-normal.caddf1a8.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!../../node_modules/.pnpm/@fontsource+kanit@5.3.0/node_modules/@fontsource/kanit/400.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* kanit-thai-400-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_next/static/media/kanit-thai-400-normal.0d0f98c0.woff2) format('woff2'), url(/_next/static/media/kanit-thai-400-normal.daca2f68.woff) format('woff');
  unicode-range: U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC;
}

/* kanit-vietnamese-400-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_next/static/media/kanit-vietnamese-400-normal.d2d83a98.woff2) format('woff2'), url(/_next/static/media/kanit-vietnamese-400-normal.6781b69f.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* kanit-latin-ext-400-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_next/static/media/kanit-latin-ext-400-normal.dc5dddab.woff2) format('woff2'), url(/_next/static/media/kanit-latin-ext-400-normal.c9424037.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* kanit-latin-400-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_next/static/media/kanit-latin-400-normal.93fbf370.woff2) format('woff2'), url(/_next/static/media/kanit-latin-400-normal.35d5b3b8.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!../../node_modules/.pnpm/@fontsource+kanit@5.3.0/node_modules/@fontsource/kanit/500.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* kanit-thai-500-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/_next/static/media/kanit-thai-500-normal.6d4309dd.woff2) format('woff2'), url(/_next/static/media/kanit-thai-500-normal.9743af98.woff) format('woff');
  unicode-range: U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC;
}

/* kanit-vietnamese-500-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/_next/static/media/kanit-vietnamese-500-normal.33d29c5e.woff2) format('woff2'), url(/_next/static/media/kanit-vietnamese-500-normal.319a3954.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* kanit-latin-ext-500-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/_next/static/media/kanit-latin-ext-500-normal.ed960ddb.woff2) format('woff2'), url(/_next/static/media/kanit-latin-ext-500-normal.12ab5261.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* kanit-latin-500-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/_next/static/media/kanit-latin-500-normal.902a729c.woff2) format('woff2'), url(/_next/static/media/kanit-latin-500-normal.739707c8.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!../../node_modules/.pnpm/@fontsource+kanit@5.3.0/node_modules/@fontsource/kanit/600.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* kanit-thai-600-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_next/static/media/kanit-thai-600-normal.4d3b82b9.woff2) format('woff2'), url(/_next/static/media/kanit-thai-600-normal.ebe84828.woff) format('woff');
  unicode-range: U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC;
}

/* kanit-vietnamese-600-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_next/static/media/kanit-vietnamese-600-normal.123321b2.woff2) format('woff2'), url(/_next/static/media/kanit-vietnamese-600-normal.159359dd.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* kanit-latin-ext-600-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_next/static/media/kanit-latin-ext-600-normal.eee6c747.woff2) format('woff2'), url(/_next/static/media/kanit-latin-ext-600-normal.cb3a0387.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* kanit-latin-600-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_next/static/media/kanit-latin-600-normal.d6ae381c.woff2) format('woff2'), url(/_next/static/media/kanit-latin-600-normal.5d404f6b.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!../../node_modules/.pnpm/@fontsource+kanit@5.3.0/node_modules/@fontsource/kanit/700.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* kanit-thai-700-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/_next/static/media/kanit-thai-700-normal.56891763.woff2) format('woff2'), url(/_next/static/media/kanit-thai-700-normal.28181269.woff) format('woff');
  unicode-range: U+02D7,U+0303,U+0331,U+0E01-0E5B,U+200C-200D,U+25CC;
}

/* kanit-vietnamese-700-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/_next/static/media/kanit-vietnamese-700-normal.327090b5.woff2) format('woff2'), url(/_next/static/media/kanit-vietnamese-700-normal.dffce00f.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* kanit-latin-ext-700-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/_next/static/media/kanit-latin-ext-700-normal.edd17269.woff2) format('woff2'), url(/_next/static/media/kanit-latin-ext-700-normal.4817bf85.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* kanit-latin-700-normal */
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/_next/static/media/kanit-latin-700-normal.24e53e3b.woff2) format('woff2'), url(/_next/static/media/kanit-latin-700-normal.9c722300.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/*!*****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/globals.css ***!
  \*****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* GROUND CALL — admin brand system (STEP 18)
   GOG Red #D6222A · Near Black #111111 · Off White #F5F5F3 */

:root {
  --red: #d6222a;
  --red-bright: #f0323b;
  --red-deep: #96161c;
  --ink: #111111;
  --ink-2: #171717;
  --ink-3: #1f1f1f;
  --panel: #1a1a1a;
  --line: rgba(245, 245, 243, 0.1);
  --line-strong: rgba(245, 245, 243, 0.2);
  --off-white: #f5f5f3;
  --gray-400: #b5b5b2;
  --gray-500: #8b8b88;
  --gray-600: #6e6e6e;
  --green: #3fc48d;
  --amber: #e8a83e;
  --radius: 6px;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

/* Read aloud, never drawn. `display: none` would take it out of the
   accessibility tree too, which is the opposite of the point. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  -webkit-clip-path: inset(50%);
          clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--ink);
  color: var(--off-white);
  /* Thai sits taller than Latin and carries marks above and below the line,
     so it needs more leading than a Latin-only UI would use. */
  font:
    400 15px/1.75 "Kanit",
    "Segoe UI",
    system-ui,
    sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/*
 * Every control is set in the page's own face.
 *
 * A form control does not inherit a font from its ancestors: every browser
 * hands it the system UI face instead, and the system face on Windows is
 * Arial, which has no Thai of its own. So a few hundred buttons on this
 * programme were being drawn in a substitute typeface that matched nothing
 * else on the screen — every tile in the panel, every player chip on the
 * bench, the step arrows, the toggles. It was fixed once for the tool ring
 * before it was noticed that the ring was not the only place.
 *
 * The family only, never the font shorthand — that would take the size and
 * the weight with it and re-flow every control on the page over a rule about
 * typefaces. What each control is sized at is already decided where it is
 * defined, and that stays decided there.
 */
button,
input,
select,
textarea,
optgroup {
  font-family: inherit;
}

/* Negative tracking crowds Thai tone marks into their neighbours; only Latin
   display text gets tightened, and that is done per-element. */
:lang(th) {
  letter-spacing: normal;
}

a {
  color: inherit;
  text-decoration: none;
}

/* ------------------------------------------------------------ shell -- */

.shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 24px;
  height: 64px;
  border-bottom: 1px solid var(--line);
  background: rgba(17, 17, 17, 0.94);
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 40;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.brand-link {
  display: inline-flex;
}

/* On the sign-in card there is room to stand the lockup up and give it air. */
.brand-stacked {
  margin-bottom: 24px;
}

/* The crest knocks the trident out of the shield, so the shield is the fill and
   the holes show whatever is behind. currentColor rather than a fixed red: on
   the sign-in card and in the header the mark sits on different surfaces, and
   inheriting keeps one rule for both. */
.brand-mark-svg {
  flex: none;
  color: var(--red);
  fill: currentColor;
}

.brand-lines {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.brand-name {
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
}

.brand-tagline {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.16em;
  line-height: 1;
  color: var(--gray-500);
}

/* ---------------------------------------------------------- aurora text -- */
/* A gradient wider than the text, clipped to the glyphs and drifted sideways.
   The colour moves through the letters; the letters do not move.

   The stops are the shine border's three, lifted: this text sits on black in
   the interface and on video on the stage, and the darker end of that palette
   goes muddy against both. Every stop here is a light one, so the word reads as
   lit rather than as painted.

   Never give this a text-shadow. `background-clip: text` paints the gradient as
   the element's background, and a background paints below the text shadow — the
   shadow lands on top of the colour and drags it toward black. */

.aurora-text {
  background-image: linear-gradient(
    100deg,
    #ff4d57 0%,
    #ff8ab0 18%,
    #ffd27a 36%,
    #ff6b78 54%,
    #ffa3c4 76%,
    #ff4d57 100%
  );
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: aurora-drift 9s linear infinite;
}

@keyframes aurora-drift {
  to {
    background-position: 260% 50%;
  }
}

/* --------------------------------------------------------- word rotate -- */
/* Every line occupies the same grid cell, so the cell is as wide and as tall as
   the widest and tallest of them and the navigation beside the lockup never
   shifts. Only one of them is visible. */

.word-rotate {
  display: inline-grid;
  overflow: hidden;
}

.word-rotate > * {
  grid-area: 1 / 1;
  white-space: nowrap;
}

.word-rotate-gauge {
  visibility: hidden;
}

.word-rotate-word {
  animation: word-rise 420ms cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes word-rise {
  from {
    opacity: 0;
    transform: translateY(0.9em);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .aurora-text {
    animation: none;
    background-position: 30% 50%;
  }
  .word-rotate-word {
    animation: none;
  }
}

.topbar nav {
  display: flex;
  gap: 4px;
  margin-left: 12px;
}

.topbar nav a {
  padding: 8px 14px;
  border-radius: var(--radius);
  font-size: 14px;
  color: var(--gray-400);
}

.topbar nav a:hover {
  background: var(--ink-3);
  color: var(--off-white);
}

.topbar .spacer {
  flex: 1 1;
}

.who {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--gray-400);
}

.role-chip {
  padding: 3px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--gray-400);
}

main.page {
  flex: 1 1;
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding: 32px 24px 80px;
}

/* ------------------------------------------------------- typography -- */

h1 {
  font-size: clamp(24px, 4vw, 32px);
  font-weight: 600;
  line-height: 1.35;
  margin: 0 0 6px;
}

h2 {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.45;
  margin: 0 0 14px;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--red);
  margin: 0 0 12px;
}

.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--red);
}

.sub {
  color: var(--gray-500);
  font-size: 14px;
  margin: 0 0 28px;
}

.section {
  margin-top: 40px;
}

/* ------------------------------------------------------------ cards -- */

.grid {
  display: grid;
  grid-gap: 14px;
  gap: 14px;
}

.grid.two {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 20px;
}

.card.link:hover {
  border-color: var(--line-strong);
  background: var(--ink-3);
}

.card h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
}

.card .meta {
  color: var(--gray-500);
  font-size: 13px;
}

.score {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--off-white);
}

/* ------------------------------------------------------------ chips -- */

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  border: 1px solid var(--line-strong);
  color: var(--gray-400);
}

.chip.state-DRAFT {
  border-color: var(--line-strong);
}
.chip.state-RESEARCHING,
.chip.state-PROCESSING,
.chip.state-PUBLISHING {
  border-color: var(--amber);
  color: var(--amber);
}
.chip.state-RESEARCH_READY,
.chip.state-CALL_READY,
.chip.state-REVIEW {
  border-color: #5a9ef5;
  color: #5a9ef5;
}
.chip.state-LIVE {
  border-color: var(--red);
  color: #fff;
  background: var(--red);
}
.chip.state-APPROVED,
.chip.state-PUBLISHED {
  border-color: var(--green);
  color: var(--green);
}
.chip.state-FAILED,
.chip.state-CANCELLED {
  border-color: #e35d5d;
  color: #e35d5d;
}

.chip.demo {
  border-color: var(--amber);
  color: var(--amber);
}

/* --------------------------------------------------------- controls -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 18px;
  line-height: 1.4;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--off-white);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

.btn:hover:not(:disabled) {
  background: var(--ink-3);
  border-color: var(--gray-600);
}

.btn.primary {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

.btn.primary:hover:not(:disabled) {
  background: var(--red-bright);
  border-color: var(--red-bright);
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn.small {
  padding: 6px 12px;
  font-size: 13px;
}

.row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}

label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--gray-500);
  margin-bottom: 6px;
}

input,
select,
textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--ink-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--off-white);
  font: inherit;
  font-size: 14px;
}

input:focus,
select:focus,
textarea:focus {
  outline: 2px solid var(--red);
  outline-offset: -1px;
}

.field {
  margin-bottom: 18px;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 16px;
  gap: 16px;
}

/* --------------------------------------------------------- messages -- */

.alert {
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1px solid;
  font-size: 14px;
  margin-bottom: 18px;
}

.alert.error {
  border-color: #e35d5d;
  background: rgba(227, 93, 93, 0.1);
  color: #ffb4b4;
}

.alert.warn {
  border-color: var(--amber);
  background: rgba(232, 168, 62, 0.1);
  color: #f3cd8d;
}

.alert.ok {
  border-color: var(--green);
  background: rgba(63, 196, 141, 0.1);
  color: #9be8c6;
}

.empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--gray-600);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}

/* -------------------------------------------------------- questions -- */

.q {
  display: grid;
  grid-template-columns: 42px 1fr;
  grid-gap: 14px;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  margin-bottom: 10px;
}

.q-num {
  font-size: 13px;
  font-weight: 700;
  color: var(--red);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}

.q-text {
  font-size: 15.5px;
  margin: 0 0 8px;
  line-height: 1.8;
}

.q-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--gray-600);
}

.q textarea {
  min-height: 72px;
  resize: vertical;
  margin-bottom: 8px;
}

.facts {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
  color: var(--gray-400);
}

.facts li {
  position: relative;
  padding-left: 16px;
  margin-bottom: 4px;
}

.facts li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--red);
}

/* ------------------------------------------------------------ login -- */

.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}

.login-card {
  width: 100%;
  max-width: 400px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 32px;
}

.seed-hint {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--gray-600);
  line-height: 1.8;
}

.seed-hint code {
  color: var(--gray-400);
}

/* ------------------------------------------------------------ table -- */

.events {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.events th,
.events td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
}

.events th {
  color: var(--gray-500);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.events td.t {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--gray-500);
}

@media (max-width: 640px) {
  .topbar {
    height: auto;
    padding: 12px 16px;
    flex-wrap: wrap;
  }
  main.page {
    padding: 24px 16px 60px;
  }
  .q {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------- shine border -- */
/* A rotating conic gradient masked to the border ring. The angle is animated
   through a registered custom property because a bare CSS variable cannot be
   interpolated — without @property the gradient would jump, not sweep. */

@property --shine-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.shine-border {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  padding: var(--shine-width, 1px);
  background: var(--shine-gradient);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
          mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: shine-rotate var(--shine-duration, 14s) linear infinite;
}

@keyframes shine-rotate {
  to {
    --shine-angle: 360deg;
  }
}

@media (prefers-reduced-motion: reduce) {
  .shine-border {
    animation: none;
    background: linear-gradient(120deg, var(--red), transparent 60%);
  }
}

/* An element wrapping a ShineBorder needs its own stacking context. */
.shine-host {
  position: relative;
  overflow: hidden;
}

/* ---------------------------------------------------------------- globe -- */

.globe-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.globe-canvas {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 1;
  opacity: 0;
  cursor: -webkit-grab;
  cursor: grab;
  transition: opacity 0.9s ease;
  contain: layout paint size;
}

.globe-legend {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-gap: 6px 10px;
  gap: 6px 10px;
  align-items: center;
  font-size: 12.5px;
  color: var(--gray-400);
}

.globe-legend b {
  color: var(--off-white);
  font-weight: 500;
}

.globe-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  box-shadow: 0 0 10px currentColor;
}

.globe-note {
  margin: 0;
  font-size: 11.5px;
  color: var(--gray-600);
  text-align: center;
}

/* ------------------------------------------------------- how it works -- */

.hero {
  display: grid;
  grid-template-columns: 1fr minmax(260px, 360px);
  grid-gap: 32px;
  gap: 32px;
  align-items: center;
  padding: 8px 0 4px;
}

.hero-copy h1 {
  margin-bottom: 10px;
}

.flow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  grid-gap: 12px;
  gap: 12px;
  counter-reset: flow;
}

.flow-step {
  position: relative;
  overflow: hidden;
  display: flex;
  gap: 14px;
  padding: 16px 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  transition:
    border-color 0.18s ease,
    background 0.18s ease;
}

a.flow-step:hover {
  border-color: var(--line-strong);
  background: var(--ink-3);
}

.flow-step .flow-icon {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  background: rgba(214, 34, 42, 0.12);
  border: 1px solid rgba(214, 34, 42, 0.3);
  color: var(--red);
}

.flow-step.done .flow-icon {
  background: rgba(63, 196, 141, 0.12);
  border-color: rgba(63, 196, 141, 0.35);
  color: var(--green);
}

.flow-step.muted .flow-icon {
  background: rgba(245, 245, 243, 0.05);
  border-color: var(--line);
  color: var(--gray-600);
}

.flow-step .flow-body {
  min-width: 0;
}

.flow-step .flow-n {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--gray-600);
}

.flow-step h3 {
  margin: 3px 0 4px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
}

.flow-step p {
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--gray-500);
}

.flow-step .flow-go {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--red);
}

/* current step marker */
.flow-step.current {
  border-color: var(--red);
  background: linear-gradient(180deg, rgba(214, 34, 42, 0.09), transparent 70%);
}

.flow-step.current .flow-n {
  color: var(--red);
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------ publish steps -- */

.publish-steps {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  counter-reset: publish;
}

.publish-step {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  grid-gap: 12px;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.publish-step:last-child {
  border-bottom: 0;
}

.publish-n {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  font-size: 13px;
  font-weight: 600;
  color: var(--gray-500);
}

.publish-step.done .publish-n {
  border-color: var(--green);
  color: var(--green);
  background: rgba(63, 196, 141, 0.1);
}

.publish-body {
  min-width: 0;
}

.publish-body b {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
}

.publish-body small {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--gray-500);
  line-height: 1.6;
}

/* ------------------------------------------------------------- news -- */

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  grid-gap: 16px;
  gap: 16px;
}

.news-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}

.news-thumb {
  aspect-ratio: 9 / 16;
  background: linear-gradient(160deg, var(--ink-3), #000);
  display: grid;
  place-items: center;
  color: var(--gray-600);
  font-size: 12px;
  position: relative;
}

.news-thumb .news-duration {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.7);
  font-size: 11px;
  color: var(--off-white);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

.news-body {
  padding: 14px 16px;
}

.news-body h3 {
  margin: 0 0 6px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
}

/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/panel-jump.css ***!
  \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ============================================ the jump bar, on both long screens ==
 *
 * Lifted out of rehearsal.css when the fortune screen grew to thirteen sections
 * and needed the same bar. It lived beside the control page's own styles, so
 * mounting the component elsewhere gave a bar with no styling at all — the
 * markup present and unreadable, which is worse than absent.
 *
 * Loaded from the root layout because both screens use it and neither owns it.
 * Every colour falls back, so it holds up on a page that does not define the
 * control room's palette.
 *
 * What is NOT here: how far a jumped heading clears the bar. That depends on
 * what the heading is and how tall the page's own sticky furniture is, so each
 * screen sets its own `scroll-margin-top` next to the headings it owns.
 */

.panel-jump {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 5;
  display: grid;
  grid-gap: 0.5rem;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--p-line, rgb(245 245 243 / 12%));
  border-radius: 0.5rem;
  background: color-mix(in srgb, var(--bg, #0b0c0f) 92%, transparent);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
}

.panel-jump-find {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--p-line, rgb(245 245 243 / 12%));
  border-radius: 0.35rem;
  background: rgb(255 255 255 / 4%);
  color: rgb(245 245 243 / 55%);
}

.panel-jump-find input {
  flex: 1 1;
  min-width: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.8rem;
  outline: none;
}

.panel-jump-find input::placeholder { color: rgb(245 245 243 / 38%); }
.panel-jump-find input:focus { color: #f5f5f3; }

.panel-jump-find button {
  border: 0;
  background: none;
  color: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.2rem;
}

.panel-jump nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  max-height: 6.5rem;
  overflow-y: auto;
}

.panel-jump nav button {
  padding: 0.22rem 0.5rem;
  border: 1px solid var(--p-line, rgb(245 245 243 / 12%));
  border-radius: 0.3rem;
  background: rgb(255 255 255 / 3%);
  color: rgb(245 245 243 / 68%);
  font: inherit;
  font-size: 0.72rem;
  white-space: nowrap;
  cursor: pointer;
}

.panel-jump nav button:hover,
.panel-jump nav button:focus-visible {
  color: #f5f5f3;
  border-color: rgb(245 245 243 / 28%);
}

/* The panel the column is showing — colour and a weight change, because a
   chip that differs only in colour is a chip half the room cannot pick out. */
.panel-jump nav button.on {
  color: var(--red-bright, #e8323b);
  border-color: color-mix(in srgb, var(--red-bright, #e8323b) 45%, transparent);
  background: color-mix(in srgb, var(--red-bright, #e8323b) 12%, transparent);
  font-weight: 600;
}

.panel-jump-none {
  font-size: 0.74rem;
  color: rgb(245 245 243 / 45%);
}

@media (prefers-reduced-motion: reduce) {
  .panel-jump { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/*
 * A row of its own, not a cell.
 *
 * `.studio` is a three-column grid — left panels, stage, right panels — and
 * the bar went in as a plain first child, which made it a grid item: it took
 * the left column's cell and shoved all three columns one place along, so the
 * left panels landed under the stage, the stage landed on the right, and the
 * right panels wrapped onto a second row. The control room read as scrambled,
 * and the chips I measured all still worked, which is why measuring the
 * component said nothing about the page it had broken.
 *
 * Spanning every column puts it back where it was meant to be: a full-width
 * strip above the three columns, sticky to the top.
 */
.studio:has(> .panel-jump) {
  /*
   * Two rows: the bar takes what it needs, the columns take the rest.
   *
   * `.studio` is `min-height: 100vh` and the default `align-content: stretch`
   * splits spare height between its rows. With one row that was invisible;
   * the moment the bar made a second, an 83px strip was being drawn 430px
   * tall and the columns started a third of the way down the screen.
   *
   * Scoped with `:has` so the session studio, which has no bar and one row,
   * is not touched at all.
   */
  grid-template-rows: auto 1fr;
}

.studio > .panel-jump {
  grid-column: 1 / -1;
  align-self: start;
}

/*
 * Wide, the box and the chips share one line.
 *
 * The bar was drawn for a 340px column, where a search box above two rows of
 * chips is the only thing that fits. Spanning the studio it is five times that
 * wide, and stacking there wasted a strip of screen above the stage on a box
 * that needs a fifth of it. Side by side the whole bar is about one row tall.
 */
@media (min-width: 900px) {
  .panel-jump {
    grid-template-columns: minmax(180px, 240px) 1fr;
    align-items: start;
    gap: 0.6rem;
  }

  .panel-jump nav {
    max-height: 4.4rem;
  }
}

/*!**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/destiny-open.css ***!
  \**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ======================================== ASTRO FORM, opened right out ==
 *
 * The strip is the eight seconds a viewer gets; this is the minute somebody
 * cuts to and talks over. Two columns because the two halves answer different
 * questions — the graph is when, the list is who — and stacking them would put
 * the eleven below the bottom of a 1080 frame.
 *
 * Its own file, loaded from the root layout, because both the analysis screen
 * and the control page mount this card. Left in rehearsal.css it would have
 * been styled on one surface and bare on the other, which is the mistake the
 * jump bar already made once this week.
 *
 * Sized in cqw against the board so it holds its proportions at any output
 * size, the same way every other graphic on that screen does.
 */

.destiny-open {
  position: absolute;
  inset: 4% 3%;
  z-index: 24;
  display: flex;
  flex-direction: column;
  gap: 0.8cqw;
  padding: 1.4cqw 1.6cqw;
  border: 1px solid rgb(242 242 239 / 14%);
  border-radius: 0.8cqw;
  background: linear-gradient(160deg, rgb(11 12 15 / 97%), rgb(16 18 22 / 97%));
  box-shadow: 0 2cqw 6cqw -2cqw rgb(0 0 0 / 85%);
  color: #f2f2ef;
  font-family: var(--font-kanit, "Kanit"), system-ui, sans-serif;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  animation: destiny-open-in 260ms ease-out both;
}

@keyframes destiny-open-in {
  from { opacity: 0; transform: translateY(1.2cqw) scale(0.99); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .destiny-open { animation: none; }
}

.destiny-open > header {
  display: grid;
  grid-gap: 0.15cqw;
  gap: 0.15cqw;
  padding-bottom: 0.7cqw;
  border-bottom: 1px solid rgb(242 242 239 / 12%);
}

.destiny-open > header small {
  display: flex;
  align-items: center;
  gap: 0.4cqw;
  font-size: 0.85cqw;
  letter-spacing: 0.18em;
  color: rgb(242 242 239 / 55%);
}

.destiny-open > header b { font-size: 1.5cqw; letter-spacing: 0.04em; }

.destiny-open > header b i {
  font-style: normal;
  margin: 0 0.5cqw;
  color: rgb(242 242 239 / 45%);
}

.destiny-open > header u {
  text-decoration: none;
  font-size: 0.8cqw;
  color: rgb(242 242 239 / 45%);
}

.destiny-open .destiny-air-warn {
  margin: 0;
  padding: 0.4cqw 0.6cqw;
  border-left: 2px solid #e8a83e;
  background: rgb(232 168 62 / 9%);
  font-size: 0.82cqw;
  color: rgb(242 242 239 / 82%);
}

.destiny-open-body {
  flex: 1 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  grid-gap: 1.2cqw;
  gap: 1.2cqw;
}

/* ------------------------------------------------------------- the graph -- */

.destiny-open .run { display: grid; grid-gap: 0.5cqw; gap: 0.5cqw; align-content: start; }

.destiny-open .run-head { display: flex; align-items: baseline; gap: 0.7cqw; }

.destiny-open .run-head small {
  display: flex;
  align-items: center;
  gap: 0.3cqw;
  font-size: 0.78cqw;
  letter-spacing: 0.14em;
  color: rgb(242 242 239 / 55%);
}

.destiny-open .run-head b { font-size: 1cqw; }

/* Running, so the minute reads as moving rather than as a static caption. */
.destiny-open .run-head b.live { color: #e8323b; }

.destiny-open .run-head .now { margin-left: auto; font-size: 1.1cqw; }
.destiny-open .run-head .now i { font-style: normal; font-weight: 700; }
.destiny-open .run-head .now i.us { color: #e8323b; }
.destiny-open .run-head .now i.them { color: #3fbf8f; }
.destiny-open .run-head .now u {
  text-decoration: none;
  margin: 0 0.3cqw;
  color: rgb(242 242 239 / 35%);
}

.destiny-open .run-chart {
  width: 100%;
  height: auto;
  border: 1px solid rgb(242 242 239 / 10%);
  border-radius: 0.3cqw;
  background: rgb(255 255 255 / 3%);
}

.destiny-open .run-chart .grid { stroke: rgb(242 242 239 / 8%); stroke-width: 1; }
.destiny-open .run-chart .mid { stroke: rgb(242 242 239 / 22%); stroke-width: 1; }

.destiny-open .run-chart .turn {
  stroke: #e8a83e;
  stroke-width: 1;
  stroke-dasharray: 4 4;
  opacity: 0.65;
}

.destiny-open .run-chart path {
  fill: none;
  stroke-width: 2.2;
  stroke-linejoin: round;
}

.destiny-open .run-chart path.us { stroke: #e8323b; }
.destiny-open .run-chart path.them { stroke: #3fbf8f; }
.destiny-open .run-chart .dot { fill: #e8323b; }
.destiny-open .run-chart .cursor { stroke: #f2f2ef; stroke-width: 1.4; opacity: 0.9; }

.destiny-open .run-chart .axis {
  fill: rgb(242 242 239 / 40%);
  font-size: 10px;
  text-anchor: end;
}

.destiny-open .run-chart .axis.foot { text-anchor: middle; }

.destiny-open .run-windows { display: flex; gap: 0.2cqw; }

.destiny-open .run-windows span {
  display: grid;
  grid-gap: 0.05cqw;
  gap: 0.05cqw;
  padding: 0.3cqw 0.2cqw;
  border-radius: 0.2cqw;
  text-align: center;
  background: rgb(255 255 255 / 4%);
  border-top: 2px solid transparent;
}

.destiny-open .run-windows span.us { border-top-color: #e8323b; }
.destiny-open .run-windows span.them { border-top-color: #3fbf8f; }
.destiny-open .run-windows span.now { background: rgb(255 255 255 / 12%); }
.destiny-open .run-windows u { text-decoration: none; font-size: 0.82cqw; }

.destiny-open .run-windows i {
  font-style: normal;
  font-size: 0.68cqw;
  color: rgb(242 242 239 / 45%);
}

.destiny-open .run-note {
  font-style: normal;
  font-size: 0.72cqw;
  line-height: 1.5;
  color: rgb(242 242 239 / 48%);
}

/* ---------------------------------------------------------- the eleven --- */

.destiny-open .squad {
  display: grid;
  grid-gap: 0.4cqw;
  gap: 0.4cqw;
  min-height: 0;
  align-content: start;
}

.destiny-open .squad > small {
  display: flex;
  align-items: center;
  gap: 0.3cqw;
  font-size: 0.78cqw;
  letter-spacing: 0.14em;
  color: rgb(242 242 239 / 55%);
}

.destiny-open .squad ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 0.25cqw;
  gap: 0.25cqw;
  overflow: hidden;
}

.destiny-open .squad li {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 2.4fr) auto minmax(0, 1.5fr) minmax(0, 1.6fr);
  align-items: center;
  grid-gap: 0.5cqw;
  gap: 0.5cqw;
  padding: 0.28cqw 0.4cqw;
  border-radius: 0.25cqw;
  background: rgb(255 255 255 / 3.5%);
}

.destiny-open .who {
  display: flex;
  align-items: center;
  gap: 0.4cqw;
  min-width: 0;
}

.destiny-open .face {
  width: 2.1cqw;
  height: 2.1cqw;
  border-radius: 50%;
  object-fit: cover;
  background: rgb(255 255 255 / 8%);
  flex: none;
}

.destiny-open .face.blank {
  display: grid;
  place-items: center;
  font-size: 0.8cqw;
  color: rgb(242 242 239 / 45%);
}

.destiny-open .named { display: grid; min-width: 0; }

.destiny-open .named b {
  font-size: 0.86cqw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.destiny-open .named i {
  font-style: normal;
  font-size: 0.66cqw;
  color: rgb(242 242 239 / 42%);
}

.destiny-open .chart { display: flex; gap: 0.45cqw; }

.destiny-open .pillar {
  display: flex;
  align-items: center;
  gap: 0.15cqw;
  padding: 0.15cqw 0.3cqw;
  border-radius: 0.2cqw;
  background: rgb(0 0 0 / 28%);
}

.destiny-open .pillar > small {
  font-size: 0.6cqw;
  color: rgb(242 242 239 / 35%);
  margin-right: 0.15cqw;
}

/* One character, said three ways. Stacked, because the hanzi is what the eye
   lands on and the readings are where it goes next. */
.destiny-open .say { display: grid; justify-items: center; line-height: 1.05; }
.destiny-open .say b { font-size: 1cqw; }

.destiny-open .say i {
  font-style: normal;
  font-size: 0.58cqw;
  color: rgb(242 242 239 / 62%);
}

.destiny-open .say u {
  text-decoration: none;
  font-size: 0.58cqw;
  color: rgb(242 242 239 / 45%);
}

.destiny-open .say em {
  font-style: normal;
  font-size: 0.52cqw;
  color: rgb(242 242 239 / 32%);
}

.destiny-open .say.big b { font-size: 1.4cqw; color: #e8a83e; }

.destiny-open .master {
  display: grid;
  justify-items: center;
  padding: 0.15cqw 0.35cqw;
  border-left: 1px solid rgb(242 242 239 / 12%);
}

.destiny-open .master > small {
  font-size: 0.58cqw;
  color: rgb(242 242 239 / 35%);
}

.destiny-open .marks { display: flex; gap: 0.35cqw; justify-content: flex-end; }
.destiny-open .marks i { display: grid; justify-items: center; font-style: normal; }

.destiny-open .marks u {
  text-decoration: none;
  font-size: 0.56cqw;
  color: rgb(242 242 239 / 38%);
  display: flex;
  align-items: center;
  gap: 0.1cqw;
}

.destiny-open .marks b { font-size: 0.9cqw; }
.destiny-open .marks .warn b { color: #e8a83e; }

.destiny-open > footer {
  padding-top: 0.5cqw;
  border-top: 1px solid rgb(242 242 239 / 12%);
  font-size: 0.68cqw;
  color: rgb(242 242 239 / 42%);
}

/* ----------------------------------- the layers under the eight characters -- */

/*
 * 十二長生, 用神, 空亡 and 神煞, as chips.
 *
 * Chips rather than another stack of stacked characters: the pillars already
 * carry four lines apiece and a fifth column built the same way would turn a
 * row into a wall. These are findings — short, few, and either present or not.
 */
.destiny-open .layers {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2cqw;
  justify-content: flex-end;
}

.destiny-open .layers i {
  display: flex;
  align-items: baseline;
  gap: 0.15cqw;
  padding: 0.1cqw 0.28cqw;
  border-radius: 0.18cqw;
  border: 1px solid rgb(242 242 239 / 12%);
  background: rgb(0 0 0 / 26%);
  font-style: normal;
  white-space: nowrap;
}

.destiny-open .layers b { font-size: 0.72cqw; }
.destiny-open .layers u {
  text-decoration: none;
  font-size: 0.58cqw;
  color: rgb(242 242 239 / 48%);
}

/* Where the day master stands in its own branch. */
.destiny-open .layers .stage b { color: #9ab8d8; }

/*
 * Strong and weak are not good and bad.
 *
 * They are which way the chart leans, and a reader acts on them in opposite
 * directions — so they are told apart by hue and by the word, never by hue
 * alone, and neither is painted in the colour this board uses for a warning.
 */
.destiny-open .layers .wants.strong b { color: #d0a15e; }
.destiny-open .layers .wants.weak b { color: #7fb0c8; }
.destiny-open .layers .wants.even b { color: rgb(242 242 239 / 60%); }

/* Whether the kickoff brings what the chart wants. Signed, because +40 and
   −40 are opposite readings of one magnitude. */
.destiny-open .layers .wants u.fit { color: #4fae86; }
.destiny-open .layers .wants u.unfit { color: #d2705f; }

/* 空亡 — a branch the decade left without a stem. */
.destiny-open .layers .empty {
  border-color: rgb(242 242 239 / 22%);
  border-style: dashed;
}
.destiny-open .layers .empty b { color: rgb(242 242 239 / 55%); }

/* 神煞 — the auxiliary stars, which are notes and not scores. */
.destiny-open .layers .star b {
  color: #c9a227;
  font-size: 0.68cqw;
}

/*!**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/board/board-plan.css ***!
  \**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ================================================ แผนทีม — the panel's own bits ==
 *
 * The revert control and the heading it sits on. Its own file rather than more
 * lines on the end of an eleven-thousand-line stylesheet, and loaded from the
 * root layout because the plan tab is mounted on both the analysis screen and
 * the control page.
 */

.board-panel-body .plan-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

/*
 * The way out of a locked box.
 *
 * Quiet until wanted: it appears only on a phase that is actually holding text
 * no mentality wrote, so it is never a button sitting there with nothing to
 * undo. Sized and coloured below the heading beside it, because it is a repair
 * and not a thing anybody should be drawn to.
 */
.board-panel-body .plan-revert {
  padding: 0.1rem 0.4rem;
  border: 1px solid rgb(245 245 243 / 18%);
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 4%);
  color: rgb(245 245 243 / 60%);
  font: inherit;
  font-size: 0.68rem;
  line-height: 1.5;
  white-space: nowrap;
  cursor: pointer;
}

.board-panel-body .plan-revert:hover,
.board-panel-body .plan-revert:focus-visible {
  color: #f5f5f3;
  border-color: rgb(245 245 243 / 34%);
  background: rgb(255 255 255 / 9%);
}

/* A button that cannot do anything says so by looking like it. Dimmed rather
   than removed: a control that disappears is one somebody hunts for. */
.board-panel-row button:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

/*!**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/source-badge.css ***!
  \**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ==================================== where a thing came from, as a chip ==
 *
 * Loaded from the root layout because both the analysis screen and the control
 * page show it — the mistake the jump bar and the ASTRO FORM card each made
 * once already, where a component reached one surface styled and the other
 * bare.
 *
 * Every state carries a word as well as a colour. A badge told apart by hue
 * alone is a badge half the room cannot read, and this one exists to answer
 * "can I trust what I am looking at", which is the last thing anybody should
 * have to guess at.
 */

.source-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.2em 0.55em;
  border-radius: 0.25em;
  border: 1px solid currentColor;
  font-size: 0.72rem;
  line-height: 1.4;
  letter-spacing: 0.06em;
  white-space: nowrap;
  background: rgb(0 0 0 / 45%);
}

.source-badge i {
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.source-badge b {
  font-weight: 700;
}

.source-badge u {
  text-decoration: none;
  font-weight: 400;
  letter-spacing: 0;
  opacity: 0.75;
}

/* Live is quiet and confident. */
.source-badge.live {
  color: #4fae86;
}

/* Stale asks to be noticed: it is from the provider and it is not now. */
.source-badge.stale {
  color: #d9a441;
}

/* Hand-made is not a fault, so it is neutral rather than a warning. */
.source-badge.manual {
  color: rgb(242 242 239 / 62%);
}

/* A dated snapshot: neither live nor typed by anyone. */
.source-badge.snapshot {
  color: #7fa8c8;
}

/*
 * Measured off the board rather than off the pitch.
 *
 * Given the same neutral ink as a hand-made arrangement, because that is what
 * it is: the number is exact, and its subject is a drawing somebody made. It
 * must never read as confidently as `live`, however fresh the arrangement is.
 *
 * The dotted underline is the part that survives a colourblind reader, a
 * greyscale print and a compressed video frame — the three ways a colour-only
 * distinction quietly stops existing.
 */
.source-badge.arranged {
  color: rgb(242 242 239 / 62%);
  -webkit-text-decoration: underline dotted currentColor 1px;
          text-decoration: underline dotted currentColor 1px;
  text-underline-offset: 0.25em;
}

/*
 * An estimate.
 *
 * Warm, like `stale`, because both mean "read this before you say it out
 * loud" — and italic so the difference is not carried by hue alone.
 */
.source-badge.inferred {
  color: #d9a441;
  font-style: italic;
}

/*
 * On the picture, in the corner.
 *
 * Sized in cqw like every other graphic on that board so it holds its
 * proportion at any output size, and pinned bottom-left where a score bar and
 * a name strip are not.
 */
.board-screen-teams > .source-badge.on-pitch {
  position: absolute;
  left: 1.4cqw;
  bottom: 1.4cqw;
  z-index: 26;
  font-size: 0.75cqw;
  padding: 0.25cqw 0.6cqw;
  border-radius: 0.25cqw;
  pointer-events: none;
}

/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/match-data.css ***!
  \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ================================== what the provider knows, on both screens ==
 *
 * Loaded from the root layout because the control page and the analysis screen
 * both mount these — the mistake three components in this app have each made
 * once, where one surface got the styling and the other got bare markup.
 */

/* ------------------------------------------------------- the timeline ----- */

.match-timeline {
  display: grid;
  grid-gap: 0.5rem;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.match-timeline .tl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.match-timeline .tl-head small {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: rgb(245 245 243 / 55%);
}

/*
 * The strip is a minute axis, so everything on it is positioned by time.
 *
 * Tall enough for a mark to be a target on a touchscreen and no taller: this
 * sits in a column that already holds twenty panels.
 */
.match-timeline .tl-strip {
  position: relative;
  height: 2.6rem;
  margin: 0.2rem 0 0.9rem;
  border-radius: 0.3rem;
  background: linear-gradient(
    to bottom,
    rgb(255 255 255 / 3%),
    rgb(255 255 255 / 6%)
  );
  border: 1px solid rgb(245 245 243 / 10%);
}

/* Half time: the one boundary every reading of a match turns on. */
.match-timeline .tl-half {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgb(245 245 243 / 22%);
}

/* Where the board is now. */
.match-timeline .tl-now {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: #f5f5f3;
  box-shadow: 0 0 6px rgb(255 255 255 / 45%);
}

.match-timeline .tl-mark {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 50%;
  background: #14161a;
  color: rgb(245 245 243 / 70%);
  font-size: 0.7rem;
  cursor: pointer;
  padding: 0;
}

.match-timeline .tl-mark:hover,
.match-timeline .tl-mark:focus-visible {
  border-color: rgb(245 245 243 / 45%);
  color: #f5f5f3;
  z-index: 2;
}

/*
 * Told apart by shape and colour together.
 *
 * A goal and a booking that differ only in hue are two marks half the room
 * reads as one, and this strip is scanned rather than studied.
 */
.match-timeline .tl-mark.goal,
.match-timeline .tl-mark.penalty {
  background: #2c6e49;
  color: #eafff3;
  width: 1.7rem;
  height: 1.7rem;
}

.match-timeline .tl-mark.own_goal {
  background: #6e2c2c;
  color: #ffeaea;
}

.match-timeline .tl-mark.yellow { color: #e8c53e; }
.match-timeline .tl-mark.red { color: #e8323b; }
.match-timeline .tl-mark.substitution { color: #7fa8c8; }
.match-timeline .tl-mark.var { color: rgb(245 245 243 / 50%); }

/* Which side, by which half of the strip the mark leans into. */
.match-timeline .tl-mark.home { margin-top: -0.45rem; }
.match-timeline .tl-mark.away { margin-top: 0.45rem; }

.match-timeline .tl-axis {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1.1rem;
  height: 1rem;
}

.match-timeline .tl-axis u {
  position: absolute;
  transform: translateX(-50%);
  text-decoration: none;
  font-size: 0.62rem;
  color: rgb(245 245 243 / 38%);
}

/* --------------------------------------------------------- the list ------- */

.match-timeline .tl-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 1px;
  gap: 1px;
  max-height: 12rem;
  overflow-y: auto;
}

.match-timeline .tl-list button {
  width: 100%;
  display: grid;
  grid-template-columns: 2.6rem 1.2rem 1fr auto;
  align-items: center;
  grid-gap: 0.4rem;
  gap: 0.4rem;
  padding: 0.28rem 0.4rem;
  border: 0;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 3%);
  color: rgb(245 245 243 / 78%);
  font: inherit;
  font-size: 0.76rem;
  text-align: left;
  cursor: pointer;
}

.match-timeline .tl-list button:hover,
.match-timeline .tl-list button:focus-visible {
  background: rgb(255 255 255 / 8%);
  color: #f5f5f3;
}

.match-timeline .tl-list b {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 55%);
}

.match-timeline .tl-list i { font-style: normal; }
.match-timeline .tl-list em { font-style: normal; color: rgb(245 245 243 / 45%); }

.match-timeline .tl-list u {
  text-decoration: none;
  font-size: 0.66rem;
  color: rgb(245 245 243 / 40%);
}

.match-timeline .tl-list li.goal button,
.match-timeline .tl-list li.penalty button { color: #7fd9a8; }
.match-timeline .tl-list li.red button { color: #ff8a90; }

.panel-note.warn {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  color: #e8a83e;
}

/* ---------------------------------------------------- the match statistics -- */

/*
 * Both sides of every figure, side by side.
 *
 * A possession number alone invites the reader to supply the other half, and
 * they supply it wrong whenever the two do not add to a hundred — which is
 * most of them. The bar is the comparison; the two numbers are the fact, and
 * neither is left to be inferred from the other.
 */
.match-stats {
  display: grid;
  grid-gap: 0.3rem;
  gap: 0.3rem;
  margin: 0.6rem 0;
}

.match-stats .stat-row {
  display: grid;
  grid-template-columns: 3.2rem 1fr 3.2rem;
  align-items: center;
  grid-gap: 0.5rem;
  gap: 0.5rem;
  font-size: 0.78rem;
}

.match-stats .stat-row > b {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.match-stats .stat-row > span { display: grid; grid-gap: 0.2rem; gap: 0.2rem; }

.match-stats .stat-row u {
  text-decoration: none;
  font-size: 0.68rem;
  text-align: center;
  color: rgb(245 245 243 / 45%);
}

.match-stats .stat-row i {
  display: block;
  height: 0.35rem;
  border-radius: 0.2rem;
  overflow: hidden;
  /* The away side is the whole bar; the home side is painted over it, so the
     two always account for exactly the width and never leave a gap that reads
     as a third value. */
  background: #3fbf8f;
}

.match-stats .stat-row em.home {
  display: block;
  height: 100%;
  background: #e8323b;
}

/* -------------------------------------------------------- who cannot play -- */

.absence-list { display: grid; grid-gap: 0.35rem; gap: 0.35rem; margin-top: 0.7rem; }

.absence-list ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 1px;
  gap: 1px;
  max-height: 11rem;
  overflow-y: auto;
}

.absence-list li {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-gap: 0.5rem;
  gap: 0.5rem;
  padding: 0.26rem 0.4rem;
  border-radius: 0.25rem;
  background: rgb(232 50 59 / 8%);
  font-size: 0.76rem;
}

.absence-list li b { font-weight: 600; }
.absence-list li span { color: rgb(245 245 243 / 55%); font-size: 0.7rem; }

/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/league-standing.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* =============================== the table and the goal windows, both screens ==
 *
 * Loaded from the root layout: the control page and the analysis screen both
 * mount these components, and every earlier one that shipped its styling with
 * only one of them arrived on the other as bare markup.
 */

/* -------------------------------------------------------------- the table -- */

.league-table {
  display: grid;
  grid-gap: 0.4rem;
  gap: 0.4rem;
  margin-top: 0.6rem;
}

.league-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.76rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

.league-table thead th {
  padding: 0.2rem 0.3rem;
  text-align: right;
  font-weight: 500;
  font-size: 0.64rem;
  letter-spacing: 0.06em;
  color: rgb(245 245 243 / 40%);
  border-bottom: 1px solid rgb(245 245 243 / 12%);
}

.league-table thead th.club { text-align: left; }
.league-table thead th.form { text-align: center; }

.league-table tbody td {
  padding: 0.22rem 0.3rem;
  text-align: right;
  color: rgb(245 245 243 / 74%);
  border-bottom: 1px solid rgb(245 245 243 / 5%);
}

.league-table tbody td.club {
  text-align: left;
  color: #f5f5f3;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.league-table tbody td.rank { color: rgb(245 245 243 / 40%); }
.league-table tbody td.goals { color: rgb(245 245 243 / 50%); }
.league-table tbody td.points { font-weight: 700; color: #f5f5f3; }

/*
 * Our own row, marked by weight and a rule rather than by colour alone.
 *
 * A tinted row is the first thing lost to a projector, a stream's colour
 * handling, or anybody who does not see red.
 */
.league-table tbody tr.ours td {
  background: rgb(255 255 255 / 6%);
  color: #f5f5f3;
  font-weight: 600;
}

.league-table tbody tr.ours td:first-child {
  box-shadow: inset 2px 0 0 #e8323b;
}

/* The rows left out, said once rather than squeezed in. */
.league-table tbody tr.gap td {
  text-align: center;
  color: rgb(245 245 243 / 25%);
  letter-spacing: 0.3em;
  padding: 0.05rem;
}

/* ------------------------------------------------------------ form dots ---- */

.form-dots {
  display: inline-flex;
  gap: 0.15rem;
  justify-content: center;
}

.form-dots.empty { color: rgb(245 245 243 / 25%); }

/* Letter and colour together: five identical circles in three hues is a row
   nobody can read at a glance, and the letter survives any screen. */
.form-dots i {
  display: grid;
  place-items: center;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 0.2rem;
  font-style: normal;
  font-size: 0.58rem;
  font-weight: 700;
  color: #0b0c0e;
  background: rgb(245 245 243 / 30%);
}

.form-dots i.w { background: #3fbf8f; }
.form-dots i.d { background: #b9b9b4; }
.form-dots i.l { background: #e8323b; color: #fff; }

/* --------------------------------------------------------- goal windows ---- */

.goal-windows {
  display: grid;
  grid-gap: 0.45rem;
  gap: 0.45rem;
  margin-top: 0.7rem;
}

/*
 * Two bars a slice, growing away from a shared centre line.
 *
 * Scored above and conceded below, so the comparison is a silhouette rather
 * than two numbers to hold in the head at once.
 */
.goal-windows .gw-chart {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  grid-gap: 0.25rem;
  gap: 0.25rem;
  align-items: center;
}

.goal-windows .gw-slice {
  display: grid;
  grid-template-rows: 3.2rem auto 3.2rem;
  align-items: end;
  justify-items: center;
  grid-gap: 0.15rem;
  gap: 0.15rem;
}

.goal-windows .gw-slice b {
  display: block;
  width: 100%;
  min-height: 2px;
  border-radius: 0.15rem 0.15rem 0 0;
  position: relative;
}

.goal-windows .gw-slice b.scored {
  align-self: end;
  background: #3fbf8f;
}

.goal-windows .gw-slice b.conceded {
  align-self: start;
  border-radius: 0 0 0.15rem 0.15rem;
  background: #e8323b;
}

/* The count on the bar, because a bar without its number is a shape somebody
   has to estimate. */
.goal-windows .gw-slice b em {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-style: normal;
  font-size: 0.6rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 80%);
}

.goal-windows .gw-slice b.scored em { top: -0.85rem; }
.goal-windows .gw-slice b.conceded em { bottom: -0.85rem; }

.goal-windows .gw-slice u {
  text-decoration: none;
  font-size: 0.6rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 45%);
  padding: 0.05rem 0;
  border-top: 1px solid rgb(245 245 243 / 10%);
  border-bottom: 1px solid rgb(245 245 243 / 10%);
  width: 100%;
  text-align: center;
}

.goal-windows .gw-legend {
  margin: 0.9rem 0 0;
  font-size: 0.68rem;
  color: rgb(245 245 243 / 45%);
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-wrap: wrap;
}

.goal-windows .gw-legend i {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 0.15rem;
}

.goal-windows .gw-legend i.scored { background: #3fbf8f; }
.goal-windows .gw-legend i.conceded { background: #e8323b; }

/* ------------------------------------------------- and on the big screen --- */

/*
 * On the analysis screen everything is sized to the board rather than to the
 * browser, because that screen is captured at whatever size the desk gives it
 * and rem there is a number somebody else chose.
 */
.board-screen .league-table table { font-size: 1.35cqw; }
.board-screen .league-table thead th { font-size: 1.1cqw; }
.board-screen .league-table tbody td { padding: 0.35cqw 0.5cqw; }
.board-screen .form-dots i {
  width: 1.7cqw;
  height: 1.7cqw;
  font-size: 1cqw;
  border-radius: 0.3cqw;
}
.board-screen .goal-windows .gw-slice { grid-template-rows: 5cqw auto 5cqw; }
.board-screen .goal-windows .gw-slice u { font-size: 1cqw; }
.board-screen .goal-windows .gw-slice b em { font-size: 1cqw; }
.board-screen .goal-windows .gw-legend { font-size: 1.1cqw; }

/*
 * Where it sits on the analysis screen.
 *
 * In the same margin column as the crests and the map, in flow beneath them —
 * not laid over the first grid cell, which is how two earlier panels on this
 * screen ended up on top of each other.
 */
.board-standing {
  display: grid;
  grid-gap: 0.5cqw;
  gap: 0.5cqw;
  padding: 1cqw 1.2cqw;
  border-radius: 0.6cqw;
  background: rgb(11 12 14 / 72%);
  border: 1px solid rgb(245 245 243 / 10%);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

.board-standing .league-table,
.board-standing .goal-windows { margin-top: 0; }

/*
 * It has to fit inside the frame that is going out.
 *
 * Measured on the first attempt: the panel came out 876px tall in a column
 * with 260px left, and pushed that column 616px past the bottom of the board —
 * so the table was cast, and cast correctly, and could not be seen. A graphic
 * that leaves the frame is the same as a graphic that never arrived.
 *
 * So the column is capped at the screen, and this panel takes what is left
 * rather than deciding how tall the margin is.
 */
.board-screen:has(.board-standing) .board-screen-teams {
  align-self: stretch;
  max-height: 100%;
  min-height: 0;
}

.board-standing {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

/*
 * And the map stands down while it is up.
 *
 * Both live in the same margin, both are the same kind of thing — context
 * beside the pitch — and two of them stacked is what made the column too tall
 * in the first place. The table is the thing the operator just asked for.
 */
.board-screen:has(.board-standing) .grounds-map { display: none; }

/*
 * A graphic that is clipped is a graphic nobody can read the end of, so this
 * one is checked rather than trusted: with the table and the chart both up,
 * 283px of the panel was being cut away silently. One at a time now, and each
 * has the whole column.
 */

/*
 * Sized to the column it is actually in.
 *
 * The screen-wide scale above is for a graphic that has the width of the
 * board; this one has a fifth of it. Measured at the larger size the table
 * needed 582px in 489 and lost the bottom row and a half without saying so.
 */
.board-screen .board-standing .league-table table { font-size: 1cqw; }
.board-screen .board-standing .league-table thead th { font-size: 0.85cqw; }
.board-screen .board-standing .league-table tbody td { padding: 0.25cqw 0.4cqw; }
.board-screen .board-standing .form-dots i {
  width: 1.3cqw;
  height: 1.3cqw;
  font-size: 0.78cqw;
}
.board-screen .board-standing .goal-windows .gw-slice {
  grid-template-rows: 4cqw auto 4cqw;
}
.board-screen .board-standing .goal-windows .gw-legend { font-size: 0.9cqw; }

/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/match-insight.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ================ the ratings and the model, on the control page and on air ==
 *
 * From the root layout, like every other pair that has to reach both screens.
 */

/* ------------------------------------------------------ player ratings ---- */

.player-ratings { display: grid; grid-gap: 0.5rem; gap: 0.5rem; margin-top: 0.7rem; }

.player-ratings .pr-side h6 {
  margin: 0.3rem 0 0.2rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: rgb(245 245 243 / 45%);
}

.player-ratings ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 1px;
  gap: 1px;
}

.player-ratings li {
  display: grid;
  grid-template-columns: 2.4rem 1fr auto;
  align-items: center;
  grid-gap: 0.45rem;
  gap: 0.45rem;
  padding: 0.22rem 0.35rem;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 3%);
  font-size: 0.76rem;
}

/*
 * The rating carries its band in a shade AND in where it sits on the scale,
 * never in hue alone — this list is scanned, and three greens in a column is
 * a ranking nobody can read off.
 */
.player-ratings .rating {
  display: grid;
  place-items: center;
  padding: 0.1rem 0;
  border-radius: 0.2rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: #0b0c0e;
  background: rgb(245 245 243 / 30%);
}

.player-ratings .rating.high { background: #3fbf8f; }
.player-ratings .rating.mid { background: #b9b9b4; }
.player-ratings .rating.low { background: #e8a83e; }
.player-ratings .rating.none {
  background: transparent;
  color: rgb(245 245 243 / 30%);
  box-shadow: inset 0 0 0 1px rgb(245 245 243 / 15%);
}

.player-ratings .who {
  color: #f5f5f3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-ratings em {
  font-style: normal;
  font-size: 0.68rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 45%);
  white-space: nowrap;
}

/* ------------------------------------------------------------ the model --- */

.forecast-card { display: grid; grid-gap: 0.4rem; gap: 0.4rem; margin-top: 0.7rem; }

/*
 * Three shares of one bar rather than three numbers.
 *
 * The three always account for the whole width, so a viewer reads the shape
 * instead of adding percentages up to check whether they are being shown all
 * of it.
 */
.forecast-card .fc-three {
  display: flex;
  height: 1.5rem;
  border-radius: 0.25rem;
  overflow: hidden;
  font-size: 0.7rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.forecast-card .fc-three span {
  display: grid;
  place-items: center;
  min-width: 0;
  overflow: hidden;
  color: #0b0c0e;
}

.forecast-card .fc-three .home { background: #e8323b; color: #fff; }
.forecast-card .fc-three .draw { background: #b9b9b4; }
.forecast-card .fc-three .away { background: #7fa8c8; }

.forecast-card .fc-names {
  margin: 0;
  display: flex;
  justify-content: space-between;
  gap: 0.4rem;
  font-size: 0.7rem;
  color: rgb(245 245 243 / 65%);
}

.forecast-card .fc-names i {
  font-style: normal;
  color: rgb(245 245 243 / 40%);
}

.forecast-card .fc-axes { display: grid; grid-gap: 0.22rem; gap: 0.22rem; margin-top: 0.2rem; }

.forecast-card .fc-axis {
  display: grid;
  grid-template-columns: 6.5rem 1fr 3.4rem;
  align-items: center;
  grid-gap: 0.4rem;
  gap: 0.4rem;
  font-size: 0.7rem;
}

.forecast-card .fc-axis u {
  text-decoration: none;
  color: rgb(245 245 243 / 55%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.forecast-card .fc-axis i {
  display: block;
  height: 0.3rem;
  border-radius: 0.2rem;
  overflow: hidden;
  /* Away is the whole bar, home painted over it: the two always account for
     the width and never leave a gap that reads as a third value. */
  background: #7fa8c8;
}

.forecast-card .fc-axis em {
  display: block;
  height: 100%;
  background: #e8323b;
}

.forecast-card .fc-axis span {
  text-align: right;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 45%);
}

/* -------------------------------------------------- and on the big screen -- */

.board-screen .board-standing .player-ratings li {
  grid-template-columns: 2.8cqw 1fr auto;
  font-size: 0.95cqw;
  padding: 0.2cqw 0.4cqw;
}
.board-screen .board-standing .player-ratings { gap: 0.3cqw; }
.board-screen .board-standing .player-ratings .pr-side h6 { margin: 0.2cqw 0 0.1cqw; }
.board-screen .board-standing .player-ratings em { font-size: 0.85cqw; }
.board-screen .board-standing .player-ratings .pr-side h6 { font-size: 0.85cqw; }
.board-screen .board-standing .forecast-card .fc-three {
  height: 2.2cqw;
  font-size: 1cqw;
}
.board-screen .board-standing .forecast-card .fc-names { font-size: 0.95cqw; }
.board-screen .board-standing .forecast-card .fc-axis {
  grid-template-columns: 8cqw 1fr 4cqw;
  font-size: 0.9cqw;
}

/*
 * The caveat is for the person working the screen, not for the picture.
 *
 * "คะแนนเป็นของผู้ให้บริการ" is a sentence the operator needs once; on air the
 * badge already says where the numbers came from, and two lines of small print
 * in a margin column is two lines that pushed the last two players out of
 * frame. Measured: 261px of the panel was being clipped away.
 */
.board-screen .board-standing .player-ratings > .panel-note,
.board-screen .board-standing .forecast-card > .panel-note { display: none; }

/* ------------------------------------------------------ the day's allowance -- */

.quota-meter {
  display: grid;
  grid-gap: 0.3rem;
  gap: 0.3rem;
  margin: 0.5rem 0 0.9rem;
  padding: 0.5rem 0.6rem;
  border-radius: 0.35rem;
  background: rgb(255 255 255 / 4%);
  border: 1px solid rgb(245 245 243 / 8%);
}

.quota-meter .qm-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.quota-meter small {
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  color: rgb(245 245 243 / 45%);
}

.quota-meter b {
  font-size: 0.8rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: #f5f5f3;
}

.quota-meter i {
  display: block;
  height: 0.35rem;
  border-radius: 0.2rem;
  overflow: hidden;
  background: rgb(245 245 243 / 12%);
}

.quota-meter em { display: block; height: 100%; background: #3fbf8f; }

/* Loud only when it is worth being loud about — a meter that is orange all day
   is one nobody reads on the day it matters. */
.quota-meter.mid em { background: #e8a83e; }
.quota-meter.high em { background: #e8323b; }
.quota-meter.high { border-color: rgb(232 50 59 / 45%); }

.quota-meter p {
  margin: 0;
  font-size: 0.66rem;
  line-height: 1.4;
  color: rgb(245 245 243 / 42%);
}

/* ------------------------------------------------------------ following live -- */

/*
 * The clock, the score and how many changes each side has made.
 *
 * Three facts, because they are the three an operator is asked for out loud
 * while a match is running and the three nobody can read off a pitch.
 */
.live-strip {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  grid-gap: 0.7rem;
  gap: 0.7rem;
  margin: 0.6rem 0;
  padding: 0.5rem 0.7rem;
  border-radius: 0.35rem;
  background: rgb(255 255 255 / 4%);
  border: 1px solid rgb(245 245 243 / 10%);
}

/* A match in play is marked by a border, not only by a colour that a stream's
   handling can flatten. */
.live-strip.running { border-color: rgb(63 191 143 / 55%); }

.live-strip .ls-clock { display: grid; justify-items: center; }

.live-strip .ls-clock b {
  font-size: 1.15rem;
  font-weight: 700;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: #f5f5f3;
  line-height: 1.1;
}

.live-strip.running .ls-clock b { color: #3fbf8f; }

.live-strip u,
.live-strip .ls-subs u {
  text-decoration: none;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: rgb(245 245 243 / 45%);
}

.live-strip .ls-score {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-width: 0;
}

.live-strip .ls-score span {
  font-size: 0.76rem;
  color: rgb(245 245 243 / 70%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-strip .ls-score b {
  font-size: 1.1rem;
  font-weight: 700;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: #f5f5f3;
}

.live-strip .ls-subs { display: grid; justify-items: center; }

.live-strip .ls-subs b {
  font-size: 0.85rem;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 78%);
}

/* Everything in play right now, so a studio is not limited to its own match. */
.live-now { display: grid; grid-gap: 0.35rem; gap: 0.35rem; margin: 0.5rem 0 0.8rem; }

.live-now ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 1px;
  gap: 1px;
  max-height: 12rem;
  overflow-y: auto;
}

.live-now li button {
  width: 100%;
  display: grid;
  grid-gap: 0.1rem;
  gap: 0.1rem;
  padding: 0.3rem 0.45rem;
  border: 0;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 3%);
  color: rgb(245 245 243 / 78%);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.live-now li button:hover,
.live-now li button:focus-visible {
  background: rgb(255 255 255 / 8%);
  color: #f5f5f3;
}

/* The one being followed, marked by a rule rather than by hue alone. */
.live-now li.on button {
  background: rgb(255 255 255 / 9%);
  box-shadow: inset 2px 0 0 #3fbf8f;
  color: #f5f5f3;
}

.live-now b { font-size: 0.76rem; font-weight: 600; }

.live-now u {
  text-decoration: none;
  font-size: 0.64rem;
  color: rgb(245 245 243 / 42%);
}

/*
 * The model with nothing in it.
 *
 * Where the three-way bar would have been, so the card keeps its height and
 * the rows below do not jump up — and set as a sentence, because a flat bar
 * in the same place would read as a measured dead heat.
 */
.fc-empty {
  margin: 0.6rem 0 0.2rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--gray-500);
}

/*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/starting-xi.css ***!
  \*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ============================================= the team sheet, as a poster ==
 *
 * Nine by sixteen, because that is the shape it is posted in. Sized in `cqw`
 * throughout so the whole thing scales with its container and comes out the
 * same at 360px in a panel and at 1080px in the export.
 */

.xi-poster {
  container-type: inline-size;
  position: relative;
  width: 100%;
  aspect-ratio: 9 / 16;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  grid-gap: 1.6cqw;
  gap: 1.6cqw;
  padding: 3cqw 3.2cqw 2.4cqw;
  overflow: hidden;
  color: var(--xi-ink, #fff);
  font-family: var(--font-kanit), system-ui, sans-serif;
  /*
   * The whole background comes from the theme, gradients and all: a look that
   * changed the grass and left the ground behind it would be a design that
   * reads as two designs stuck together.
   */
  background: var(--xi-backdrop);
}

/* ------------------------------------------------------------- the head -- */

.xi-head {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 12cqw;
}

.xi-head h1 {
  margin: 0;
  font-size: 8.4cqw;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1;
  text-align: center;
  /* Lifted off the ground by its own glow rather than by a box, so the title
     sits in the picture instead of on top of it. */
  text-shadow:
    0 0 3cqw rgb(255 255 255 / 45%),
    0 0.4cqw 1.2cqw rgb(0 0 0 / 45%);
}

.xi-logo {
  position: absolute;
  right: 0;
  top: 0;
  width: 15cqw;
  height: 15cqw;
  object-fit: contain;
  filter: drop-shadow(0 0.4cqw 1cqw rgb(0 0 0 / 55%));
}

/* ---------------------------------------------------------- the fixture -- */

.xi-fixture {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2.4cqw;
  padding: 1.6cqw 3cqw;
  border-radius: 999px;
  /* An edge the theme chooses — gold on the red poster, because that is the
     one colour there that is neither the club's nor the pitch's. */
  border: 0.5cqw solid var(--xi-bar-edge, #f0b429);
  background: var(--xi-bar, linear-gradient(180deg, #d61f26, #8c1116));
  box-shadow: 0 0.6cqw 2cqw rgb(0 0 0 / 40%);
}

.xi-fixture span {
  /* White, not the poster's ink: the bar has a ground of its own, and on the
     cream sheet the maroon ink sank straight into it. */
  color: #fff;
  font-size: 4cqw;
  font-weight: 800;
  letter-spacing: -0.01em;
  text-align: center;
  flex: 1 1;
  min-width: 0;
  /* One line. "MANCHESTER UNITED" wrapped onto two and the bar grew a second
     row, which is a different graphic. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.xi-fixture i {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 6cqw;
  height: 6cqw;
  border-radius: 50%;
  background: #fff;
  color: var(--xi-bar-ink, #8c1116);
  font-style: normal;
  font-size: 2.8cqw;
  font-weight: 800;
}

/* ----------------------------------------------------------- the pitch -- */

.xi-pitch {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 0;
}

.xi-turf {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.xi-band { fill: var(--xi-turf); }
.xi-band.dark { fill: var(--xi-turf-dark); }

.xi-lines polygon,
.xi-lines polyline {
  fill: none;
  stroke: var(--xi-line, rgb(255 255 255 / 78%));
  stroke-width: 1;
  /* Drawn in a space that is stretched to the box, so the stroke has to be
     told not to stretch with it or the touchlines come out heavier across
     than along. */
  vector-effect: non-scaling-stroke;
}

/* ---------------------------------------------------------- the players -- */

.xi-player {
  position: absolute;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  width: 22cqw;
}

.xi-player img,
.xi-player .xi-face-blank {
  width: 15cqw;
  height: 15cqw;
  border-radius: 50%;
  object-fit: cover;
  object-position: top center;
  /* No ring and no shadow box: the cut-out sits on the grass the way these
     graphics do, and a circle drawn round it would make eleven badges. */
  filter: drop-shadow(0 0.6cqw 0.8cqw rgb(0 0 0 / 45%));
}

/*
 * Selected: a ring round the photograph.
 *
 * Round the face, because that is what a person means by "this one" — the
 * first version outlined the whole grab area, face and name plate together,
 * and read as a box somebody had drawn rather than as a selection.
 */
.xi-player.on img,
.xi-player.on .xi-face-blank {
  box-shadow:
    0 0 0 0.7cqw #3fbf8f,
    0 0 2.5cqw rgb(63 191 143 / 70%);
}

.xi-player .xi-face-blank {
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 42%);
  box-shadow: inset 0 0 0 0.4cqw rgb(255 255 255 / 30%);
  font-size: 5cqw;
  font-weight: 800;
}

/*
 * The name plate: number in the club's red, surname on white.
 *
 * One object rather than two, because that is how it is read — and the number
 * is on the left where a shirt carries it, not floating beside the name.
 */
.xi-plate {
  display: flex;
  align-items: center;
  /* Clear of the chin, not across it: the plate is a caption under the face,
     and the first version had it overlapping. */
  margin-top: 0.6cqw;
  border-radius: 0.6cqw;
  overflow: hidden;
  background: var(--xi-plate, #fff);
  color: var(--xi-plate-ink, #14161a);
  font-size: 3cqw;
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 0.4cqw 1cqw rgb(0 0 0 / 40%);
}

.xi-plate i {
  display: grid;
  place-items: center;
  padding: 0.9cqw 1.1cqw;
  background: var(--xi-plate-number, var(--xi-accent));
  color: #fff;
  font-style: normal;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

.xi-plate {
  padding-right: 1.4cqw;
}

.xi-plate i + * { padding-left: 1cqw; }

/* The surname sits beside the number with its own breathing room. */
.xi-plate::after { content: ""; }

/* ------------------------------------------------------------- the subs -- */

.xi-subs {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  grid-gap: 2.4cqw;
  gap: 2.4cqw;
  padding-top: 1cqw;
}

.xi-subs b {
  padding: 0.8cqw 2cqw;
  border-radius: 0.6cqw;
  background: var(--xi-accent);
  font-size: 3.4cqw;
  font-weight: 800;
  letter-spacing: 0.04em;
}

.xi-subs p {
  margin: 0;
  font-size: 3.1cqw;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: 0.01em;
}

/* ================================== the guest's page: the poster, and handles ==
 *
 * Opened on a phone by somebody who was sent a link. No navigation, no menu
 * and nothing to get lost in, because there is nowhere else to go.
 */

.xi-guest {
  min-height: 100dvh;
  display: grid;
  grid-gap: 1rem;
  gap: 1rem;
  padding: 1rem;
  background: #0b0c0e;
  color: #f5f5f3;
  font-family: var(--font-kanit), system-ui, sans-serif;
}

@media (min-width: 900px) {
  .xi-guest {
    grid-template-columns: minmax(0, 1fr) 22rem;
    align-items: start;
    padding: 1.5rem;
  }
}

.xi-guest-stage {
  position: relative;
  width: 100%;
  max-width: 30rem;
  margin: 0 auto;
  /* Nothing scrolls the page while a face is being dragged across it. */
  touch-action: none;
}

/*
 * The handles sit over the poster, never inside it.
 *
 * The poster has to be exactly what the picture saves, so anything that exists
 * only for editing lives out here — otherwise the exported graphic carries the
 * editing furniture, which is the classic way a "save as image" ships a screen
 * instead of a picture.
 */
/* Placed on the pitch by measurement, not by `inset: 0` — the pitch is one
   row of the poster, and covering the whole poster put every handle a hundred
   and eighty pixels below its player. */
.xi-handles {
  position: absolute;
  pointer-events: none;
}

/*
 * The grab area covers the face and its plate, which is what a person thinks
 * of as "the player". Measured: an 8% nudge put it on the plate alone, 29px
 * below the face somebody was aiming at.
 */
.xi-handle {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 20%;
  height: 15%;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: -webkit-grab;
  cursor: grab;
  pointer-events: auto;
}

.xi-handle:active { cursor: -webkit-grabbing; cursor: grabbing; }

/*
 * The grab area draws nothing of its own.
 *
 * What a selection looks like is the ring on the photograph, which is drawn by
 * the poster. An outline here as well would be two marks for one state, and
 * the one people read is the circle.
 *
 * A keyboard focus ring stays, because somebody tabbing through has no cursor
 * to tell them where they are.
 */
.xi-handle:focus-visible {
  outline: 2px dashed rgb(255 255 255 / 80%);
  outline-offset: -2px;
}

/* ------------------------------------------------------------- the tools -- */

.xi-guest-tools {
  display: grid;
  grid-gap: 0.7rem;
  gap: 0.7rem;
  align-content: start;
  padding: 1rem;
  border-radius: 0.6rem;
  background: rgb(255 255 255 / 4%);
  border: 1px solid rgb(255 255 255 / 10%);
}

.xi-guest-tools h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
}

.xi-guest-hint,
.xi-guest-foot {
  margin: 0;
  font-size: 0.72rem;
  line-height: 1.5;
  color: rgb(245 245 243 / 50%);
}

.xi-guest-field { display: grid; grid-gap: 0.25rem; gap: 0.25rem; }

.xi-guest-field span {
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgb(245 245 243 / 45%);
}

.xi-guest-field select,
.xi-guest-field textarea {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border-radius: 0.35rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: rgb(0 0 0 / 35%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.82rem;
  resize: vertical;
}

.xi-guest-row { display: flex; gap: 0.4rem; flex-wrap: wrap; }

.xi-guest-row button {
  flex: 1 1 8rem;
  padding: 0.55rem 0.7rem;
  border-radius: 0.4rem;
  border: 1px solid rgb(255 255 255 / 18%);
  background: rgb(255 255 255 / 6%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

.xi-guest-row button:disabled { opacity: 0.5; cursor: default; }

/* Saving is the act the page exists for, so it is the one thing coloured. */
.xi-guest-save:not(:disabled) {
  background: #e8323b;
  border-color: #e8323b;
}

.xi-guest-note {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: #7fd9a8;
}

.xi-guest-empty {
  min-height: 100dvh;
  display: grid;
  place-content: center;
  grid-gap: 0.5rem;
  gap: 0.5rem;
  text-align: center;
  background: #0b0c0e;
  color: #f5f5f3;
  font-family: var(--font-kanit), system-ui, sans-serif;
}

.xi-guest-empty h1 { margin: 0; font-size: 1.6rem; letter-spacing: 0.04em; }
.xi-guest-empty p { margin: 0; color: rgb(245 245 243 / 55%); }

/*
 * The graphic, previewed where it is sent from.
 *
 * Sending a picture you have not seen is how a wrong badge goes out. Narrow on
 * purpose: it is a check, not the working surface.
 */
.xi-preview {
  max-width: 18rem;
  margin: 0.6rem 0;
  border-radius: 0.4rem;
  overflow: hidden;
  box-shadow: 0 0.4rem 1.4rem rgb(0 0 0 / 45%);
}

/* ------------------------------------------ what the official graphic said -- */

.official-read { display: grid; grid-gap: 0.3rem; gap: 0.3rem; margin: 0.4rem 0 0.6rem; }

.official-read ol {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-gap: 1px;
  gap: 1px;
  counter-reset: xi;
}

.official-read li {
  display: grid;
  grid-template-columns: 1.8rem 1fr auto;
  align-items: center;
  grid-gap: 0.45rem;
  gap: 0.45rem;
  padding: 0.22rem 0.4rem;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 3%);
  font-size: 0.76rem;
}

/* A name the read could not place: marked, never dropped. Ten players and a
   hole still looks like a team sheet. */
.official-read li.lost { background: rgb(232 50 59 / 12%); }

.official-read li b {
  text-align: center;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 60%);
}

.official-read li span { color: #f5f5f3; }

.official-read li i {
  font-style: normal;
  margin-left: 0.3rem;
  padding: 0 0.22rem;
  border-radius: 0.2rem;
  background: #e8323b;
  font-size: 0.6rem;
  font-weight: 700;
}

.official-read li u {
  text-decoration: none;
  font-size: 0.68rem;
  color: rgb(245 245 243 / 45%);
}

.official-read li.lost u { color: #ff9aa0; }

.panel-note.ok { color: #7fd9a8; }

/* The upload control is a label wrapping a hidden input, so it needs the
   button's own hand cursor and disabled look. */
label.btn.small { cursor: pointer; }
label.btn.small.busy { opacity: 0.6; cursor: default; }

/* ------------------------------------------------- the guest's own tools -- */

.xi-guest-shapes { display: flex; flex-wrap: wrap; gap: 0.25rem; }

.xi-guest-shapes button {
  padding: 0.3rem 0.5rem;
  border-radius: 0.3rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: rgb(255 255 255 / 5%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.xi-guest-shapes button:hover { background: rgb(255 255 255 / 12%); }

.xi-guest-squad {
  display: grid;
  grid-gap: 1px;
  gap: 1px;
  max-height: 14rem;
  overflow-y: auto;
  padding-right: 0.15rem;
}

.xi-guest-squad button {
  display: grid;
  grid-template-columns: 1.7rem 1fr;
  align-items: center;
  grid-gap: 0.4rem;
  gap: 0.4rem;
  padding: 0.28rem 0.4rem;
  border: 0;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 4%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.76rem;
  text-align: left;
  cursor: pointer;
}

.xi-guest-squad button:hover:not(:disabled) { background: rgb(255 255 255 / 11%); }
.xi-guest-squad button:disabled { opacity: 0.4; cursor: default; }

/* Already on the pitch: shown, not hidden, so the list stays the squad. */
.xi-guest-squad button.on { box-shadow: inset 2px 0 0 #3fbf8f; }

.xi-guest-squad button i {
  font-style: normal;
  text-align: center;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 50%);
}

/* Nothing here: the ring on the photograph is the selection. */

/* The public address, kept beside the button that uses it. */
.xi-base { display: grid; grid-gap: 0.2rem; gap: 0.2rem; margin: 0.4rem 0; }

.xi-base span {
  font-size: 0.64rem;
  letter-spacing: 0.06em;
  color: rgb(245 245 243 / 45%);
}

.xi-base input {
  padding: 0.35rem 0.5rem;
  border-radius: 0.3rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: rgb(0 0 0 / 30%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.76rem;
}

/* -------------------------------------------- the bench, as removable badges -- */

/*
 * It was a comma-separated box, which made deleting one substitute a
 * text-editing job with the comma either side of it. A cross on the name is
 * what everybody reaches for instead.
 */
.xi-subs-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  min-height: 1.6rem;
}

.xi-subs-badges em {
  font-style: normal;
  font-size: 0.7rem;
  color: rgb(245 245 243 / 40%);
}

.xi-sub-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0.16rem 0.2rem 0.16rem 0.45rem;
  border-radius: 999px;
  background: rgb(255 255 255 / 8%);
  font-size: 0.72rem;
  font-weight: 600;
}

.xi-sub-badge button {
  display: grid;
  place-items: center;
  width: 1.05rem;
  height: 1.05rem;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 12%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.82rem;
  line-height: 1;
  cursor: pointer;
}

.xi-sub-badge button:hover { background: #e8323b; }

/* ------------------------------------------------- the squad list, per row -- */

.xi-squad-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  grid-gap: 0.3rem;
  gap: 0.3rem;
  border-radius: 0.25rem;
  background: rgb(255 255 255 / 4%);
}

.xi-squad-row.on { box-shadow: inset 2px 0 0 #3fbf8f; }

.xi-squad-row > button {
  display: grid;
  grid-template-columns: 1.7rem 1fr;
  align-items: center;
  grid-gap: 0.4rem;
  gap: 0.4rem;
  padding: 0.28rem 0.4rem;
  border: 0;
  background: transparent;
  color: #f5f5f3;
  font: inherit;
  font-size: 0.76rem;
  text-align: left;
  cursor: pointer;
}

.xi-squad-row > button:hover:not(:disabled) { color: #fff; }
.xi-squad-row > button:disabled { opacity: 0.45; cursor: default; }

.xi-squad-row > button i {
  font-style: normal;
  text-align: center;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgb(245 245 243 / 50%);
}

/* The tick that names a substitute, beside the name it names. */
.xi-squad-row label {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding-right: 0.4rem;
  font-size: 0.62rem;
  color: rgb(245 245 243 / 45%);
  cursor: pointer;
}

.xi-logo-pick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 8rem;
  padding: 0.55rem 0.7rem;
  border-radius: 0.4rem;
  border: 1px solid rgb(255 255 255 / 18%);
  background: rgb(255 255 255 / 6%);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

/* ============================ handing the graphic out, and watching it go ==
 *
 * Two square tiles, an address bar, and badges saying what the other end is
 * doing. It was three plain buttons and a line of text, and the report both
 * times was "I pressed it and no link appeared".
 */

.xi-share { display: grid; grid-gap: 0.5rem; gap: 0.5rem; margin: 0.5rem 0 0.8rem; }

.xi-share-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  grid-gap: 0.4rem;
  gap: 0.4rem;
}

/*
 * A tile: picture on top, two or three words under it.
 *
 * Big enough to be a target on a touchscreen and square enough to be read as
 * an action rather than as a row in a list.
 */
.xi-tile {
  display: grid;
  justify-items: center;
  align-content: center;
  grid-gap: 0.35rem;
  gap: 0.35rem;
  min-height: 4.6rem;
  padding: 0.7rem 0.5rem;
  border: 1px solid rgb(255 255 255 / 16%);
  border-radius: 0.45rem;
  background: linear-gradient(180deg, rgb(255 255 255 / 7%), rgb(255 255 255 / 3%));
  color: #f5f5f3;
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.xi-tile:hover:not(:disabled),
.xi-tile:focus-visible {
  background: linear-gradient(180deg, rgb(255 255 255 / 13%), rgb(255 255 255 / 6%));
  border-color: rgb(255 255 255 / 38%);
}

.xi-tile:disabled { opacity: 0.5; cursor: default; }

.xi-tile svg { color: #e8323b; }

.xi-tile b {
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.25;
}

/* ------------------------------------------------------------ the address -- */

.xi-link-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-gap: 0.3rem;
  gap: 0.3rem;
  align-items: stretch;
}

.xi-link-bar input {
  min-width: 0;
  padding: 0.42rem 0.55rem;
  border-radius: 0.35rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: rgb(0 0 0 / 40%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.74rem;
  /* Selectable and readable: the point of showing it is that somebody can
     check it before sending. */
  text-overflow: ellipsis;
}

.xi-link-bar button {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0 0.6rem;
  border-radius: 0.35rem;
  border: 1px solid rgb(255 255 255 / 18%);
  background: rgb(255 255 255 / 8%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.xi-link-bar button:hover { background: rgb(255 255 255 / 15%); }

/* -------------------------------------------------------------- the state -- */

.xi-status { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }

.xi-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.32rem;
  padding: 0.22rem 0.5rem;
  border-radius: 999px;
  background: rgb(255 255 255 / 6%);
  font-size: 0.68rem;
  font-weight: 600;
  color: rgb(245 245 243 / 70%);
}

/* A dot and a word, never a colour alone — this is read at a glance across a
   desk, and a switcher downstream can flatten any hue. */
.xi-badge i {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: rgb(245 245 243 / 35%);
}

.xi-badge.live { color: #7fd9a8; background: rgb(63 191 143 / 14%); }
.xi-badge.live i {
  background: #3fbf8f;
  animation: xi-pulse 1.8s ease-in-out infinite;
}

.xi-badge.idle { color: #e8c53e; background: rgb(232 197 62 / 12%); }
.xi-badge.idle i { background: #e8c53e; }

.xi-badge.done { color: #7fa8c8; background: rgb(127 168 200 / 14%); }
.xi-badge.done i { background: #7fa8c8; }

@keyframes xi-pulse {
  50% { opacity: 0.3; }
}

/* Somebody who asked for nothing to move gets a steady dot. */
@media (prefers-reduced-motion: reduce) {
  .xi-badge.live i { animation: none; }
}

.xi-stop {
  padding: 0.22rem 0.5rem;
  border-radius: 999px;
  border: 1px solid rgb(255 255 255 / 16%);
  background: transparent;
  color: rgb(245 245 243 / 55%);
  font: inherit;
  font-size: 0.66rem;
  cursor: pointer;
}

.xi-stop:hover { color: #ff9aa0; border-color: rgb(232 50 59 / 55%); }

/* ------------------------------------------------ the shapes, as pictures -- */

/*
 * Three to a row: six names in a line is a list to read, and six pictures in
 * two rows is a thing to recognise.
 */
.xi-shape-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 0.35rem;
  gap: 0.35rem;
}

.xi-shape-tile {
  display: grid;
  justify-items: center;
  grid-gap: 0.25rem;
  gap: 0.25rem;
  padding: 0.45rem 0.3rem 0.4rem;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 0.4rem;
  background: linear-gradient(180deg, rgb(255 255 255 / 6%), rgb(255 255 255 / 2%));
  color: #f5f5f3;
  font: inherit;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.xi-shape-tile:hover,
.xi-shape-tile:focus-visible {
  background: linear-gradient(180deg, rgb(255 255 255 / 12%), rgb(255 255 255 / 5%));
  border-color: rgb(255 255 255 / 36%);
}

.xi-shape-tile b {
  font-size: 0.68rem;
  font-weight: 700;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.shape-icon { display: block; }
.shape-icon .si-pitch { fill: rgb(63 191 143 / 12%); stroke: rgb(255 255 255 / 26%); stroke-width: 0.6; }
.shape-icon .si-half { stroke: rgb(255 255 255 / 18%); stroke-width: 0.5; }
.shape-icon .si-dot { fill: #f5f5f3; }
/* The keeper, so a shape is read from its own end rather than either way up. */
.shape-icon .si-dot.keeper { fill: #e8c53e; }

.xi-shape-tile:hover .shape-icon .si-pitch { fill: rgb(63 191 143 / 22%); }

/* --------------------------------------------- three ticks beside a name -- */

.xi-squad-row {
  grid-template-columns: 1fr auto auto auto;
}

.xi-tick {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.05rem;
  padding: 0.15rem 0.28rem;
  font-size: 0.55rem;
  letter-spacing: 0.02em;
  color: rgb(245 245 243 / 42%);
  cursor: pointer;
}

.xi-tick input { margin: 0; accent-color: #3fbf8f; }
.xi-tick.hurt input { accent-color: #e8323b; }

/* Ruled out: struck through and dimmed, but still on the list — "he is
   injured" and "he is not in the squad" are different sentences, and only one
   of them is worth seeing while a side is being picked. */
.xi-squad-row.hurt > button { text-decoration: line-through; opacity: 0.5; }
.xi-squad-row.hurt { box-shadow: inset 2px 0 0 #e8323b; }

.xi-guest-field input[type="text"] {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border-radius: 0.35rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: rgb(0 0 0 / 35%);
  color: #f5f5f3;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* ================================== every action on this page, as a tile ==
 *
 * One shape for all of them: a mark on top, two or three words under it. A
 * page whose controls are half tiles and half text buttons reads as two
 * different tools stuck together, and this one is used by somebody who did not
 * build it.
 */

.xi-acts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6.2rem, 1fr));
  grid-gap: 0.35rem;
  gap: 0.35rem;
}

.xi-act {
  display: grid;
  justify-items: center;
  align-content: center;
  grid-gap: 0.3rem;
  gap: 0.3rem;
  min-height: 4.2rem;
  padding: 0.6rem 0.4rem;
  border: 1px solid rgb(255 255 255 / 15%);
  border-radius: 0.42rem;
  background: linear-gradient(180deg, rgb(255 255 255 / 7%), rgb(255 255 255 / 2.5%));
  color: #f5f5f3;
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.xi-act:hover:not(:disabled),
.xi-act:focus-visible {
  background: linear-gradient(180deg, rgb(255 255 255 / 13%), rgb(255 255 255 / 5%));
  border-color: rgb(255 255 255 / 36%);
}

.xi-act:disabled { opacity: 0.45; cursor: default; }

.xi-act svg { color: rgb(245 245 243 / 78%); }

.xi-act b {
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.25;
  /* A name inside a label — "เอา FERNANDES ออก" — must not push the tile
     wider than its column. */
  overflow-wrap: anywhere;
}

/* Saving is the act this page exists for, so it is the one thing coloured. */
.xi-act.save:not(:disabled) {
  background: linear-gradient(180deg, #ef4048, #cf2129);
  border-color: #ef4048;
}

.xi-act.save:not(:disabled) svg { color: #fff; }

/*
 * Clearing is the one act that cannot be undone from here, so it is marked —
 * by an outline rather than by a fill, which would make it the loudest thing
 * on a panel where saving is the point.
 */
.xi-act.danger { border-color: rgb(232 50 59 / 45%); }
.xi-act.danger svg { color: #ff9aa0; }
.xi-act.danger:hover { border-color: #e8323b; }

/* The public address lives with the link it builds, not three panels away. */
.xi-base em {
  display: block;
  margin-top: 0.15rem;
  font-style: normal;
  font-size: 0.62rem;
  line-height: 1.4;
  color: #e8a83e;
}

.xi-base.warn input { border-color: rgb(232 168 62 / 55%); }

.xi-guest-empty code {
  font-size: 0.72rem;
  color: rgb(245 245 243 / 35%);
  word-break: break-all;
}

/* ------------------------------------------------------------- the themes -- */

/*
 * Painted with the theme it chooses rather than labelled with its name: the
 * thing being picked is how the poster looks, and a list of words is a list
 * somebody has to try one at a time.
 */
.xi-theme-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(5.2rem, 1fr));
  grid-gap: 0.35rem;
  gap: 0.35rem;
}

.xi-theme-tile {
  display: grid;
  justify-items: center;
  grid-gap: 0.25rem;
  gap: 0.25rem;
  padding: 0.4rem 0.3rem 0.35rem;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 0.4rem;
  background: rgb(255 255 255 / 4%);
  color: #f5f5f3;
  font: inherit;
  cursor: pointer;
}

.xi-theme-tile:hover { border-color: rgb(255 255 255 / 34%); }

/* Chosen, by outline as well as fill — the swatch is already carrying colour,
   so the selected state cannot be a colour too. */
.xi-theme-tile.on {
  border-color: #f5f5f3;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 45%);
}

.xi-theme-tile b { font-size: 0.62rem; font-weight: 600; }

/* A miniature of the poster: the ground, the pitch on it, and the accent. */
.xi-swatch {
  display: block;
  width: 100%;
  aspect-ratio: 9 / 11;
  border-radius: 0.25rem;
  overflow: hidden;
  background: var(--sw-ground);
  display: grid;
  place-items: center;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 12%);
}

.xi-swatch i {
  display: block;
  width: 64%;
  height: 62%;
  border-radius: 0.12rem;
  background: var(--sw-turf);
  border: 1px solid var(--sw-line);
  box-shadow: 0 0.12rem 0 var(--sw-accent);
}

/* ---------------------------------------------- the menu a right-click opens -- */

/*
 * Small, at the pointer, and gone the moment anything else is touched. A menu
 * that has to be dismissed by finding its own close button is a menu in the
 * way of the thing it was opened over.
 */
.xi-menu {
  position: fixed;
  z-index: 40;
  display: grid;
  min-width: 11rem;
  padding: 0.25rem;
  border-radius: 0.4rem;
  border: 1px solid rgb(255 255 255 / 16%);
  background: #14161a;
  box-shadow: 0 0.6rem 1.8rem rgb(0 0 0 / 55%);
}

.xi-menu-item {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  width: 100%;
  padding: 0.42rem 0.5rem;
  border: 0;
  border-radius: 0.28rem;
  background: transparent;
  color: #f5f5f3;
  font: inherit;
  font-size: 0.78rem;
  text-align: left;
  cursor: pointer;
}

.xi-menu-item:hover { background: rgb(255 255 255 / 10%); }
.xi-menu-item svg { color: rgb(245 245 243 / 70%); flex: 0 0 auto; }

/* Removing is the one item here that cannot be undone. */
.xi-menu-item.danger:hover { background: rgb(232 50 59 / 22%); color: #ff9aa0; }
.xi-menu-item.danger svg { color: #ff9aa0; }

/*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@babel+core@7._a8a9dc27c3fd81163761d1f52e737783/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/match-web.css ***!
  \*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ============================================================ ใยเกม ==========
 *
 * ผังเหตุการณ์ทั้งเกมในภาพเดียว ใช้ได้ทั้งบนหน้าซ้อมและบนจอที่ออกอากาศ
 *
 * ทุกอย่างในไฟล์นี้อยู่ในหน่วยของ SVG ไม่ใช่พิกเซล เพราะกราฟิกตัวเดียวกัน
 * ต้องขึ้นได้ทั้งในแผงกว้าง 380px ข้างหน้าซ้อม และเต็มจอ 1920 โดยไม่ต้องมีสองชุด
 */

.match-web {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.9rem 1rem 1rem;
  border-radius: 0.6rem;
  background: rgb(12 13 16 / 82%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 8%);
}

.mw-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}

.mw-head small {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--gray-500);
}

.match-web svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Inside the capped lower third, height wins and the picture letterboxes
   rather than being cut off at the ankles. */
.match-web.screen svg {
  min-height: 0;
  max-height: 100%;
}

/* ---------------------------------------------------------------- ฉากหลัง -- */

/*
 * เส้นเวลาเป็นเส้นบาง ๆ สีเดียว ไม่ใช่เส้นประ
 *
 * เส้นประบนกราฟถูกอ่านว่า "ค่าประมาณ" หรือ "เส้นเกณฑ์" เสมอ ทั้งที่นี่คือ
 * แค่ตะแกรงบอกนาที — ให้มันถอยไปอยู่ข้างหลังด้วยความจาง ไม่ใช่ด้วยรูปแบบเส้น
 */
.mw-tick line {
  stroke: rgb(255 255 255 / 7%);
  stroke-width: 1;
}

.mw-tick text {
  fill: var(--gray-600);
  font-size: 13px;
  text-anchor: middle;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

.mw-half {
  stroke: rgb(255 255 255 / 16%);
  stroke-width: 1.5;
}

.mw-lane line {
  stroke: rgb(255 255 255 / 6%);
  stroke-width: 1;
}

.mw-name {
  fill: #f5f5f3;
  font-size: 14px;
  font-weight: 600;
  text-anchor: end;
}

.mw-rating {
  font-size: 11px;
  font-weight: 600;
  text-anchor: end;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  fill: var(--gray-600);
}

.mw-rating.high { fill: #3fbf8f; }
.mw-rating.mid { fill: #b9b9b4; }
.mw-rating.low { fill: #e8a83e; }

/* ------------------------------------------------------------ เส้นความสัมพันธ์ */

/*
 * เส้นวาดตัวเองจากต้นทางไปปลายทาง ไม่ใช่จาง ๆ แล้วโผล่ทั้งเส้น
 *
 * ทิศทางของเหตุการณ์คือครึ่งหนึ่งของความหมาย — คนจ่ายอยู่ต้นเส้น คนยิงอยู่ปลาย
 * การให้เส้นเดินจากต้นไปปลายจึงเป็นการเล่าเรื่องนั้นซ้ำ ไม่ใช่แค่ทำให้ดูเคลื่อนไหว
 * ระยะ 900 หน่วยพอสำหรับเส้นโค้งที่ยาวที่สุดในเฟรมนี้
 */
.mw-curve {
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-dasharray: 900;
}

.mw-curve.on {
  animation: mw-draw 900ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.mw-curve.off {
  /* ยังไม่ถึงนาทีนั้น — ซ่อนไว้ ไม่ใช่ทำให้จาง เพราะเงาจาง ๆ ของสิ่งที่ยัง
     ไม่เกิดขึ้น อ่านเป็น "เกิดแล้วแต่ไม่สำคัญ" */
  display: none;
}

@keyframes mw-draw {
  from { stroke-dashoffset: 900; }
  to { stroke-dashoffset: 0; }
}

.mw-curve.assist {
  stroke: #e8c33e;
}

.mw-curve.sub {
  stroke: rgb(160 200 255 / 55%);
  stroke-width: 1.6;
  /* เส้นประเฉพาะการเปลี่ยนตัว เพราะมันคือการสลับ ไม่ใช่การส่งต่อ
     และเป็นเส้นชนิดเดียวในผังที่ไม่ได้แปลว่า "คนนี้ทำให้คนนั้นได้ประตู" */
  stroke-dasharray: 6 5;
  animation-name: mw-fade;
}

@keyframes mw-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ------------------------------------------------------------------ จุดเหตุการณ์ */

.mw-mark circle,
.mw-mark rect {
  fill: #f5f5f3;
  stroke: #0c0d10;
  stroke-width: 2;
}

.mw-mark.on {
  animation: mw-pop 520ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.mw-mark.off { display: none; }

@keyframes mw-pop {
  from { opacity: 0; transform: scale(0.2); }
  to { opacity: 1; transform: scale(1); }
}

.mw-mark.goal circle,
.mw-mark.penalty circle {
  fill: #3fbf8f;
}

.mw-mark.own_goal circle { fill: #e0574f; }
.mw-mark.yellow rect { fill: #e8c33e; }
.mw-mark.red rect { fill: #e0574f; }
.mw-mark.var circle { fill: rgb(160 200 255 / 70%); }

/* ------------------------------------------------------------------ นาฬิกา -- */

/*
 * เส้นนาทีปัจจุบัน — เส้นเดียวในผังที่ขยับได้
 *
 * ไม่ใส่ transition เพราะนาฬิกาของบอร์ดเดินทีละนาที การเลื่อนแบบนุ่ม ๆ
 * ระหว่างสองนาทีจะทำให้เส้นอยู่ในตำแหน่งที่ไม่ตรงกับนาทีไหนเลยเป็นวินาที ๆ
 */
.mw-now {
  stroke: #e0574f;
  stroke-width: 2;
  opacity: 0.9;
}

.mw-note {
  margin: 0;
  font-size: 0.68rem;
  line-height: 1.6;
  color: var(--gray-600);
}

@media (prefers-reduced-motion: reduce) {
  .mw-curve.on,
  .mw-mark.on {
    animation: none;
  }
  .mw-curve.on { stroke-dashoffset: 0; }
}

/* ---------------------------------------------------- ตอนขึ้นจอออกอากาศ ---- */

/*
 * วางพาดล่างของภาพ ไม่ใช่ยัดในคอลัมน์ซ้าย
 *
 * ไทม์ไลน์เก้าสิบนาทีต้องการความกว้าง — บีบลงคอลัมน์ 325px แล้วชื่อนักเตะ
 * เหลือสูงประมาณ 4 พิกเซล ซึ่งอ่านไม่ออกทั้งบนจอและในคลิปที่ตัดออกไป
 * ตำแหน่งนี้คือที่ที่กราฟิกไทม์ไลน์ในการถ่ายทอดสดอยู่กันอยู่แล้ว
 *
 * ยึดกับ .board-screen-inner ซึ่งเป็น position: relative อยู่แล้ว
 */
.match-web.screen {
  position: absolute;
  left: 3%;
  right: 3%;
  bottom: 3%;
  z-index: 6;
  /*
   * It can never be taller than the lower third, whatever it is given.
   *
   * The component keeps the number of lanes down, and that is the real fix —
   * but a graphic that is wrong about its own height runs off the top of the
   * frame rather than being clipped, and a producer watching the panel would
   * not see it happen. This is the floor under that: worst case the picture
   * shrinks to fit and stays inside the screen it was sent to.
   */
  max-height: 44cqh;
  overflow: hidden;
  padding: 1.1cqh 1.4cqw 1.2cqh;
  background: rgb(10 11 14 / 88%);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  animation: mw-rise 520ms cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes mw-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.match-web.screen .mw-head small { font-size: 0.62cqw; }
.match-web.screen .mw-note { font-size: 0.52cqw; }

/*
 * บนจอใหญ่ตัวหนังสือในกราฟไม่ต้องขยายตาม เพราะ viewBox ขยายให้เองอยู่แล้ว
 * แต่เส้นบาง ๆ ต้องหนาขึ้นนิดหนึ่ง ไม่งั้นพอถูกบีบอัดเป็นวิดีโอแล้วหายไปเลย
 */
.match-web.screen .mw-lane line { stroke-width: 1.4; }
.match-web.screen .mw-tick line { stroke-width: 1.4; }
.match-web.screen .mw-curve { stroke-width: 3; }
.match-web.screen .mw-curve.sub { stroke-width: 2.2; }

@media (prefers-reduced-motion: reduce) {
  .match-web.screen { animation: none; }
}

