/* The site's fonts, as Google Fonts serves them, from the site itself: Marcellus for headings and
   letters, Noto Sans for the rest. A browser fetches only the files covering characters on the page.
   A changed file takes a new name, since public/_headers lets browsers keep them for good. */
@font-face { font-family: "Marcellus"; font-weight: 400; font-display: swap; src: url(/fonts/marcellus-v14-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Marcellus"; font-weight: 400; font-display: swap; src: url(/fonts/marcellus-v14-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-cyrillic-ext.woff2) format("woff2"); unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-cyrillic.woff2) format("woff2"); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-devanagari.woff2) format("woff2"); unicode-range: U+0900-097F, U+1CD0-1CF4, U+1CF7-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B0A; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-greek-ext.woff2) format("woff2"); unicode-range: U+1F00-1FFF; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-greek.woff2) format("woff2"); unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-vietnamese.woff2) format("woff2"); 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; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Noto Sans"; font-weight: 400 700; font-display: swap; src: url(/fonts/noto-sans-v42-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
:root {
  color-scheme: light;
  --ink: #221D38; --muted: #5C5874; --card: #FFFFFF; --track: rgba(226, 222, 240, .8);
  --elyos: #3F7EE8; --elyos-ink: #2D5BB0; --asmodian: #7A5AE0; --asmodian-ink: #5B3FC4;
  --shadow: 0 14px 34px -20px rgba(40, 60, 140, .45);
  --display: Marcellus, Georgia, serif;
}
* { box-sizing: border-box; }
/* The background color is the top of the sky because iOS 26 tints its status bar with it. */
body {
  margin: 0; min-height: 100vh; color: var(--ink); font: 15px/1.5 "Noto Sans", system-ui, sans-serif;
  background: linear-gradient(180deg, #DCEAF8 0, #EEF4FB 420px, #F8FAFD 100%) no-repeat, #DCEAF8;
}
/* Text is only selectable where it's worth copying, so holding a card to drag it doesn't select
   what's printed on it. Inputs have to opt back in, or iOS won't let them be typed in. */
body { -webkit-user-select: none; user-select: none; }
input, h1, .error { -webkit-user-select: text; user-select: text; }
a { color: var(--asmodian-ink); }
/* Tapping twice quickly shouldn't zoom the page. */
a, button { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
img { display: block; }
.hidden { position: absolute; left: -9999px; }
.note { color: var(--muted); font-size: 13px; }

/* Clouds drifting across the top of the sky. */
.sky { position: absolute; inset: 0 0 auto; height: 480px; overflow: hidden; pointer-events: none; }
.sky i { position: absolute; border-radius: 50%; filter: blur(40px); opacity: .85; animation: drift 28s ease-in-out infinite alternate; }
.sky i:nth-child(1) { width: 520px; height: 260px; left: -80px; top: 40px; background: #FFFFFF; }
.sky i:nth-child(2) { width: 600px; height: 300px; right: -120px; top: -60px; background: #C9E0FA; }
.sky i:nth-child(3) { width: 420px; height: 200px; left: 38%; top: 160px; background: #FFF6E3; animation-duration: 36s; }
.sky i:nth-child(4) { width: 380px; height: 180px; right: 18%; top: 250px; background: #FFFFFF; animation-duration: 22s; }
@keyframes drift { to { transform: translate3d(60px, -20px, 0) scale(1.08); } }

main { position: relative; max-width: 1120px; margin: 0 auto; padding: 24px 16px 72px; }
footer { margin-top: 64px; text-align: center; }
h1 { margin: 0; font: 400 clamp(40px, 8vw, 64px)/1 var(--display); overflow-wrap: anywhere; }
h2 { margin: 40px 0 16px; font: 400 30px/1.2 var(--display); }

/* The header: the brand, the site's areas as pills with the one a page is in raised, the search,
   and Install as a dark pill. Under 1000px the search takes a row of its own. On a phone it
   waits behind a button, page.js opens it there, and Install isn't offered, so the header keeps
   to one row. */
.top { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.brand { flex: none; display: flex; align-items: center; gap: 10px; color: var(--ink); text-decoration: none; font: 24px var(--display); }
.brand img { border-radius: 10px; }
.areas { display: flex; gap: 2px; margin-right: auto; }
.areas a { padding: 6px 14px; border-radius: 999px; color: var(--ink); font-weight: 600; text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .areas a:hover { background: rgba(255, 255, 255, .5); } }
.areas a[aria-current] { background: #fff; box-shadow: 0 6px 16px -10px rgba(40, 60, 140, .5); }
.get {
  flex: none; display: inline-flex; align-items: center; height: 40px; padding: 0 18px; border-radius: 20px;
  background: var(--ink); color: #fff; font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.toggle {
  display: none; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .75); color: var(--asmodian-ink); box-shadow: 0 10px 30px -14px rgba(60, 80, 170, .35);
}
.toggle[aria-expanded="true"] { background: #fff; }
/* The corner: a circle like the search's button, linking to the visitor's characters, which page.js
   swaps for the avatar of someone signed in, as Clerk draws it. */
.account {
  flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255, 255, 255, .75); color: var(--asmodian-ink); box-shadow: 0 10px 30px -14px rgba(60, 80, 170, .35);
}
div.account { background: none; }
.top .search { flex: 1 1 360px; max-width: 540px; }
.top .query { padding: 4px; }
.top .search input { height: 38px; padding: 0 10px; }
.top .search button { height: 38px; padding: 0 18px; }
@media (max-width: 999px) { .top .search { order: 1; flex-basis: 100%; max-width: none; } }
@media (max-width: 639px) {
  .top { gap: 12px 8px; }
  .areas a { padding: 6px 10px; font-size: 14px; }
  .top .get, .top .search { display: none; }
  .toggle { display: grid; }
  .top.searching .search { display: flex; }
}
/* Phones keep the brand's picture and not its name, and close the header up, so the search's button
   and the corner still fit on its one row. */
@media (max-width: 429px) {
  .brand span { position: absolute; left: -9999px; }
  .areas a { padding: 6px 8px; }
}
@media (max-width: 374px) {
  .top { column-gap: 6px; }
  .areas a { padding: 6px 7px; }
}
.search { display: flex; flex-direction: column; gap: 8px; flex: 0 1 460px; min-width: min(100%, 260px); }
.query, select { box-shadow: 0 10px 30px -14px rgba(60, 80, 170, .35); }
.query { display: flex; gap: 8px; padding: 6px; border-radius: 30px; background: rgba(255, 255, 255, .75); }
.search input { flex: 1; min-width: 0; height: 44px; padding: 0 16px; border: 0; background: transparent; font: inherit; font-size: 16px; color: var(--ink); border-radius: 22px; }
.search input::placeholder { color: #64607A; }
.search button {
  height: 44px; padding: 0 24px; border: 0; border-radius: 22px; cursor: pointer;
  background: linear-gradient(90deg, var(--elyos), var(--asmodian)); color: #fff; font: 600 15px "Noto Sans", sans-serif;
  transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
.search button:active { transform: scale(.96); }
/* Where a search looks: the region and the server as small violet pills inside the box, each as
   wide as what's picked. Where the box has too little room for them beside room to type a name,
   the name and the button go under them. A select's text is 16px wherever it's tapped, since iOS
   zooms in on one any smaller. */
#search .query { flex-wrap: wrap; }
.search .name { flex: 1 1 220px; display: flex; gap: 8px; min-width: 0; }
.welcome .name { flex-basis: 260px; }
.where { flex: none; display: flex; align-items: center; gap: 4px; }
.where select {
  flex: none; field-sizing: content; height: 32px; padding: 0 26px 0 12px; border-radius: 16px; box-shadow: none;
  background-color: #EFEBFB; background-position: right 10px center; background-size: 9px 6px;
  color: var(--asmodian-ink); font-size: 14px; font-weight: 700;
}
@media (pointer: coarse) { .where select { font-size: 16px; } }
/* Selects (the search's region and server, and the battles page's server and period) are pills
   with a chevron in the site's purple. Browsers that let a select's list be styled draw it as a
   card; the rest keep their own list. */
.filters { display: flex; gap: 8px; }
select {
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%235B3FC4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  flex: 1; min-width: 0; height: 40px; padding: 0 36px 0 16px; border: 0; border-radius: 20px; cursor: pointer;
  -webkit-appearance: none; appearance: none; color: var(--ink); font: 16px "Noto Sans", sans-serif;
  background: rgba(255, 255, 255, .75) var(--chevron) no-repeat right 15px center / 12px 8px;
}
select:focus-visible { outline: 2px solid var(--asmodian); outline-offset: 2px; }
@supports (appearance: base-select) {
  select, ::picker(select) { appearance: base-select; }
  select { display: flex; align-items: center; background-image: none; padding-right: 15px; }
  select::picker-icon { content: ""; width: 12px; height: 8px; margin-left: auto; background: var(--chevron) no-repeat center / contain; transition: rotate .2s; }
  select:open::picker-icon { rotate: 180deg; }
  .where select { gap: 8px; padding-right: 11px; }
  .where select::picker-icon { width: 9px; height: 6px; }
  ::picker(select) {
    margin-top: 6px; max-height: 320px; padding: 6px; border: 0; border-radius: 18px; background: var(--card); box-shadow: var(--shadow);
  }
  optgroup { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); padding-top: 6px; }
  optgroup[label="Elyos"] { color: var(--elyos-ink); }
  optgroup[label="Asmodian"] { color: var(--asmodian-ink); }
  option { padding: 6px 12px; border-radius: 12px; color: var(--ink); font-size: 15px; font-weight: 400; letter-spacing: 0; text-transform: none; }
  option::checkmark { display: none; }
  option:hover, option:focus-visible { background: #F0EBFF; outline: 0; }
  option:checked { background: var(--asmodian-ink); color: #fff; font-weight: 600; }
}
#status:empty { display: none; }

.results { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; margin-top: 24px; }
.result {
  display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 20px; background: var(--card);
  color: var(--ink); text-decoration: none; box-shadow: var(--shadow); transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
@media (hover: hover) { .result:hover { transform: translateY(-3px); } }
.result:active { transform: scale(.98); }
.result img { width: 48px; height: 48px; border-radius: 16px; object-fit: cover; background: #F1EEFA; }
.result b { display: block; }
.result.elyos b { color: var(--elyos-ink); }
.result.asmodian b { color: var(--asmodian-ink); }

.hero { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 24px; margin-top: 40px; }
.hero img, .hero .portrait { width: 112px; height: 112px; border-radius: 36px; box-shadow: 0 16px 40px -18px rgba(60, 80, 170, .5); }
.hero img { object-fit: cover; background: #fff; }
/* A character the census heard of, which has no picture of them, has their initial in its place, as on a killmail. */
.hero .portrait { font-size: 56px; }
.who { flex: 1 1 280px; display: flex; flex-direction: column; gap: 8px; }
.pills { display: flex; flex-wrap: wrap; gap: 8px; }
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border-radius: 999px; background: rgba(255, 255, 255, .85); font-size: 13px; font-weight: 600; }
.pill.elyos { color: var(--elyos-ink); }
.pill.asmodian { color: var(--asmodian-ink); }
.pill.cp { font-weight: 700; }
a.pill { text-decoration: none; }
/* Tags say what a thing is (its side, server, legion, map or place, or a part in a fight) as small
   soft pills, in its side's tint when it's a side's. A small tag goes where rows are dense or a
   chart is tight. A search shows as a tag that × takes off. Figures say how many: a bold number
   and its quiet words, spaced apart. Together they stand in for words split by dots. */
.facets { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.facet { display: inline-flex; align-items: baseline; gap: 5px; padding: 0 9px; border-radius: 999px; background: #EEEBF6; color: var(--ink); font-size: 12px; font-weight: 600; line-height: 22px; letter-spacing: 0; text-transform: none; white-space: nowrap; text-decoration: none; }
.facet.small { padding: 0 6px; color: var(--muted); font-size: 10.5px; font-weight: 700; line-height: 16px; vertical-align: 1px; }
.facet:is(.elyos, .asmodian) { background: var(--side-soft); color: var(--side-ink); }
.facet small { color: var(--muted); font-size: 11px; font-weight: 600; }
.facet.crit { background: #FFE39A; color: #6B4700; }
.facet.off { align-items: center; gap: 6px; padding-right: 3px; background: #EFEBFB; color: var(--asmodian-ink); font-weight: 700; vertical-align: middle; }
.facet.off i { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: rgba(91, 63, 196, .14); font-style: normal; font-size: 12px; line-height: 1; }
.figures { display: inline-flex; flex-wrap: wrap; gap: 0 14px; color: var(--muted); font: 400 13px "Noto Sans", system-ui, sans-serif; letter-spacing: 0; text-transform: none; }
.figures b { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
/* A note holding a row of tags or figures lays them out with room between. */
.note:has(> :is(.facets, .figures)) { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.place { margin-top: 24px; }
/* The gear grade, as a small card set down at the end of the hero. On a phone it moves up beside
   the portrait, so the name gets a line of its own. */
.card.mini { flex: none; align-self: center; margin-left: auto; width: 88px; height: 120px; border-radius: 18px; rotate: 4deg; }
.mini .inner { border-radius: 15px; }
.mini .face, .fan .face { padding: 0; align-items: center; justify-content: center; gap: 6px; }
.mini b { font: 44px/1 var(--display); color: var(--letter); }
.mini .face span, .fan .face span { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
@media (max-width: 560px) { .hero img, .hero .portrait { order: -2; } .hero .card.mini { order: -1; } }

/* The front page: the search under a headline, beside a hand of cards in every finish, dealt out
   from D to BiS when the page opens, or over it on a phone. Under them, what's on: the next siege
   or Nahma and the latest battles side by side, the census of each region and what the addon
   does. */
.welcome { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 440px); align-items: center; gap: 8px 40px; margin-top: clamp(32px, 7vw, 80px); }
.welcome h1 { font-size: clamp(40px, 6.4vw, 68px); line-height: 1.02; }
.welcome .lead { max-width: 520px; margin: 18px 0 26px; color: var(--muted); font-size: 17px; }
.welcome .search { max-width: 580px; }
.welcome .query { padding: 8px; }
.welcome .where select { height: 40px; padding-left: 16px; border-radius: 20px; }
.fan { --w: 112px; --step: 44px; display: grid; justify-items: center; height: calc(var(--w) * 2.1); }
@media (max-width: 859px) {
  .welcome { grid-template-columns: minmax(0, 1fr); }
  .fan { --w: clamp(56px, 15vw, 112px); --step: min(44px, 8vw); height: calc(var(--w) * 1.9); margin-top: 16px; }
}
@media (max-width: 639px) { .welcome .lead { font-size: 15px; margin: 12px 0 18px; } }
.fan > div {
  grid-area: 1 / 1; translate: calc(var(--at) * var(--step)) calc(var(--at) * var(--at) * var(--w) * .06); rotate: calc(var(--at) * 6deg);
  transition: scale .3s cubic-bezier(.34, 1.56, .64, 1); animation: deal .7s calc((var(--at) + 3) * 70ms) cubic-bezier(.2, .9, .3, 1.1) backwards;
}
@media (hover: hover) { .fan > div:hover { z-index: 1; scale: 1.08; } }
.fan .card { width: var(--w); height: calc(var(--w) * 1.4); border-radius: 22px; }
.fan .inner { border-radius: 19px; }
.fan b { font: calc(var(--w) * .38)/1 var(--display); color: var(--letter); }
@keyframes deal { from { opacity: 0; translate: 0 40px; rotate: 0deg; } }
.now { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 28px; }
@media (max-width: 859px) { .now { grid-template-columns: minmax(0, 1fr); } }
/* Side by side, the timers and the battles end level: the shorter's rows grow to the other's length.
   Fewer battles than the three it lists keep their size, and end short. */
.now > section { display: flex; flex-direction: column; }
.now #timers { flex: 1; display: flex; flex-direction: column; gap: 12px; }
.now .timetable, .now .rows { flex: 1; }
.now .timetable { display: flex; flex-direction: column; }
.now .timetable li, .now .rows:has(> .row + .row + .row) > .row { flex: 1; }
.now .timetable li { align-content: center; }
.now .card.headliner { margin-top: 0; }
.now .headliner h3 { font-size: 30px; }
.now .headliner .count b { font-size: 38px; }
/* Each region's census is a cell of one panel, ruled off from the cells left of and over it by a
   shadow, which the panel's edge cuts off where there are none. */
.overview { display: flex; flex-wrap: wrap; overflow: hidden; }
.overview > div { flex: 1 1 200px; padding: 16px 20px 18px; box-shadow: -1px -1px 0 var(--track); }
.overview h3 { margin: 0; font: 400 22px/1.2 var(--display); }
.overview .factions { display: flex; justify-content: space-between; gap: 8px; margin: 8px 0 6px; font-size: 13px; font-weight: 600; }
.overview .split { height: 8px; }
.overview .note { margin: 8px 0 0; }
.pitch {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-top: 48px; padding: 18px 22px;
  border: 1px dashed #CFC8EA; border-radius: 22px; background: rgba(255, 255, 255, .6);
}
.pitch + .pitch { margin-top: 12px; }
.pitch p { flex: 1 1 320px; margin: 0; }
.pitch .get { background: var(--card); color: var(--ink); box-shadow: var(--shadow); }

.boards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.board { background: var(--card); border-radius: 20px; padding: 14px 18px; box-shadow: var(--shadow); display: flex; flex-direction: column; }
.board.piece { flex-direction: row; align-items: center; gap: 12px; padding: 12px 16px 12px 12px; }
.piece img { width: 40px; height: 40px; border-radius: 12px; }
.piece b { display: block; }

/* Grades. Each one's colors step down in lightness as well as hue, so they still read without color. */
.bis { --letter: #5B3A00; --chip: conic-gradient(from 200deg, #FFE7A3, #FFC6E5, #C6D8FF, #C9F5E6, #FFE7A3); --fill: linear-gradient(90deg, #FF9FC6, #FFC861, #7FD8FF, #B08CFF, #FF9FC6); }
.splus { --letter: #7A4E00; --chip: linear-gradient(135deg, #FFE7A3, #FFC6E5, #C6D8FF); --fill: linear-gradient(90deg, #FF9FC6, #FFC861, #7FD8FF, #B08CFF); }
.s { --letter: #8A5A00; --chip: linear-gradient(135deg, #FFF0C2, #F2CF78); --fill: linear-gradient(90deg, #E2B24B, #F5D47E); }
.a { --letter: #4A4F66; --chip: linear-gradient(135deg, #F4F6FB, #D5DAE8); --fill: linear-gradient(90deg, #9AA4BD, #C9CFDF); }
.b { --letter: #2D5BB0; --chip: #D6E6FF; --fill: #4C8DF0; }
.c { --letter: #136B63; --chip: #CDEFEA; --fill: #2DB3A6; }
.d, .ungraded { --letter: #5C5874; --chip: #ECEAF2; --fill: #B4B0C4; }
.letter { color: var(--letter); }

/* A card is three layers: the foil sits under the printed text, as on a real card, and the glare
   sits on top. page.js writes --mx/--my (where the light is) and --rx/--ry (the tilt). A card
   leaves drags that start up or down to the page, so a finger scrolls past it and tilts it by
   moving sideways, and holding one still doesn't open iOS's menu for its image. */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; }
/* A column of 1fr would grow to fit a long item name, which a card keeps to one line. */
@media (max-width: 400px) { .cards { grid-template-columns: minmax(0, 1fr); } }
.card {
  --rx: 0deg; --ry: 0deg; --mx: 50%; --my: 50%; --o: 0; --glare: .5; touch-action: pan-y pinch-zoom; -webkit-touch-callout: none;
  border-radius: 26px; padding: 3px; background: #E9E6F2;
  transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .6s cubic-bezier(.2, .9, .3, 1.25), box-shadow .4s; box-shadow: var(--shadow);
}
@media (hover: hover) { .card:hover { box-shadow: 0 26px 50px -22px rgba(40, 60, 140, .55); } }
.inner { position: relative; height: 100%; border-radius: 23px; background: var(--card); overflow: hidden; isolation: isolate; }
.foil, .glare { position: absolute; inset: 0; pointer-events: none; }
.face { position: relative; z-index: 1; height: 100%; padding: 18px 20px; display: flex; flex-direction: column; gap: 12px; }
.glare {
  z-index: 2; opacity: calc(var(--o) * var(--glare)); transition: opacity .3s; mix-blend-mode: soft-light;
  background: radial-gradient(farthest-corner circle at var(--mx) var(--my), rgba(255, 255, 255, .9) 0%, rgba(255, 255, 255, .25) 28%, rgba(255, 255, 255, 0) 55%);
}
.card header { display: flex; align-items: center; gap: 12px; }
.card header img { width: 46px; height: 46px; border-radius: 16px; background: rgba(241, 238, 250, .85); }
.card header div { flex: 1; min-width: 0; }
/* A piece's enchant level sits on its icon's corner, gold once it can't go higher. */
.picture { position: relative; flex: none; }
.enchant {
  position: absolute; right: -5px; bottom: -5px; padding: 0 5px; border-radius: 999px; background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; box-shadow: 0 0 0 2px var(--card);
}
.enchant.max { background: linear-gradient(135deg, #E2B24B, #B9821F); }
.card header b { display: block; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card header .note { display: block; }
.card header .facet { margin-top: 4px; }
.card .letter {
  min-width: 44px; height: 44px; padding: 0 8px; border-radius: 14px; display: grid; place-items: center;
  font: 24px var(--display); background: var(--chip);
}
.line { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; font-size: 13px; }
.line > span + span { font-weight: 600; }
.line.zero { color: var(--muted); }
.bar { grid-column: 1 / -1; height: 8px; border-radius: 4px; background: var(--track); overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 4px; background: var(--fill); }

/* The BiS and S+ borders move, which painting the card's own background would repaint the whole
   card for, every frame. So each moves on a layer of its own under the card's face, by turning or
   sliding it, which the compositor does without painting anything again. */
.card.bis, .card.splus { position: relative; overflow: hidden; background: none; }
.card.bis::before, .card.splus::before { content: ""; position: absolute; pointer-events: none; }

/* BiS: textured foil, the finish card games put above holo. The rainbow sits under an etched
   crosshatch and denser glitter, which catch the light across the whole card, inside a gold
   border with a rainbow running around it. */
.card.bis { --glare: 1; }
/* A square twice the card's longer side covers it at every turn, whatever its shape, however its
   text wraps: `aspect-ratio` carries each side's minimum over to the other. */
.card.bis::before {
  left: 50%; top: 50%; min-width: 200%; min-height: 200%; aspect-ratio: 1; translate: -50% -50%;
  background: conic-gradient(#E9B949, #FFB3D1, #A9D4FF, #B6F2D6, #FFE29A, #E9B949); animation: spin 8s linear infinite;
}
.bis .foil {
  opacity: calc(.5 + var(--o) * .35); transition: opacity .3s;
  background:
    radial-gradient(circle at 30% 40%, #fff 0 1px, transparent 1.6px) 0 0 / 13px 13px,
    radial-gradient(circle at 70% 70%, #fff 0 1.2px, transparent 1.8px) 0 0 / 19px 19px,
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .5) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-45deg, rgba(255, 255, 255, .5) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(115deg, #FFB3D1 0%, #FFE29A 7%, #B6F2D6 14%, #A9D4FF 21%, #D6BEFF 28%, #FFB3D1 35%) var(--mx) var(--my) / 400% 400%;
}
@keyframes spin { to { rotate: 1turn; } }
/* S+: holographic. Rainbow bands slide against the pointer, with glitter on top, in a shimmering border. */
.card.splus { --glare: 1; }
.card.splus::before {
  inset: 0 auto 0 0; width: 300%;
  background: linear-gradient(115deg, #FFE7A3, #FFC6E5 25%, #C6D8FF 50%, #C9F5E6 75%, #FFE7A3); animation: sheen 6s ease-in-out infinite alternate;
}
.splus .foil {
  opacity: calc(.35 + var(--o) * .35); transition: opacity .3s;
  background:
    radial-gradient(circle at 20% 30%, #fff 0 1px, transparent 1.5px) 0 0 / 23px 23px,
    radial-gradient(circle at 70% 60%, #fff 0 1px, transparent 1.5px) 0 0 / 31px 31px,
    repeating-linear-gradient(115deg, #FFB3D1 0%, #FFE29A 7%, #B6F2D6 14%, #A9D4FF 21%, #D6BEFF 28%, #FFB3D1 35%) var(--mx) var(--my) / 400% 400%;
}
/* S: gold foil, one bright band that follows the light. */
.card.s { --glare: .9; background: linear-gradient(135deg, #F3D27E, #FFF3CF 45%, #D9A73E); }
.s .foil {
  opacity: calc(.3 + var(--o) * .3); transition: opacity .3s;
  background: linear-gradient(115deg, #EBCB7A 0%, #F7E7B4 38%, #FFFDF2 48%, #F2D58E 56%, #D9AE4F 100%) var(--mx) var(--my) / 300% 300%;
}
/* A: silver, the same band in cool pearl. */
.card.a { --glare: .8; background: linear-gradient(135deg, #C9CFDF, #F7F8FC 45%, #AEB6CB); }
.a .foil {
  opacity: calc(.25 + var(--o) * .3); transition: opacity .3s;
  background: linear-gradient(115deg, #D5DAE8 0%, #EEF0F8 38%, #FFFFFF 48%, #E3DCF7 56%, #C3CADB 100%) var(--mx) var(--my) / 300% 300%;
}
/* B and C: glossy card stock, glare only. D: matte. */
.card.b { --glare: .6; background: #E3ECFB; }
.card.c { --glare: .35; background: #E2F2EF; }
.card.d, .card.ungraded { --glare: 0; }
.card.d .inner, .card.ungraded .inner { background: #FBFAFD; }
@keyframes sheen { to { translate: calc(-200% / 3) 0; } }

/* A piece's card turns over to the best item of its slot. Both sides share one cell, as tall as
   the taller. The side leaving turns edge-on and then hides, and the side arriving shows at once,
   edge-on, and turns in, so neither needs backface-visibility, which Safari drops on children with
   transforms of their own. The sides turn on wrappers, since page.js writes a card's own
   transition as it tilts. */
.flip { display: grid; grid-template-columns: minmax(0, 1fr); perspective: 1400px; cursor: pointer; }
.side { grid-area: 1 / 1; display: grid; grid-template-columns: minmax(0, 1fr); transition: rotate .18s cubic-bezier(.2, .7, .3, 1) .18s, visibility 0s; }
.flip > .back, .flip.turned > .front { visibility: hidden; transition: rotate .18s cubic-bezier(.7, 0, .8, .3), visibility 0s .18s; }
.flip > .back { rotate: y -90deg; }
.flip.turned > .front { rotate: y 90deg; }
.flip.turned > .back { visibility: visible; rotate: none; transition: rotate .18s cubic-bezier(.2, .7, .3, 1) .18s, visibility 0s; }
/* The row that says a card turns over, along the bottom of both sides, so it stays put as the
   card turns. */
.turn {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: auto -8px 0; padding: 6px 8px;
  border: 1.5px dashed rgba(91, 63, 196, .3); border-radius: 10px; background: none; color: var(--asmodian-ink);
  font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer; transition: background .2s, border-color .2s;
}
.turn span:last-child { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.turn svg { width: 12px; height: 12px; }
.back .turn { background: rgba(255, 255, 255, .7); }
@media (hover: hover) { .flip:hover .turn { background: #F6F3FF; border-color: rgba(91, 63, 196, .55); } }
.turn:focus-visible { outline: 2px solid var(--asmodian); outline-offset: 2px; }
/* The back: a star for the slot's best item, and each of its lines checked if the piece has it. */
.card .star {
  width: 46px; height: 46px; border-radius: 16px; display: grid; place-items: center; color: #7A4E00; font-size: 22px;
  background: conic-gradient(from 200deg, #FFE7A3, #FFC6E5, #C6D8FF, #C9F5E6, #FFE7A3);
}
.line.ideal { grid-template-columns: 18px 1fr auto; }
.line.ideal .bar { grid-column: 2 / -1; }
.mark {
  grid-row: span 2; align-self: start; width: 18px; height: 18px; margin-top: 1px; border-radius: 50%; display: grid; place-items: center;
  background: #CDEFEA; color: #136B63; font-size: 11px; font-style: normal; font-weight: 700; line-height: 1;
}
.line.lacking { color: var(--muted); }
.line.lacking .mark { background: none; box-shadow: inset 0 0 0 1.5px #C9C4DA; }
.line.lacking .bar i { opacity: .25; }

/* A piece still loading: grey stand-ins for its icon and lines, with a shimmer passing over them.
   The shimmer slides on a layer of its own, like the S+ border. */
.loading .face > i, .loading header i { position: relative; display: block; height: 30px; border-radius: 8px; overflow: hidden; }
.loading .face > i::before, .loading header i::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 300%; pointer-events: none;
  background: linear-gradient(90deg, var(--track) 30%, #F6F4FB 50%, var(--track) 70%); animation: shimmer 1.4s linear infinite;
}
.loading header i { flex: none; width: 46px; height: 46px; border-radius: 16px; }
@keyframes shimmer { from { translate: calc(-200% / 3) 0; } to { translate: 0 0; } }

/* A kept piece being fetched again: a spinner and a word along the card's foot, in the face's
   bottom padding, so the card keeps its size as page.js puts it there and takes it away. */
.refresh {
  position: absolute; left: 0; right: 0; bottom: 3px; margin: 0; display: flex; align-items: center; justify-content: center; gap: 5px;
  color: var(--muted); font-size: 9.5px; font-weight: 700; line-height: 12px; letter-spacing: .12em; text-transform: uppercase;
}
.refresh::before { content: ""; width: 7px; height: 7px; border: 1.5px solid; border-top-color: transparent; border-radius: 50%; animation: spin .8s linear infinite; }

@media (prefers-reduced-motion: reduce) {
  .sky i, .card.bis::before, .card.splus::before, .loading i::before, .refresh::before, .fan > div { animation: none; }
  .card { transition: box-shadow .4s; }
  .flip > .side, .flip.turned > .side { rotate: none; transition: none; }
}

/* How we score and the addon's page: long reads on the sky, with formulas and notes set off in the
   site's violet. */
.how { color: var(--asmodian-ink); font-weight: 600; text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .how:hover { text-decoration: underline; } }
.read { max-width: 760px; margin: 40px auto 0; }
.read h3 { margin: 28px 0 8px; font-size: 17px; }
.read .lead { font-size: 17px; }
.read figure { margin: 24px 0; }
.read figure img { width: 100%; height: auto; border-radius: 20px; box-shadow: var(--shadow); }
.read figcaption { margin-top: 8px; }
.read li + li { margin-top: 6px; }
.button {
  display: inline-block; padding: 12px 24px; border-radius: 22px; color: #fff; text-decoration: none; font-weight: 600;
  background: linear-gradient(90deg, var(--elyos), var(--asmodian)); transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
.button:active { transform: scale(.96); }
/* The install page's two ways to have kisk, side by side where they fit, each a card opening its page. */
.installs { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-top: 24px; }
.installs a {
  display: flex; flex-direction: column; gap: 10px; padding: 20px 22px; border-radius: 22px; background: var(--card);
  color: var(--ink); text-decoration: none; box-shadow: var(--shadow); transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
@media (hover: hover) { .installs a:hover { transform: translateY(-3px); } }
.installs a:active { transform: scale(.98); }
.installs h2 { margin: 0; }
.installs p { flex: 1; margin: 0; }
button.button { border: 0; font: inherit; font-weight: 600; cursor: pointer; }

/* A character's claim page (`mepage.tsx`): what to do, what came of the last press, and its buttons. */
.claim { max-width: 640px; margin-top: 28px; }
.claim .lead { font-size: 17px; }
.claim form { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 20px; }
.said { padding: 12px 16px; border-radius: 16px; background: #F0EBFF; color: var(--asmodian-ink); font-weight: 600; }
.quiet { padding: 12px 8px; border: 0; background: none; color: var(--muted); font: inherit; font-weight: 600; cursor: pointer; }
/* While someone's showing a character, a bar empties over the time they have left, and page.js says
   below it how kisk's checking is going. */
.watch { margin-top: 20px; }
.watch .bar { height: 8px; border-radius: 4px; background: var(--track); overflow: hidden; }
.watch .bar span {
  display: block; height: 100%; background: linear-gradient(90deg, var(--elyos), var(--asmodian));
  transform-origin: left; animation: drain linear forwards;
}
@keyframes drain { from { transform: scaleX(var(--from)); } to { transform: scaleX(0); } }
.watch .note { margin-top: 10px; }
/* A claimed character: a tick that draws itself, and once they've just shown it, confetti falling in
   the factions' colors. */
.claimed { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.claimed h2 { margin: 0; }
.claimed .lead { margin: 0; }
.done-tick { width: 64px; height: 64px; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.done-tick circle { stroke: var(--asmodian); stroke-width: 3; stroke-dasharray: 151; stroke-dashoffset: 151; animation: draw .6s ease-out forwards; }
.done-tick path { stroke: var(--elyos); stroke-width: 4; stroke-dasharray: 34; stroke-dashoffset: 34; animation: draw .35s .5s ease-out forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.confetti { position: fixed; inset: 0; z-index: 10; overflow: hidden; pointer-events: none; }
.confetti i {
  position: absolute; top: -16px; width: 8px; height: 14px; border-radius: 2px; background: var(--asmodian);
  opacity: 0; animation: fall ease-in forwards;
}
.confetti i:nth-child(3n) { background: var(--elyos); }
.confetti i:nth-child(4n+1) { background: #FFC94D; width: 10px; height: 10px; border-radius: 50%; }
@keyframes fall {
  0% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate3d(var(--dx), 105vh, 0) rotate(var(--turn)); }
}
/* `/me`: each character someone owns, with Not mine under it, which opens to the button that gives it up. */
.owned { display: flex; flex-direction: column; gap: 2px; }
.release summary { width: max-content; padding: 4px 8px; color: var(--muted); font-size: 14px; font-weight: 600; cursor: pointer; list-style: none; }
.release summary::-webkit-details-marker { display: none; }
.release .quiet { padding: 4px 8px; color: var(--asmodian-ink); }
@media (prefers-reduced-motion: reduce) {
  .done-tick :is(circle, path) { animation: none; stroke-dashoffset: 0; }
  .confetti { display: none; }
}
.formula {
  margin: 16px 0; padding: 14px 18px; border-radius: 16px; background: #F0EBFF; color: var(--asmodian-ink);
  border: 1px solid rgba(91, 63, 196, .16); font-weight: 600; line-height: 1.6;
}
.letters { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin: 16px 0; }
.letters div { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 6px; border-radius: 16px; background: var(--card); box-shadow: var(--shadow); }
.letters .letter { min-width: 44px; height: 44px; padding: 0 8px; border-radius: 14px; display: grid; place-items: center; font: 22px var(--display); background: var(--chip); }
/* Wide tables scroll inside their own box, so the page never scrolls sideways on a phone. */
.table { overflow-x: auto; margin: 16px 0; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); }
.table table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th, .table td { padding: 8px 14px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--track); }
.table tr:last-child td { border-bottom: 0; }
.table th { color: var(--muted); font-weight: 600; }
.table .number { text-align: right; white-space: nowrap; }
.table tr.zero { color: var(--muted); }
/* A row of the drops pages whose share is of too few kills to go by. */
.table tr.few, .table td.few { color: var(--muted); }
/* The drops page's forms, one to find a monster and one an item, side by side where they fit. */
.finders { display: flex; flex-wrap: wrap; gap: 12px; margin: 16px 0; }
.classes .pills { margin: 16px 0; }
.classes label { cursor: pointer; }
.classes .class { display: none; }
.nerds { margin-top: 64px; padding-top: 8px; border-top: 1px solid var(--track); }
.read code { font-size: 12px; padding: 1px 5px; border-radius: 6px; background: rgba(255, 255, 255, .8); }

/* Killmails: one death, the battle around it, and a character's list. Elyos read blue and
   Asmodians purple throughout, as on the search results. */
.elyos { --side: var(--elyos); --side-ink: var(--elyos-ink); --side-soft: #E6F0FF; --fill: linear-gradient(90deg, #3F7EE8, #7FA8F0); }
.asmodian { --side: var(--asmodian); --side-ink: var(--asmodian-ink); --side-soft: #F0EBFF; --fill: linear-gradient(90deg, #7A5AE0, #A890EE); }
span.elyos, b.elyos { color: var(--elyos-ink); }
span.asmodian, b.asmodian { color: var(--asmodian-ink); }
.panel { background: var(--card); border-radius: 24px; box-shadow: var(--shadow); }
.headline { margin-top: 48px; display: flex; flex-direction: column; gap: 14px; }
.headline h1 { font-size: clamp(34px, 6vw, 56px); line-height: 1.05; }
.pill.label { background: var(--ink); color: #fff; letter-spacing: .08em; text-transform: uppercase; font-size: 11px; }
.pill.link { color: var(--asmodian-ink); text-decoration: none; }
.role { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--side-ink); }

.versus { display: grid; grid-template-columns: minmax(0, 1fr) 56px minmax(0, 1fr); align-items: center; gap: 12px; margin-top: 32px; }
.versus:has(> :only-child) { grid-template-columns: minmax(0, 1fr); }
.vs { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--ink); color: #fff; font: 20px var(--display); box-shadow: var(--shadow); }
.fighter { padding: 20px; display: flex; gap: 16px; align-items: center; border-top: 4px solid var(--side); }
.fighter > img, .portrait { flex: none; width: 88px; height: 88px; border-radius: 28px; object-fit: cover; background: var(--side-soft); }
.portrait { display: grid; place-items: center; font: 40px var(--display); color: var(--side-ink); }
.fighter.fallen > img { filter: grayscale(.85); opacity: .85; }
.fighter > div { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.fighter .name { font: 28px/1.1 var(--display); color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.fighter .pills { gap: 6px; }
.fighter .pill { background: var(--side-soft); }
.fighter .cp { font-weight: 700; }
.fighter .blow { font-size: 13px; color: var(--muted); }
.fighter .blow b { color: var(--ink); font-weight: 600; }
@media (max-width: 560px) {
  .fighter { padding: 16px; gap: 14px; }
  .fighter > img, .portrait { width: 72px; height: 72px; border-radius: 22px; }
  .portrait { font-size: 32px; }
  .fighter .name { font-size: 26px; }
}
@media (max-width: 720px) { .versus { grid-template-columns: minmax(0, 1fr); } .vs { display: none; } }

.timeline { --heal: #2DB3A6; --control: #E34948; --defiance: #EDA100; padding: 24px 24px 18px; }
.stats { display: flex; flex-wrap: wrap; gap: 24px; align-items: baseline; margin-bottom: 18px; }
.stats > div { display: flex; flex-direction: column; }
.stats b { font: 400 32px/1.1 var(--display); }
/* The plot is a grid of rows, each named in the gutter on its left: the windows of crowd control
   and Defiance, the HP, a lane for each attacker, the heals and the axis. The overlay lies over the
   HP and the lanes, right of the gutter, for the shading, the cursor and the readout. On a phone
   the gutter goes, and each lane's name sits over its top. */
.plot { --gutter: 148px; position: relative; display: grid; grid-template-columns: var(--gutter) minmax(0, 1fr); cursor: crosshair; touch-action: pan-y; }
.plot:focus-visible { outline: 2px solid var(--side); outline-offset: 6px; border-radius: 4px; }
.plot > :is(.head, .who) { grid-column: 1; min-width: 0; padding-right: 12px; display: flex; flex-direction: column; justify-content: center; gap: 0; line-height: 1.3; }
.plot > .head .note { font-size: 11.5px; }
.plot > .body { grid-column: 2; position: relative; min-width: 0; }
.plot .who > b { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plot .who > span { font-size: 11.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.plot .who .final { background: var(--side-soft); color: var(--side-ink); }
.plot .who.heals > b { color: #136B63; }
.overlay { position: absolute; left: var(--gutter); right: 0; top: var(--windows); bottom: 22px; pointer-events: none; }
.health { position: relative; height: 110px; border-bottom: 1px solid var(--track); }
.health svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.health .area { fill: color-mix(in srgb, var(--side) 12%, transparent); }
.health .total { fill: none; stroke: var(--side-ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
/* Without HP the caption takes the chart's place, below the Killed pill, and the chart grows to
   hold it on a narrow phone. */
.health:has(> .caption) { height: auto; min-height: 110px; display: grid; place-items: center; padding: 24px 16px 12px; }
.health .caption { max-width: 640px; text-align: center; }
.health .full { position: absolute; left: 0; right: 0; top: -7px; height: 16px; border-bottom: 1px dashed var(--track); }
.killed { position: absolute; right: 0; top: -2px; padding: 2px 8px; border-radius: 999px; background: var(--ink); color: #fff; font-size: 11px; font-weight: 700; white-space: nowrap; }
.killed small { opacity: .65; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; }
/* Each window's label takes a row of its own when it would cover another's. Its padding is on the
   text inside, so a label squeezed narrower than its padding is clipped rather than widened. */
.windows { height: var(--windows); }
.windows > span { position: absolute; top: calc(2px + var(--row, 0) * 20px); height: 18px; min-width: 3px; overflow: hidden; border-radius: 4px; font-size: 11px; font-weight: 700; line-height: 18px; color: #fff; }
.windows > span > span { display: block; padding: 0 6px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.windows .control { background: var(--control); }
.windows .defiance { background: var(--defiance); color: var(--ink); }
.shade { position: absolute; top: 0; bottom: 0; }
.shade.control { background: color-mix(in srgb, var(--control) 10%, transparent); }
.shade.defiance { background: color-mix(in srgb, var(--defiance) 14%, transparent); }
/* In each lane the attacker's hits rise to a line near its foot, `--base` from its top, and the
   victim's hits on them hang from it. The heals rise from the foot of a lane of their own. */
.lane { --base: 24px; position: relative; height: 34px; border-bottom: 1px solid var(--track); }
.lane:not(.heals)::before { content: ""; position: absolute; left: 0; right: 0; top: var(--base); height: 1px; background: var(--track); }
.tick { position: absolute; width: 3px; margin-left: -1.5px; background: var(--hit); }
.tick.taken { bottom: calc(100% - var(--base)); border-radius: 2px 2px 0 0; --hit: color-mix(in srgb, var(--side) 45%, white); --crit: var(--side-ink); }
.tick.dealt { top: calc(var(--base) + 1px); border-radius: 0 0 2px 2px; }
.tick.healed { bottom: 1px; border-radius: 2px 2px 0 0; --hit: #8FD6CC; --crit: #136B63; }
.plot.asmodian .tick.dealt { --hit: color-mix(in srgb, var(--elyos) 45%, white); --crit: var(--elyos-ink); }
.plot.elyos .tick.dealt { --hit: color-mix(in srgb, var(--asmodian) 45%, white); --crit: var(--asmodian-ink); }
.tick.crit { background: var(--crit); }
.tick.crit::after { content: ""; position: absolute; left: 50%; width: 6px; height: 6px; margin-left: -3px; border-radius: 50%; background: inherit; }
.tick:is(.taken, .healed).crit::after { top: -6px; }
.tick.dealt.crit::after { bottom: -6px; }
.cursor { position: absolute; top: 0; bottom: 0; width: 1px; margin-left: -.5px; background: var(--ink); opacity: .5; }
.tip { position: absolute; top: 8px; z-index: 2; width: max-content; max-width: min(340px, 80vw); padding: 10px 12px; border-radius: 12px; background: var(--card); box-shadow: var(--shadow), 0 0 0 1px var(--track); font-size: 13px; line-height: 1.4; }
.tip header { display: flex; justify-content: space-between; gap: 16px; margin-bottom: 6px; }
.tip header b { font: 400 18px/1.1 var(--display); }
.tip p { display: flex; align-items: baseline; gap: 8px; margin: 2px 0 0; }
.tip p::before { content: ""; flex: none; width: 10px; height: 3px; border-radius: 2px; background: var(--key); transform: translateY(-3px); }
.tip p b { margin-left: auto; padding-left: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tip .taken { --key: var(--side); }
.tip .healed { --key: var(--heal); }
.tip .control { --key: var(--control); }
.tip .defiance { --key: var(--defiance); }
.plot.asmodian .tip .dealt { --key: var(--elyos); }
.plot.elyos .tip .dealt { --key: var(--asmodian); }
.plot > .axis { height: 22px; }
.plot > .axis span { position: absolute; top: 4px; transform: translateX(-50%); white-space: nowrap; }
@media (max-width: 560px) {
  .timeline { padding: 20px 16px 14px; }
  .plot { --gutter: 0px; }
  .plot > .head { display: none; }
  .plot > .who { grid-column: 2; z-index: 1; height: 0; padding: 0; flex-direction: row; justify-content: flex-start; align-items: flex-start; gap: 4px; overflow: visible; }
  .plot .who > :is(b, span) { padding: 0 3px; border-radius: 4px; font-size: 11px; background: rgba(255, 255, 255, .85); }
  .lane { --base: 30px; height: 44px; }
}

.breakdowns { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
/* On a phone the breakdowns sit in a row that swipes sideways, with the next one peeking in. */
@media (max-width: 720px) {
  .breakdowns { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 16px; gap: 12px; margin: -8px -16px -24px; padding: 8px 16px 24px; }
  .breakdown { flex: 0 0 min(86%, 360px); scroll-snap-align: start; }
}
.breakdown { padding: 20px 22px; display: flex; flex-direction: column; gap: 12px; }
.breakdown .head { display: flex; align-items: baseline; gap: 8px; }
.breakdown .head b { font: 400 22px var(--display); color: var(--side-ink); }
.breakdown .head .note { margin-left: auto; text-align: right; }
.breakdown .hits { margin-left: 4px; }
.breakdown .foot { margin: auto -22px -20px; padding: 10px 22px 12px; background: var(--side-soft); border-radius: 0 0 24px 24px; color: var(--side-ink); font-size: 13px; }

/* Who fought: a row a player, with links to their gear and their killmails. */
.fought { overflow: hidden; }
.fought > div { display: flex; align-items: center; gap: 12px; padding: 10px 16px; }
.fought > div + div { border-top: 1px solid var(--track); }
.fought > div > img, .fought .portrait { flex: none; width: 44px; height: 44px; border-radius: 14px; object-fit: cover; background: var(--side-soft); font-size: 20px; }
.fought .what { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fought .what b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fought .what .note { font-size: 12.5px; line-height: 1.35; }
@media (max-width: 560px) { .fought .links { flex-direction: column; align-items: flex-end; gap: 2px; } }
.seen { padding: 16px 20px; display: flex; flex-direction: column; gap: 4px; }
.seen .facets { gap: 6px; }

#filter { max-width: 460px; }

.score { margin-top: 28px; padding: 22px 24px; display: flex; flex-wrap: wrap; gap: 14px; }
.score .side { flex: 1; min-width: 200px; display: flex; flex-direction: column; }
.score .side.asmodian { text-align: right; }
.score .side b { font: 400 44px/1 var(--display); color: var(--side-ink); }
.score .side .facet { align-self: flex-start; margin-top: 6px; }
.score .side.asmodian .facet { align-self: flex-end; }
.split { flex-basis: 100%; display: flex; height: 12px; border-radius: 6px; overflow: hidden; gap: 3px; }
.split i { background: var(--fill); }
.sides { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: 16px; }
.sides .table { margin: 0; }
:is(.sides, .answer) td a { color: var(--ink); font-weight: 600; text-decoration: none; }

/* A battle: the search across the bottom of the score's card, a card under it for what it found,
   each side's legions, which open to their players, then a strip of each minute's kills over a
   feed of the deaths. What was found is marked in yellow. */
#find { position: relative; flex: 1 1 100%; max-width: none; margin-top: 8px; scroll-margin-top: 12px; }
#find .query { background: #F4F2FA; box-shadow: none; }
#find .query:focus-within { background: #fff; box-shadow: 0 0 0 2px rgba(91, 63, 196, .35); }
#find input:focus { outline: none; }
/* Its suggestions, in a card under it drawn like a select's list: a row each as it's typed, the
   kind of each in a chip, and each side's hardest hitters as tiles before. A match is marked in
   the yellow of what a search found. */
.picks {
  position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 5; overflow: hidden; border-radius: 22px; background: var(--card);
  box-shadow: 0 28px 60px -24px rgba(40, 60, 140, .55), 0 0 0 1px rgba(91, 63, 196, .08);
}
.picks .kinds { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px 8px; }
/* They're buttons in the search's form, which would draw them like its Find button. */
.picks .kinds .pill { height: auto; padding: 4px 12px; border: 0; cursor: pointer; background: #F4F2FA; color: var(--ink); font: 600 13px "Noto Sans", sans-serif; }
.picks .kinds small { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.picks .kinds [aria-pressed="true"] { background: var(--ink); color: #fff; }
.picks .kinds [aria-pressed="true"] small { color: rgba(255, 255, 255, .7); }
.picks .list { overflow-y: auto; overscroll-behavior: contain; padding: 0 6px 6px; }
.pick { display: flex; align-items: center; gap: 12px; padding: 7px 10px; border-radius: 14px; cursor: pointer; }
.pick[aria-selected="true"] { background: #F0EBFF; }
.glyph { flex: none; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: var(--side-soft); color: var(--side-ink); }
.pick .what { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.pick .what > b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick .what .note { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick .kind { flex: none; font-size: 10.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--side-ink); }
.picks mark { margin: 0 -1px; padding: 0 1px; border-radius: 3px; background: #FFE39A; color: #6B4700; }
.picks .more { margin: 0; padding: 0 16px 10px; }
.picks .hint { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 0; padding: 14px 16px 6px; color: var(--muted); font-size: 14px; }
.picks .hint .glyph { width: 30px; height: 30px; background: #F0EBFF; color: var(--asmodian-ink); }
.picks .hint span:not(.glyph, .note) { flex: 1 1 200px; min-width: 0; }
.picks .hint .note { flex: none; margin-left: auto; }
.picks .offers { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 14px; padding: 8px 14px 14px; }
.picks .offers .role { display: block; margin: 0 0 8px 2px; }
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pick.tile { flex-direction: column; gap: 4px; min-width: 0; padding: 12px 8px 10px; border-radius: 16px; background: #FBFAFD; box-shadow: inset 0 0 0 1px var(--track); text-align: center; line-height: 1.25; }
.pick.tile b { max-width: 100%; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick.tile .note { font-size: 12px; }
.pick.tile[aria-selected="true"] { background: #F0EBFF; box-shadow: inset 0 0 0 1.5px rgba(91, 63, 196, .35); }
.picks .keys { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin: 0; padding: 8px 14px; border-top: 1px solid var(--track); background: #FAF9FD; color: var(--muted); font-size: 12px; }
.picks .keys .end { margin-left: auto; }
.picks kbd {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; margin-right: 5px; padding: 0 5px; border-radius: 6px; background: #fff;
  box-shadow: inset 0 0 0 1px rgba(91, 63, 196, .18), 0 1px 0 rgba(34, 29, 56, .08); color: var(--ink); font: 600 11px "Noto Sans", sans-serif;
}
/* A touch screen has no keys to name, and a phone's rows tell a legion from a player by the glyph. */
@media (pointer: coarse) { .picks .keys { display: none; } }
@media (max-width: 560px) { .pick .kind { display: none; } }
.answer { margin-top: 16px; padding: 18px 20px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; border-top: 4px solid var(--side); }
.answer .who { flex: 1 1 200px; display: flex; flex-direction: column; gap: 2px; }
.answer .who > .facets { margin-bottom: 4px; }
.answer .name { font: 30px/1.1 var(--display); color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.answer .stats { margin: 0; gap: 22px; }
.answer .stats b { font-size: 26px; }
.links { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.answer .links { flex-basis: 100%; flex-wrap: wrap; gap: 8px 18px; padding-top: 10px; border-top: 1px solid var(--track); }
.answer .clear { margin-left: auto; color: var(--muted); }
.answer .roster { flex: 0 0 calc(100% + 40px); min-width: 0; margin: 0 -20px; background: #FBFAFD; }
.answer .roster .table { margin: 0; border-radius: 0; box-shadow: none; background: none; }
/* A legion's card shows its first few players over a fold that holds them all, so while it's open
   the few go. */
.answer .roster:has(> .folded[open]) > .table { display: none; }
/* A legion's row names who the search found in it, and wraps rather than cut their name off. */
.hit { display: inline-block; max-width: 100%; margin-left: 6px; padding: 1px 8px; border-radius: 999px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: 1px; background: #FFE39A; color: #6B4700; font-size: 11px; font-weight: 700; }
.legion.found > summary b { white-space: normal; overflow-wrap: anywhere; }
.legions h3 { margin: 0 0 8px; font: 400 22px var(--display); color: var(--side-ink); }
.legions h3 .figures { margin-left: 4px; vertical-align: 3px; }
.legion-list { border-radius: 20px; background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.legion-list .cols, .legion > summary { display: grid; grid-template-columns: minmax(0, 1fr) 56px 104px 84px; gap: 10px; align-items: center; padding: 8px 14px; font-size: 13px; }
.legion-list .cols { color: var(--muted); font-weight: 600; }
.legion-list .cols span:not(:first-child), .legion > summary > span { text-align: right; font-variant-numeric: tabular-nums; }
.legion, .folded { border-top: 1px solid var(--track); }
.legion > summary, .folded > summary, .feed summary { position: relative; cursor: pointer; list-style: none; }
:is(.legion, .folded, .feed details) > summary::-webkit-details-marker { display: none; }
.legion > summary b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legion > summary b::before { content: "▸"; display: inline-block; width: 14px; color: var(--muted); transition: rotate .15s; }
.legion[open] > summary b::before { rotate: 90deg; }
.legion > summary i { position: absolute; left: 14px; bottom: 0; height: 3px; border-radius: 2px; background: var(--fill); }
@media (hover: hover) { .legion > summary:hover { background: #F6F4FB; } }
.legion.found > summary, tr.found td { background: #FFF6DA; }
.legion .table { margin: 0; border-radius: 0; box-shadow: none; background: #FBFAFD; }
.legion .table > .note { margin: 0; padding: 8px 14px; }
:is(.legion, .answer) .table td.rank { width: 1%; padding-right: 0; color: var(--muted); }
.folded > summary, .feed summary { padding: 8px 14px; background: #FAF9FD; color: var(--asmodian-ink); font-size: 13px; font-weight: 600; }
:is(.folded, .feed details) > summary::before { content: "▸"; display: inline-block; width: 14px; transition: rotate .15s; }
:is(.folded, .feed details)[open] > summary::before { rotate: 90deg; }
.feed details { border-top: 1px solid var(--track); }
.strip { padding: 14px 18px 8px; }
.strip .bars { position: relative; height: 64px; }
.strip .bars::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--track); }
.strip .bars > * { position: absolute; top: 0; bottom: 0; border-radius: 4px; }
@media (hover: hover) { .strip .bars a:hover { background: rgba(91, 63, 196, .08); } }
.strip .bars i { position: absolute; left: 15%; right: 15%; max-width: 24px; margin: 0 auto; background: var(--side); }
.strip i.up { bottom: 50%; border-radius: 3px 3px 0 0; }
.strip i.down { top: calc(50% + 1px); border-radius: 0 0 3px 3px; }
.strip .narrowed i { opacity: .25; }
.strip .narrowed i.kept { opacity: 1; }
.strip .axis { position: relative; height: 22px; }
.strip .axis span { position: absolute; top: 4px; transform: translateX(-50%); white-space: nowrap; }
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 14px 0 4px; }
.chips .pill { color: var(--ink); text-decoration: none; }
.chips .pill[aria-current] { background: var(--ink); color: #fff; }
.chips > .note { margin-left: auto; }
.minute { margin-top: 14px; scroll-margin-top: 16px; }
.minute > header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0 4px 8px; }
.minute > header time { font: 400 20px var(--display); }
.minute > header .split { flex: 0 0 120px; height: 8px; align-self: center; }
.feed { border-radius: 18px; background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.feed a { display: flex; align-items: center; gap: 10px; padding: 7px 14px; border-top: 1px solid var(--track); color: var(--ink); text-decoration: none; font-size: 14px; }
.feed > a:first-child { border-top: 0; }
@media (hover: hover) { .feed a:hover { background: #F6F4FB; } }
.feed time { flex: none; width: 76px; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.feed .what { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed .tags { flex: none; display: flex; flex-direction: column; gap: 3px; }
.feed .tag { width: 56px; font-size: 10px; }
@media (max-width: 480px) {
  .legion-list .cols, .legion > summary { grid-template-columns: minmax(0, 1fr) 40px 92px; }
  .legion-list .cols span:last-child, .legion > summary > span:last-of-type { display: none; }
  .strip .axis span:nth-child(even) { display: none; }
  .feed .what { white-space: normal; overflow-wrap: anywhere; }
}

/* The census. A server's page shows its classes as cards, the three most played larger than the
   rest, and stands three of its legions on a podium over a ranking of the rest, as its wings and
   titles are ranked, all in its faction's colors. Every server together is a board, a card a
   region: each faction's characters between its servers, over a column of each faction's servers,
   which link to their own census. A legion's page ranks its members the same way. */
/* A server's three counts stay in a row on a phone, and a legion's four go two by two. */
@media (max-width: 560px) {
  .census .tally { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .census .tally:has(> :nth-child(4)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .census .tally .panel { padding: 12px 14px; }
  .census .tally b { font-size: 26px; }
}
.class-cards { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; }
.class-cards .panel { min-width: 0; padding: 14px 18px 16px; display: flex; flex-direction: column; gap: 6px; border-radius: 22px; }
.class-cards .panel:nth-child(-n+3) { grid-column: span 2; }
.class-cards header { display: flex; justify-content: space-between; align-items: center; }
.class-cards .share { padding: 2px 10px; border-radius: 999px; background: var(--side-soft); color: var(--side-ink); font-size: 12px; font-weight: 700; }
.class-cards h3 { margin: 2px 0 0; font: 400 26px/1.1 var(--display); overflow-wrap: anywhere; }
.class-cards p { margin: 0; }
.class-cards p b { font: 400 36px/1 var(--display); font-variant-numeric: tabular-nums; }
.class-cards .bar { margin-top: 4px; }
/* The rest are smaller, and say only how many. */
.class-cards .panel:nth-child(n+4) h3 { font-size: 21px; }
.class-cards .panel:nth-child(n+4) p b { font-size: 30px; }
.class-cards .panel:nth-child(n+4) p .note { position: absolute; left: -9999px; }
@media (max-width: 900px) {
  .class-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .class-cards .panel:nth-child(-n+3) { grid-column: auto; }
  .class-cards .panel:first-child { grid-column: 1 / -1; }
}
@media (max-width: 560px) { .class-cards .panel { padding: 12px 14px; } .class-cards h3 { font-size: 22px; } .class-cards p b { font-size: 30px; } }
.heading { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 40px 0 16px; scroll-margin-top: 16px; }
.heading h2 { margin: 0; }
.heading .tabs, .heading > .how { margin: 0 0 0 auto; }
.heading .tabs a { padding: 6px 16px; font-size: 14px; }
/* The first stands in the middle, raised, and on a phone they stand in line. */
.podium { display: flex; justify-content: center; align-items: flex-end; gap: 16px; margin: 0 0 16px; padding: 0; list-style: none; }
.podium .panel { flex: 0 1 calc((100% - 32px) / 3); min-width: 0; padding: 22px 20px 20px; display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; border-top: 4px solid var(--side); }
.podium .first { order: 2; padding-top: 40px; }
.podium .second { order: 1; }
.podium .third { order: 3; }
.medal { display: grid; place-items: center; width: 52px; height: 52px; margin-bottom: 8px; border-radius: 50%; font-size: 22px; font-weight: 700; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .7), var(--shadow); }
.first .medal { background: linear-gradient(135deg, #F3D27E, #FFF3CF 45%, #D9A73E); color: #7A4E00; }
.second .medal { background: linear-gradient(135deg, #C9CFDF, #F7F8FC 45%, #AEB6CB); color: #4A4F66; }
.third .medal { background: linear-gradient(135deg, #E7B48E, #FCEBDD 45%, #B9784A); color: #7A4320; }
.podium .name { max-width: 100%; font: 400 32px/1.1 var(--display); overflow-wrap: anywhere; }
:is(.podium .name, .ranking b) a { color: inherit; text-decoration: none; }
@media (hover: hover) { :is(.podium .name, .ranking b) a:hover { text-decoration: underline; } }
.podium .first .name { font-size: 40px; }
.podium .stats { margin: 12px 0 0; gap: 8px 28px; justify-content: center; }
.podium .stats b { font-size: 26px; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .podium { flex-direction: column; align-items: stretch; gap: 12px; }
  .podium .panel { order: 0; padding-top: 22px; }
  .podium .first .name { font-size: 34px; }
}
.ranking { margin: 0; padding: 0; list-style: none; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.ranking li { position: relative; display: grid; grid-template-columns: 22px minmax(0, 1fr) repeat(var(--columns), 104px); gap: 10px; align-items: center; padding: 9px 14px 11px; font-size: 13px; }
.ranking li + li { border-top: 1px solid var(--track); }
.ranking .cols { padding: 8px 14px; color: var(--muted); font-weight: 600; }
.ranking li > span { text-align: right; font-variant-numeric: tabular-nums; }
.ranking .rank { text-align: center; color: var(--muted); font-weight: 700; }
.ranking b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ranking i { position: absolute; left: 46px; bottom: 0; height: 3px; border-radius: 2px; background: var(--fill); }
@media (max-width: 480px) { .ranking li { grid-template-columns: 20px minmax(0, 1fr) repeat(var(--columns), 80px); } .ranking i { left: 44px; } }
.census .all { margin: 14px 0 0; text-align: center; }
/* The census of gathering: each row a bar of how its gathers went, great successes in the colors
   the game gives the grades of what they gave, Unique's gold, Epic's blue and Rare's green, then
   successes in Common's gray, parted by the card's color, and the fails the empty track after
   them. A great success of a grade kisk doesn't know is violet. The percents beside it say the
   same for anyone who can't tell the colors apart. */
.gathering { --unique: #D9A73E; --epic: #3B7DD8; --rare: #4FA845; --unknown: #8466EA; --success: #8E8AA8; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 12px; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 12px; height: 12px; border-radius: 4px; background: var(--track); }
.gathering .unique { background: var(--unique); }
.gathering .epic { background: var(--epic); }
.gathering .rare { background: var(--rare); }
.gathering .unknown { background: var(--unknown); }
.gathering .success { background: var(--success); }
.rates { margin: 0 0 16px; padding: 0; list-style: none; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.rates li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; align-items: center; padding: 10px 16px 12px; font-size: 13px; }
.rates li + li { border-top: 1px solid var(--track); }
.rates b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rates .n { color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.rates .figures { grid-column: 1 / -1; }
.split { grid-column: 1 / -1; display: flex; height: 10px; border-radius: 4px; background: var(--track); overflow: hidden; }
.split i { flex: none; height: 100%; }
.split i + i { border-left: 2px solid var(--card); }
/* The chart of a server's combat power: a column each 5k of it, the characters at the level cap
   rising from the line and those still leveling hanging under it, as the battle strip hangs the
   Elyos' kills. A class stands in front of the whole server, in gray. A line marks the least combat
   power of each top share, its label in the first of `--rows` rows it covers no other in, which
   page.js works out, and on the left of its line where the right runs out of room. The bars under
   the line grow as far as `--under`, or as far as those over it. */
.census .chips { margin: 0 0 14px; }
.chips .pill small { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.chips .pill[aria-current] small { color: rgba(255, 255, 255, .7); }
.spread { --rest: #A9A4BD; --behind: #D3CFE2; padding: 16px 20px 8px; }
.spread:focus-visible { outline: 2px solid var(--side); outline-offset: 4px; }
.spread .up { --key: var(--side); }
.spread .down { --key: var(--rest); }
.spread .behind { --key: var(--behind); }
.spread .key { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 6px; font-size: 12.5px; color: var(--muted); }
.spread .key span::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 6px; border-radius: 3px; background: var(--key); vertical-align: -1px; }
.spread .marked { position: relative; padding-top: calc(var(--rows) * 18px + 4px); cursor: crosshair; touch-action: pan-y; }
.spread .columns { position: relative; height: calc(var(--reach) + var(--under, var(--reach)) + 1px); }
.spread .columns::before { content: ""; position: absolute; left: 0; right: 0; top: var(--reach); height: 1px; background: var(--track); }
.spread .column { position: absolute; top: 0; bottom: 0; border-radius: 4px; }
.spread .column.on { background: rgba(91, 63, 196, .08); }
.spread .column i { position: absolute; left: 1px; right: 1px; max-width: 24px; margin: 0 auto; background: var(--key); }
.spread i.up { bottom: calc(100% - var(--reach)); border-radius: 3px 3px 0 0; }
.spread i.down { top: calc(var(--reach) + 1px); border-radius: 0 0 3px 3px; }
.cutoff { position: absolute; top: calc(var(--row) * 18px + 1px); bottom: 0; width: 1px; margin-left: -.5px; background: rgba(34, 29, 56, .3); pointer-events: none; }
.cutoff b { position: absolute; z-index: 1; top: -1px; left: 3px; padding: 0 3px; border-radius: 4px; background: rgba(255, 255, 255, .92); color: var(--muted); font-size: 11px; font-weight: 700; line-height: 16px; white-space: nowrap; }
.cutoff.left b { left: auto; right: 3px; }
.cutoff b span { color: var(--ink); }
.spread .tip > .note { display: block; margin-top: 6px; font-size: 12px; }
.spread .axis { position: relative; height: 22px; }
.spread .axis span { position: absolute; top: 4px; transform: translateX(-50%); white-space: nowrap; font-size: 12px; font-variant-numeric: tabular-nums; }
.spread .axis span:first-child { transform: none; }
/* Too few characters to chart: the strip's outline, saying so. */
.spread.empty .marked { cursor: default; }
.spread.empty .column i, .spread.empty .columns::before { background: #EEECF5; }
.spread .none { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; }
.spread .none span { padding: 4px 14px; border-radius: 999px; background: rgba(255, 255, 255, .9); color: var(--muted); font-size: 14px; font-weight: 600; }
@media (max-width: 560px) {
  .spread { padding: 14px 14px 6px; }
  .spread .axis span:nth-child(even) { display: none; }
}
/* The gathering page's charts, in the combat power chart's style, several to a panel. A rank's
   material rises in the color the game gives it, Common's gray, Fine's green, Pure's blue and
   Radiant's gold, and the rest of the materials in gray behind the one picked. What the Appraiser
   added stands on the base roll, parted from it, in a berry no rank's color is near, even to an
   eye that can't tell red from green. Great successes rise in the accent, and a column of too few
   gathers to go by is faded. */
.gathers { --side: var(--asmodian); --common: #8E8AA8; --fine: #4FA845; --pure: #3B7DD8; --radiant: #D9A73E; --other: #DEDAEC; --other-down: #ECEAF3; --faded: #EEECF5; --appraised: #C2417F; --appraised-other: #EBCADB; }
.gathers .spread .common { --key: var(--common); }
.gathers .spread .fine { --key: var(--fine); }
.gathers .spread .pure { --key: var(--pure); }
.gathers .spread .radiant { --key: var(--radiant); }
.gathers .spread .other { --key: var(--other); }
.gathers .spread .down.other { --key: var(--other-down); }
.gathers .spread .cap { --key: var(--appraised); }
.gathers .spread .cap.other { --key: var(--appraised-other); }
.gathers .spread .faded { --key: var(--faded); }
.gathers .spread i.cap { bottom: calc(100% - var(--reach) + var(--lift)); }
.gathers .spread .key b { color: var(--ink); }
.spread .spread { padding: 0; }
.gathers .spread h3 { margin: 0 0 2px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.gathers .spread h3 i { display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--key); vertical-align: 1px; }
.gathers .charts { display: grid; grid-template-columns: var(--widths); gap: 14px 22px; align-items: end; }
.gathers .charts.talents { --widths: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); margin-top: 14px; }
.gathers .spread .axis span { transform: translateX(-50%); }
.gathers .spread .axis .start { transform: none; }
.gathers .spread .axis .end { transform: translateX(-100%); }
.gathers .foot { margin: 0 0 6px; font-size: 12px; }
.gathers .foot b { color: var(--ink); }
.gathers .chips { margin: 0 0 14px; }
.gathers .charts .spread .axis span { font-size: 11px; }
@media (max-width: 560px) {
  .gathers .charts:not(.talents) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gathers .charts .spread .axis span:nth-child(even) { display: inline; }
}
/* /stats: a panel of charts in the gathering page's style each, side by side where there's room.
   The addons of older versions stack over the latest's, in gray. */
.usage { --side: var(--asmodian); }
.usage .charts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 22px 28px; align-items: end; }
.usage .spread h3 { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.usage .spread h3 + .note { margin: 0 0 4px; }
.usage .spread .older { --key: var(--rest); }
.usage .spread i.older { bottom: calc(100% - var(--reach) + var(--lift)); }
.usage .spread .axis span { transform: translateX(-50%); font-size: 11px; }
.usage .spread .axis .start { transform: none; }
.usage .spread .axis .end { transform: translateX(-100%); }
.region { margin-top: 20px; padding: 20px 24px 12px; }
.region > header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.region h2 { margin: 0; font-size: 28px; }
.region .score { margin: 10px 0 8px; padding: 0; gap: 8px; }
/* With no notes under them, the factions' counts fit side by side on a phone. */
.region .score .side { min-width: 0; }
.region .score .side b { font-size: 30px; font-variant-numeric: tabular-nums; }
.region .split { height: 10px; }
.servers { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); gap: 0 28px; }
.server { position: relative; display: flex; align-items: center; gap: 12px; padding: 9px 2px 12px; border-top: 1px solid var(--track); color: var(--ink); text-decoration: none; }
@media (hover: hover) { .server:hover { background: #F6F4FB; } }
.server .what { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.server .what b { font-weight: 600; color: var(--side-ink); }
.server .what .note { font-size: 12px; }
.server .what .facets { margin-top: 4px; }
.server > b { font: 400 22px/1 var(--display); font-variant-numeric: tabular-nums; }
.server i { position: absolute; left: 2px; bottom: 0; height: 3px; border-radius: 2px; background: var(--fill); }
@media (max-width: 560px) { .region { padding: 16px 16px 8px; } }

/* Maps: where a killmail's victim died, and a battle's deaths. The land is white in
   the sky, where Reshanta's islands float, and drawn from where things are (see maps.rs). Marks
   and labels lie over it so they keep their size at any width. Each label was placed so it covers
   no other on a phone, or else only on a map as wide as it gets, and hides on a narrower one. */
.whereabouts { padding: 20px 24px 16px; }
.whereabouts .near { margin: 0 0 14px; color: var(--muted); }
.whereabouts .near b { color: var(--ink); font-weight: 600; }
.whereabouts .near .facet { margin-left: 4px; vertical-align: 1px; }
@media (max-width: 560px) { .whereabouts { padding: 16px 12px 12px; } }
/* The outline keeps the map's edge where land runs to it, white on the white panel. */
.map { position: relative; overflow: hidden; container-type: inline-size; border-radius: 16px; background: #DCEAF8; outline: 1px solid rgba(40, 60, 140, .1); outline-offset: -1px; }
/* A map too close in for its land draws a line every scale bar apart instead, as the page says. */
.map.grid {
  background-color: #F4F7FC;
  background-image: linear-gradient(90deg, rgba(40, 60, 140, .1) 1px, transparent 1px), linear-gradient(rgba(40, 60, 140, .1) 1px, transparent 1px);
}
.map svg { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 3px 3px rgba(40, 60, 140, .18)); }
.map .land { fill: none; stroke: #FFFFFF; stroke-linecap: round; }
.map > :not(svg), .map .world > * { position: absolute; }
/* page.js grows and moves the world as the map zooms. */
.map .world { left: 0; top: 0; width: 100%; height: 100%; }
/* Zoomed in, a drag looks around the map; zoomed out, it scrolls the page. A double tap zooms the
   map rather than the page. */
.atlas .map { touch-action: manipulation; }
.atlas .map.zoomed { touch-action: none; cursor: grab; }
.map.dragging { cursor: grabbing; }
.atlas { position: relative; }
.zoom { position: absolute; right: 10px; bottom: 10px; display: flex; gap: 4px; }
.zoom button {
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px;
  background: rgba(255, 255, 255, .92); box-shadow: 0 1px 4px rgba(40, 60, 140, .25);
  color: var(--ink); font-family: inherit; font-size: 20px; font-weight: 600; line-height: 1; cursor: pointer;
}
.zoom button:disabled { opacity: .45; cursor: default; }
.zoom button:focus-visible { outline: 2px solid var(--asmodian); outline-offset: 2px; }
.zoom svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.map .landmark { width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: #8C88A3; }
.map .mark { width: 10px; height: 10px; margin: -5px 0 0 -5px; border: 1.5px solid #fff; border-radius: 50%; background: var(--side); }
.map .mark.nobody { --side: #B4B0C4; }
.map .mark.faded { opacity: .3; }
.map .mark.victim { width: 20px; height: 20px; margin: -10px 0 0 -10px; border-width: 2px; background: var(--side-ink); box-shadow: 0 2px 6px rgba(34, 29, 56, .35); }
.map .mark.victim::before, .map .mark.victim::after { content: ""; position: absolute; left: 3px; right: 3px; top: 50%; height: 2px; margin-top: -1px; border-radius: 1px; background: #fff; rotate: 45deg; }
.map .mark.victim::after { rotate: -45deg; }
.map a.mark { transition: scale .15s; }
@media (hover: hover) { .map a.mark:hover { z-index: 1; scale: 1.5; } }
.map .label {
  transform: translate(7px, -50%); padding: 0 3px; border-radius: 4px; background: rgba(255, 255, 255, .8);
  color: var(--muted); font-size: 11.5px; line-height: 16px; white-space: nowrap; pointer-events: none;
}
.map .label.left { transform: translate(calc(-100% - 7px), -50%); }
@container (max-width: 1039px) { .map .label.wide { display: none; } }
.map .scale { left: 12px; bottom: 10px; height: 5px; border: 1.5px solid var(--ink); border-top: 0; }
.map .scale span { position: absolute; left: 0; bottom: 5px; font-size: 11px; font-weight: 600; line-height: 16px; white-space: nowrap; }

/* A character's tabs, and beside them This is me, which goes under them on a phone. */
.sections { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin-top: 28px; }
.sections .tabs { margin-top: 0; }
.tabs { display: flex; gap: 4px; margin-top: 28px; padding: 4px; border-radius: 999px; background: rgba(255, 255, 255, .6); width: fit-content; }
.tabs :is(a, button) { padding: 8px 20px; border: 0; border-radius: 999px; background: none; text-decoration: none; font: 600 15px "Noto Sans", sans-serif; color: var(--ink); cursor: pointer; }
.tabs :is(a[aria-current], button[aria-pressed="true"]) { background: #fff; box-shadow: 0 6px 16px -10px rgba(40, 60, 140, .5); }
.tabs button:focus-visible { outline: 2px solid var(--asmodian); outline-offset: 2px; }
/* A character's three tabs only fit the narrowest phones with less room around each. */
@media (max-width: 400px) { .tabs :is(a, button) { padding: 8px 14px; } }
.tally { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 24px 0; }
.tally .panel { padding: 14px 18px; display: flex; flex-direction: column; }
.tally b { font: 400 34px/1.1 var(--display); }
/* What the census heard a character show, on their profile, which are names rather than counts. */
.facts { grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.facts b { font-size: 24px; }
.rows { display: flex; flex-direction: column; gap: 10px; }
.row { display: flex; align-items: center; gap: 14px; padding: 12px 18px; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); color: var(--ink); text-decoration: none; transition: transform .2s cubic-bezier(.34, 1.56, .64, 1); }
@media (hover: hover) { .row:hover { transform: translateY(-2px); } }
.row .what { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.row .what > b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row > .note { text-align: right; }
/* A battle on the battles page: its score, and with a search, the part of whoever it found, in the
   yellow of what a search finds. The strip over the list links to a battle's row. */
.battle { flex-wrap: wrap; gap: 8px 22px; scroll-margin-top: 16px; }
.battle .what { flex: 1 1 300px; gap: 3px; }
.battle:target { outline: 2px solid var(--asmodian); outline-offset: 2px; }
.kda { flex: none; padding: 2px 10px; border-radius: 999px; background: #FFE39A; color: #6B4700; font-size: 12px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* With a legion found, the pill splits: how many of its players were there, then what they did. */
.kda small { margin: -2px 5px -2px -10px; padding: 2px 8px 2px 10px; border-radius: 999px 0 0 999px; background: rgba(107, 71, 0, .1); font-size: inherit; font-weight: 600; }
.kills { flex: 0 0 150px; display: flex; flex-direction: column; gap: 5px; }
.kills .nums { display: flex; justify-content: space-between; align-items: baseline; }
.kills b { font: 400 22px/1 var(--display); }
.kills .split { flex: none; height: 8px; }
@media (max-width: 480px) { .battle .kills { flex: 1 1 150px; max-width: 220px; margin-left: auto; } }
.tag { flex: none; width: 64px; padding: 3px 0; border-radius: 999px; text-align: center; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.tag.kill { background: #E6F0FF; color: var(--elyos-ink); }
.tag.death { background: #ECEAF2; color: var(--muted); }
.tag.assist { background: #F0EBFF; color: var(--asmodian-ink); }

/* Progression: what a character's kisk addon shared, or the word on how to share it, over what the
   official armory shows. Each kind of title and each genus is a panel with a bar in the faction's
   color, over folds that list what's in it. */
.progress:not(.elyos, .asmodian) { --fill: linear-gradient(90deg, #2DB3A6, #7FD8C9); }
.progress h2 + .sub { margin: -10px 0 16px; }
.invite { margin-top: 24px; padding: 18px 22px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.invite b { font: 400 24px/1.2 var(--display); }
.invite p { margin: 0; max-width: 680px; }
.tracks { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 12px; align-items: start; }
.track { overflow: hidden; }
.track .head { padding: 14px 18px; display: flex; flex-direction: column; gap: 8px; }
.track header { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.track header b { font: 400 22px/1.2 var(--display); }
.wearing { margin: 0; display: flex; flex-direction: column; }
.wearing b { font-weight: 600; }
.titles, .pets { margin: 0; padding: 0; list-style: none; max-height: 440px; overflow-y: auto; }
.titles li { display: flex; flex-direction: column; padding: 9px 18px; border-top: 1px solid var(--track); }
.titles.open li:first-child { border-top: 0; }
.titles b { font-weight: 600; }
.about { margin-top: 2px; font-size: 13px; white-space: pre-line; }
.pets li { display: flex; justify-content: space-between; gap: 12px; padding: 6px 18px; border-top: 1px solid var(--track); font-size: 14px; }
.pets li.done { color: var(--muted); }
.progress .board { gap: 2px; }
.progress .board .bar { margin-top: 6px; }

/* Upgrades: what it takes to bring each piece to S+. A piece to reroll is a card: a bar from its
   score now to the range its plan ends in, whichever stats land, with S+ marked and the average
   ticked; its rerolls, numbered in the character's order on foil coins; and the stats they aim
   for, by how they compare with the best of them. The card to start on is framed in foil. The
   other lists are a board each and a row per piece. */
.routes { display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; list-style: none; }
.route { padding: 16px 18px; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); }
.route.next {
  padding: 13px 15px; border: 3px solid transparent;
  background: linear-gradient(var(--card), var(--card)) padding-box, conic-gradient(from 200deg, #FFE7A3, #FFC6E5, #C6D8FF, #C9F5E6, #FFE7A3) border-box;
  box-shadow: 0 20px 44px -24px rgba(120, 80, 200, .7);
}
.route header { display: flex; align-items: center; gap: 14px; }
.route header > div { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.route header .pill.label { background: linear-gradient(90deg, #D9488F, #D68A10, #1E8FCB, #6E4BD8); color: #fff; }
:is(.route, .plan) .picture img { width: 44px; height: 44px; border-radius: 12px; background: #F1EEFA; }
.reach { position: relative; height: 10px; margin: 32px 0 4px; border-radius: 999px; background: var(--track); }
.reach i { position: absolute; }
.reach .now { top: 0; bottom: 0; left: 0; border-radius: 999px; background: var(--fill); }
.reach .aim { top: -9px; bottom: -9px; border-left: 1.5px dashed var(--asmodian-ink); }
.reach .aim span { position: absolute; top: -19px; left: -9px; font: 13px/1 var(--display); font-style: normal; color: var(--asmodian-ink); }
.reach .band { top: -3px; bottom: -3px; border-radius: 999px; background: linear-gradient(90deg, #FF9FC6, #FFC861, #7FD8FF, #B08CFF); box-shadow: 0 0 0 2px var(--card); }
.reach .mean { top: -6px; bottom: -6px; width: 3px; margin-left: -1.5px; border-radius: 2px; background: var(--ink); }
.route .average { margin: 0; text-align: right; }
.steps { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 12px 0 0; padding: 0; list-style: none; }
.steps li { display: flex; align-items: center; gap: 8px; }
.steps li + li::before { content: "→"; color: var(--muted); }
.step { display: inline-flex; align-items: center; gap: 8px; padding: 3px 12px 3px 3px; border-radius: 999px; background: #F4F1FC; font-size: 13px; }
.step b { font-weight: 600; }
.step .note { font-size: 12px; }
.route.next .steps li:first-child .step { background: var(--card); box-shadow: inset 0 0 0 1.5px #E7B95A; }
.coin, ol.plan li::before {
  width: 24px; height: 24px; flex: none; border-radius: 50%; display: grid; place-items: center; font: 13px/1 var(--display); color: #5B3A00;
  background: conic-gradient(from 200deg, #FFE7A3, #FFC6E5, #C6D8FF, #C9F5E6, #FFE7A3); box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .85), 0 3px 8px -3px rgba(90, 60, 0, .45);
}
.route .lead { margin: 14px 0 8px; }
.targets { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: center; gap: 7px 14px; margin: 0; font-size: 13px; }
.targets dt { display: flex; align-items: baseline; gap: 8px; }
.targets dt b { min-width: 3.2em; }
.targets dd { margin: 0; }
.facet.best { background: linear-gradient(135deg, #FFE7A3, #F2C14E); color: #5B3A00; }
.facet.good { background: #E4DCFF; color: #3E2A8C; }
.then { display: flex; align-items: center; gap: 6px; margin: 12px 0 0; color: var(--asmodian-ink); font-size: 13px; font-weight: 600; }
.board.plan { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.plan li { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 4px 14px; padding: 12px 18px; }
.plan li + li { border-top: 1px solid var(--track); }
ol.plan li { grid-template-columns: 24px auto minmax(0, 1fr); counter-increment: step; }
ol.plan li::before { content: counter(step); }
.plan .what { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.plan .what b { font-weight: 600; }
.plan .facets { margin-top: 1px; }
.named { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.grades { color: var(--muted); font-size: 13px; white-space: nowrap; }
.grades .letter { font: 15px var(--display); }
@media (max-width: 560px) {
  .route { padding: 14px; }
  .route.next { padding: 11px; }
  .targets dt { flex-direction: column; gap: 0; }
  .plan li { align-items: start; }
  ol.plan li::before { margin-top: 10px; }
}

/* Timers: the open world's timetable on a region's servers. The next siege or Nahma is a card in
   the S grade's gold, over what's on and what's next, and the week's sieges and Nahma by the days
   of the reader's clock, which page.js lays out. Each event keeps one color down the page. */
[data-event="siege"] { --event: #3A3170; }
[data-event="nahma"] { --event: #C2549B; }
[data-event="arena"] { --event: #4C8DF0; }
[data-event="kaira"] { --event: #8A6BE6; }
[data-event="rift"] { --event: #2DB3A6; }
[data-event="festival"] { --event: #E2B24B; }
.controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.controls #filter { flex: 0 1 220px; }
.controls .tabs { margin-top: 0; }
#clock[hidden] { display: none; }
/* A card this wide would swing far out at a gear card's tilt, so it's seen from further away. */
.card.headliner { margin-top: 28px; transform: perspective(2600px) rotateX(var(--rx)) rotateY(var(--ry)); }
.headliner .face { flex-flow: row wrap; align-items: center; gap: 14px 24px; padding: 20px 24px; }
.headliner .what { flex: 1 1 280px; }
.headliner :is(h2, h3) { margin: 0; font: 400 36px/1.1 var(--display); }
.headliner p { margin: 6px 0 0; }
.headliner p:first-of-type::first-letter { text-transform: uppercase; }
/* "Tomorrow at 9:00 PM" goes to the next line whole, rather than leave its PM there alone. */
.headliner time { white-space: nowrap; }
.headliner .count { margin-left: auto; text-align: right; }
/* Marcellus has no tabular figures, so a countdown in it would change width every second and move
   the card's text and what's under it. It keeps the room of 00:00:00, about 4em, when it's shorter,
   as under ten hours or a day out. */
.headliner .count b { display: block; min-width: 4em; font: 400 44px/1 "Noto Sans", sans-serif; font-variant-numeric: tabular-nums; color: var(--letter); }
.timetable { margin: 0; padding: 4px 0; list-style: none; }
.timetable li { --fill: var(--event); display: grid; grid-template-columns: 10px minmax(0, 1fr) auto; gap: 4px 14px; align-items: center; padding: 11px 20px; border-top: 1px solid var(--track); }
.timetable li:first-child { border-top: 0; }
.timetable .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--event); }
.timetable .reset .dot { background: none; box-shadow: inset 0 0 0 2px var(--ink); }
.timetable b { display: block; font-weight: 600; }
.timetable .note { display: block; }
.timetable .when { text-align: right; }
.timetable .when b { white-space: nowrap; font-variant-numeric: tabular-nums; }
.timetable .bar { grid-column: 2 / -1; height: 6px; }
/* The week, a column a day. Without page.js it's the runs in a row, each with its day. */
.week { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
.week ul { flex: 1; margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.day { display: flex; flex-direction: column; gap: 2px; min-height: 150px; padding: 10px 10px 12px; border-radius: 18px; background: rgba(255, 255, 255, .6); }
.day.today { background: var(--card); box-shadow: var(--shadow); }
.day > b { font: 400 19px/1.1 var(--display); }
.day > .note { margin-bottom: 8px; font-size: 12px; }
.week [data-event] { padding: 7px 8px; border-left: 3px solid var(--event); border-radius: 4px 12px 12px 4px; background: color-mix(in srgb, var(--event) 11%, #fff); }
.week [data-event] time { display: block; font: 400 16px/1.2 var(--display); white-space: nowrap; }
.week [data-event] span { display: block; font-size: 12px; font-weight: 600; line-height: 1.25; }
.week .done { opacity: .45; }
.week .live { box-shadow: 0 0 0 2px #E2B24B; }
.week [data-event="weekly-reset"] { margin-top: auto; display: flex; flex-wrap: wrap; gap: 0 4px; padding: 0; border: 0; background: none; }
.week [data-event="weekly-reset"] :is(time, span) { font: 700 11.5px/1.3 "Noto Sans", sans-serif; }
.week [data-event="weekly-reset"] span { order: -1; }
#timers > .note { margin-top: 16px; }
@media (max-width: 560px) {
  .headliner .count { margin-left: 0; text-align: left; }
  .timetable li { padding: 10px 16px; }
  .week { grid-template-columns: minmax(0, 1fr); }
  .day { display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-rows: auto 1fr; column-gap: 12px; min-height: 0; }
  .day > ul { grid-column: 2; grid-row: 1 / span 2; }
}

/* Dark: the same sky at night. The clouds turn to nebulae over a field of stars, the cards are
   printed on dark stock so their foils glow, and every ink lightens to read on it. */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --ink: #ECE8FA; --muted: #A6A1C2; --card: #1B1934; --track: rgba(210, 200, 255, .1);
    --elyos: #4D8BF0; --elyos-ink: #93B8FF; --asmodian: #8466EA; --asmodian-ink: #BBA6FF;
    --shadow: 0 14px 34px -18px rgba(0, 0, 0, .8), 0 0 0 1px rgba(210, 200, 255, .07);
    /* What's printed on the ink's color, as on a label pill: white by day, the night by night. */
    --on-ink: #15132A;
    --raised: #24214A; --sunk: #16142C; --hover: rgba(187, 166, 255, .07); --found: rgba(255, 205, 90, .12);
  }
  /* As by day, the background color is the top of the sky, for iOS 26's status bar. */
  body { background: linear-gradient(180deg, #0F1433 0, #0C0F26 420px, #0A0B1C 100%) no-repeat, #0F1433; }

  /* Stars only where no heading reaches, so none reads as a full stop. */
  .sky {
    background:
      radial-gradient(1px 1px at 6% 4%, rgba(255, 255, 255, 0.6) 50%, transparent),
      radial-gradient(1.5px 1.5px at 19% 7%, rgba(255, 255, 255, 0.8) 50%, transparent),
      radial-gradient(1px 1px at 33% 3%, rgba(255, 255, 255, 0.5) 50%, transparent),
      radial-gradient(1px 1px at 47% 6%, rgba(255, 255, 255, 0.6) 50%, transparent),
      radial-gradient(1.5px 1.5px at 61% 2%, rgba(255, 255, 255, 0.7) 50%, transparent),
      radial-gradient(1px 1px at 74% 7%, rgba(255, 255, 255, 0.5) 50%, transparent),
      radial-gradient(1px 1px at 86% 3%, rgba(255, 255, 255, 0.6) 50%, transparent),
      radial-gradient(1px 1px at 97% 6%, rgba(255, 255, 255, 0.5) 50%, transparent),
      radial-gradient(1px 1px at 55% 66%, rgba(255, 255, 255, 0.55) 50%, transparent),
      radial-gradient(1.5px 1.5px at 63% 84%, rgba(255, 255, 255, 0.7) 50%, transparent),
      radial-gradient(1px 1px at 71% 71%, rgba(255, 255, 255, 0.5) 50%, transparent),
      radial-gradient(1px 1px at 79% 92%, rgba(255, 255, 255, 0.55) 50%, transparent),
      radial-gradient(1.5px 1.5px at 88% 76%, rgba(255, 255, 255, 0.7) 50%, transparent),
      radial-gradient(1px 1px at 96% 88%, rgba(255, 255, 255, 0.5) 50%, transparent),
      radial-gradient(1px 1px at 50% 94%, rgba(255, 255, 255, 0.45) 50%, transparent);
    -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent);
  }
  .sky i { opacity: .5; }
  .sky i:nth-child(1) { background: #3B2E86; }
  .sky i:nth-child(2) { background: #1E3C8A; }
  .sky i:nth-child(3) { background: #5E2E6E; }
  .sky i:nth-child(4) { background: #2A2470; }

  /* Search and selects. */
  .query, select { box-shadow: 0 10px 30px -14px rgba(0, 0, 0, .7), 0 0 0 1px rgba(210, 200, 255, .08); }
  .query { background: rgba(32, 29, 66, .8); }
  .search input::placeholder { color: #8E89AE; }
  select {
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23BBA6FF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-color: rgba(32, 29, 66, .8);
  }
  @supports (appearance: base-select) {
    ::picker(select) { background: var(--raised); }
    option:hover, option:focus-visible { background: var(--hover); }
    option:checked { background: var(--asmodian); }
  }

  /* Surfaces that were white or nearly. */
  .result img, .card header img, :is(.route, .plan) .picture img { background: var(--raised); }
  .hero img { background: var(--raised); }
  .hero img, .hero .portrait { box-shadow: 0 16px 40px -18px rgba(0, 0, 0, .8); }
  .pill { background: rgba(40, 36, 80, .85); }
  .facet { background: rgba(255, 255, 255, .08); }
  .facet.crit { background: rgba(255, 205, 90, .2); color: #FFD97A; }
  .facet.best { background: rgba(255, 205, 90, .2); color: #FFD97A; }
  .facet.good { background: rgba(132, 102, 234, .28); color: #D3C6FF; }
  .step { background: rgba(255, 255, 255, .06); }
  .facet.off { background: rgba(132, 102, 234, .22); }
  .facet.off i { background: rgba(187, 166, 255, .2); }
  .kda small { background: rgba(255, 217, 122, .12); }
  .read code { background: rgba(255, 255, 255, .08); }
  .said { background: rgba(132, 102, 234, .14); }
  .formula { background: rgba(132, 102, 234, .14); border-color: rgba(187, 166, 255, .2); }
  .tabs { background: rgba(255, 255, 255, .05); }
  @media (hover: hover) { .areas a:hover { background: var(--hover); } }
  :is(.areas a[aria-current], .toggle[aria-expanded="true"]) { background: var(--raised); box-shadow: 0 6px 16px -10px rgba(0, 0, 0, .8), 0 0 0 1px rgba(210, 200, 255, .08); }
  :is(.toggle, a.account) { background: rgba(32, 29, 66, .8); box-shadow: 0 10px 30px -14px rgba(0, 0, 0, .7), 0 0 0 1px rgba(210, 200, 255, .08); }
  .where select { background-color: rgba(132, 102, 234, .2); }
  .pitch { background: rgba(255, 255, 255, .04); border-color: rgba(187, 166, 255, .25); }
  .pitch .get { background: var(--raised); }
  .tabs :is(a[aria-current], button[aria-pressed="true"]) { background: var(--raised); box-shadow: 0 6px 16px -10px rgba(0, 0, 0, .8), 0 0 0 1px rgba(210, 200, 255, .08); }
  .day { background: rgba(255, 255, 255, .035); }
  :is(.pill.label, .vs, .killed, .chips .pill[aria-current], .picks .kinds [aria-pressed="true"], .top .get) { color: var(--on-ink); }
  .chips .pill[aria-current] small, .picks .kinds [aria-pressed="true"] small { color: rgba(21, 19, 42, .65); }
  .enchant { background: #3A3566; box-shadow: 0 0 0 2px var(--card); }

  /* Grades: dark chips with the letter lit, rather than pastel chips with the letter dark. */
  .bis { --letter: #FFE29A; --chip: conic-gradient(from 200deg, rgba(255, 214, 120, .3), rgba(255, 150, 200, .3), rgba(140, 180, 255, .3), rgba(120, 230, 200, .3), rgba(255, 214, 120, .3)); }
  .splus { --letter: #FFD27A; --chip: linear-gradient(135deg, rgba(255, 214, 120, .28), rgba(255, 150, 200, .28), rgba(140, 180, 255, .28)); }
  .s { --letter: #F2C661; --chip: linear-gradient(135deg, rgba(242, 198, 97, .3), rgba(217, 167, 62, .16)); }
  .a { --letter: #D9DEEC; --chip: linear-gradient(135deg, rgba(217, 222, 236, .2), rgba(174, 182, 203, .1)); --fill: linear-gradient(90deg, #7D88A6, #B4BCD2); }
  .b { --letter: #93B8FF; --chip: rgba(76, 141, 240, .22); }
  .c { --letter: #6FD8CA; --chip: rgba(45, 179, 166, .2); }
  .d, .ungraded { --letter: #A6A1C2; --chip: rgba(255, 255, 255, .07); --fill: #615C80; }

  /* Cards on dark stock. Pastel foil over dark turns grey, so the foils are faint, and each finish
     shows in its stock instead: bronze for S, gunmetal for A and deep iridescence for S+ and BiS,
     which glow in their colors, letter and all. The glow is a still shadow, so a card that tilts
     or a border that moves paints nothing again. A glare bright enough to show on dark is a
     spotlight on the pointer, so there's none: the foils' sliding bands are the light a card
     catches. */
  .card { background: #2D2A52; box-shadow: var(--shadow), var(--glow, 0 0 #0000); }
  @media (hover: hover) { .card:hover { box-shadow: 0 26px 50px -22px rgba(0, 0, 0, .9), 0 0 0 1px rgba(210, 200, 255, .1), var(--glow, 0 0 #0000); } }
  .glare { display: none; }
  .bis .foil { opacity: calc(.16 + var(--o) * .2); }
  .splus .foil { opacity: calc(.12 + var(--o) * .2); }
  .s .foil { opacity: calc(.1 + var(--o) * .14); }
  .a .foil { opacity: calc(.06 + var(--o) * .12); }
  .card.bis { --glow: -12px -8px 36px -10px rgba(255, 150, 200, .5), 12px -8px 36px -10px rgba(255, 214, 120, .5), 12px 8px 36px -10px rgba(120, 230, 200, .45), -12px 8px 36px -10px rgba(140, 180, 255, .5); }
  .card.splus { --glow: -10px -6px 32px -12px rgba(255, 150, 200, .55), 10px 6px 32px -12px rgba(140, 180, 255, .55); }
  .card.s { --glow: 0 0 30px -8px rgba(242, 198, 97, .5); background: linear-gradient(135deg, #B8913A, #F3D88F 45%, #8E6A1E); }
  .card.a { --glow: 0 0 26px -10px rgba(217, 222, 236, .35); background: linear-gradient(135deg, #79819A, #D5DAE8 45%, #626A82); }
  .card.b { background: #2B4378; }
  .card.c { background: #1F4B4D; }
  .card.bis .inner { background: linear-gradient(135deg, #3A1A3C, #1B2550 45%, #10363A); }
  .card.splus .inner { background: linear-gradient(135deg, #34183F, #1B2348 55%, #2C1F3A); }
  .card.s .inner { background: linear-gradient(160deg, #33280F, #1E1A24 70%); }
  .card.a .inner { background: linear-gradient(160deg, #2A2F3E, #1C1C2C 70%); }
  .card.d .inner, .card.ungraded .inner { background: #19172E; }
  :is(.card.s, .card.splus, .card.bis) :is(.letter, .face > b) { text-shadow: 0 0 16px color-mix(in srgb, var(--letter) 55%, transparent); }
  .card .star { color: #FFE29A; background: conic-gradient(from 200deg, rgba(255, 214, 120, .3), rgba(255, 150, 200, .3), rgba(140, 180, 255, .3), rgba(120, 230, 200, .3), rgba(255, 214, 120, .3)); }
  .turn { border-color: rgba(187, 166, 255, .25); }
  .back .turn { background: rgba(21, 19, 42, .6); }
  @media (hover: hover) { .flip:hover .turn { background: var(--hover); border-color: rgba(187, 166, 255, .45); } }
  .mark { background: rgba(45, 179, 166, .2); color: #6FD8CA; }
  .line.lacking .mark { box-shadow: inset 0 0 0 1.5px rgba(210, 200, 255, .22); }
  .loading .face > i::before, .loading header i::before { background: linear-gradient(90deg, var(--track) 30%, rgba(210, 200, 255, .18) 50%, var(--track) 70%); }

  /* Factions, and the soft tints behind them. */
  .elyos { --side-soft: rgba(77, 139, 240, .16); }
  .asmodian { --side-soft: rgba(132, 102, 234, .18); }
  .tag.kill { background: rgba(77, 139, 240, .16); }
  .tag.death { background: rgba(255, 255, 255, .07); }
  .tag.assist { background: rgba(132, 102, 234, .18); }

  /* A killmail's timeline: a crit lights up on dark, where it darkened on white. */
  .tick.taken { --hit: color-mix(in srgb, var(--side) 55%, var(--card)); }
  .plot.asmodian .tick.dealt { --hit: color-mix(in srgb, var(--elyos) 55%, var(--card)); }
  .plot.elyos .tick.dealt { --hit: color-mix(in srgb, var(--asmodian) 55%, var(--card)); }
  .tick.healed { --hit: color-mix(in srgb, var(--heal) 55%, var(--card)); --crit: #6FD8CA; }
  .plot .who.heals > b { color: #6FD8CA; }
  .windows .defiance { color: #2A1F00; }
  @media (max-width: 560px) { .plot .who > :is(b, span) { background: rgba(27, 25, 52, .85); } }

  /* Rows that open, hover or were found. */
  .answer .roster, .legion .table, .pick.tile { background: var(--sunk); }
  @media (hover: hover) {
    .legion > summary:hover, .feed a:hover, .server:hover { background: var(--hover); }
  }
  .folded > summary, .feed summary, .picks .keys { background: var(--sunk); }
  .legion.found > summary, tr.found td { background: var(--found); }
  :is(.picks mark, .hit, .kda) { background: rgba(255, 205, 90, .2); color: #FFD97A; }

  /* A battle's search and its suggestions. */
  #find .query { background: rgba(255, 255, 255, .05); }
  #find .query:focus-within { background: var(--raised); box-shadow: 0 0 0 2px rgba(187, 166, 255, .4); }
  .picks { background: var(--raised); box-shadow: 0 28px 60px -24px rgba(0, 0, 0, .9), 0 0 0 1px rgba(210, 200, 255, .1); }
  .picks .kinds .pill:not([aria-pressed="true"]) { background: rgba(255, 255, 255, .07); }
  .pick[aria-selected="true"], .picks .hint .glyph { background: rgba(132, 102, 234, .2); }
  .pick.tile[aria-selected="true"] { background: rgba(132, 102, 234, .2); box-shadow: inset 0 0 0 1.5px rgba(187, 166, 255, .4); }
  .picks kbd { background: var(--card); box-shadow: inset 0 0 0 1px rgba(187, 166, 255, .2), 0 1px 0 rgba(0, 0, 0, .4); }

  /* The census. */
  .medal { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35), var(--shadow); }
  .spread { --rest: #6E6990; --behind: #34305A; }
  .cutoff { background: rgba(236, 232, 250, .3); }
  .cutoff b, .spread .none span { background: rgba(27, 25, 52, .92); }
  .spread.empty .column i, .spread.empty .columns::before { background: rgba(255, 255, 255, .06); }
  .gathering { --unique: #B8862A; --epic: #4A7FD4; --rare: #3F9440; --unknown: #9A7AF5; --success: #6A6588; }
  .gathers { --common: #6A6588; --fine: #3F9440; --pure: #4A7FD4; --radiant: #B8862A; --other: #3A365E; --other-down: #2C2950; --faded: rgba(255, 255, 255, .06); --appraised: #CC4F8A; --appraised-other: #4E2E48; }

  /* Maps: Reshanta's islands pale in the night. */
  .map { background: #131A3E; outline-color: rgba(210, 200, 255, .1); }
  .map.grid { background-color: #121632; background-image: linear-gradient(90deg, rgba(210, 200, 255, .08) 1px, transparent 1px), linear-gradient(rgba(210, 200, 255, .08) 1px, transparent 1px); }
  .map svg { filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .5)); }
  .map .land { stroke: #3E4880; }
  .map .landmark { background: #7D7898; }
  .map .label { background: rgba(19, 26, 62, .8); }
  /* The victim's mark is filled with the side's ink, light by night, so its cross turns dark. */
  .map .mark.victim::before, .map .mark.victim::after { background: var(--on-ink); }
  .zoom button { background: rgba(36, 33, 74, .92); box-shadow: 0 1px 4px rgba(0, 0, 0, .5); }

  /* Timers: the siege's near-black indigo turns to its near-white, as the ink does. */
  [data-event="siege"] { --event: #CFC6F5; }
  .week [data-event] { background: color-mix(in srgb, var(--event) 18%, var(--card)); }
}
