/* /Components/Account/Pages/Manage/EnableAuthenticator.razor.rz.scp.css */
.key-label[b-jxh6d78qbr] {
  color: var(--text-subtle);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  margin: 0 0 .35rem;
  text-transform: uppercase;
}

.key[b-jxh6d78qbr] {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 1rem;
  letter-spacing: .12em;
  margin: 0;
  padding: .6rem .7rem;
  overflow-wrap: anywhere;
}

.key-aside[b-jxh6d78qbr] {
  font-size: .88rem;
  margin: .5rem 0 1.6rem;
}

.key-aside a[b-jxh6d78qbr] {
  color: var(--accent-text);
}

.enrolled[b-jxh6d78qbr] {
  margin: 0 0 1.6rem;
}
/* /Components/Account/Shared/StatusMessage.razor.rz.scp.css */
.status[b-vw85654e3c] {
  margin-bottom: 1.2rem;
}
/* /Components/Admin/Analytics/AnalyticsPeriodField.razor.rz.scp.css */
.period[b-sclkgtnv0z] {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1rem;
}

.period[b-sclkgtnv0z]  .field-row {
  margin: 0;
}

.period select[b-sclkgtnv0z] {
  min-width: 11rem;
}

.period-range[b-sclkgtnv0z] {
  align-items: end;
  display: flex;
  gap: .5rem;
}

.period-range input[b-sclkgtnv0z] {
  min-width: 9.5rem;
}

/* The custom range is rendered visible, so a reader without script keeps both
   controls and the server reads whichever one the form submitted. Once theme.js
   has marked the document as scripted, the range is drawn only while Custom
   range is the selection: :checked follows the select as it changes, so nothing
   has to run again after an enhanced navigation replaced the page. */
html.js .period-range[b-sclkgtnv0z] {
  display: none;
}

html.js .period-preset:has(.period-custom:checked) ~ .period-range[b-sclkgtnv0z] {
  display: flex;
}

@media (max-width: 880px) {
  .period[b-sclkgtnv0z] {
    align-items: stretch;
    flex-direction: column;
    width: 100%;
  }

  .period select[b-sclkgtnv0z] {
    min-width: 0;
  }

  /* From and To stay side by side: they are read as one interval, and a date
     field is narrow enough that stacking them would only add scrolling. */
  .period-range > *[b-sclkgtnv0z] {
    flex: 1;
    min-width: 0;
  }

  .period-range input[b-sclkgtnv0z] {
    min-width: 0;
  }
}
/* /Components/Admin/Analytics/ClickDivisionCard.razor.rz.scp.css */
/* One division of the period's outbound clicks. The card sits on the panel that
   heads the five of them, raised off it rather than outlined, so they read as
   one block and not as five panels; secondary text on that ground uses
   --text-muted, which carries the contrast the raised surface needs in both
   flavors.

   The whole card is a link, so it carries the positioning, the hover and the
   focus ring a whole-card link needs, and a chevron that says where it leads.
   The grid the cards are laid out in belongs to the page, not here. */

.cut[b-cc53q6ly79] {
  background: var(--surface-raised);
  border-radius: var(--radius);
  padding: .7rem .8rem;
}

.cut-head[b-cc53q6ly79] {
  align-items: baseline;
  display: flex;
  gap: .5rem;
}

.cut-name[b-cc53q6ly79] {
  font-size: .9rem;
  font-weight: 600;
  margin: 0;
}

/* The whole-card-link idiom — the stretched anchor and its focus behaviour —
   lives in app.css. What stays here is how this card lights up: an outline
   rather than a border, because these sit raised on a panel and have no border
   to recolour, so a border would change the card's own size. */
.link-card:hover[b-cc53q6ly79] {
  outline: 1px solid color-mix(in srgb, var(--accent) 55%, var(--border));
}

.link-card:focus-within[b-cc53q6ly79] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The way in, in the drawing. It agrees with the heading and the outline rather
   than saying anything of its own, so it is hidden from assistive technology. */
.cut-chevron[b-cc53q6ly79] {
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
}

.link-card:hover .cut-chevron[b-cc53q6ly79],
.link-card:focus-within .cut-chevron[b-cc53q6ly79] {
  color: var(--accent);
}

/* How many entries the division holds, read against the rows below it. Small,
   muted, and never in the numbers column — that column is clicks, and a second
   kind of number in it would be read as a third click figure. */
.cut-count[b-cc53q6ly79] {
  color: var(--text-muted);
  font-size: .74rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  margin-left: auto;
}

/* An ordered list because the order is the information. No divider between the
   entries: the rhythm of the rows is the separation. */
.cut-top[b-cc53q6ly79] {
  counter-reset: rank;
  display: grid;
  gap: .3rem;
  list-style: none;
  margin: .6rem 0 0;
  padding: 0;
}

.cut-top li[b-cc53q6ly79] {
  align-items: baseline;
  column-gap: .5rem;
  counter-increment: rank;
  display: grid;
  font-size: .82rem;
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.cut-top li[b-cc53q6ly79]::before {
  color: var(--text-muted);
  content: counter(rank);
  font-size: .74rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* A long entry truncates rather than wrapping: the rank and the number keep
   their columns, and a name on two lines would break the alignment that makes
   the three rows comparable. */
.cut-entry[b-cc53q6ly79] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cut-num[b-cc53q6ly79] {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.cut-none[b-cc53q6ly79] {
  color: var(--text-muted);
  font-size: .82rem;
  margin: .6rem 0 0;
}
/* /Components/Admin/Analytics/ClickHistoryDays.razor.rz.scp.css */
/* ---- the click history ----
   A log, not a ranking: no rank, no bar and no comparison, so the rows are
   narrower than the ranking's and a page holds more of them. The rows are raised
   inside the listing panel, so secondary text uses --text-on-raised. The column
   template is one custom property, so the header and the rows cannot drift
   apart. */

.rows-head[b-vi3zn95q7j],
.rows[b-vi3zn95q7j] {
  --history-cols: 4rem minmax(0, 1fr) 9rem 12rem;
}

.rows-head[b-vi3zn95q7j] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--history-cols);
  letter-spacing: .08em;
  padding: 0 .85rem .45rem;
  text-transform: uppercase;
}

/* The day is a heading of the rows under it, set in the same small capitals as
   the column names so the two read as one layer above the rows. */
.day-title[b-vi3zn95q7j] {
  color: var(--text-muted);
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: .08em;
  margin: 1.1rem 0 .5rem .85rem;
  text-transform: uppercase;
}

.rows-head + .day-title[b-vi3zn95q7j] {
  margin-top: 0;
}

.day-facts[b-vi3zn95q7j] {
  color: var(--text-subtle);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: none;
}

.rows[b-vi3zn95q7j] {
  display: grid;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.row[b-vi3zn95q7j] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-columns: var(--history-cols);
  padding: .65rem .85rem;
  row-gap: .35rem;
}

.time[b-vi3zn95q7j] {
  color: var(--text-on-raised);
  font-size: .85rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.row-main[b-vi3zn95q7j] {
  min-width: 0;
}

.row-name[b-vi3zn95q7j] {
  font-size: .95rem;
  font-weight: 600;
}

.row-name a[b-vi3zn95q7j] {
  color: inherit;
}

.row-name a:hover[b-vi3zn95q7j] {
  text-decoration: underline;
}

.row-meta[b-vi3zn95q7j] {
  color: var(--text-on-raised);
  font-size: .78rem;
  margin-top: .1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell[b-vi3zn95q7j] {
  color: var(--text-on-raised);
  font-size: .85rem;
}

/* The column header names each cell on a wide screen, so the cell does not name
   itself twice there; stacked, the header is gone and the name comes back. */
.cell-sub[b-vi3zn95q7j] {
  display: none;
}

@media (max-width: 880px) {
  .rows-head[b-vi3zn95q7j] {
    display: none;
  }

  .rows[b-vi3zn95q7j] {
    --history-cols: 3.5rem minmax(0, 1fr);
  }

  .row > .cell[b-vi3zn95q7j] {
    grid-column: 2;
  }

  .cell-sub[b-vi3zn95q7j] {
    display: inline;
    font-size: .72rem;
    margin-inline-end: .4rem;
  }
}
/* /Components/Admin/Analytics/DailyClickChart.razor.rz.scp.css */
/* ---- the head ----
   Three facts as labelled pairs, not as a sentence: each one is found by its
   label, and the date sits on the fact it belongs to instead of at the end of a
   line shared by all three. */

.chart-head[b-tr8vsbjrc1] {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.5rem;
  justify-content: space-between;
  margin-bottom: 1.1rem;
}

.chart-title[b-tr8vsbjrc1] {
  font-size: 1.1rem;
  line-height: 1.3;
  margin: 0;
}

.chart-facts[b-tr8vsbjrc1] {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1.4rem;
  margin: 0;
}

.chart-facts > div[b-tr8vsbjrc1] {
  align-items: baseline;
  display: flex;
  gap: .4rem;
}

.chart-facts dt[b-tr8vsbjrc1] {
  color: var(--text-muted);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.chart-facts dd[b-tr8vsbjrc1] {
  font-size: .95rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  margin: 0;
}

.chart-facts dd small[b-tr8vsbjrc1] {
  color: var(--text-subtle);
  font-size: .76rem;
  font-weight: 600;
  margin-left: .3rem;
}

/* ---- the bars ----
   One image with a label. The bars hold the 3:1 a non-text graphic needs rather
   than the tint a decoration could use, because here the shape is the
   information. */

.chart[b-tr8vsbjrc1] {
  align-items: end;
  display: grid;
  gap: .2rem;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  height: 7rem;
  position: relative;
}

.chart > span[b-tr8vsbjrc1] {
  background: color-mix(in srgb, var(--accent) 75%, var(--surface-raised));
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  height: var(--h);
  min-height: 2px;
}

/* The highest day is the one the facts line names, so it is drawn as the one the
   eye lands on. The naming is what makes it readable; the color only agrees. */
.chart .peak[b-tr8vsbjrc1] {
  background: var(--accent);
}

/* The average, drawn at its own height on the same scale the bars use, so which
   days stood above it is readable — which no number can say. It is a grid item
   like the bars, so it is taken out of the flow to span the whole frame. */
.chart-avg[b-tr8vsbjrc1] {
  border-top: 1px dashed var(--text-muted);
  grid-area: 1 / 1 / 2 / -1;
  left: 0;
  position: absolute;
  right: 0;
}

.chart-axis[b-tr8vsbjrc1] {
  color: var(--text-subtle);
  display: flex;
  font-size: .74rem;
  justify-content: space-between;
  margin-top: .5rem;
}

.chart-none[b-tr8vsbjrc1] {
  color: var(--text-muted);
  margin: 0;
}

@media (max-width: 880px) {
  .chart[b-tr8vsbjrc1] {
    height: 5.5rem;
  }
}
/* /Components/Admin/Analytics/Dashboard.razor.rz.scp.css */
/* ---- the head ----
   The period is the whole of the head: the bar above names the screen, and this
   is the one control that changes every number below it. The control itself is
   AnalyticsPeriodField's, shared with the outbound-clicks listing. */

.page-head[b-wznn0r23gx] {
  margin-bottom: 1.25rem;
}

/* ---- metric tiles (ANL-DASH-001) ----
   The tiles are StatTile's markup and are styled next to it; what belongs here
   is the row they sit in, which is this screen's decision about how many fit. */

.stats[b-wznn0r23gx] {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr));
  margin-bottom: 1.5rem;
}

/* ---- the two columns ---- */

.columns[b-wznn0r23gx] {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr) 22.5rem;
}

.primary[b-wznn0r23gx] {
  min-width: 0;
}

.block-empty[b-wznn0r23gx] {
  color: var(--text-muted);
  margin: 0;
}

/* ---- division cards (ANL-DASH-002) ----
   One card per division. The cards themselves are ClickDivisionCard's markup and
   are styled next to it; what belongs here is the grid they sit in. */

.cuts[b-wznn0r23gx] {
  display: grid;
  gap: .6rem;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
}

/* ---- the side column ----
   Integrations is a Panel; it leads nowhere, so it needs nothing a Panel does not
   already draw. Catalog and Unresolved reports are destinations, so each is a
   card: the same surface, plus the hover and focus ring a whole-card link needs —
   which is why both are written out here rather than reusing Panel, whose heading
   is a string and has nowhere to put the anchor. */

/* Grid rather than a margin between siblings: two of the three panels are the
   Panel component's markup, which a scoped rule of this page cannot select. */
.side[b-wznn0r23gx] {
  display: grid;
  gap: 1.5rem;
}

.side-card[b-wznn0r23gx] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.6rem;
}

.side-title[b-wznn0r23gx] {
  font-size: 1.1rem;
  line-height: 1.3;
  margin: 0 0 .75rem;
}

/* A side panel's figure is the tile's figure drawn somewhere else. */
.side-value[b-wznn0r23gx] {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
  margin: 0;
}

.side-foot[b-wznn0r23gx] {
  color: var(--text-subtle);
  font-size: .78rem;
  margin: .3rem 0 0;
  padding-top: .3rem;
}

/* The whole-card-link idiom — the stretched anchor and its focus behaviour —
   lives in app.css. What stays here is how this card lights up: it has a border
   to recolour, which the division cards on a panel do not. */
.link-card:hover[b-wznn0r23gx] {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}

.link-card:focus-within[b-wznn0r23gx] {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Three states of one number, so they share a card instead of taking three
   (ADM-CAT-002). */
.totals[b-wznn0r23gx] {
  display: grid;
  gap: .5rem;
  grid-template-columns: repeat(3, 1fr);
  text-align: center;
}

.totals div[b-wznn0r23gx] {
  background: var(--surface-raised);
  border-radius: var(--radius);
  padding: .65rem .3rem;
}

.totals b[b-wznn0r23gx] {
  display: block;
  font-size: 1.35rem;
  letter-spacing: -.02em;
}

.totals span[b-wznn0r23gx] {
  color: var(--text-muted);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* ---- states ----
   An answer instead of the tiles, drawn the way every other administration
   screen draws one. Panel and Callout write their own markup, so the rules
   reach through them. */

.state[b-wznn0r23gx]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-wznn0r23gx]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

@media (max-width: 1080px) {
  .columns[b-wznn0r23gx] {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 880px) {
  /* One division per row: a ranked list needs its full width, and a name
     truncated to half a phone screen stops identifying anything. */
  .cuts[b-wznn0r23gx] {
    grid-template-columns: minmax(0, 1fr);
  }

  .side-card[b-wznn0r23gx] {
    padding: 1.1rem;
  }

  .side-value[b-wznn0r23gx] {
    font-size: 1.55rem;
  }
}

/* The first few subjects waiting, read against the count above them: three rows
   against 12 says most of the queue is not here, three against 3 says the panel
   is the whole of it. The reader subtracts. */
.waiting[b-wznn0r23gx] {
  display: grid;
  gap: .4rem;
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
}

.waiting li[b-wznn0r23gx] {
  align-items: baseline;
  background: var(--surface-raised);
  border-radius: var(--radius-sm);
  display: flex;
  gap: .6rem;
  justify-content: space-between;
  padding: .45rem .6rem;
}

.waiting-name[b-wznn0r23gx] {
  font-size: .82rem;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.waiting-name span[b-wznn0r23gx] {
  color: var(--text-subtle);
  font-weight: 500;
}

.waiting-count[b-wznn0r23gx] {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
/* /Components/Admin/Analytics/GameMetrics.razor.rz.scp.css */
/* ---- the head ----
   This screen carries a title block for the same reason the editor does: the
   administrative bar names a section and not a record, and this is a screen
   about one game. It is the editor's head with the commands taken out — the two
   buttons are destinations, not decisions, because nothing on this page writes
   anything.

   No arrow back beside the name. The editor dropped its own, and the way back is
   the Games entry in the bar above, which is where a reader of either screen
   walks up. */

.page-head[b-mq2e1na3ig] {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1rem;
  margin-bottom: 1.1rem;
}

.title-row[b-mq2e1na3ig] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
}

.title-row h1[b-mq2e1na3ig] {
  font-size: 1.5rem;
  letter-spacing: -.02em;
  margin: 0;
}

.head-actions[b-mq2e1na3ig] {
  display: flex;
  gap: .5rem;
  margin-left: auto;
}

/* ---- the period ----
   Every figure below this line is the answer to one window, so the window is
   chosen once above all of them and no section carries a control of its own. The
   control itself is AnalyticsPeriodField's, shared with the dashboard and the
   outbound-clicks listing; what belongs here is where it sits. */

.period-bar[b-mq2e1na3ig] {
  margin-bottom: 1.25rem;
}

/* ---- the period's figures ----
   The tiles are StatTile's markup and are styled next to it; what belongs here
   is the row they sit in, which is this screen's decision about how many fit. */

.stats[b-mq2e1na3ig] {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin-bottom: 1.5rem;
}

/* ---- the daily series ----
   The chart is DailyClickChart's markup and is styled next to it; what belongs
   here is the surface it sits on. On one game the shape usually has a cause: a
   patch shipped inside the window is a peak here and a New row below. */

.chart-panel[b-mq2e1na3ig] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  padding: 1.25rem;
}

/* ---- the division switch ----
   Outside the listing, because it does not narrow the list: it decides what the
   list is counting. Each segment is an address of its own and carries the window
   with it. */

.switch[b-mq2e1na3ig] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  display: flex;
  flex-wrap: wrap;
  gap: .2rem;
  margin-bottom: .9rem;
  padding: .25rem;
}

.switch a[b-mq2e1na3ig] {
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  font-size: .85rem;
  font-weight: 600;
  padding: .4rem .9rem;
  text-decoration: none;
}

.switch a:hover[b-mq2e1na3ig] {
  background: var(--surface-raised);
  color: var(--text);
}

.switch a[aria-current="page"][b-mq2e1na3ig] {
  background: var(--accent);
  color: var(--accent-contrast);
}

.switch a:focus-visible[b-mq2e1na3ig] {
  outline-offset: -2px;
}

/* ---- the listing ----
   No filters inside it, which is the difference from the catalog-wide ranking:
   there a filter is what makes a list of thousands readable, and here the list is
   one game's own records. */

.listing[b-mq2e1na3ig] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
}

.block-empty[b-mq2e1na3ig] {
  color: var(--text-muted);
  margin: 0;
}

/* ---- the rows ----
   A ranking is a table of numbers, built from grid rows rather than a table: the
   columns have to collapse into a readable block on a phone, and every cell
   states its own subject — clicks, of this game, vs previous — so nothing is lost
   when the header goes. The rows are raised inside the panel rather than being
   cards on the page, so secondary text inside them uses --text-on-raised.

   The column template is one custom property, so the header and the rows cannot
   drift apart, and a division that states no share drops the column by rewriting
   it in one place. */

.rows-head[b-mq2e1na3ig],
.rows[b-mq2e1na3ig] {
  --row-cols: 2.5rem minmax(0, 1fr) 7.5rem 8.5rem;
}

.rows-head.with-share[b-mq2e1na3ig],
.rows.with-share[b-mq2e1na3ig] {
  --row-cols: 2.5rem minmax(0, 1fr) 7.5rem 7rem 8.5rem;
}

/* Decorative, like every other listing header here: a scanning aid for a wide
   screen, and it disappears with the wide layout. */
.rows-head[b-mq2e1na3ig] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--row-cols);
  letter-spacing: .08em;
  padding: 0 .85rem .45rem;
  text-transform: uppercase;
}

.rows-head .num[b-mq2e1na3ig] {
  text-align: right;
}

.rows[b-mq2e1na3ig] {
  counter-reset: rank;
  display: grid;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.row[b-mq2e1na3ig] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius);
  column-gap: 1rem;
  counter-increment: rank;
  display: grid;
  grid-template-columns: var(--row-cols);
  padding: .7rem .85rem;
  row-gap: .5rem;
}

/* The rank is the list's own order, so it is a counter and not a cell of data:
   read as a list the rows still say first, second, third, and no printed number
   can contradict the sorting. */
.row[b-mq2e1na3ig]::before {
  color: var(--text-on-raised);
  content: counter(rank);
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.row-main[b-mq2e1na3ig] {
  min-width: 0;
}

.row-name[b-mq2e1na3ig] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  font-size: .95rem;
  font-weight: 600;
  gap: .45rem;
}

.row-name a[b-mq2e1na3ig] {
  color: inherit;
}

.row-name a:hover[b-mq2e1na3ig] {
  text-decoration: underline;
}

.row-meta[b-mq2e1na3ig] {
  color: var(--text-on-raised);
  font-size: .78rem;
  margin-top: .1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The bar is the clicks cell drawn against the largest in the division, so the
   distance between the rows in front of the reader is visible without
   arithmetic. It carries no value of its own. */
.row-bar[b-mq2e1na3ig] {
  background: var(--surface-high);
  border-radius: var(--radius-pill);
  height: .3rem;
  margin-top: .45rem;
  max-width: 22rem;
  overflow: hidden;
}

.row-bar i[b-mq2e1na3ig] {
  background: var(--accent);
  display: block;
  height: 100%;
}

.cell[b-mq2e1na3ig] {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.cell b[b-mq2e1na3ig] {
  display: block;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.01em;
}

/* The column header names the number, so the number does not name itself twice.
   The subject stays in the markup because the header is what carries it, and the
   header goes away with the wide layout — below 880px it comes back, next to the
   value it belongs to. */
.cell-sub[b-mq2e1na3ig] {
  display: none;
}

/* The arrow is set off from the figure by space the markup does not carry: a
   literal one between an aria-hidden element and the number it points at is
   whitespace the renderer is free to drop. */
.change-glyph[b-mq2e1na3ig] {
  margin-inline-end: .25rem;
}

/* Direction is carried by the arrow and the word beside the figure; the color
   only agrees with them. Neither direction is good or bad by itself — a patch
   losing clicks once the next one ships is the normal case — so no change is a
   status badge. */
.up b[b-mq2e1na3ig] {
  color: var(--up-text);
  font-weight: 700;
}

.down b[b-mq2e1na3ig] {
  color: var(--danger-text);
  font-weight: 700;
}

.flat b[b-mq2e1na3ig] {
  color: var(--text-muted);
}

/* ---- unresolved reports ----
   Outside the form and outside the period, and that placement is the statement:
   a report is not period-scoped and does not come from the analytics store, so it
   is not one of the figures the window governs and it stands when that window
   returns nothing. */

.reports[b-mq2e1na3ig] {
  margin-top: 2rem;
}

.panel-value[b-mq2e1na3ig] {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
  margin: 0;
}

.panel-foot[b-mq2e1na3ig] {
  color: var(--text-subtle);
  font-size: .78rem;
  margin: .3rem 0 0;
  padding-top: .3rem;
}

/* One subject per row, raised inside the panel the way the ranking's rows are
   raised inside the listing — so secondary text inside them takes
   --text-on-raised. The row wraps rather than collapsing into a grid: it holds
   four short things and no column of numbers to line up. */
.report-rows[b-mq2e1na3ig] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
}

.report-row[b-mq2e1na3ig] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1rem;
  padding: .7rem .85rem;
}

.report-what[b-mq2e1na3ig] {
  flex: 1 1 16rem;
}

.report-title[b-mq2e1na3ig] {
  font-size: .92rem;
  font-weight: 600;
}

.report-meta[b-mq2e1na3ig] {
  color: var(--text-on-raised);
  font-size: .78rem;
  margin-top: .1rem;
}

/* The age over the day it counts from, which is what says what the duration
   measures — the shape the queue's own rows give the same figure. */
.report-when[b-mq2e1na3ig] {
  color: var(--text-on-raised);
  font-size: .72rem;
}

.report-when b[b-mq2e1na3ig] {
  color: var(--text);
  display: block;
  font-size: .82rem;
  font-weight: 700;
}

/* ---- states ----
   An answer instead of the figures, drawn the way every other administration
   screen draws one. Panel and Callout write their own markup, so the rules reach
   through them. */

.state[b-mq2e1na3ig]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-mq2e1na3ig]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

/* An accent link on a callout tint is the tightest contrast on the page, so
   inside a callout a link takes the callout's own text color and keeps the
   underline as its affordance. */
.state[b-mq2e1na3ig]  .callout a {
  color: var(--text);
  text-decoration: underline;
}

@media (max-width: 880px) {
  .head-actions[b-mq2e1na3ig] {
    margin-left: 0;
    width: 100%;
  }

  .head-actions .btn[b-mq2e1na3ig] {
    flex: 1;
  }

  /* The header goes with the column layout it labels. Stacked, each number keeps
     its own subject and moves to the left edge with it: a right-aligned number
     under a left-aligned name reads as belonging to the row above. */
  .rows-head[b-mq2e1na3ig] {
    display: none;
  }

  .rows[b-mq2e1na3ig],
  .rows.with-share[b-mq2e1na3ig] {
    --row-cols: 2.5rem minmax(0, 1fr);
  }

  .row[b-mq2e1na3ig] {
    row-gap: .35rem;
  }

  .row > .cell[b-mq2e1na3ig] {
    grid-column: 2;
  }

  .cell[b-mq2e1na3ig] {
    align-items: baseline;
    display: flex;
    gap: .4rem;
    text-align: left;
  }

  .cell b[b-mq2e1na3ig] {
    display: inline;
  }

  .cell-sub[b-mq2e1na3ig] {
    color: var(--text-on-raised);
    display: inline;
    font-size: .72rem;
  }

  .listing[b-mq2e1na3ig] {
    padding: .75rem;
  }
}
/* /Components/Admin/Analytics/OutboundClicks.razor.rz.scp.css */
/* ---- the head ----
   This screen carries a visible title and the dashboard does not: the bar above
   names a section, Analytics, and not this screen. Beside it sits the period,
   the one control that changes every figure below it; the filters belong to the
   list and live with it. The control itself is AnalyticsPeriodField's, shared
   with the dashboard — what belongs here is where it sits. */

.page-head[b-3f3zm66zfx] {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}

.page-head h1[b-3f3zm66zfx] {
  font-size: 1.5rem;
  letter-spacing: -.02em;
  margin: 0;
}

/* ---- the period's figures ----
   The tiles are StatTile's markup and are styled next to it; what belongs here
   is the row they sit in, which is this screen's decision about how many fit. */

.stats[b-3f3zm66zfx] {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr));
  margin-bottom: 1.5rem;
}

/* ---- the daily series ----
   The chart is DailyClickChart's markup and is styled next to it; what belongs
   here is the surface it sits on. */

.chart-panel[b-3f3zm66zfx] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  padding: 1.25rem;
}

/* ---- the division switch ----
   Outside the listing, because it does not narrow the list: it decides what the
   list is counting. Each segment is an address of its own and carries the
   window with it. */

.switch[b-3f3zm66zfx] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  display: flex;
  flex-wrap: wrap;
  gap: .2rem;
  margin-bottom: .9rem;
  padding: .25rem;
}

.switch a[b-3f3zm66zfx] {
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  font-size: .85rem;
  font-weight: 600;
  padding: .4rem .9rem;
  text-decoration: none;
}

.switch a:hover[b-3f3zm66zfx] {
  background: var(--surface-raised);
  color: var(--text);
}

.switch a[aria-current="page"][b-3f3zm66zfx] {
  background: var(--accent);
  color: var(--accent-contrast);
}

.switch a:focus-visible[b-3f3zm66zfx] {
  outline-offset: -2px;
}

/* ---- the listing ----
   The filters are part of the list and not part of the page: they narrow which
   clicks the ranking counts and change nothing above it, so they sit inside the
   same panel, above the rows. They are separated from the rows by space and by
   nothing else — a rule there would be the only divider on the page. */

.listing[b-3f3zm66zfx] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
}

.filters[b-3f3zm66zfx] {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-bottom: 1.25rem;
}

.filters[b-3f3zm66zfx]  .field-row {
  margin: 0;
}

.filters .search[b-3f3zm66zfx] {
  flex: 1 1 15rem;
  max-width: 22rem;
}

.filters .filter[b-3f3zm66zfx] {
  flex: 0 1 9.5rem;
}

.filters .filter-wide[b-3f3zm66zfx] {
  flex: 0 1 12rem;
}

.filters .field[b-3f3zm66zfx] {
  width: 100%;
}

.filters .actions[b-3f3zm66zfx] {
  display: flex;
  gap: .5rem;
  margin-left: auto;
}

/* Applied filters as chips: the reader has to see what is narrowing the ranking
   without reopening every control, and an answer of nothing is only readable
   next to the filters that produced it. */

.applied[b-3f3zm66zfx] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1rem;
}

.applied-label[b-3f3zm66zfx] {
  color: var(--text-muted);
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.chips[b-3f3zm66zfx] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}

.chip[b-3f3zm66zfx] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius-pill);
  display: inline-flex;
  font-size: .8rem;
  gap: .4rem;
  padding: .25rem .5rem .25rem .75rem;
}

.chip a[b-3f3zm66zfx] {
  color: var(--text-on-raised);
  line-height: 1;
  padding: 0 .25rem;
  text-decoration: none;
}

.chip a:hover[b-3f3zm66zfx] {
  color: var(--text);
}

/* ---- the rows ----
   A ranking is a table of numbers, built from grid rows rather than a table: the
   columns have to collapse into a readable block on a phone, and every cell
   states its own subject — clicks, of period, vs previous — so nothing is lost
   when the header goes. The rows are raised inside the panel rather than being
   cards on the page, so secondary text inside them uses --text-on-raised.

   The column template is one custom property, so the header and the rows cannot
   drift apart, and a division that states no share drops the column by rewriting
   it in one place. */

.rows-head[b-3f3zm66zfx],
.rows[b-3f3zm66zfx] {
  --row-cols: 2.5rem minmax(0, 1fr) 7.5rem 8.5rem;
}

.rows-head.with-share[b-3f3zm66zfx],
.rows.with-share[b-3f3zm66zfx] {
  --row-cols: 2.5rem minmax(0, 1fr) 7.5rem 7rem 8.5rem;
}

/* Decorative, like the games listing's header: a scanning aid for a wide screen,
   and it disappears with the wide layout. */
.rows-head[b-3f3zm66zfx] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--row-cols);
  letter-spacing: .08em;
  padding: 0 .85rem .45rem;
  text-transform: uppercase;
}

.rows-head .num[b-3f3zm66zfx] {
  text-align: right;
}

.rows[b-3f3zm66zfx] {
  counter-reset: rank;
  display: grid;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.row[b-3f3zm66zfx] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius);
  column-gap: 1rem;
  counter-increment: rank;
  display: grid;
  grid-template-columns: var(--row-cols);
  padding: .7rem .85rem;
  row-gap: .5rem;
}

/* The rank is the list's own order, so it is a counter and not a cell of data:
   read as a list the rows still say first, second, third, and no printed number
   can contradict the sorting. */
.row[b-3f3zm66zfx]::before {
  color: var(--text-on-raised);
  content: counter(rank);
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.row-main[b-3f3zm66zfx] {
  min-width: 0;
}

.row-name[b-3f3zm66zfx] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  font-size: .95rem;
  font-weight: 600;
  gap: .45rem;
}

.row-name a[b-3f3zm66zfx] {
  color: inherit;
}

.row-name a:hover[b-3f3zm66zfx] {
  text-decoration: underline;
}

.row-meta[b-3f3zm66zfx] {
  color: var(--text-on-raised);
  font-size: .78rem;
  margin-top: .1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The bar is the clicks cell drawn against the largest on the page, so the
   distance between the rows in front of the reader is visible without
   arithmetic. It carries no value of its own. */
.row-bar[b-3f3zm66zfx] {
  background: var(--surface-high);
  border-radius: var(--radius-pill);
  height: .3rem;
  margin-top: .45rem;
  max-width: 22rem;
  overflow: hidden;
}

.row-bar i[b-3f3zm66zfx] {
  background: var(--accent);
  display: block;
  height: 100%;
}

.cell[b-3f3zm66zfx] {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.cell b[b-3f3zm66zfx] {
  display: block;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.01em;
}

/* The column header names the number, so the number does not name itself twice.
   The subject stays in the markup because the header is what carries it, and the
   header goes away with the wide layout — below 880px it comes back, next to the
   value it belongs to. */
.cell-sub[b-3f3zm66zfx] {
  display: none;
}

/* The arrow is set off from the figure by space the markup does not carry: a
   literal one between an aria-hidden element and the number it points at is
   whitespace the renderer is free to drop. */
.change-glyph[b-3f3zm66zfx] {
  margin-inline-end: .25rem;
}

/* Direction is carried by the arrow and the word beside the figure; the color
   only agrees with them. Neither direction is good or bad by itself — a game
   losing clicks after its launch week is not a fault — so no change is a status
   badge. --up-text is the theme's rise colour, mixed for a raised surface. */
.up b[b-3f3zm66zfx] {
  color: var(--up-text);
  font-weight: 700;
}

.down b[b-3f3zm66zfx] {
  color: var(--danger-text);
  font-weight: 700;
}

.flat b[b-3f3zm66zfx] {
  color: var(--text-muted);
}

/* ---- states ----
   An answer instead of the rows, drawn the way every other administration screen
   draws one. Panel and Callout write their own markup, so the rules reach
   through them. */

.state[b-3f3zm66zfx]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-3f3zm66zfx]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

/* An accent link on a callout tint is the tightest contrast on the page, so
   inside a callout a link takes the callout's own text color and keeps the
   underline as its affordance. */
.state[b-3f3zm66zfx]  .callout a {
  color: var(--text);
  text-decoration: underline;
}

@media (max-width: 1080px) {
  .filters .actions[b-3f3zm66zfx] {
    margin-left: 0;
  }
}

@media (max-width: 880px) {
  .page-head[b-3f3zm66zfx] {
    align-items: stretch;
    flex-direction: column;
  }

  .filters .search[b-3f3zm66zfx],
  .filters .filter[b-3f3zm66zfx],
  .filters .filter-wide[b-3f3zm66zfx] {
    flex: 1 1 8rem;
    max-width: none;
  }

  .filters .actions[b-3f3zm66zfx] {
    flex: 1 1 100%;
  }

  .filters .actions .btn[b-3f3zm66zfx] {
    flex: 1;
  }

  /* The header goes with the column layout it labels. Stacked, each number keeps
     its own subject and moves to the left edge with it: a right-aligned number
     under a left-aligned name reads as belonging to the row above. */
  .rows-head[b-3f3zm66zfx] {
    display: none;
  }

  .rows[b-3f3zm66zfx],
  .rows.with-share[b-3f3zm66zfx] {
    --row-cols: 2.5rem minmax(0, 1fr);
  }

  .row[b-3f3zm66zfx] {
    row-gap: .35rem;
  }

  .row > .cell[b-3f3zm66zfx] {
    grid-column: 2;
  }

  .cell[b-3f3zm66zfx] {
    align-items: baseline;
    display: flex;
    gap: .4rem;
    text-align: left;
  }

  .cell b[b-3f3zm66zfx] {
    display: inline;
  }

  .cell-sub[b-3f3zm66zfx] {
    color: var(--text-on-raised);
    display: inline;
    font-size: .72rem;
  }

  .listing[b-3f3zm66zfx] {
    padding: .75rem;
  }
}
/* /Components/Admin/Developers/DeveloperListing.razor.rz.scp.css */
/* ---- the head ----
   The same head as the games listing: the search on the left, the command
   that writes on the right. Its top edge is the line both share, so an error
   under the new name does not move the search. */

.toolbar[b-sipef2ucew] {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.search[b-sipef2ucew] {
  display: flex;
  flex: 1 1 20rem;
  gap: .5rem;
  max-width: 32rem;
}

.search .field[b-sipef2ucew] {
  flex: 1;
  min-width: 0;
}

/* EditForm and InputText write the form and the input, so the rules reach
   through them. */
.toolbar[b-sipef2ucew]  .create {
  flex: 0 1 26rem;
}

.create-row[b-sipef2ucew] {
  display: flex;
  gap: .5rem;
}

.create-row[b-sipef2ucew]  input {
  flex: 1;
  min-width: 0;
}

.filters[b-sipef2ucew] {
  margin-bottom: 1.1rem;
}

/* ---- the listing ----
   One column template for the header and the rows, declared on the section
   both live in, so the two cannot drift apart. */

.listing[b-sipef2ucew] {
  /* The last column holds Rename, Restore and Delete side by side. */
  --developer-columns: minmax(0, 1fr) 8rem 15rem;
}

.listing-head[b-sipef2ucew] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--developer-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.developers[b-sipef2ucew] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A row is a card that stays put, as on the games listing: it is not itself a
   click target, the buttons inside it are. */
.developer[b-sipef2ucew] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "main games actions";
  grid-template-columns: var(--developer-columns);
  min-height: 3.6rem;
  padding: .7rem .9rem;
  row-gap: .45rem;
}

.developer-main[b-sipef2ucew] {
  grid-area: main;
  min-width: 0;
}

.developer-name[b-sipef2ucew] {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  overflow-wrap: anywhere;
}

.developer-games[b-sipef2ucew] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  grid-area: games;
}

.developer-actions[b-sipef2ucew] {
  display: flex;
  gap: .4rem;
  grid-area: actions;
  justify-content: flex-end;
}

/* ---- states ----
   An answer instead of rows: centered on its panel, with the way on under it.
   Panel and Callout write their own markup, so the rules reach through them. */

.state[b-sipef2ucew]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-sipef2ucew]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

.state p[b-sipef2ucew] {
  color: var(--text-muted);
  margin: 0 auto 1.1rem;
  max-width: 46ch;
}

.state p:last-child[b-sipef2ucew] {
  margin-bottom: 0;
}

@media (max-width: 880px) {
  /* The header goes with the one-line layout it labels. The count drops under
     the name, and the buttons keep a column of their own. */
  .listing-head[b-sipef2ucew] {
    display: none;
  }

  .listing[b-sipef2ucew] {
    --developer-columns: minmax(0, 1fr) auto;
  }

  .developer[b-sipef2ucew] {
    grid-template-areas:
      "main actions"
      "games actions";
  }
}

@media (max-width: 560px) {
  .toolbar[b-sipef2ucew]  .create {
    flex-basis: 100%;
  }

  .listing[b-sipef2ucew] {
    --developer-columns: minmax(0, 1fr);
  }

  .developer[b-sipef2ucew] {
    grid-template-areas:
      "main"
      "games"
      "actions";
  }

  .developer-actions .btn[b-sipef2ucew] {
    flex: 1;
  }
}
/* /Components/Admin/Games/GameEditor.razor.rz.scp.css */
/* The editor's commands close the heading's line, away from the name and its
   state. On a narrow screen they take a line of their own at full width. */
.head-actions[b-zf873b2dab] {
  display: flex;
  gap: .5rem;
  margin-left: auto;
}

/* ---- layout ----
   The sections take the width and the lifecycle a narrow column beside them.
   The column is sticky, so the state's commands stay in view however far down
   the sections the reader has gone. */
.layout[b-zf873b2dab] {
  align-items: start;
  display: grid;
  gap: .85rem;
  grid-template-columns: minmax(0, 1fr) 13rem;
}

.side[b-zf873b2dab] {
  position: sticky;
  top: 1rem;
}

.sections[b-zf873b2dab],
.subcards[b-zf873b2dab] {
  display: grid;
  gap: .85rem;
  min-width: 0;
}

/* ---- section switch ----
   One control with two positions, drawn as a track around both: there are two
   sections and there will stay two, which a strip of separate pills — the
   listing's tabs, an open-ended filter set — would not say. Each position is a
   link, and the one shown is filled as every current thing is filled. */
.switch[b-zf873b2dab] {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 999px;
  display: inline-flex;
  padding: .25rem;
  width: fit-content;
}

.switch-option[b-zf873b2dab] {
  border-radius: 999px;
  color: var(--text-muted);
  font-size: .88rem;
  font-weight: 600;
  padding: .4rem 1.25rem;
  text-align: center;
  text-decoration: none;
}

.switch-option:hover[b-zf873b2dab] {
  background: var(--surface);
  color: var(--text);
}

.switch-option:focus-visible[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.switch-option[aria-current="page"][b-zf873b2dab],
.switch-option[aria-current="page"]:hover[b-zf873b2dab] {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* ---- releases ----
   A navigator down the left and the one record it has open beside it. The
   navigator is the raised surface and it sticks, because a navigator that
   scrolls away stops being one; the record sits on the panel's own surface,
   since two raised surfaces side by side would read as alternatives. */
.releases[b-zf873b2dab] {
  align-items: start;
  display: grid;
  gap: 1rem;
  grid-template-columns: 17rem minmax(0, 1fr);
}

.rel-nav[b-zf873b2dab] {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .9rem;
  position: sticky;
  top: 1rem;
}

.rel-head[b-zf873b2dab] {
  align-items: center;
  display: flex;
  gap: .5rem;
  justify-content: space-between;
  margin-bottom: .6rem;
}

.rel-head .field-label[b-zf873b2dab] {
  margin-bottom: 0;
}

.rel-filter[b-zf873b2dab] {
  display: flex;
  gap: .4rem;
  margin-bottom: .75rem;
}

.rel-filter .field[b-zf873b2dab] {
  font-size: .85rem;
  min-width: 0;
  padding: .35rem .55rem;
}

.rel-list[b-zf873b2dab] {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rel-version[b-zf873b2dab],
.rel-patch[b-zf873b2dab] {
  border-left: 2px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
}

.rel-version[b-zf873b2dab] {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .5rem;
  padding: .4rem .5rem;
}

.rel-version .rel-name[b-zf873b2dab] {
  font-size: .9rem;
  font-weight: 700;
}

.rel-version .rel-when[b-zf873b2dab] {
  margin-left: auto;
}

.rel-version:hover[b-zf873b2dab],
.rel-version.is-open[b-zf873b2dab],
.rel-patch:hover[b-zf873b2dab] {
  background: var(--surface);
}

/* The open version's patches, set in under it; the indent is what says they
   belong to it. */
.rel-body[b-zf873b2dab] {
  margin: .3rem 0 .9rem;
  padding-left: .75rem;
}

/* Derived, and said so: the languages of a version are the union of what its
   patches carry, and there is nothing here to edit. */
.rel-derived[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .78rem;
  margin: 0 0 .5rem;
  padding: 0 .45rem;
}

.rel-patch[b-zf873b2dab] {
  display: grid;
  gap: 0 .6rem;
  grid-template-columns: minmax(0, 1fr) auto;
  padding: .3rem .45rem;
}

.rel-patch .rel-name[b-zf873b2dab] {
  font-size: .85rem;
  font-weight: 600;
  grid-column: 1;
  grid-row: 1;
}

.rel-langs[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .78rem;
  grid-column: 1;
  grid-row: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rel-when[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .78rem;
}

.rel-patch .rel-when[b-zf873b2dab] {
  align-self: center;
  grid-column: 2;
  grid-row: 1 / 3;
}

/* The record open is the current page of its link: marked by the accent edge
   and the name, never by the tone alone. */
.rel-version[aria-current="page"][b-zf873b2dab],
.rel-patch[aria-current="page"][b-zf873b2dab] {
  background: var(--surface);
  border-left-color: var(--accent);
}

.rel-version[aria-current="page"] .rel-name[b-zf873b2dab],
.rel-patch[aria-current="page"] .rel-name[b-zf873b2dab] {
  color: var(--accent-text);
}

.rel-version:focus-visible[b-zf873b2dab],
.rel-patch:focus-visible[b-zf873b2dab],
.rel-more:focus-visible[b-zf873b2dab],
.rel-add:focus-visible[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.rel-more[b-zf873b2dab],
.rel-add[b-zf873b2dab] {
  border-radius: var(--radius-sm);
  display: block;
  font-size: .8rem;
  padding: .35rem .45rem;
}

.rel-more[b-zf873b2dab] {
  color: var(--accent-text);
}

.rel-add[b-zf873b2dab] {
  color: var(--text-muted);
  text-decoration: none;
}

.rel-add:hover[b-zf873b2dab],
.rel-add[aria-current="page"][b-zf873b2dab] {
  background: var(--surface);
  color: var(--text);
}

/* ---- the record open ---- */
.detail[b-zf873b2dab] {
  min-width: 0;
  padding: .2rem .2rem 0;
}

/* FormField spaces consecutive rows apart; in these grids the grid's gap
   spaces them instead. */
.ver-grid[b-zf873b2dab]  .field-row + .field-row,
.patch-grid[b-zf873b2dab]  .field-row + .field-row,
.mirror-grid[b-zf873b2dab]  .field-row + .field-row,
.ver-grid .field-row + .field-row[b-zf873b2dab],
.patch-grid .field-row + .field-row[b-zf873b2dab],
.mirror-grid .field-row + .field-row[b-zf873b2dab] {
  margin-top: 0;
}

.ver-grid[b-zf873b2dab] {
  display: grid;
  gap: 1rem .85rem;
  grid-template-columns: minmax(8rem, 12rem) minmax(9rem, 11rem) minmax(0, 1fr) 9rem;
}

.ver-grid .ver-status[b-zf873b2dab] {
  grid-column: 4;
  grid-row: 1;
}

.ver-notes[b-zf873b2dab],
.patch-notes[b-zf873b2dab] {
  grid-column: 1 / -1;
}

/* A patch's row keeps only what is singular about it: the number, the date,
   the build and the status. */
.patch-grid[b-zf873b2dab] {
  display: grid;
  gap: 1rem .85rem;
  grid-template-columns: 5rem minmax(9rem, 11rem) minmax(9rem, 14rem) minmax(0, 1fr) 9rem;
}

.patch-grid .patch-status[b-zf873b2dab] {
  grid-column: 5;
}

/* Printed, at the height of the fields beside it. */
.patch-no[b-zf873b2dab] {
  align-items: center;
  display: flex;
  font-size: 1rem;
  font-weight: 700;
  min-height: 2.45rem;
}

.patch-no.is-pending[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .82rem;
  font-weight: 600;
  line-height: 1.25;
}

/* The languages every build of the patch carries, at the form's width. */
.patch-sets[b-zf873b2dab] {
  margin-top: 1.1rem;
}

.patch-sets .checks[b-zf873b2dab] {
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}

.patch-sets .validation-message[b-zf873b2dab],
.build-plats .validation-message[b-zf873b2dab] {
  display: block;
  margin-top: .4rem;
}

/* A patch's languages are the whole closed set, some two hundred, so a typed
   filter narrows the list. It needs script, so it is scripted-only
   (controls.css); without it the list scrolls, and a box the filter hides
   keeps its state. */
.choice-filter[b-zf873b2dab] {
  margin-top: .4rem;
}

.checks .choice[hidden][b-zf873b2dab] {
  display: none;
}

.choice-empty[b-zf873b2dab] {
  margin: .4rem 0 0;
}

.choice-code[b-zf873b2dab] {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: .78rem;
  margin-left: .2rem;
}

.carried[b-zf873b2dab] {
  margin-top: 1.35rem;
}

.carried .note[b-zf873b2dab],
.carried .derived[b-zf873b2dab] {
  margin: .3rem 0 0;
}

.detail-actions[b-zf873b2dab] {
  display: flex;
  justify-content: flex-end;
  margin-top: 1.1rem;
}

/* ---- builds ----
   The files the patch ships as (ADR-039), stacked: each is a bordered block
   of its own, headed by the platforms it runs on, holding its mirrors. The
   patch above holds what every build shares, so a build draws only what can
   differ. */
.builds[b-zf873b2dab] {
  margin-top: 1.75rem;
}

.builds-head[b-zf873b2dab] {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1rem;
  margin-bottom: .85rem;
}

.build-list[b-zf873b2dab] {
  display: grid;
  gap: 1rem;
  margin-bottom: 1rem;
}

.build[b-zf873b2dab] {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-width: 0;
  padding: .9rem 1rem 1rem;
}

.build-head[b-zf873b2dab] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: .75rem;
}

/* Five platforms, so the group is one short row, not a scrolling list. */
.build-plats[b-zf873b2dab] {
  margin-bottom: .9rem;
}

.build-plats .checks[b-zf873b2dab] {
  gap: .1rem 1.25rem;
  grid-template-columns: repeat(5, max-content);
  max-height: none;
  overflow: visible;
}

.build-plats .check:has(:disabled)[b-zf873b2dab] {
  color: var(--text-subtle);
  cursor: default;
}

/* A platform's glyph dims with the name it stands beside. */
.build-plats .check:has(:disabled)[b-zf873b2dab] {
  --platform-icon-color: currentColor;
}

.build-foot[b-zf873b2dab] {
  margin: .9rem 0 0;
}

.build-new > .build-plats[b-zf873b2dab] {
  margin-bottom: 0;
}

.builds-note[b-zf873b2dab] {
  margin: 1rem 0 0;
}

/* ---- mirrors ----
   The hosts of one build's file. Each is a unit of its own on the raised
   surface, stacked in the order they are offered, because what is compared is
   the set of them. The row keeps a host label, an address, the instructions
   and a place — nothing that describes the build. */
.builds-title[b-zf873b2dab],
.build-title[b-zf873b2dab],
.mirror-title[b-zf873b2dab] {
  font-size: .92rem;
  font-weight: 700;
  margin: 0;
}

.builds-head .note[b-zf873b2dab],
.mirror-actions .note[b-zf873b2dab],
.deletion-actions .note[b-zf873b2dab] {
  margin: 0;
}

.mirror-list[b-zf873b2dab] {
  display: grid;
  gap: .75rem;
  list-style: none;
  margin: 0 0 .75rem;
  padding: 0;
}

.mirror-head[b-zf873b2dab] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .6rem;
  margin-bottom: .8rem;
}

.mirror-enabled[b-zf873b2dab] {
  margin-left: auto;
}

/* Three columns: the name beside the address, the instructions beside the
   place. The address and the instructions are the long values. */
.mirror-grid[b-zf873b2dab] {
  display: grid;
  gap: 1rem .85rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.mirror-wide[b-zf873b2dab] {
  grid-column: span 2;
}

/* The slot the next record goes in, drawn as the slot: dashed and never
   filled, the emptiest thing in its panel. Closed, the new mirror is one such
   line; open, it is drawn as the mirror it will be, with its command at its
   foot. The media section's add area is the same slot around a file input. */
.mirror-new > summary[b-zf873b2dab],
.add-area[b-zf873b2dab] {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  font-size: .88rem;
  font-weight: 600;
  padding: .7rem 1rem;
  text-align: center;
}

.mirror-new > summary[b-zf873b2dab] {
  list-style: none;
}

.mirror-new > summary:hover[b-zf873b2dab],
.add-area:hover[b-zf873b2dab] {
  background: var(--surface-raised);
  color: var(--text);
}

.mirror-new[open] > summary[b-zf873b2dab] {
  border: 0;
  color: var(--text);
  margin-bottom: .8rem;
  padding: 0;
  text-align: left;
}

/* The actions row of the record, with the note that explains the command
   beside it. */
.mirror-actions[b-zf873b2dab],
.deletion-actions[b-zf873b2dab] {
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem 1rem;
}

/* ---- publication ----
   One command per row at the column's width, each note under the command it
   explains. */
.commands[b-zf873b2dab] {
  display: grid;
  gap: .5rem;
}

.commands .note[b-zf873b2dab] {
  margin: 0;
}

/* One part of the game, set on the raised surface inside the panel: its own
   container is what separates it from the next part, so none needs a rule.
   A mirror, and the new one once open, is a part of its patch drawn the same
   way. */
/* The question before a delete stands where the archived notice stood, drawn
   as a part of the editor with the danger tone on its own edge: it is the one
   decision on the page until it is answered. */
.confirm-slot[b-zf873b2dab] {
  background: var(--surface-raised);
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  padding: .85rem 1rem;
}

.subcard[b-zf873b2dab],
.mirror[b-zf873b2dab],
.mirror-new[open][b-zf873b2dab] {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem 1.25rem;
}

.section-title[b-zf873b2dab] {
  font-size: .95rem;
  font-weight: 700;
  margin: 0 0 1rem;
}

/* The address reads as one line: the fixed part of the URL, then the part the
   administrator chooses. On a narrow screen the field drops under it. */
.slug[b-zf873b2dab] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .5rem;
}

.prefix[b-zf873b2dab] {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: .85rem;
}

/* InputText writes the input, so the rule reaches through it. */
.slug[b-zf873b2dab]  input {
  flex: 1 1 16rem;
  font-family: var(--font-mono);
  width: auto;
}

/* ---- the language picker ----
   A picker and not a strip of tabs: a strip promises a count, wraps into
   ragged rows at a dozen languages, and reads as page navigation. A closed
   picker is one line however many locales the site has, looks like the choice
   that governs the fields under it, and keeps the coverage count where the
   choice is made. */
.picker > summary[b-zf873b2dab] {
  align-items: center;
  background: var(--field-bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  list-style: none;
  padding: .55rem .7rem;
}

.picker > summary[b-zf873b2dab]::-webkit-details-marker,
.mirror-new > summary[b-zf873b2dab]::-webkit-details-marker {
  display: none;
}

.picker > summary:hover[b-zf873b2dab] {
  border-color: var(--accent);
}

.picker > summary:focus-visible[b-zf873b2dab],
.mirror-new > summary:focus-visible[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.picker-current[b-zf873b2dab] {
  font-weight: 600;
}

.picker-state[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .85rem;
}

.picker-hint[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .8rem;
  margin-left: auto;
}

.picker-caret[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .7rem;
}

.picker[open] .picker-caret[b-zf873b2dab] {
  transform: rotate(180deg);
}

/* The open list fills the width in columns and scrolls after a few rows, so
   forty languages cost the same height as four. It takes the panel's surface,
   one step back from the raised card it opens in. A category or tag group
   opens the same list, of checkboxes instead of links. */
.picker-list[b-zf873b2dab],
.checks[b-zf873b2dab] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  display: grid;
  gap: .1rem .35rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  list-style: none;
  margin: .4rem 0 0;
  max-height: 13rem;
  overflow-y: auto;
  padding: .4rem;
}

/* The state follows the name as the rest of the phrase, not pushed to the
   cell's edge, where a column of names and a column of states would read as
   two lists. */
.picker-list a[b-zf873b2dab] {
  border-radius: var(--radius-sm);
  color: var(--text);
  display: block;
  font-size: .88rem;
  padding: .35rem .5rem;
  text-decoration: none;
}

.picker-list a:hover[b-zf873b2dab] {
  background: var(--surface-raised);
}

.picker-list a:focus-visible[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.picker-list a[aria-current="page"][b-zf873b2dab] {
  background: var(--surface-raised);
  color: var(--accent-text);
  font-weight: 700;
}

/* Only a translated language says so on screen; the rest are dimmer, and say
   "not translated" to assistive technology. Absence repeated on every row
   would be the loudest thing in the list. */
.picker-list a.is-empty[b-zf873b2dab] {
  color: var(--text-muted);
}

.picker-list[b-zf873b2dab]  .badge {
  margin-left: .4rem;
}

.picker-add[b-zf873b2dab] {
  margin-top: .75rem;
}

/* A refusal about the translation as a whole, read before its fields. */
.content-error[b-zf873b2dab] {
  margin: 1rem 0;
}

/* Two short fields that belong together — the SEO title and description, the
   engine and the release date: side by side where there is room. */
.pair[b-zf873b2dab] {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 1rem;
}

.pair[b-zf873b2dab]  .field-row + .field-row {
  margin-top: 0;
}

/* The original title and its language: the title takes the width, and the
   language a column wide enough for the longest name in the list. A row
   follows it, which FormField would otherwise space from a row before it. */
.title-pair[b-zf873b2dab] {
  grid-template-columns: minmax(0, 1fr) 13rem;
  margin-bottom: 1rem;
}

.content-actions[b-zf873b2dab] {
  display: flex;
  justify-content: flex-end;
  margin-top: 1.1rem;
}

/* ---- store pages ----
   One row per page: the store, the code people search for, the page's link,
   and its ✕. Only the first row shows the labels; the rows under it line up
   with it and keep theirs for a screen reader. */
.stores[b-zf873b2dab] {
  display: grid;
  gap: .5rem;
}

.store-row[b-zf873b2dab] {
  align-items: end;
  display: grid;
  gap: .6rem;
  grid-template-columns: 10rem 10rem minmax(0, 1fr) auto;
}

.store-row[b-zf873b2dab]  .field-row + .field-row {
  margin-top: 0;
}

.store-row + .store-row[b-zf873b2dab]  .field-label {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  position: absolute;
  width: 1px;
}

.store-row .code[b-zf873b2dab] {
  font-family: var(--font-mono);
}

.stores-actions[b-zf873b2dab] {
  margin-top: .75rem;
}

/* ---- classification ----
   A category or tag group is the language picker's disclosure with the
   group's label in its head, and the count of what is checked where the
   picker keeps its coverage count. */
.disclosure .field-label[b-zf873b2dab] {
  margin-bottom: 0;
}

.checks .choice[b-zf873b2dab] {
  padding: .3rem .5rem;
}

.disclosure + .validation-message[b-zf873b2dab],
.credit-line + .validation-message[b-zf873b2dab] {
  display: block;
  margin-top: .4rem;
}

/* A value the screen shows and does not edit. */
.derived[b-zf873b2dab] {
  margin: 0;
}

/* The platforms side by side, each its glyph then its name, with no comma to
   read past. */
.derived-platforms[b-zf873b2dab] {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .9rem;
}

.derived-note[b-zf873b2dab] {
  margin: .5rem 0 0;
}

/* FormField spaces its own rows; these are the rows the editor writes. */
.field-row + .field-row[b-zf873b2dab] {
  margin-top: 1rem;
}

.note[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .85rem;
  margin: 0 0 .6rem;
}

.credit-add + .note[b-zf873b2dab],
.taxonomy-note[b-zf873b2dab] {
  margin: .5rem 0 0;
}

.note a[b-zf873b2dab] {
  color: var(--accent-text);
}

/* The credits fill the width in columns, as the language list does; a game
   credits a handful, so the list is never tall. */
.credits[b-zf873b2dab] {
  display: grid;
  gap: .35rem 1rem;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  list-style: none;
  margin: 0 0 .75rem;
  padding: 0;
}

.credits li[b-zf873b2dab],
.checks .choice[b-zf873b2dab] {
  align-items: center;
  display: flex;
  gap: .5rem;
}

.check[b-zf873b2dab] {
  align-items: center;
  cursor: pointer;
  display: inline-flex;
  font-size: .92rem;
  gap: .5rem;
}

.check input[b-zf873b2dab] {
  accent-color: var(--accent);
  height: 1rem;
  width: 1rem;
}

/* The credit search: the text and its command on one line, the matches and the
   command that records a new studio on the next, so a narrow column wraps each
   pair rather than breaking one apart. */
.credit-line[b-zf873b2dab] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.credit-line + .credit-line[b-zf873b2dab] {
  margin-top: .5rem;
}

.credit-add[b-zf873b2dab]  select,
.credit-add[b-zf873b2dab]  input {
  max-width: 24rem;
}

/* The matches developer-picker.js reads while the name is typed wear the
   combobox skin of controls.css; only their width belongs to this screen, which
   keeps them under the field they open beneath rather than the card's. */
.credit-add .combobox-list[b-zf873b2dab] {
  max-width: 24rem;
}

.note + .note[b-zf873b2dab] {
  margin-top: .35rem;
}

/* ---- media ----
   The gallery: one tile per image, the cover first. The picture is the tile's
   face and the radio in its foot is its state and its keyboard target; the
   label's ::after is stretched over the whole tile, so a click anywhere on the
   picture chooses it. Whatever else in the tile must stay clickable — the
   commands, the alt text — is lifted above that layer (.pick-over). */
.media-head[b-zf873b2dab] {
  align-items: baseline;
  display: flex;
  gap: .75rem;
  margin-bottom: 1rem;
}

.media-head .section-title[b-zf873b2dab] {
  margin: 0;
}

.media[b-zf873b2dab] {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}

/* Drawn even without a tile, as the place a chosen file is previewed in. */
.media:empty[b-zf873b2dab] {
  display: none;
}

.media-tile[b-zf873b2dab] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 0;
  overflow: hidden;
  position: relative;
}

.media-tile:hover[b-zf873b2dab] {
  border-color: var(--border-strong);
}

/* Focus lands on the radio in a corner, or on a command, so the ring is drawn
   on the tile they govern. */
.media-tile:focus-within[b-zf873b2dab] {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The chosen tile says so twice: the accent edge, and the word in its foot. */
.media-tile:has(input[type="radio"]:checked)[b-zf873b2dab] {
  border-color: var(--accent);
}

.media-tile .cover[b-zf873b2dab] {
  aspect-ratio: 16 / 10;
  background: var(--surface-raised);
  display: block;
  object-fit: cover;
  width: 100%;
}

.media-foot[b-zf873b2dab] {
  align-items: center;
  display: flex;
  gap: .5rem;
  justify-content: space-between;
  padding: .35rem .5rem 0;
}

.media-foot .check[b-zf873b2dab] {
  font-size: .78rem;
  gap: .35rem;
}

.media-tile:has(input[type="radio"]:checked) .media-foot .check[b-zf873b2dab] {
  color: var(--accent-text);
  font-weight: 700;
}

.pick-label[b-zf873b2dab] {
  cursor: pointer;
}

.pick-label[b-zf873b2dab]::after {
  content: "";
  inset: 0;
  position: absolute;
}

.pick-over[b-zf873b2dab] {
  position: relative;
  z-index: 1;
}

.media-commands[b-zf873b2dab] {
  display: inline-flex;
  gap: .1rem;
}

/* A control whose glyph is its whole label, so it is drawn bare: a frame
   around a single "×" reads as a button that lost its text. Its name is its
   aria-label. */
.icon-btn[b-zf873b2dab] {
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  padding: .15rem .35rem;
}

.icon-btn:hover[b-zf873b2dab] {
  color: var(--text);
}

.icon-btn:focus-visible[b-zf873b2dab],
.icon-btn:has(input:focus-visible)[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.media-alt[b-zf873b2dab] {
  padding: .35rem .5rem .5rem;
}

/* Marked for removal: the picture fades, the alt text gives way to the note,
   and the × stays lit, pressed, until a second click takes the mark back. */
.removal-note[b-zf873b2dab] {
  color: var(--text-muted);
  display: none;
  font-size: .78rem;
  margin: 0;
  padding: .55rem .5rem .75rem;
}

.media-tile:has(.media-remove input:checked)[b-zf873b2dab],
.media-pending[b-zf873b2dab] {
  border-style: dashed;
}

.media-tile:has(.media-remove input:checked) .cover[b-zf873b2dab] {
  opacity: .35;
}

.media-tile:has(.media-remove input:checked) .media-remove[b-zf873b2dab] {
  background: var(--surface-raised);
  color: var(--text);
}

.media-tile:has(.media-remove input:checked) .removal-note[b-zf873b2dab] {
  display: block;
}

.media-tile:has(.media-remove input:checked) .media-alt[b-zf873b2dab] {
  display: none;
}

/* A file chosen and not yet saved is dashed like the slot it came from (above),
   and named as what the save will make it. */
.pending-note[b-zf873b2dab] {
  color: var(--text-muted);
  font-size: .78rem;
  padding: .2rem 0 .55rem;
}

.media-alt .field[b-zf873b2dab] {
  font-size: .8rem;
  padding: .3rem .5rem;
}

.media-state[b-zf873b2dab] {
  margin-top: .9rem;
}

/* The file input inside the add area is clipped out of view, so the label
   draws its focus — on keyboard focus only, not after every click. */
.media-add[b-zf873b2dab] {
  align-items: center;
  display: flex;
  gap: .5rem;
  margin-top: 1rem;
}

.add-area[b-zf873b2dab] {
  align-items: center;
  display: flex;
  flex: 1;
  gap: .5rem;
  justify-content: center;
}

.add-area:has(:focus-visible)[b-zf873b2dab] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.add-area .glyph[b-zf873b2dab] {
  font-size: 1.1rem;
  font-weight: 400;
  line-height: 1;
}

.media-add[hidden][b-zf873b2dab] {
  display: none;
}

.media-full[b-zf873b2dab] {
  margin: 1rem 0 0;
}

/* Too narrow for a second column: the lifecycle follows the sections, and is
   no longer pinned, where it would cover the form it belongs to. */
@media (max-width: 1024px) {
  .layout[b-zf873b2dab] {
    grid-template-columns: minmax(0, 1fr);
  }

  .side[b-zf873b2dab] {
    position: static;
  }

  .releases[b-zf873b2dab] {
    grid-template-columns: 14rem minmax(0, 1fr);
  }

  .ver-grid[b-zf873b2dab] {
    grid-template-columns: minmax(0, 1fr) 10rem;
  }

  .ver-grid .ver-status[b-zf873b2dab] {
    grid-column: 2;
    grid-row: auto;
  }

  .patch-grid[b-zf873b2dab] {
    grid-template-columns: 5rem minmax(0, 1fr) minmax(0, 1fr);
  }

  .patch-grid .patch-status[b-zf873b2dab] {
    grid-column: auto;
  }
}

@media (max-width: 880px) {
  .subcard[b-zf873b2dab] {
    padding: .9rem;
  }

  /* One column: the navigator above the record, no longer pinned. */
  .releases[b-zf873b2dab],
  .patch-grid[b-zf873b2dab],
  .mirror-grid[b-zf873b2dab] {
    grid-template-columns: minmax(0, 1fr);
  }

  .build-plats .checks[b-zf873b2dab] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .build[b-zf873b2dab] {
    padding: .8rem .7rem .85rem;
  }

  .mirror-wide[b-zf873b2dab] {
    grid-column: auto;
  }

  /* The store and the code side by side with the ✕, the link under them. */
  .store-row[b-zf873b2dab] {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  }

  .store-row-link[b-zf873b2dab] {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .rel-nav[b-zf873b2dab] {
    position: static;
  }

  .switch[b-zf873b2dab] {
    display: flex;
    width: 100%;
  }

  .switch-option[b-zf873b2dab] {
    flex: 1;
  }

  .head-actions[b-zf873b2dab] {
    margin-left: 0;
    width: 100%;
  }

  .head-actions .btn[b-zf873b2dab] {
    flex: 1;
  }

  .pair[b-zf873b2dab],
  .title-pair[b-zf873b2dab] {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* /Components/Admin/Games/GameListing.razor.rz.scp.css */
/* ---- the head ---- */

.toolbar[b-iod19zeiw1] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.search[b-iod19zeiw1] {
  display: flex;
  flex: 1 1 20rem;
  gap: .5rem;
  max-width: 32rem;
}

.search .field[b-iod19zeiw1] {
  flex: 1;
  min-width: 0;
}

.filters[b-iod19zeiw1] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-bottom: 1.1rem;
}

/* The label sits beside its select rather than above it: the order is one
   line of the head, not a form to fill in. FormField writes the row and the
   label, so the rules reach through it. */
.sort[b-iod19zeiw1] {
  align-items: center;
  display: flex;
  gap: .5rem;
}

.sort[b-iod19zeiw1]  .field-row {
  align-items: center;
  display: flex;
  gap: .5rem;
}

.sort[b-iod19zeiw1]  .field-label {
  margin-bottom: 0;
}

.sort select[b-iod19zeiw1] {
  min-width: 12rem;
  padding-bottom: .4rem;
  padding-top: .4rem;
}

/* ---- the listing ----
   One column template for the header and the rows, declared on the section
   both live in, so the two cannot drift apart. */

.listing[b-iod19zeiw1] {
  --game-columns: 3rem minmax(0, 1fr) 8rem 11rem 11rem;
}

.listing-head[b-iod19zeiw1] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--game-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.games[b-iod19zeiw1] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A working list is scanned line by line, so a row is a card that stays put:
   no lift and no highlight, since it is not itself a click target. */
.game[b-iod19zeiw1] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "thumb main status when actions";
  grid-template-columns: var(--game-columns);
  padding: .7rem .9rem;
  row-gap: .45rem;
}

.thumb[b-iod19zeiw1] {
  aspect-ratio: 1;
  background: var(--surface-high);
  border-radius: var(--radius-sm);
  grid-area: thumb;
  width: 3rem;
}

.game-main[b-iod19zeiw1] {
  grid-area: main;
  min-width: 0;
}

/* Text, not a link: the Edit button is the row's way in, and a linked name
   would make the same place reachable twice. */
.game-name[b-iod19zeiw1] {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
}

.game-credits[b-iod19zeiw1] {
  color: var(--text-subtle);
  font-size: .78rem;
  margin: .15rem 0 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.game-status[b-iod19zeiw1] {
  grid-area: status;
}

.game-when[b-iod19zeiw1] {
  color: var(--text-subtle);
  font-size: .8rem;
  grid-area: when;
}

.game-when time[b-iod19zeiw1] {
  color: var(--text);
  display: block;
  font-size: .82rem;
  font-weight: 600;
}

.game-actions[b-iod19zeiw1] {
  display: flex;
  gap: .4rem;
  grid-area: actions;
  justify-content: flex-end;
}

/* ---- states ----
   An answer instead of rows: centered on its panel, with the way on under it.
   Panel and Callout write their own markup, so the rules reach through them. */

.state[b-iod19zeiw1]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-iod19zeiw1]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

.state p[b-iod19zeiw1] {
  color: var(--text-muted);
  margin: 0 auto 1.1rem;
  max-width: 46ch;
}

@media (max-width: 880px) {
  /* The header goes with the one-line layout it labels. The state and the
     dates stack beside the name, and the button keeps a column of its own. */
  .listing-head[b-iod19zeiw1] {
    display: none;
  }

  .listing[b-iod19zeiw1] {
    --game-columns: 3rem minmax(0, 1fr) auto auto;
  }

  .game[b-iod19zeiw1] {
    grid-template-areas:
      "thumb main status actions"
      "thumb main when actions";
  }

  .game-status[b-iod19zeiw1],
  .game-when[b-iod19zeiw1] {
    justify-self: end;
    text-align: right;
  }
}

@media (max-width: 560px) {
  .listing[b-iod19zeiw1] {
    --game-columns: 3rem minmax(0, 1fr);
  }

  .game[b-iod19zeiw1] {
    grid-template-areas:
      "thumb main"
      "thumb status"
      "when when"
      "actions actions";
  }

  .game-status[b-iod19zeiw1],
  .game-when[b-iod19zeiw1] {
    justify-self: start;
    text-align: left;
  }

  /* On a phone the way in is the row's whole point, so it takes the width. */
  .game-actions .btn[b-iod19zeiw1] {
    flex: 1;
  }

  .sort[b-iod19zeiw1],
  .sort[b-iod19zeiw1]  .field-row {
    width: 100%;
  }

  .sort select[b-iod19zeiw1] {
    flex: 1;
    min-width: 0;
  }
}
/* /Components/Admin/Mcp/McpTokenListing.razor.rz.scp.css */
/* ---- the head ----
   The same shape as the other administration heads: what the screen is about
   on the left, the one command that writes on the right. Its top edge is the
   line both share, so a refusal under the name does not move the text. */

.toolbar[b-qys8pd853k] {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.intro[b-qys8pd853k] {
  flex: 1 1 18rem;
  max-width: 44ch;
}

.intro p[b-qys8pd853k] {
  color: var(--text-muted);
  margin: 0;
}

/* EditForm and InputText write the form and the input, so the rules reach
   through them. */
.toolbar[b-qys8pd853k]  .create {
  flex: 1 1 26rem;
}

/* Three controls on one line where they fit, and wrapping rather than pushing
   the button past the edge where they do not. */
.create-row[b-qys8pd853k] {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.create-row[b-qys8pd853k]  input {
  flex: 2 1 9rem;
  min-width: 0;
}

.create-row[b-qys8pd853k]  select {
  flex: 1 1 8rem;
  min-width: 0;
}

.create-row .btn[b-qys8pd853k] {
  flex: 0 0 auto;
}

/* ---- the value, shown once ----
   Set apart from everything else on the screen, because it is the one thing
   here that cannot be read again. Panel and Callout write their own markup, so
   the rules reach through them. */

.issued[b-qys8pd853k] {
  margin-bottom: 1.1rem;
}

.issued[b-qys8pd853k]  .callout {
  margin-bottom: 1rem;
}

.token-value[b-qys8pd853k] {
  background: var(--surface-sunken, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 0 0 .6rem;
  overflow-wrap: anywhere;
  padding: .7rem .9rem;
}

.token-value code[b-qys8pd853k] {
  font-size: .92rem;
}

.token-expiry[b-qys8pd853k] {
  color: var(--text-subtle);
  font-size: .82rem;
  margin: 0;
}

/* ---- the listing ----
   One column template for the header and the rows, declared on the section
   both live in, so the two cannot drift apart. */

.listing[b-qys8pd853k] {
  --token-columns: minmax(0, 1fr) 9rem 9rem 7rem;
}

.listing-head[b-qys8pd853k] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--token-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.tokens[b-qys8pd853k] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A row is a card that stays put, as on the other listings: it is not itself a
   click target, the button inside it is. */
.token[b-qys8pd853k] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "main expires used actions";
  grid-template-columns: var(--token-columns);
  min-height: 3.6rem;
  padding: .7rem .9rem;
  row-gap: .45rem;
}

.token-main[b-qys8pd853k] {
  grid-area: main;
  min-width: 0;
}

.token-name[b-qys8pd853k] {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  overflow-wrap: anywhere;
}

.token-meta[b-qys8pd853k] {
  align-items: center;
  color: var(--text-subtle);
  display: flex;
  font-size: .82rem;
  gap: .45rem;
  margin: .2rem 0 0;
}

.token-expires[b-qys8pd853k] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  grid-area: expires;
}

.token-used[b-qys8pd853k] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  grid-area: used;
}

.token-actions[b-qys8pd853k] {
  display: flex;
  gap: .4rem;
  grid-area: actions;
  justify-content: flex-end;
}

/* ---- states ----
   An answer instead of rows: centered on its panel. */

.state[b-qys8pd853k]  .panel {
  padding: 2rem;
  text-align: center;
}

.state p[b-qys8pd853k] {
  color: var(--text-muted);
  margin: 0 auto;
  max-width: 46ch;
}

@media (max-width: 880px) {
  /* The header goes with the one-line layout it labels. The dates drop under
     the name, and the button keeps a column of its own. */
  .listing-head[b-qys8pd853k] {
    display: none;
  }

  .listing[b-qys8pd853k] {
    --token-columns: minmax(0, 1fr) auto;
  }

  .token[b-qys8pd853k] {
    grid-template-areas:
      "main actions"
      "expires actions"
      "used actions";
  }
}

@media (max-width: 560px) {
  .toolbar[b-qys8pd853k]  .create {
    flex-basis: 100%;
  }

  .create-row[b-qys8pd853k]  select {
    flex: 1 1 100%;
  }

  .listing[b-qys8pd853k] {
    --token-columns: minmax(0, 1fr);
  }

  .token[b-qys8pd853k] {
    grid-template-areas:
      "main"
      "expires"
      "used"
      "actions";
  }

  .token-actions .btn[b-qys8pd853k] {
    flex: 1;
  }
}
/* /Components/Admin/Reports/AuditRecord.razor.rz.scp.css */
/* The record of an act already taken: the same shape as the field that produced
   it, so a decided row reads as the open one after the fact. It is drawn at two
   sizes — under one report, where it is an aside to the account above it, and
   under a row, where it is the answer the row now carries. The container sets
   which, so the record itself has one rule. */

.audit[b-11bf1sxddo] {
  display: grid;
  gap: .25rem;
}

.audit-who[b-11bf1sxddo] {
  color: var(--text-muted);
  font-size: var(--audit-who-size, .76rem);
}

.audit-note[b-11bf1sxddo] {
  font-size: var(--audit-note-size, .88rem);
  margin: 0;
  max-width: 70ch;
}
/* /Components/Admin/Reports/ReportEvidence.razor.rz.scp.css */
/* ---- the evidence ----
   The reports standing against one subject, drawn the same way whether the row
   is still waiting or already decided. The styles live with the markup, because
   scoped CSS follows the file its elements are declared in. */

.reports[b-a25epqtnkg] {
  display: grid;
  gap: .75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.report[b-a25epqtnkg] {
  display: grid;
  gap: .2rem;
}

.report-head[b-a25epqtnkg] {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.report-reason[b-a25epqtnkg] {
  font-size: .88rem;
  font-weight: 600;
}

.report-when[b-a25epqtnkg] {
  color: var(--text-subtle);
  font-size: .76rem;
}

/* What the visitor typed: the only thing on this screen the administrator did
   not write. */
.report-comment[b-a25epqtnkg] {
  color: var(--text-muted);
  font-size: .85rem;
  margin: 0;
  max-width: 70ch;
}

.report-comment.none[b-a25epqtnkg] {
  color: var(--text-subtle);
  font-style: italic;
}

/* Where a report was re-filed from, and why: the shared audit record, set one
   step quieter than the account it sits under, because the reason, the comment
   and the time are the reporter's and this line is the reader's. */
.report-move[b-a25epqtnkg] {
  --audit-who-size: .72rem;
  --audit-note-size: .8rem;
  margin-top: .3rem;
}

/* The one control that belongs to a single report. Beside the account it is a
   judgement about, and never in the row's own line of commands. */
.report-command[b-a25epqtnkg] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: .35rem;
}
/* /Components/Admin/Reports/ReportQueue.razor.rz.scp.css */
/* ---- the head ----
   The state is navigation and sits above the panel, because it decides which
   list is on screen. Everything that narrows or arranges that list is inside
   the panel with the rows. */

.status-row[b-knni7y4di5] {
  margin-bottom: 1.1rem;
}

/* ---- the filters ----
   One form: the search, the subject, the reason and the order, so one
   submission carries every choice the reader made about this list. Two forms
   would mean applying a reason drops the order or repeats it in a hidden field
   that can fall out of step with the visible control. */

.filters[b-knni7y4di5] {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  /* Separated from the rows by space and by nothing else. */
  margin-bottom: 1.25rem;
}

.filters .search[b-knni7y4di5] {
  flex: 1 1 15rem;
  max-width: 22rem;
}


.filter[b-knni7y4di5] {
  flex: 0 1 11rem;
}

.filter-wide[b-knni7y4di5] {
  flex: 0 1 14rem;
}

.filters .field[b-knni7y4di5] {
  width: 100%;
}

.filters .actions[b-knni7y4di5] {
  display: flex;
  gap: .5rem;
  margin-left: auto;
}

/* ---- the rows ----
   One column template for the header and the rows, declared on the section both
   live in, so the two cannot drift apart.

   The row is `queue-row` and not `row`: Bootstrap's grid owns that name, and a
   details element carrying it would be laid out as a flex container before any
   rule here was read. */

.listing[b-knni7y4di5] {
  --row-columns: 3rem minmax(0, 1fr) 14rem 7.5rem 8.5rem 1.4rem;
}

.rows-head[b-knni7y4di5] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--row-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.rows[b-knni7y4di5] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.queue-row[b-knni7y4di5] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.queue-row > summary[b-knni7y4di5] {
  align-items: center;
  column-gap: 1rem;
  cursor: pointer;
  display: grid;
  grid-template-areas: "count main reasons state when caret";
  grid-template-columns: var(--row-columns);
  border-radius: var(--radius);
  list-style: none;
  padding: .7rem .9rem;
  row-gap: .5rem;
}

.queue-row > summary[b-knni7y4di5]::-webkit-details-marker {
  display: none;
}

.queue-row > summary:hover[b-knni7y4di5] {
  background: var(--surface-raised);
}

.queue-row > summary:focus-visible[b-knni7y4di5] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* What the queue is scanned by, and the reason one row is opened before
   another. */
.row-count[b-knni7y4di5] {
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  grid-area: count;
}

.row-main[b-knni7y4di5] {
  grid-area: main;
  min-width: 0;
}

.row-name[b-knni7y4di5] {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  font-size: .95rem;
  font-weight: 600;
  gap: .45rem;
  line-height: 1.3;
}

/* Where the report landed, in the order the model nests it. The line ending at
   the patch is the first thing that says which of the two kinds this row is. */
.row-where[b-knni7y4di5] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-weight: 500;
}

/* The reasons the reports carry and how many carried each. Text rather than a
   row of tags: a breakdown is read, not scanned for one value. */
.row-reasons[b-knni7y4di5] {
  display: grid;
  gap: .15rem;
  grid-area: reasons;
}

.reason[b-knni7y4di5] {
  color: var(--text-subtle);
  display: flex;
  font-size: .78rem;
  gap: .5rem;
  justify-content: space-between;
}

.reason b[b-knni7y4di5] {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.row-state[b-knni7y4di5] {
  display: grid;
  gap: .2rem;
  grid-area: state;
  justify-items: start;
}

/* The kind, named above the badge, because a mirror and a patch do not share a
   state vocabulary. */
.subject-kind[b-knni7y4di5] {
  color: var(--text-subtle);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.row-when[b-knni7y4di5] {
  color: var(--text-subtle);
  font-size: .8rem;
  grid-area: when;
}

.row-when b[b-knni7y4di5] {
  color: var(--text);
  display: block;
  font-size: .82rem;
  font-weight: 700;
}

/* Where the shared .disclosure-caret sits in the row: its own column at the end.
   The mark itself, and its flip when the row opens, are the primitive's. */
.row-caret[b-knni7y4di5] {
  grid-area: caret;
  justify-self: end;
}

/* ---- the evidence ----
   The body steps one surface up from the row it opens inside, so its edge is
   visible without a line drawn between it and the head. */

.row-body[b-knni7y4di5] {
  background: var(--surface-raised);
  border-radius: var(--radius-sm);
  margin: 0 .9rem .9rem;
  padding: .9rem;
}

.section-title[b-knni7y4di5] {
  color: var(--text-muted);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .08em;
  margin: 0 0 .7rem;
  text-transform: uppercase;
}

/* The evidence itself is drawn by ReportEvidence and styled there. What stays
   here is the one control this screen puts inside it: the select naming the
   mirror a report would be moved down to, which is written in this file and
   therefore carries this file's scope. */
.report-command .field[b-knni7y4di5] {
  max-width: 12rem;
}

/* ---- deciding ----
   One form for the row: the evidence, the note it is explained in, and the
   three outcomes. None of them is filled — they are alternatives the evidence
   decides between. */

.decide .note[b-knni7y4di5] {
  margin-top: 1rem;
  max-width: 70ch;
}

.decide textarea.field[b-knni7y4di5] {
  width: 100%;
}

/* What disabling this subject would take down. Neither a label nor a value, and
   the only line here that is neither. */
.consequence[b-knni7y4di5] {
  color: var(--text-muted);
  font-size: .8rem;
  margin: .6rem 0 0;
  max-width: 70ch;
}

.row-actions[b-knni7y4di5] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: 1rem;
}

/* The destination keeps the left of the row and the outcomes keep the right, so
   a command that changes nothing is never next to one that does. */
.row-actions .spacer[b-knni7y4di5] {
  flex: 1 1 auto;
}

.section-title.decided[b-knni7y4di5] {
  margin-top: 1.1rem;
}

/* ---- states ----
   An answer instead of rows: centered on its panel, with the way on under it. */

.state[b-knni7y4di5]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-knni7y4di5]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

.state p[b-knni7y4di5] {
  color: var(--text-muted);
  margin: 0 auto 1.1rem;
  max-width: 46ch;
}

@media (max-width: 1080px) {
  .filters .actions[b-knni7y4di5] {
    margin-left: 0;
  }
}

@media (max-width: 880px) {
  .filters .search[b-knni7y4di5] {
    max-width: none;
  }

  .filter[b-knni7y4di5] {
    flex: 1 1 12rem;
  }

  .filters .actions[b-knni7y4di5] {
    flex: 1 1 100%;
  }

  .filters .actions .btn[b-knni7y4di5] {
    flex: 1;
  }

  /* The header goes with the column layout it labels, and every cell moves
     under the name it belongs to. The count keeps its own column: it is what
     the queue is scanned by, and a number that changes column between layouts
     is a number that has to be looked for twice. */
  .rows-head[b-knni7y4di5] {
    display: none;
  }

  .listing[b-knni7y4di5] {
    --row-columns: 3rem minmax(0, 1fr) 1.4rem;
  }

  .queue-row > summary[b-knni7y4di5] {
    grid-template-areas:
      "count main    caret"
      ".     reasons ."
      ".     state   ."
      ".     when    .";
    row-gap: .4rem;
  }

  .row-when b[b-knni7y4di5] {
    display: inline;
  }

  .row-body[b-knni7y4di5] {
    margin: 0 .6rem .6rem;
    padding: .75rem;
  }

  /* The outcomes stop being a right-hand group and become a wrapped list: at
     this width there is no room to separate them from the destination, and a
     spacer that collapses to nothing would only leave an uneven gap. */
  .row-actions .spacer[b-knni7y4di5] {
    display: none;
  }

  .row-actions .btn[b-knni7y4di5] {
    flex: 1 1 auto;
  }
}
/* /Components/Admin/Shared/Combobox.razor.rz.scp.css */
/* Without script, the select and its button on one line. With it, the field
   and its list, and the select is not shown — but is still what is sent. */
.combobox-fallback[b-p1x8i2efi5] {
  display: flex;
  gap: .5rem;
}

.combobox-fallback select[b-p1x8i2efi5] {
  flex: 1 1 14rem;
  max-width: 26rem;
}

.combobox-scripted[b-p1x8i2efi5] {
  display: none;
}

html.js .combobox-fallback[b-p1x8i2efi5] {
  display: none;
}

html.js .combobox-scripted[b-p1x8i2efi5] {
  display: block;
  max-width: 26rem;
}

.combobox-detail[b-p1x8i2efi5] {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 400;
  margin-left: .2rem;
}

/* /Components/Admin/Taxonomy/PatchToolVersionListing.razor.rz.scp.css */
/* The taxonomy listing's layout (TaxonomyListing.razor.css) with a release
   date and notes beside the label: the same head, the same row, the same
   breakpoints, so moving between the screens under Taxonomy changes the words
   and the columns in between. */

/* ---- the head ----
   The search, then the command that writes on a line of its own, because it
   has three fields. Every field carries a visible label. */

.toolbar[b-lns98sccc9] {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  margin-bottom: 1rem;
}

.search[b-lns98sccc9] {
  flex: 1 1 18rem;
  max-width: 30rem;
}

.search-row[b-lns98sccc9] {
  display: flex;
  gap: .5rem;
}

.search-row .field[b-lns98sccc9] {
  flex: 1;
  min-width: 0;
}

/* EditForm, FormField and the inputs write their own markup, so the rules
   reach through them. */
.toolbar[b-lns98sccc9]  .create {
  flex: 1 1 100%;
}

/* Labels, fields and messages each keep a row of their own across the
   fields, so the button stays level with the fields whatever a message under
   one of them does. */
.create-fields[b-lns98sccc9] {
  column-gap: .5rem;
  display: grid;
  grid-template-columns: minmax(0, 14rem) 10.5rem minmax(0, 1fr) auto;
  grid-template-rows: auto auto auto;
}

.create-fields[b-lns98sccc9]  .field-row {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  margin: 0;
}

/* FormField spaces a field from the one above it; side by side there is
   nothing above, and the rule has to outweigh FormField's own. */
.toolbar .create-fields[b-lns98sccc9]  .field-row + .field-row {
  margin-top: 0;
}

.create-fields > .btn[b-lns98sccc9] {
  align-self: start;
  grid-column: 4;
  grid-row: 2;
}

.filters[b-lns98sccc9] {
  margin-bottom: 1.1rem;
}

/* ---- the listing ----
   One column template for the header and the rows, declared on the section
   both live in, so the two cannot drift apart. */

.listing[b-lns98sccc9] {
  /* The last column holds Edit, Restore and Delete side by side. */
  --value-columns: minmax(0, 13rem) 8rem minmax(0, 1fr) 7rem 14rem;
}

.reference-note[b-lns98sccc9] {
  color: var(--text-muted);
  font-size: .85rem;
  margin: 0 0 .9rem;
  max-width: 72ch;
}

.listing-head[b-lns98sccc9] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--value-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.values[b-lns98sccc9] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A row is a card that stays put: it is not itself a click target, the
   buttons inside it are. */
.value[b-lns98sccc9] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "main date notes references actions";
  grid-template-columns: var(--value-columns);
  min-height: 3.6rem;
  padding: .7rem .9rem;
  row-gap: .45rem;
}

/* The row being edited hands its columns to the form inside it. */
.value.editing[b-lns98sccc9] {
  display: block;
}

.values[b-lns98sccc9]  .value-form {
  align-items: start;
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "main date notes references actions";
  grid-template-columns: var(--value-columns);
  row-gap: .45rem;
}

.value-main[b-lns98sccc9] {
  grid-area: main;
  min-width: 0;
}

.value-name[b-lns98sccc9] {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  overflow-wrap: anywhere;
}

.value-date[b-lns98sccc9] {
  color: var(--text-muted);
  font-size: .85rem;
  font-variant-numeric: tabular-nums;
  grid-area: date;
}

.value-notes[b-lns98sccc9] {
  grid-area: notes;
  min-width: 0;
}

/* Notes are read at a glance here and in full when the row is edited, so a
   long one stops after two lines rather than stretching the row. */
.notes-text[b-lns98sccc9] {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  color: var(--text-muted);
  display: -webkit-box;
  font-size: .85rem;
  line-height: 1.4;
  margin: 0;
  overflow: hidden;
  overflow-wrap: anywhere;
  white-space: pre-line;
}

.toolbar[b-lns98sccc9]  textarea.notes,
.values[b-lns98sccc9]  textarea.notes {
  min-height: 2.6rem;
  resize: vertical;
}

.value-references[b-lns98sccc9] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  grid-area: references;
}

.value-actions[b-lns98sccc9] {
  display: flex;
  gap: .4rem;
  grid-area: actions;
  justify-content: flex-end;
}

/* The patches that name no version are not a version, and their row reads as
   a note beside the versions rather than one of them. */
.without-tool-version .value-name[b-lns98sccc9] {
  color: var(--text-muted);
  font-style: italic;
}

/* An open row's patches, under every column of it, set apart by space. */
.value-panel[b-lns98sccc9] {
  grid-column: 1 / -1;
  padding-top: .5rem;
}

/* In the form, the count and the buttons line up with the fields' text rather
   than with the middle of whatever the notes grew to. */
.editing .value-references[b-lns98sccc9] {
  padding-top: .6rem;
}

.editing .value-actions[b-lns98sccc9] {
  padding-top: .2rem;
}

/* ---- states ----
   An answer instead of rows: centered on its panel, with the way on under it.
   Panel and Callout write their own markup, so the rules reach through them. */

.state[b-lns98sccc9]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-lns98sccc9]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

.state p[b-lns98sccc9] {
  color: var(--text-muted);
  margin: 0 auto 1.1rem;
  max-width: 46ch;
}

.state p:last-child[b-lns98sccc9] {
  margin-bottom: 0;
}

@media (max-width: 980px) {
  .create-fields[b-lns98sccc9] {
    grid-template-columns: minmax(0, 1fr) 10.5rem;
    row-gap: .75rem;
  }

  .create-fields[b-lns98sccc9]  .field-row:nth-of-type(3) {
    grid-column: 1 / -1;
  }

  .create-fields > .btn[b-lns98sccc9] {
    grid-column: 1 / -1;
    grid-row: auto;
    justify-self: start;
  }
}

@media (max-width: 880px) {
  /* The header goes with the one-line layout it labels. The date, the notes
     and the count drop under the label, and the buttons keep a column of
     their own. */
  .listing-head[b-lns98sccc9] {
    display: none;
  }

  .listing[b-lns98sccc9] {
    --value-columns: minmax(0, 1fr) auto;
  }

  .value[b-lns98sccc9],
  .values[b-lns98sccc9]  .value-form {
    grid-template-areas:
      "main actions"
      "date actions"
      "notes actions"
      "references actions";
  }

  .editing .value-references[b-lns98sccc9] {
    padding-top: 0;
  }
}

@media (max-width: 560px) {
  .create-fields[b-lns98sccc9] {
    grid-template-columns: minmax(0, 1fr);
  }

  .listing[b-lns98sccc9] {
    --value-columns: minmax(0, 1fr);
  }

  .value[b-lns98sccc9],
  .values[b-lns98sccc9]  .value-form {
    grid-template-areas:
      "main"
      "date"
      "notes"
      "references"
      "actions";
  }

  .value-actions .btn[b-lns98sccc9] {
    flex: 1;
  }
}
/* /Components/Admin/Taxonomy/ReferenceList.razor.rz.scp.css */
/* What refers to one value, inside its row on a taxonomy listing. A plain
   list: the record on the left, its note on the right, so the rows read down
   the name and the notes line up. */

.reference-list[b-vzuryxqqfr] {
  display: grid;
  gap: .35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.reference-item[b-vzuryxqqfr] {
  align-items: baseline;
  display: flex;
  gap: 1rem;
}

/* The way to the record, and the only link here. Its colour is the one app.css
   gives every link. */
.reference-link[b-vzuryxqqfr] {
  flex-grow: 1;
  font-size: .85rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.reference-aside[b-vzuryxqqfr] {
  color: var(--text-subtle);
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
}

.reference-list-empty[b-vzuryxqqfr] {
  color: var(--text-subtle);
  font-size: .82rem;
  margin: 0;
}
/* /Components/Admin/Taxonomy/StoreGames.razor.rz.scp.css */
/* One store's games, inside its row on the store listing. A plain list: the
   game on the left, its code there on the right, so the rows read down the
   names and the codes line up. */

.store-games[b-ug1p912g3r] {
  display: grid;
  gap: .35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.store-game[b-ug1p912g3r] {
  align-items: baseline;
  display: flex;
  gap: 1rem;
}

/* The way to the game, and the only link here. Its colour is the one app.css
   gives every link. */
.store-game-name[b-ug1p912g3r] {
  flex-grow: 1;
  font-size: .85rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.store-game-code[b-ug1p912g3r] {
  color: var(--text-subtle);
  font-family: var(--font-mono);
  font-size: .78rem;
}

.store-games-empty[b-ug1p912g3r] {
  color: var(--text-subtle);
  font-size: .82rem;
  margin: 0;
}
/* /Components/Admin/Taxonomy/StoreIconEditor.razor.rz.scp.css */
/* The editor opens under the row's one line, as the games a store's count
   opens do: what the icon is now, the file to put in its place, and the way
   out. */
.store-icon-editor[b-s2d8asvd2p] {
  display: grid;
  gap: .55rem;
}

.store-icon-current[b-s2d8asvd2p] {
  align-items: center;
  color: var(--text-muted);
  display: flex;
  font-size: .85rem;
  gap: .55rem;
  margin: 0;
}

.store-icon-upload[b-s2d8asvd2p] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.store-icon-upload .field[b-s2d8asvd2p] {
  flex: 1 1 16rem;
  min-width: 0;
}

.store-icon-hint[b-s2d8asvd2p] {
  color: var(--text-subtle);
  font-size: .8rem;
  margin: 0;
}

.store-icon-actions[b-s2d8asvd2p] {
  display: flex;
  gap: .4rem;
}
/* /Components/Admin/Taxonomy/TaxonomyListing.razor.rz.scp.css */
/* The developer listing's layout, drawn for any taxonomy: the same head, the
   same row, the same breakpoints, so moving between the screens under
   Taxonomy changes the words and nothing else. */

/* ---- the head ----
   The search on the left, the command that writes on the right. Its top edge
   is the line both share, so an error under the new name does not move the
   search. */

.toolbar[b-v97rmuxkhh] {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.search[b-v97rmuxkhh] {
  display: flex;
  flex: 1 1 20rem;
  gap: .5rem;
  max-width: 32rem;
}

.search .field[b-v97rmuxkhh] {
  flex: 1;
  min-width: 0;
}

/* EditForm and InputText write the form and the input, so the rules reach
   through them. */
.toolbar[b-v97rmuxkhh]  .create {
  flex: 0 1 26rem;
}

.create-row[b-v97rmuxkhh] {
  display: flex;
  gap: .5rem;
}

.create-row[b-v97rmuxkhh]  input {
  flex: 1;
  min-width: 0;
}

.filters[b-v97rmuxkhh] {
  margin-bottom: 1.1rem;
}

/* ---- the listing ----
   One column template for the header and the rows, declared on the section
   both live in, so the two cannot drift apart. */

.listing[b-v97rmuxkhh] {
  /* The last column holds Rename, Restore and Delete side by side. */
  --value-columns: minmax(0, 1fr) 8rem 15rem;
}

/* A screen whose rows edit something besides the name has one button more.
   The narrower breakpoints' .listing rules come later, so they still win. */
.listing-editable[b-v97rmuxkhh] {
  --value-columns: minmax(0, 1fr) 8rem 19rem;
}

.reference-note[b-v97rmuxkhh] {
  color: var(--text-muted);
  font-size: .85rem;
  margin: 0 0 .9rem;
  max-width: 72ch;
}

.listing-head[b-v97rmuxkhh] {
  color: var(--text-muted);
  column-gap: 1rem;
  display: grid;
  font-size: .72rem;
  font-weight: 800;
  grid-template-columns: var(--value-columns);
  letter-spacing: .08em;
  padding: 0 .9rem .45rem;
  text-transform: uppercase;
}

.values[b-v97rmuxkhh] {
  display: grid;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A row is a card that stays put: it is not itself a click target, the
   buttons inside it are. */
.value[b-v97rmuxkhh] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  column-gap: 1rem;
  display: grid;
  grid-template-areas: "main references actions";
  grid-template-columns: var(--value-columns);
  min-height: 3.6rem;
  padding: .7rem .9rem;
  row-gap: .45rem;
}

.value-main[b-v97rmuxkhh] {
  grid-area: main;
  min-width: 0;
}

/* What a screen draws before the name, such as a store's icon, sits on the
   name's line. */
.value-lead[b-v97rmuxkhh] {
  align-items: center;
  display: flex;
  gap: .55rem;
  min-width: 0;
}

.value-name[b-v97rmuxkhh] {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  overflow-wrap: anywhere;
}

/* The open row keeps its one line and grows a panel under it, so what refers to
   the value reads as a list rather than wrapping through the columns. Named by
   no area, it lands on an implicit row after them, whatever the breakpoint's
   columns are. */
.value-panel[b-v97rmuxkhh] {
  border-top: 1px solid var(--border);
  grid-column: 1 / -1;
  padding-top: .7rem;
}

.value-references[b-v97rmuxkhh] {
  color: var(--text-subtle);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  grid-area: references;
}

.value-actions[b-v97rmuxkhh] {
  display: flex;
  gap: .4rem;
  grid-area: actions;
  justify-content: flex-end;
}

/* ---- states ----
   An answer instead of rows: centered on its panel, with the way on under it.
   Panel and Callout write their own markup, so the rules reach through them. */

.state[b-v97rmuxkhh]  .panel {
  padding: 2rem;
  text-align: center;
}

.state[b-v97rmuxkhh]  .callout {
  margin: 0 auto 1rem;
  max-width: 52ch;
  text-align: left;
}

.state p[b-v97rmuxkhh] {
  color: var(--text-muted);
  margin: 0 auto 1.1rem;
  max-width: 46ch;
}

.state p:last-child[b-v97rmuxkhh] {
  margin-bottom: 0;
}

@media (max-width: 880px) {
  /* The header goes with the one-line layout it labels. The count drops under
     the name, and the buttons keep a column of their own. */
  .listing-head[b-v97rmuxkhh] {
    display: none;
  }

  .listing[b-v97rmuxkhh] {
    --value-columns: minmax(0, 1fr) auto;
  }

  .value[b-v97rmuxkhh] {
    grid-template-areas:
      "main actions"
      "references actions";
  }
}

@media (max-width: 560px) {
  .toolbar[b-v97rmuxkhh]  .create {
    flex-basis: 100%;
  }

  .listing[b-v97rmuxkhh] {
    --value-columns: minmax(0, 1fr);
  }

  .value[b-v97rmuxkhh] {
    grid-template-areas:
      "main"
      "references"
      "actions";
  }

  .value-actions .btn[b-v97rmuxkhh] {
    flex: 1;
  }
}
/* /Components/Admin/Taxonomy/TaxonomyNav.razor.rz.scp.css */
/* Words, not pills: the pills under it are the listing's own tabs, and the two
   levels must not read as one row of filters. The screen being read is marked
   by its colour and a short accent under the word, not by a rule across the
   page. */
.taxonomy-nav[b-dcydj84wob] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.5rem;
  margin-bottom: 1.25rem;
}

.taxonomy-nav a[b-dcydj84wob] {
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-size: .95rem;
  font-weight: 600;
  padding: .2rem 0 .35rem;
  text-decoration: none;
}

.taxonomy-nav a:hover[b-dcydj84wob] {
  color: var(--text);
}

.taxonomy-nav a:focus-visible[b-dcydj84wob] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.taxonomy-nav a[aria-current="page"][b-dcydj84wob] {
  border-bottom-color: var(--accent);
  color: var(--text);
}
/* /Components/Downloads/ArchivePassword.razor.rz.scp.css */
/* The archive password: one row tinted and framed by the accent, so it is seen
   before a mirror is picked and again before the file is fetched. Tokens for
   every colour and logical properties for every side; the value is a code on
   the plain surface, beside the button that copies it. */

.archive-password[b-yq47i2g28k] {
  align-items: center;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--surface));
  border-radius: var(--radius);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  justify-content: space-between;
  padding-block: .75rem;
  padding-inline: .9rem;
}

.archive-password-label[b-yq47i2g28k] {
  align-items: center;
  display: inline-flex;
  font-size: .9rem;
  font-weight: 700;
  gap: .45rem;
}

.archive-password-key[b-yq47i2g28k] {
  block-size: 1.15em;
  color: var(--accent);
  fill: none;
  flex: none;
  inline-size: 1.15em;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

.archive-password-value[b-yq47i2g28k] {
  align-items: center;
  display: inline-flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.archive-password-code[b-yq47i2g28k] {
  background: var(--surface);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 1rem;
  padding-block: .25rem;
  padding-inline: .6rem;
  user-select: all;
}

/* Both labels share one cell, so the button is as wide as the longer one
   and saying "Copied" never resizes it; only the current one is drawn. */
.archive-password-copy[b-yq47i2g28k] {
  display: inline-grid;
}

.archive-password-copy > span[b-yq47i2g28k] {
  grid-area: 1 / 1;
}

.archive-password-copy:not(.is-copied) .archive-password-copied-label[b-yq47i2g28k],
.archive-password-copy.is-copied .archive-password-copy-label[b-yq47i2g28k] {
  visibility: hidden;
}
/* /Components/Layout/AdminLayout.razor.rz.scp.css */
/* Longhand, for the same reason as the account frame: .shell owns the sides. */
.admin-page[b-v9t9g9bu2n] {
  --platform-icon-color: var(--text-muted);
  padding-bottom: 4rem;
  padding-top: 2rem;
}

.topnav[b-v9t9g9bu2n] {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

/* NavLink writes the anchor, so the rules reach through it. */
.topnav[b-v9t9g9bu2n]  a {
  color: var(--text-muted);
  font-size: .9rem;
  text-decoration: none;
}

.topnav[b-v9t9g9bu2n]  a:hover {
  color: var(--text);
}

.topnav[b-v9t9g9bu2n]  a.active {
  color: var(--text);
  font-weight: 600;
}

.topnav[b-v9t9g9bu2n]  a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sign-out[b-v9t9g9bu2n] {
  margin: 0 0 0 auto;
}

@media (max-width: 880px) {
  .admin-page[b-v9t9g9bu2n] {
    padding-top: 1.25rem;
  }
}
/* /Components/Layout/AuthLayout.razor.rz.scp.css */
/* Longhand: the shorthand would drop the horizontal padding .shell provides and
   run the card to the viewport edge. */
.auth-page[b-4kmuvxkmqs] {
  padding-bottom: 4rem;
  padding-top: 3rem;
}

.auth-main[b-4kmuvxkmqs] {
  margin: 0 auto;
  max-width: 27rem;
  width: 100%;
}

@media (max-width: 880px) {
  .auth-page[b-4kmuvxkmqs] {
    padding-bottom: 3rem;
    padding-top: 2rem;
  }
}
/* /Components/Layout/LanguageSwitcher.razor.rz.scp.css */
/* The list opens under the control and aligns to its inline end, which is the
   outer edge of the bar in either direction. Logical properties only. */

.language-switcher[b-zmfctmfnjo] {
  position: relative;
}

/* The summary is the frame's bare button (controls.css), like the theme
   control beside it; only what a summary needs on top of that is here. */
.language-switcher summary[b-zmfctmfnjo] {
  list-style: none;
}

.language-switcher summary[b-zmfctmfnjo]::-webkit-details-marker {
  display: none;
}

.language-switcher[open] summary[b-zmfctmfnjo] {
  background: var(--surface);
  color: var(--text);
}

.locale-code[b-zmfctmfnjo] {
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .06em;
}

/* Points down while the list is closed and up while it is open. */
.chevron[b-zmfctmfnjo] {
  block-size: .75rem;
  fill: none;
  flex: none;
  inline-size: .75rem;
  opacity: .7;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

.language-switcher[open] .chevron[b-zmfctmfnjo] {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: no-preference) {
  .chevron[b-zmfctmfnjo] {
    transition: transform .2s ease;
  }
}

/* Two columns, so sixteen locales fit without the list reaching the bottom of
   the window; one on a phone, where two would cut the longer names. */
.language-list[b-zmfctmfnjo] {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 .75rem 2rem color-mix(in srgb, var(--ctp-crust) 45%, transparent);
  display: grid;
  gap: .1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  inline-size: 26rem;
  inset-block-start: calc(100% + .4rem);
  inset-inline-end: 0;
  list-style: none;
  margin: 0;
  max-inline-size: calc(100vw - 2rem);
  padding: .35rem;
  position: absolute;
  z-index: 20;
}

@media (max-width: 30rem) {
  .language-list[b-zmfctmfnjo] {
    grid-template-columns: 1fr;
    inline-size: 16rem;
    max-block-size: 70vh;
    overflow-y: auto;
  }
}

.language-list a[b-zmfctmfnjo] {
  align-items: center;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  display: flex;
  font-size: .9rem;
  gap: .6rem;
  padding: .4rem .65rem;
  text-decoration: none;
  white-space: nowrap;
}

.language-list .locale-code[b-zmfctmfnjo] {
  color: var(--text-subtle);
  font-size: .7rem;
  min-inline-size: 1.6rem;
}

.language-list a[aria-current="true"] .locale-code[b-zmfctmfnjo] {
  color: var(--accent-text);
}

.language-list a:hover[b-zmfctmfnjo] {
  background: var(--surface-raised);
  color: var(--text);
}

.language-list a:focus-visible[b-zmfctmfnjo] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.language-list a[aria-current="true"][b-zmfctmfnjo] {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 600;
}
/* /Components/Layout/PublicLayout.razor.rz.scp.css */
/* Logical properties only: the frame mirrors under dir="rtl" without a rule of
   its own. */

.site-header[b-v6jpodwy36] {
  background: var(--bg-deep);
  border-block-end: 1px solid var(--border);
}

.site-header-inner[b-v6jpodwy36] {
  align-items: center;
  display: flex;
  gap: 1rem;
  min-block-size: 3.5rem;
}

.site-nav[b-v6jpodwy36] {
  align-items: center;
  display: flex;
  gap: 1rem;
}

.site-nav a[b-v6jpodwy36] {
  color: var(--text-muted);
  font-size: .95rem;
  font-weight: 600;
  text-decoration: none;
}

.site-nav a:hover[b-v6jpodwy36],
.footer-group a:hover[b-v6jpodwy36] {
  color: var(--text);
}

/* The catalog is a soft pill that fills with the accent on hover, so a visitor
   who landed on a game page sees there is more behind it. */
.site-nav .catalog-link[b-v6jpodwy36] {
  align-items: center;
  background: var(--accent-soft);
  border-radius: 999px;
  color: var(--accent-text);
  display: inline-flex;
  font-weight: 700;
  gap: .45rem;
  padding-block: .45rem;
  padding-inline: .8rem 1rem;
}

.site-nav .catalog-link:hover[b-v6jpodwy36] {
  background: var(--accent);
  color: var(--accent-contrast);
}

.catalog-icon[b-v6jpodwy36] {
  flex-shrink: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .site-nav .catalog-link[b-v6jpodwy36] {
    transition: background-color .15s ease, color .15s ease;
  }

  .catalog-icon[b-v6jpodwy36] {
    transition: transform .25s ease;
  }

  .catalog-link:hover .catalog-icon[b-v6jpodwy36] {
    transform: rotate(90deg);
  }
}

.site-controls[b-v6jpodwy36] {
  align-items: center;
  display: flex;
  gap: .6rem;
  margin-inline-start: auto;
}

/* The footer stands on the header's ground and is set apart by it and its
   spacing alone, never by a rule (PUB-FOOTER-001). */
.site-footer[b-v6jpodwy36] {
  background: var(--bg-deep);
  color: var(--text);
}

.site-footer-inner[b-v6jpodwy36] {
  display: flex;
  flex-direction: column;
  gap: 3rem;
  padding-block: 3rem 2rem;
}

/* Four tracks whether Community is drawn or not, so the columns keep their
   places when it is absent (PUB-FOOTER-004). */
.footer-columns[b-v6jpodwy36] {
  display: grid;
  gap: 3rem;
  grid-template-columns: 2fr 1fr 1fr 1fr;
}

.footer-brand[b-v6jpodwy36] {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-inline-size: 24rem;
}

.footer-description[b-v6jpodwy36] {
  color: var(--text-muted);
  font-size: .875rem;
  line-height: 1.6;
  margin: 0;
}

.footer-adults[b-v6jpodwy36] {
  align-items: center;
  color: var(--text-subtle);
  display: flex;
  font-size: .8125rem;
  gap: .625rem;
  margin: 0;
}

.adults-badge[b-v6jpodwy36] {
  background: var(--danger-soft);
  border-radius: 999px;
  color: var(--danger-text);
  flex-shrink: 0;
  font-weight: 800;
  padding: .25rem .625rem;
}

.footer-group summary[b-v6jpodwy36] {
  color: var(--text);
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: calc(.06em * var(--label-tracking));
  list-style: none;
  text-transform: uppercase;
}

.footer-group summary[b-v6jpodwy36]::-webkit-details-marker {
  display: none;
}

.footer-group nav[b-v6jpodwy36] {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin-block-start: .75rem;
}

.footer-group a[b-v6jpodwy36] {
  align-items: center;
  color: var(--text-muted);
  display: inline-flex;
  font-size: .875rem;
  gap: .375rem;
  text-decoration: none;
}

.site-nav a:focus-visible[b-v6jpodwy36],
.footer-group a:focus-visible[b-v6jpodwy36],
.footer-group summary:focus-visible[b-v6jpodwy36] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The arrow points away from the text, so it turns with the reading direction. */
.outbound:dir(rtl)[b-v6jpodwy36] {
  transform: scaleX(-1);
}

.footer-copyright[b-v6jpodwy36] {
  color: var(--text-subtle);
  font-size: .8125rem;
  margin: 0;
}

/* Wider than a phone, a group is a column whose links show whether it is open
   or not, and its summary is the column's heading. */
@media (min-width: 640px) {
  .footer-group[b-v6jpodwy36]::details-content {
    content-visibility: visible;
  }

  .footer-group .chevron[b-v6jpodwy36] {
    display: none;
  }
}

/* On a phone the brand and the groups stack, and each group folds: a summary
   and its links are targets of at least 44px (PUB-FOOTER-004). */
@media (max-width: 639.98px) {
  .site-footer-inner[b-v6jpodwy36] {
    gap: 2rem;
    padding-block: 2.5rem 2rem;
  }

  .footer-columns[b-v6jpodwy36] {
    gap: .5rem;
    grid-template-columns: 1fr;
  }

  .footer-brand[b-v6jpodwy36] {
    gap: .875rem;
    margin-block-end: 1.5rem;
    max-inline-size: none;
  }

  .footer-group[b-v6jpodwy36] {
    background: var(--bg);
    border-radius: var(--radius);
  }

  .footer-group summary[b-v6jpodwy36] {
    align-items: center;
    cursor: pointer;
    display: flex;
    font-size: .875rem;
    justify-content: space-between;
    letter-spacing: normal;
    min-block-size: 3rem;
    padding-inline: 1rem;
    text-transform: none;
  }

  .footer-group[open] .chevron[b-v6jpodwy36] {
    transform: rotate(180deg);
  }

  .footer-group nav[b-v6jpodwy36] {
    gap: 0;
    margin-block-start: 0;
    padding-block-end: .5rem;
  }

  .footer-group a[b-v6jpodwy36] {
    display: flex;
    font-size: .9375rem;
    min-block-size: 2.75rem;
    padding-inline: 1rem;
  }
}
/* /Components/Public/Games/DeveloperGames.razor.rz.scp.css */
/* The way to the developer's whole list, at the end of its name's line. */
.see-all[b-v29wgsku43] {
  align-items: center;
  color: var(--accent-text);
  display: inline-flex;
  font-size: .85rem;
  font-weight: 700;
  gap: .3rem;
  text-decoration: none;
  white-space: nowrap;
}

.see-all:hover[b-v29wgsku43] {
  text-decoration: underline;
}

/* Points the way the line reads, so it turns round under RTL. */
.arrow[b-v29wgsku43] {
  block-size: 1em;
  fill: none;
  flex: none;
  inline-size: 1em;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.arrow:dir(rtl)[b-v29wgsku43] {
  transform: scaleX(-1);
}
/* /Components/Public/Games/GameCard.razor.rz.scp.css */
/* One game as a card, wherever the public site draws one: the catalog's grid
   and the home page's New grid. Tokens for every colour and logical properties
   for every side, so it reads in both flavors and mirrors under dir="rtl". The
   tints under a cover are app.css's, shared with every cover the site draws. */


/* The card does not need a button of its own: the title's link is stretched
   over the whole surface, so the card is one link and one focus stop. */
.catalog-card[b-ovloez6ypk] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.4);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  transition: border-color .18s ease, box-shadow .22s ease, transform .22s ease;
}

.catalog-card:hover[b-ovloez6ypk] {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}

/* Only where a pointer can rest: on a touch screen a hover state sticks after
   the tap. The card lifts and takes a soft glow of the accent, the cover zooms
   a little inside its frame, and a light sweeps across it once. Nothing
   changes size, so nothing around the card is laid out again. */
@media (hover: hover) {
  .catalog-card:hover[b-ovloez6ypk] {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), 0 14px 30px color-mix(in srgb, var(--accent) 28%, transparent);
    transform: translateY(-3px);
  }

  .catalog-card:hover .cover-image[b-ovloez6ypk] {
    transform: scale(1.05);
  }

  .catalog-card:hover .cover[b-ovloez6ypk]::after {
    transform: translateX(calc(120% * var(--sheen-direction)));
    transition: transform .8s ease;
  }
}

@media (prefers-reduced-motion: reduce) {
  .catalog-card[b-ovloez6ypk],
  .cover-image[b-ovloez6ypk] {
    transition: none;
  }

  .catalog-card:hover[b-ovloez6ypk],
  .catalog-card:hover .cover-image[b-ovloez6ypk],
  .catalog-card:hover .cover[b-ovloez6ypk]::after {
    transform: none;
  }
}

.catalog-card:focus-within[b-ovloez6ypk] {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.card-link[b-ovloez6ypk]::after {
  content: "";
  inset: 0;
  position: absolute;
  z-index: 1;
}

.card-link[b-ovloez6ypk] {
  color: var(--text);
  text-decoration: none;
}

.catalog-card:hover .card-link[b-ovloez6ypk] {
  text-decoration: underline;
}

.card-link:focus-visible[b-ovloez6ypk] {
  outline: none;
}

/* What the game runs on and is offered in, under the title: the platforms at
   the inline start and the languages at the inline end. The row lies over the
   title's stretched link, so a pointer resting on a mark or on the languages
   shows its name, while the gaps between them still open the game. */
.card-offer[b-ovloez6ypk] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem .5rem;
  justify-content: space-between;
  pointer-events: none;
  position: relative;
  z-index: 2;
}

.card-offer[b-ovloez6ypk]  .platform-mark,
.card-languages[b-ovloez6ypk] {
  pointer-events: auto;
}

/* The languages after the platforms even when there are none to put first. */
.card-languages[b-ovloez6ypk] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: 999px;
  color: var(--text-muted);
  display: inline-flex;
  font-size: .7rem;
  font-weight: 800;
  gap: .3rem;
  letter-spacing: .04em;
  line-height: 1;
  margin-inline-start: auto;
  padding: .3rem .5rem;
  white-space: nowrap;
}

/* The reader's own language takes the accent, so it is found at a glance. */
.card-languages-readers[b-ovloez6ypk] {
  background: var(--accent-soft);
  color: var(--accent-text);
}

.card-languages-more[b-ovloez6ypk] {
  font-weight: 700;
  opacity: .75;
}

/* It takes the space the card has left over, so the meta line below sits on the
   card's floor and the whole row's dates line up however long a title runs. */
.card-body[b-ovloez6ypk] {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: .5rem;
  padding: .9rem 1rem 1rem;
}

.card-title[b-ovloez6ypk] {
  font-size: 1rem;
  font-weight: 700;
  margin: 0;
}

.card-meta[b-ovloez6ypk] {
  align-items: center;
  color: var(--text-subtle);
  display: flex;
  flex-wrap: wrap;
  font-size: .78rem;
  gap: .5rem;
  justify-content: space-between;
  margin: auto 0 0;
}

.card-engine[b-ovloez6ypk] {
  background: var(--surface-raised);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-weight: 600;
  padding: .15rem .45rem;
  white-space: nowrap;
}

/* The cover's frame. Its shape is fixed here, so a card does not move when
   its cover arrives, and the tint of the theme's own hues is under it — legible
   in Latte and in Mocha alike — with the initials on it for a game without one. */
.cover[b-ovloez6ypk] {
  align-items: center;
  aspect-ratio: 16 / 10;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--cover-from) 55%, var(--surface)),
    color-mix(in srgb, var(--cover-to) 55%, var(--surface)));
  display: flex;
  justify-content: center;
  order: -1;
  overflow: hidden;
  position: relative;
}

/* The light that sweeps across the cover on hover, parked outside the frame
   until then. It lets every pointer through to the link beneath it, and
   travels from the inline start to the inline end, so it mirrors under RTL. */
.cover[b-ovloez6ypk]::after {
  --sheen-direction: 1;
  background: linear-gradient(115deg, transparent 30%, var(--cover-sheen) 48%, transparent 62%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
  transform: translateX(calc(-120% * var(--sheen-direction)));
}

.cover:dir(rtl)[b-ovloez6ypk]::after {
  --sheen-direction: -1;
}

/* Cropped to the frame rather than letterboxed: a card is a way in, and the
   game's page shows the picture whole. */
.cover-image[b-ovloez6ypk] {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: cover;
  transition: transform .5s cubic-bezier(.2, .7, .2, 1);
}

.cover-initials[b-ovloez6ypk] {
  color: var(--text);
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -.03em;
  opacity: .85;
}

@media (max-width: 560px) {
  .cover-initials[b-ovloez6ypk] {
    font-size: 1.35rem;
  }
}
/* /Components/Public/Games/GameCatalog.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the screen
   reads in both flavors and mirrors under dir="rtl". */

.catalog-title[b-i8evv9w67e] {
  color: var(--text);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  line-height: 1.15;
  margin-block: 0 1.5rem;
}

/* The filters sit beside the results, at the inline start: the left in English
   and the right in Arabic, because a grid places its first track there. The
   results take whatever the panel leaves, and the panel keeps its own height
   rather than stretching down the whole grid. */
.catalog-layout[b-i8evv9w67e] {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 16rem minmax(0, 1fr);
}

.catalog-filters[b-i8evv9w67e] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.4);
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: 1.25rem 1.25rem 0;
}

/* ---- the search field: a glyph at its start, the "/" key at its end ---- */

.search-field[b-i8evv9w67e] {
  align-items: center;
  display: flex;
  position: relative;
}

.search-field .field[b-i8evv9w67e] {
  min-inline-size: 0;
  padding-inline: 2.2rem;
}

/* Every mark the panel draws is a stroked line icon at the text's size. */
.search-glyph[b-i8evv9w67e],
.opener-glyph[b-i8evv9w67e],
.sheet-close svg[b-i8evv9w67e],
.submit-arrow[b-i8evv9w67e],
.remove-glyph[b-i8evv9w67e] {
  block-size: 1rem;
  fill: none;
  flex: none;
  inline-size: 1rem;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.4;
}

.search-glyph[b-i8evv9w67e] {
  color: var(--text-subtle);
  inset-inline-start: .75rem;
  pointer-events: none;
  position: absolute;
}

.search-key[b-i8evv9w67e] {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: .3rem;
  color: var(--text-subtle);
  font: 700 .7rem/1 var(--font-mono);
  inset-inline-end: .6rem;
  padding: .2rem .4rem;
  pointer-events: none;
  position: absolute;
}

/* Only where there is a keyboard to press it with, and only while the field
   is waiting for a term. */
.search-field .field:focus ~ .search-key[b-i8evv9w67e],
.search-field .field:not(:placeholder-shown) ~ .search-key[b-i8evv9w67e] {
  visibility: hidden;
}

@media not ((hover: hover) and (pointer: fine)) {
  .search-key[b-i8evv9w67e] {
    visibility: hidden;
  }
}

/* ---- the facets ---- */

/* On a wide screen the sheet is only a column in the panel: what the browser
   gives a popover (hidden, fixed, framed) is undone here, and the narrow
   layout below puts it back as a sheet. */
.filter-facets[b-i8evv9w67e] {
  background: none;
  block-size: auto;
  border: 0;
  color: inherit;
  display: flex;
  flex-direction: column;
  inline-size: auto;
  inset: auto;
  margin: 0;
  overflow: visible;
  padding: 0;
  position: static;
}

.filters-opener[b-i8evv9w67e],
.sheet-head[b-i8evv9w67e],
.filter-clear-all[b-i8evv9w67e] {
  display: none;
}

.filter-groups[b-i8evv9w67e] {
  display: flex;
  flex-direction: column;
  gap: .6rem;
}

/* The count and the button that clears it sit on the heading's line; the
   button is beside the summary rather than in it, which takes no control. */
.facet[b-i8evv9w67e] {
  position: relative;
}

/* The counts: of a facet's ticked boxes, of the filters asked for (on the
   opener of the sheet), and of the boxes changed since the page arrived,
   which inverts the pill inside the filled button. */
.facet-count[b-i8evv9w67e],
.filter-count[b-i8evv9w67e],
.filter-pending[b-i8evv9w67e] {
  background: var(--accent);
  border-radius: 999px;
  color: var(--accent-contrast);
  font-size: .7rem;
  font-weight: 800;
  line-height: 1;
  min-inline-size: 1.15rem;
  padding: .2rem .4rem;
  text-align: center;
}

.filter-pending[b-i8evv9w67e] {
  background: var(--accent-contrast);
  color: var(--accent-text);
}

.facet-clear[b-i8evv9w67e] {
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--accent-text);
  cursor: pointer;
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  inset-block-start: -.2rem;
  inset-inline-end: 0;
  padding: .2rem .4rem;
  position: absolute;
}

.facet-clear:hover[b-i8evv9w67e] {
  background: var(--accent-soft);
}

.facet-clear:focus-visible[b-i8evv9w67e] {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.facet[b-i8evv9w67e]  .fold-body {
  margin-block-start: .5rem;
}

.facet-options[b-i8evv9w67e] {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The whole row is the label, so the name is as easy a target as the box, and
   a ticked row takes the accent's tint, so what filters the list is seen at a
   glance down a long facet. A platform's glyph takes the accent with it. */
.facet-option[b-i8evv9w67e] {
  --platform-icon-color: var(--text-muted);
  align-items: center;
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  display: flex;
  font-size: .92rem;
  gap: .6rem;
  padding-block: .4rem;
  padding-inline: .5rem;
}

.facet-option:hover[b-i8evv9w67e] {
  background: var(--surface-raised);
}

.facet-option:has(input:checked)[b-i8evv9w67e] {
  --platform-icon-color: var(--accent-text);
  background: var(--accent-soft);
  color: var(--accent-soft-text);
  font-weight: 600;
}

.facet-option span[b-i8evv9w67e] {
  min-inline-size: 0;
  overflow-wrap: anywhere;
}

/* A box of the theme's own: the tick is a shape cut in the accent's contrast,
   scaled up from nothing when the box is checked. */
.facet-option input[b-i8evv9w67e] {
  appearance: none;
  background: var(--field-bg);
  block-size: 1.1rem;
  border: 1.5px solid var(--border-strong);
  border-radius: .35rem;
  cursor: pointer;
  display: grid;
  flex: none;
  inline-size: 1.1rem;
  margin: 0;
  place-content: center;
}

.facet-option input[b-i8evv9w67e]::before {
  background: var(--accent-contrast);
  block-size: .62rem;
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0, 43% 62%);
  content: "";
  inline-size: .62rem;
  transform: scale(0);
}

.facet-option input:checked[b-i8evv9w67e] {
  background: var(--accent);
  border-color: var(--accent);
}

.facet-option input:checked[b-i8evv9w67e]::before {
  transform: scale(1);
}

.facet-option:hover input:not(:checked)[b-i8evv9w67e] {
  border-color: var(--accent);
}

.facet-option input:focus-visible[b-i8evv9w67e] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Forced colours replace the fill and the tick both, so the box goes back to
   the system's own, which those modes draw legibly. */
@media (forced-colors: active) {
  .facet-option input[b-i8evv9w67e] {
    appearance: auto;
  }

  .facet-option input[b-i8evv9w67e]::before {
    content: none;
  }
}

/* A facet long enough to be narrowed scrolls inside its group, its ends
   fading so the reader sees there is more. The field that narrows it needs
   script, so it is scripted-only (controls.css); without script the list
   scrolls and every box still submits. */
.facet-options-scroll[b-i8evv9w67e] {
  mask-image: linear-gradient(transparent, #000 .75rem, #000 calc(100% - .75rem), transparent);
  max-block-size: 15rem;
  overflow-y: auto;
  padding-block: .5rem;
  padding-inline-end: .25rem;
  scrollbar-width: thin;
}

.facet-options li[hidden][b-i8evv9w67e] {
  display: none;
}

.facet-filter[b-i8evv9w67e] {
  margin-block-end: .25rem;
}

.facet-filter .field[b-i8evv9w67e] {
  font-size: .88rem;
  inline-size: 100%;
  min-inline-size: 0;
  padding-block: .45rem;
}

.facet-empty[b-i8evv9w67e] {
  color: var(--text-muted);
  font-size: .88rem;
  margin: .25rem 0 0;
  padding-inline: .35rem;
}

/* ---- the button at the panel's floor ----
   It sticks to the bottom of the screen while the panel runs past it, so it
   is in reach from the first screen however long the facets are. The panel
   is no scroll container, so nothing clips the button's glow and the page is
   the only thing that scrolls. */

.filter-dock[b-i8evv9w67e] {
  background: linear-gradient(transparent, var(--surface) 40%);
  display: flex;
  gap: .6rem;
  inset-block-end: 0;
  margin-inline: -1.25rem;
  padding: 1rem 1.25rem 1.25rem;
  position: sticky;
}

.filter-submit[b-i8evv9w67e] {
  --arrow-direction: 1;
  align-items: center;
  display: flex;
  flex: 1;
  gap: .5rem;
  justify-content: center;
}

.filter-submit:dir(rtl)[b-i8evv9w67e] {
  --arrow-direction: -1;
}

.submit-arrow[b-i8evv9w67e] {
  transform: scaleX(var(--arrow-direction));
}

/* The button glows when a pointer rests on it and dims back when pressed.
   Where motion is welcome, it also lifts, its arrow leans forward, and a
   press sinks it (below). Only where a pointer can rest: on a touch screen a
   hover state sticks after the tap. */
@media (hover: hover) {
  .filter-submit:hover[b-i8evv9w67e] {
    box-shadow: 0 6px 20px color-mix(in srgb, var(--accent) 40%, transparent);
  }
}

.filter-submit:active[b-i8evv9w67e] {
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Pressed and on its way (catalog-filters.js): the label gives way to a
   spinner and the word for searching, and a second press is not taken. */
.submit-spinner[b-i8evv9w67e],
.submit-busy[b-i8evv9w67e] {
  display: none;
}

.filter-submit[data-busy][b-i8evv9w67e] {
  pointer-events: none;
}

.filter-submit[data-busy] .submit-label[b-i8evv9w67e],
.filter-submit[data-busy] .filter-pending[b-i8evv9w67e],
.filter-submit[data-busy] .submit-arrow[b-i8evv9w67e] {
  display: none;
}

.filter-submit[data-busy] .submit-busy[b-i8evv9w67e] {
  display: inline;
}

.filter-submit[data-busy] .submit-spinner[b-i8evv9w67e] {
  animation: submit-spin-b-i8evv9w67e .7s linear infinite;
  block-size: .9rem;
  border: 2px solid color-mix(in srgb, var(--accent-contrast) 35%, transparent);
  border-block-start-color: var(--accent-contrast);
  border-radius: 50%;
  display: block;
  inline-size: .9rem;
}

@keyframes submit-spin-b-i8evv9w67e {
  to {
    transform: rotate(360deg);
  }
}

/* A group opens and closes by growing to its height where the browser can
   animate to a height it does not know; elsewhere it opens at once. */
@media (prefers-reduced-motion: no-preference) {
  .facet[b-i8evv9w67e] {
    interpolate-size: allow-keywords;
  }

  .facet[b-i8evv9w67e]  details::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size .22s ease, content-visibility .22s allow-discrete;
  }

  .facet[b-i8evv9w67e]  details[open]::details-content {
    block-size: auto;
  }

  .facet-option[b-i8evv9w67e],
  .facet-option input[b-i8evv9w67e] {
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
  }

  .facet-option input[b-i8evv9w67e]::before {
    transition: transform .18s cubic-bezier(.3, 1.6, .6, 1);
  }

  .filter-submit[b-i8evv9w67e] {
    transition: background-color .15s ease, box-shadow .2s ease, transform .15s ease;
  }

  .submit-arrow[b-i8evv9w67e] {
    transition: transform .2s ease;
  }

  .filter-submit:active[b-i8evv9w67e] {
    transform: scale(.97);
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .filter-submit:hover[b-i8evv9w67e] {
    transform: translateY(-2px);
  }

  .filter-submit:hover .submit-arrow[b-i8evv9w67e] {
    transform: translateX(calc(3px * var(--arrow-direction))) scaleX(var(--arrow-direction));
  }

  .filter-submit:hover:active[b-i8evv9w67e] {
    transform: scale(.97);
  }
}

/* The spinner still turns, slower: it is the only sign the page is coming. */
@media (prefers-reduced-motion: reduce) {
  .filter-submit[data-busy] .submit-spinner[b-i8evv9w67e] {
    animation-duration: 2s;
  }
}

/* ---- the criteria in force, above the grid ---- */

.active-filters[b-i8evv9w67e] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.active-filter[b-i8evv9w67e] {
  --platform-icon-color: var(--accent-text);
  align-items: center;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  color: var(--accent-soft-text);
  display: inline-flex;
  font-size: .82rem;
  font-weight: 600;
  gap: .4rem;
  padding-block: .32rem;
  padding-inline: .75rem .45rem;
  text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease;
  white-space: nowrap;
}

.remove-glyph[b-i8evv9w67e] {
  block-size: 1.1rem;
  border-radius: 50%;
  inline-size: 1.1rem;
  padding: .25rem;
  stroke-width: 3.2;
  transition: background-color .15s ease, color .15s ease;
}

.active-filter:hover[b-i8evv9w67e] {
  border-color: var(--accent);
  text-decoration: none;
}

.active-filter:hover .remove-glyph[b-i8evv9w67e] {
  background: var(--accent);
  color: var(--accent-contrast);
}

.active-filter:focus-visible[b-i8evv9w67e],
.active-filters-clear:focus-visible[b-i8evv9w67e] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.active-filters-clear[b-i8evv9w67e] {
  color: var(--text-muted);
  font-size: .82rem;
  font-weight: 600;
  margin-inline-start: .25rem;
}

.active-filters-clear:hover[b-i8evv9w67e] {
  color: var(--text);
}

/* The order of a search, above the grid at its inline end: the right in English
   and the left in Arabic, because a flex row ends where the direction does. The
   label sits beside its list rather than above it, so the bar stays one line. */
.catalog-toolbar[b-i8evv9w67e] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  justify-content: flex-end;
  margin-block-end: 1rem;
}

.catalog-toolbar .field-label[b-i8evv9w67e] {
  margin: 0;
}

.catalog-toolbar .field[b-i8evv9w67e] {
  inline-size: auto;
  min-inline-size: 11rem;
}

/* The cards size themselves: as many as fit at a readable width, and never one
   so narrow that a title has to wrap on every word. At the widest layout, this
   width and gap beside the filter column fit four cards in a row, the number
   the component's FirstRowCards loads without waiting; change one, check the
   other. */
.catalog-grid[b-i8evv9w67e] {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The page numbers close the feed, centred and set well apart from the last row
   of cards, so they read as the way on rather than as part of a card. */
.catalog-results[b-i8evv9w67e]  .pagination {
  margin: 3rem auto 0;
}

/* The block that stands in for the grid when there is no grid to draw: a
   catalog with nothing published, or criteria that matched nothing. It is named
   for its shape and not for either of them, so the state that carries an action
   and the state that carries none are the same block with and without one. */
.catalog-state[b-i8evv9w67e] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.6);
  padding: clamp(1.5rem, 4vw, 3rem);
  text-align: center;
}

.catalog-state h2[b-i8evv9w67e] {
  color: var(--text);
  font-size: 1.5rem;
  font-weight: 700;
  margin-block: 0 .75rem;
}

.catalog-state p[b-i8evv9w67e] {
  color: var(--text-muted);
  margin: 0 auto;
  max-inline-size: 46ch;
}

.catalog-state .btn[b-i8evv9w67e] {
  margin-block-start: 1.25rem;
}

/* Too narrow for a panel beside the grid: the filters go above it, full width,
   and the button stays at the panel's floor. */
@media (max-width: 880px) {
  .catalog-layout[b-i8evv9w67e] {
    grid-template-columns: minmax(0, 1fr);
  }

  .filter-dock[b-i8evv9w67e] {
    position: static;
  }

  /* Where the browser has popovers, the panel is only the search and the
     button that opens the sheet, side by side, and the grid starts right under
     them; the facets wait in a sheet that rises from the floor of the screen,
     over a dimmed page that closes it when tapped. Without popovers, the
     facets stay in the panel, as above. */
  @supports selector(:popover-open) {
    .catalog-filters[b-i8evv9w67e] {
      align-items: center;
      background: none;
      border: 0;
      flex-direction: row;
      gap: .5rem;
      padding: 0;
    }

    /* Still read, not drawn: the declarations of .visually-hidden
       (controls.css), which a class cannot apply only below a width. */
    .filters-title[b-i8evv9w67e],
    .filter-search .field-label[b-i8evv9w67e] {
      border: 0;
      clip-path: inset(50%);
      height: 1px;
      margin: -1px;
      overflow: hidden;
      padding: 0;
      position: absolute;
      white-space: nowrap;
      width: 1px;
    }

    .filter-search[b-i8evv9w67e] {
      flex: 1;
      min-inline-size: 0;
    }

    .filters-opener[b-i8evv9w67e] {
      align-items: center;
      display: inline-flex;
      gap: .45rem;
      white-space: nowrap;
    }

    .filter-facets[b-i8evv9w67e] {
      background: var(--surface);
      border-radius: 1.4rem 1.4rem 0 0;
      box-shadow: 0 -12px 30px rgb(0 0 0 / .3);
      color: var(--text);
      inline-size: 100%;
      inset: auto 0 0;
      max-block-size: 86dvh;
      max-inline-size: 100%;
      overflow: hidden;
      position: fixed;
      transform: translateY(100%);
    }

    .filter-facets:not(:popover-open)[b-i8evv9w67e] {
      display: none;
    }

    .filter-facets:popover-open[b-i8evv9w67e] {
      transform: none;
    }

    .filter-facets[b-i8evv9w67e]::backdrop {
      background: rgb(17 17 27 / .55);
    }

    .sheet-head[b-i8evv9w67e] {
      align-items: center;
      display: flex;
      justify-content: space-between;
      padding: 1rem 1.1rem .6rem;
    }

    .sheet-title[b-i8evv9w67e] {
      font-size: 1.1rem;
      font-weight: 700;
    }

    .sheet-close[b-i8evv9w67e] {
      background: var(--surface-raised);
      block-size: 2.25rem;
      border: 0;
      border-radius: 50%;
      color: var(--text-muted);
      cursor: pointer;
      display: grid;
      inline-size: 2.25rem;
      place-content: center;
    }

    .sheet-close:focus-visible[b-i8evv9w67e] {
      outline: 2px solid var(--accent);
      outline-offset: 2px;
    }

    .filter-groups[b-i8evv9w67e] {
      flex: 1;
      min-block-size: 0;
      overflow-y: auto;
      overscroll-behavior: contain;
      padding: .3rem 1.1rem 1rem;
    }

    .filter-dock[b-i8evv9w67e] {
      background: var(--surface);
      margin: 0;
      padding: .8rem 1.1rem 1.1rem;
    }

    .filter-clear-all[b-i8evv9w67e] {
      display: inline-block;
    }

    /* The page under the sheet: the criteria in force run along one line that
       scrolls sideways rather than pushing the grid down. */
    .active-filters[b-i8evv9w67e] {
      flex-wrap: nowrap;
      margin-inline: -1.25rem;
      overflow-x: auto;
      padding-inline: 1.25rem;
      scrollbar-width: none;
    }

    .active-filters li[b-i8evv9w67e] {
      flex: none;
    }
  }
}

@media (max-width: 880px) and (prefers-reduced-motion: no-preference) {
  @supports selector(:popover-open) {
    .filter-facets[b-i8evv9w67e] {
      transition: transform .3s cubic-bezier(.2, .9, .3, 1), overlay .3s allow-discrete, display .3s allow-discrete;
    }

    .filter-facets[b-i8evv9w67e]::backdrop {
      transition: background-color .3s ease, overlay .3s allow-discrete, display .3s allow-discrete;
    }

    @starting-style {
      .filter-facets:popover-open[b-i8evv9w67e] {
        transform: translateY(100%);
      }

      .filter-facets:popover-open[b-i8evv9w67e]::backdrop {
        background: transparent;
      }
    }
  }
}

@media (max-width: 560px) {
  .catalog-grid[b-i8evv9w67e] {
    gap: .75rem;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  }

  .catalog-toolbar .field[b-i8evv9w67e] {
    flex: 1;
  }
}
/* /Components/Public/Games/GameDetail.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the page
   reads in both flavors and mirrors under dir="rtl": the downloads take the
   inline end, which is the left in Arabic. */

.game-title[b-v51z0oivpb] {
  color: var(--text);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  line-height: 1.15;
  margin-block: 0 1.5rem;
  overflow-wrap: anywhere;
}

/* The original title is the heading's second line, so the heading gives it
   the space it keeps below itself otherwise. */
.game-title:has(+ .game-original-title)[b-v51z0oivpb] {
  margin-block-end: 0.25rem;
}

.game-original-title[b-v51z0oivpb] {
  color: var(--text-muted);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.35;
  margin-block: 0 1.5rem;
  overflow-wrap: anywhere;
}

.game-layout[b-v51z0oivpb] {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-areas: "main side";
  grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
}

/* With pictures, they head the first column and the downloads run beside both
   the pictures and the rest; the last row takes whatever height the downloads
   leave over, so no gap opens under the pictures. */
.game-layout.has-gallery[b-v51z0oivpb] {
  grid-template-areas: "gallery side" "main side";
  grid-template-rows: auto 1fr;
}

.game-layout[b-v51z0oivpb]  .game-gallery {
  grid-area: gallery;
  min-inline-size: 0;
}

.game-main[b-v51z0oivpb],
.game-side[b-v51z0oivpb] {
  display: grid;
  gap: 1.5rem;
  min-inline-size: 0;
}

.game-main[b-v51z0oivpb] {
  grid-area: main;
}

.game-side[b-v51z0oivpb] {
  grid-area: side;
}

/* One column: the pictures, then the downloads, then the description and the
   rest. */
@media (max-width: 980px) {
  .game-layout[b-v51z0oivpb] {
    grid-template-areas: "side" "main";
    grid-template-columns: minmax(0, 1fr);
  }

  .game-layout.has-gallery[b-v51z0oivpb] {
    grid-template-areas: "gallery" "side" "main";
    grid-template-rows: auto;
  }
}

.prose p[b-v51z0oivpb] {
  color: var(--text-muted);
  margin-block: 0 .8rem;
  max-inline-size: 68ch;
  white-space: pre-line;
}

.prose p:last-child[b-v51z0oivpb] {
  margin-block-end: 0;
}

/* Categories and tags side by side while the column is wide enough to say
   they are two different things. */
.classification[b-v51z0oivpb] {
  display: grid;
  gap: 1.25rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.classification .section-label[b-v51z0oivpb] {
  margin-block-end: .6rem;
}

.versions[b-v51z0oivpb] {
  display: grid;
  gap: .8rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.version-label[b-v51z0oivpb] {
  font-weight: 700;
}

.version-date[b-v51z0oivpb] {
  color: var(--text-muted);
  font-size: .85rem;
  margin-inline-start: .5rem;
}

.version-notes[b-v51z0oivpb] {
  color: var(--text-muted);
  font-size: .9rem;
  margin-block: .2rem 0;
  white-space: pre-line;
}
/* /Components/Public/Games/GameDownloads.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side. What makes a
   patch read as one group is that its rows sit tight together and the next
   group does not: no border, which would be a third frame inside the panel.
   Which parts show is download-choices.css's business; this file only draws
   them. */

.download-choices[b-18ywjoepyi] {
  display: grid;
  gap: 1.1rem;
}

/* The pickers: the platform as a row of options on one track, the language as
   a list. Every option is one column of the same width, and the column's floor
   holds the longest glyph and name, Windows, which PlatformName keeps on one
   line: a row with no room for another column wraps it whole. */
.platform-choices[b-18ywjoepyi] {
  border: 0;
  margin: 0;
  min-inline-size: 0;
  padding: 0;
}

.platform-options[b-18ywjoepyi] {
  background: var(--surface-raised);
  border-radius: var(--radius);
  display: grid;
  gap: .25rem;
  grid-template-columns: repeat(auto-fit, minmax(6.75rem, 1fr));
  padding: .25rem;
}

/* An option is part of the track until it is chosen, and the chosen one fills
   with the accent. */
.platform-option[b-18ywjoepyi] {
  align-items: center;
  background: transparent;
  border-color: transparent;
  border-radius: calc(var(--radius) - .25rem);
  color: var(--text-muted);
  display: flex;
  font-weight: 700;
  justify-content: center;
  min-block-size: 2.6rem;
  padding-inline: .5rem;
}

.platform-option:hover[b-18ywjoepyi] {
  background: var(--surface-high);
  color: var(--text);
}

.platform-choice:checked + .platform-option[b-18ywjoepyi] {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent-contrast);
}

.platform-choice:focus-visible + .platform-option[b-18ywjoepyi] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.language-choice[b-18ywjoepyi] {
  inline-size: 100%;
}

/* The label's row has room for the link download-language.js adds beside it,
   so nothing moves when it arrives. The script's link carries no scope of this
   component, hence ::deep. */
.language-choice-head[b-18ywjoepyi] {
  align-items: baseline;
  column-gap: .75rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin-block-end: .35rem;
  min-block-size: 1.3rem;
}

.language-choice-head .field-label[b-18ywjoepyi] {
  margin: 0;
}

.language-choice-head[b-18ywjoepyi]  a {
  font-size: .82rem;
  font-weight: 600;
}

.no-match[b-18ywjoepyi] {
  color: var(--text-muted);
  font-size: .88rem;
  margin: 0;
}

.patches[b-18ywjoepyi] {
  display: grid;
  gap: 1.3rem;
}

.patch[b-18ywjoepyi] {
  display: grid;
  gap: .55rem;
}

/* The patch says what it is on one quiet line, version, number and date, over
   the download it offers: the download is what the panel is for. */
.patch-head[b-18ywjoepyi] {
  align-items: baseline;
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: .8rem;
  gap: .2rem .45rem;
}

.release-label[b-18ywjoepyi] {
  color: var(--text);
  font-size: .85rem;
  font-weight: 700;
  margin: 0;
}

.patch-name[b-18ywjoepyi] {
  font-weight: 700;
}

.patch-name[b-18ywjoepyi]::before,
.patch-date[b-18ywjoepyi]::before {
  content: "·";
  margin-inline-end: .45rem;
}

/* A build: one file of the patch, the mirrors that serve it. A little more space before the next build is what tells the files
   apart, again without a frame. */
.build[b-18ywjoepyi] {
  display: grid;
  gap: .45rem;
}

.build + .build[b-18ywjoepyi] {
  margin-block-start: .5rem;
}

.mirrors[b-18ywjoepyi] {
  display: grid;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.mirror-links[b-18ywjoepyi] {
  display: contents;
}

.mirror-download[b-18ywjoepyi] {
  align-items: center;
  color: var(--text);
  display: grid;
  overflow: hidden;
  position: relative;
  text-decoration: none;
}

.mirror-download:hover[b-18ywjoepyi] {
  text-decoration: none;
}

.mirror-download:focus-visible[b-18ywjoepyi] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.mirror-download-icon[b-18ywjoepyi] {
  block-size: 1em;
  fill: none;
  inline-size: 1em;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

.mirror-download-host[b-18ywjoepyi] {
  overflow-wrap: anywhere;
}

.mirror-instructions[b-18ywjoepyi] {
  color: var(--text-muted);
  font-size: .82rem;
  margin: 0;
  white-space: pre-line;
}

/* The first mirror: one large button, the label over the host that serves
   it, filled with the accent and glowing under it. Its report sits below,
   off the button, so reporting never reads as part of downloading. */
.mirrors-primary .mirror[b-18ywjoepyi] {
  display: grid;
  gap: .45rem;
}

.mirrors-primary .mirror-download[b-18ywjoepyi] {
  background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 72%, var(--accent-contrast)));
  border-radius: calc(var(--radius) * 1.2);
  box-shadow: 0 10px 28px color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--accent-contrast);
  column-gap: .9rem;
  grid-template-columns: auto minmax(0, 1fr);
  padding-block: .9rem;
  padding-inline: 1rem 1.1rem;
}

.mirrors-primary .mirror-download-icon[b-18ywjoepyi] {
  background: color-mix(in srgb, var(--accent-contrast) 16%, transparent);
  block-size: 2.75rem;
  border-radius: 50%;
  grid-row: span 2;
  inline-size: 2.75rem;
  padding: .7rem;
}

.mirrors-primary .mirror-download-label[b-18ywjoepyi] {
  font-size: 1.15rem;
  font-weight: 800;
  line-height: 1.2;
}

.mirrors-primary .mirror-download-host[b-18ywjoepyi] {
  font-size: .82rem;
  font-weight: 600;
}

/* The light that sweeps across the button on hover, parked outside it until
   then, travelling from the inline start to the inline end. */
.mirrors-primary .mirror-download[b-18ywjoepyi]::after {
  --sheen-direction: 1;
  background: linear-gradient(115deg, transparent 30%, color-mix(in srgb, var(--accent-contrast) 22%, transparent) 48%, transparent 62%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
  transform: translateX(calc(-120% * var(--sheen-direction)));
}

.mirrors-primary .mirror-download:dir(rtl)[b-18ywjoepyi]::after {
  --sheen-direction: -1;
}

/* The other mirrors: a short list under the button, each its host behind the
   download glyph, with its report at the end of the row. The label stays in
   the link's name and leaves the row. */
.other-mirrors[b-18ywjoepyi] {
  color: var(--text-muted);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: calc(.08em * var(--label-tracking));
  margin: .35rem 0 0;
  text-transform: uppercase;
}

.mirrors-other .mirror[b-18ywjoepyi] {
  align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius);
  column-gap: .75rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  padding-block: .45rem;
  padding-inline: .8rem .7rem;
  row-gap: .3rem;
}

.mirrors-other .mirror-download[b-18ywjoepyi] {
  column-gap: .5rem;
  font-size: .9rem;
  font-weight: 700;
  grid-template-columns: auto minmax(0, 1fr);
  justify-self: start;
}

.mirrors-other .mirror-download-icon[b-18ywjoepyi] {
  color: var(--accent-text);
}

.mirrors-other .mirror-download:hover[b-18ywjoepyi] {
  color: var(--accent-text);
}

.mirrors-other .mirror-download-label[b-18ywjoepyi] {
  block-size: 1px;
  clip: rect(0 0 0 0);
  inline-size: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
}

.mirrors-other .mirror-instructions[b-18ywjoepyi] {
  grid-column: 1 / -1;
  grid-row: 2;
}

.mirrors-other[b-18ywjoepyi]  .report-trigger {
  margin-block-start: 0;
}

.mirrors-other .mirror:has(.report-answer) .mirror-report[b-18ywjoepyi] {
  grid-column: 1 / -1;
}

/* Motion, only for a visitor who has not asked for less. A patch rises into
   place as the choices reveal it, the button first and the other mirrors
   after it; only where a pointer can rest does the button lift, glow
   brighter, sweep its light and nudge its glyph. Nothing changes size, so
   nothing is laid out again. */
@media (prefers-reduced-motion: no-preference) {
  .patch[b-18ywjoepyi] {
    animation: patch-rise-b-18ywjoepyi .4s cubic-bezier(.2, .8, .2, 1) both;
  }

  .other-mirrors[b-18ywjoepyi],
  .mirrors-other[b-18ywjoepyi] {
    animation: patch-rise-b-18ywjoepyi .4s cubic-bezier(.2, .8, .2, 1) .08s both;
  }

  .platform-option[b-18ywjoepyi] {
    transition: background-color .2s ease, box-shadow .2s ease, color .2s ease;
  }

  .mirror-download[b-18ywjoepyi] {
    transition: box-shadow .22s ease, color .15s ease, transform .22s ease;
  }

  .mirrors-primary .mirror-download:active[b-18ywjoepyi] {
    transform: scale(.99);
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .mirrors-primary .mirror-download:hover[b-18ywjoepyi] {
    box-shadow: 0 14px 34px color-mix(in srgb, var(--accent) 48%, transparent);
    transform: translateY(-2px);
  }

  .mirrors-primary .mirror-download:hover[b-18ywjoepyi]::after {
    transform: translateX(calc(120% * var(--sheen-direction)));
    transition: transform .8s ease;
  }

  .mirror-download:hover .mirror-download-icon[b-18ywjoepyi] {
    animation: download-nudge-b-18ywjoepyi .7s ease-in-out infinite;
  }
}

@keyframes patch-rise-b-18ywjoepyi {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes download-nudge-b-18ywjoepyi {
  0%,
  100% {
    translate: 0 0;
  }

  50% {
    translate: 0 3px;
  }
}
/* /Components/Public/Games/GameFacts.razor.rz.scp.css */
/* The platform marks, then JoiPlay where it applies, on one row that wraps. */
.platform-facts[b-922jpdg0kr] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}

/* A game's pages on stores, side by side and wrapping: each the store's icon,
   or its first letter in the icon's square, then its code in the monospace
   codes are written in or its name, then the arrow saying the link leaves the
   site. The text underlines only under the pointer. */

.store-links[b-922jpdg0kr] {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .9rem;
}

.store-link[b-922jpdg0kr] {
  align-items: center;
  color: var(--text);
  display: inline-flex;
  flex-wrap: wrap;
  gap: .4rem;
  overflow-wrap: anywhere;
  text-decoration: none;
}

.store-link:is(:hover, :focus-visible) :is(.store-name, .store-code)[b-922jpdg0kr] {
  text-decoration: underline;
}

.store-name[b-922jpdg0kr] {
  font-weight: 600;
}

.store-code[b-922jpdg0kr] {
  font-family: var(--font-mono);
  font-size: .82rem;
}

.store-out[b-922jpdg0kr] {
  color: var(--text-subtle);
  font-size: .8rem;
}

/* The developers, each a pill linking to the catalog filtered by it: the
   shape of the page's other values, lifted to the accent under the pointer. */
.developer-links[b-922jpdg0kr] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.developer-links a[b-922jpdg0kr] {
  background: var(--surface-high);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text);
  display: inline-block;
  font-size: .8rem;
  font-weight: 600;
  line-height: 1.4;
  padding: .2rem .65rem;
  text-decoration: none;
}

.developer-links a:is(:hover, :focus-visible)[b-922jpdg0kr] {
  border-color: var(--accent);
  color: var(--accent-text);
}
/* /Components/Public/Games/GameGallery.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the
   gallery reads in both flavors and mirrors under dir="rtl". It is the same
   surface as the page's other parts. */

.game-gallery[b-3wmogxrv51] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
}

/* The stage, and the strip under it. */
.gallery[b-3wmogxrv51] {
  display: grid;
  gap: .15rem;
}

.stage[b-3wmogxrv51] {
  counter-reset: gallery-frame;
  position: relative;
}

/* The shape is the stage's, not the picture's: a picture of another shape is
   shown whole inside it rather than cropped, since a screenshot's edges are
   part of what it shows. A frame that is not drawn is not loaded by it. */
.stage-frame[b-3wmogxrv51] {
  aspect-ratio: 16 / 9;
  background: var(--bg-deep);
  border-radius: var(--radius);
  display: none;
  margin: 0;
  overflow: hidden;
  position: relative;
}

.is-single .stage-frame[b-3wmogxrv51],
:checked + .stage-frame[b-3wmogxrv51] {
  display: block;
}

.stage-image[b-3wmogxrv51] {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: contain;
}

/* With script, the picture itself opens the full-screen view. */
html.js .stage-image[b-3wmogxrv51] {
  cursor: zoom-in;
}

/* Each edge of the stage steps to the neighbouring picture. It stays out of the
   way until a pointer comes over the stage, then darkens toward its side under
   a chevron; a touch screen has no hover, so there it is always faintly
   drawn. Every edge is drawn as the one on the left, darkening and pointing
   leftward, and the one on the right is its mirror image: the next picture's
   on a left-to-right page, the previous picture's on a right-to-left one. */
.edge[b-3wmogxrv51] {
  align-items: center;
  background: linear-gradient(to right, color-mix(in srgb, var(--bg-deep) 55%, transparent), transparent);
  color: var(--text);
  cursor: pointer;
  display: flex;
  inline-size: 22%;
  inset-block: 0;
  justify-content: left;
  opacity: 0;
  padding-inline: 1rem;
  position: absolute;
  transition: opacity .2s ease;
}

.edge-previous[b-3wmogxrv51] {
  inset-inline-start: 0;
}

.edge-next[b-3wmogxrv51] {
  inset-inline-end: 0;
}

.edge-next:dir(ltr)[b-3wmogxrv51],
.edge-previous:dir(rtl)[b-3wmogxrv51] {
  transform: scaleX(-1);
}

.stage:hover .edge[b-3wmogxrv51] {
  opacity: .35;
}

.stage:hover .edge:hover[b-3wmogxrv51] {
  opacity: 1;
}

/* Every mark in the gallery is a stroked line icon. */
.edge svg[b-3wmogxrv51],
.stage-zoom svg[b-3wmogxrv51],
.strip-step svg[b-3wmogxrv51],
.viewer-button svg[b-3wmogxrv51] {
  block-size: 1.15rem;
  fill: none;
  inline-size: 1.15rem;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

.edge svg[b-3wmogxrv51] {
  block-size: 1.8rem;
  filter: drop-shadow(0 1px 2px color-mix(in srgb, var(--bg-deep) 80%, transparent));
  inline-size: 1.8rem;
  stroke-width: 2.4;
}

/* The picture's place among them, in the stage's lower corner: the buttons up
   to the checked one are counted, so the count is drawn rather than written,
   and the page's text carries no number per picture. */
.stage > input[b-3wmogxrv51] {
  counter-increment: gallery-frame;
}

.stage > :checked ~ input[b-3wmogxrv51] {
  counter-increment: none;
}

.stage-count[b-3wmogxrv51]::before {
  content: counter(gallery-frame) " / " attr(data-total);
}

.stage-count[b-3wmogxrv51] {
  background: color-mix(in srgb, var(--bg-deep) 72%, transparent);
  border-radius: 999px;
  color: var(--text);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  inset-block-end: .7rem;
  inset-inline-end: .7rem;
  padding: .25rem .6rem;
  pointer-events: none;
  position: absolute;
}

/* A round button laid over a picture: the full-screen button, the strip's
   steps and the full-screen view's controls. */
.stage-zoom[b-3wmogxrv51],
.strip-step[b-3wmogxrv51],
.viewer-button[b-3wmogxrv51] {
  align-items: center;
  background: color-mix(in srgb, var(--bg-deep) 72%, transparent);
  block-size: 2.4rem;
  border: 0;
  border-radius: 50%;
  color: var(--text);
  cursor: pointer;
  display: inline-flex;
  inline-size: 2.4rem;
  justify-content: center;
  padding: 0;
  transition: opacity .2s ease, background-color .2s ease;
}

.stage-zoom:hover[b-3wmogxrv51],
.strip-step:hover[b-3wmogxrv51],
.viewer-button:hover[b-3wmogxrv51] {
  background: var(--bg-deep);
}

.stage-zoom:focus-visible[b-3wmogxrv51],
.strip-step:focus-visible[b-3wmogxrv51],
.viewer-button:focus-visible[b-3wmogxrv51] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The full-screen button waits in the stage's upper corner until a pointer
   comes over the stage, or the keyboard reaches it. */
.stage-zoom[b-3wmogxrv51] {
  inset-block-start: .7rem;
  inset-inline-end: .7rem;
  opacity: 0;
  position: absolute;
  z-index: 1;
}

.stage:hover .stage-zoom[b-3wmogxrv51],
.stage-zoom:focus-visible[b-3wmogxrv51] {
  opacity: 1;
}

/* Every chevron is drawn pointing back and mirrored where it steps on: on a
   left-to-right page "on" is rightward, on a right-to-left one leftward. */
:is(.strip-on, .viewer-on):dir(ltr) svg[b-3wmogxrv51],
:is(.strip-back, .viewer-back):dir(rtl) svg[b-3wmogxrv51] {
  transform: scaleX(-1);
}

/* ---- the strip ----
   One row however many pictures there are: five and a part of the sixth fit,
   so a cut picture at the end says the row goes on. The padding leaves room
   for a thumbnail that rises with its ring, and for the focus outline, both of
   which the scrolling box would otherwise clip. */
.strip-wrap[b-3wmogxrv51] {
  position: relative;
}

.strip[b-3wmogxrv51] {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding: .45rem .4rem;
  scroll-padding-inline: .4rem;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}

/* With script, the steps and the fading end stand in for the scrollbar. */
html.js .strip[b-3wmogxrv51] {
  scrollbar-width: none;
}

html.js .strip[b-3wmogxrv51]::-webkit-scrollbar {
  display: none;
}

/* The end the row goes on past fades out, as game-gallery.js marks it. */
.strip[data-more="end"]:dir(ltr)[b-3wmogxrv51],
.strip[data-more="start"]:dir(rtl)[b-3wmogxrv51] {
  mask-image: linear-gradient(to right, #000 82%, transparent);
}

.strip[data-more="start"]:dir(ltr)[b-3wmogxrv51],
.strip[data-more="end"]:dir(rtl)[b-3wmogxrv51] {
  mask-image: linear-gradient(to left, #000 82%, transparent);
}

.strip[data-more="both"][b-3wmogxrv51] {
  mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}

.strip-step[b-3wmogxrv51] {
  block-size: 2rem;
  inline-size: 2rem;
  inset-block-start: 50%;
  opacity: 0;
  position: absolute;
  transform: translateY(-50%);
  z-index: 1;
}

.strip-back[b-3wmogxrv51] {
  inset-inline-start: -.35rem;
}

.strip-on[b-3wmogxrv51] {
  inset-inline-end: -.35rem;
}

.strip-wrap:hover .strip-step:not([disabled])[b-3wmogxrv51] {
  opacity: 1;
}

.strip-step[disabled][b-3wmogxrv51] {
  pointer-events: none;
}

.thumb[b-3wmogxrv51] {
  --thumb-opacity: .55;
  aspect-ratio: 16 / 10;
  background: var(--bg-deep);
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  flex: 0 0 calc((100% - 4 * .5rem) / 5.4);
  overflow: hidden;
  padding: 0;
  position: relative;
  scroll-snap-align: start;
  transition: transform .18s ease;
}

.thumb-image[b-3wmogxrv51] {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: cover;
  opacity: var(--thumb-opacity);
  transition: opacity .18s ease;
}

/* The thumbnail at the checked button's place is marked, and the one at the
   focused button's place ringed. The buttons sit on the stage and the
   thumbnails in the strip, so no sibling rule reaches from one to the other;
   each place is named instead, one for the cover and one for every
   screenshot a game may hold (Game.MaxScreenshots). */
.gallery:has(> .stage > input:nth-of-type(1):checked) .thumb:nth-child(1)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(2):checked) .thumb:nth-child(2)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(3):checked) .thumb:nth-child(3)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(4):checked) .thumb:nth-child(4)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(5):checked) .thumb:nth-child(5)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(6):checked) .thumb:nth-child(6)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(7):checked) .thumb:nth-child(7)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(8):checked) .thumb:nth-child(8)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(9):checked) .thumb:nth-child(9)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(10):checked) .thumb:nth-child(10)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(11):checked) .thumb:nth-child(11)[b-3wmogxrv51] {
  --thumb-opacity: 1;
  box-shadow: 0 0 0 2px var(--accent);
}

.gallery:has(> .stage > input:nth-of-type(1):focus-visible) .thumb:nth-child(1)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(2):focus-visible) .thumb:nth-child(2)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(3):focus-visible) .thumb:nth-child(3)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(4):focus-visible) .thumb:nth-child(4)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(5):focus-visible) .thumb:nth-child(5)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(6):focus-visible) .thumb:nth-child(6)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(7):focus-visible) .thumb:nth-child(7)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(8):focus-visible) .thumb:nth-child(8)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(9):focus-visible) .thumb:nth-child(9)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(10):focus-visible) .thumb:nth-child(10)[b-3wmogxrv51],
.gallery:has(> .stage > input:nth-of-type(11):focus-visible) .thumb:nth-child(11)[b-3wmogxrv51] {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---- the full-screen view ----
   The picture as large as the window allows, whole, with the steps beside it
   and the thumbnails under it. It fills the viewport less its scrollbar, which
   a percentage of the fixed box is and 100vw is not. Its picture is written by
   script, so the rule reaches it through ::deep. */
.viewer[b-3wmogxrv51] {
  background: color-mix(in srgb, var(--bg-deep) 95%, transparent);
  block-size: 100%;
  border: 0;
  color: var(--text);
  inline-size: 100%;
  margin: 0;
  max-block-size: none;
  max-inline-size: none;
  padding: 0;
}

.viewer[b-3wmogxrv51]::backdrop {
  background: transparent;
}

.viewer[open][b-3wmogxrv51] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
}

.viewer-bar[b-3wmogxrv51] {
  align-items: center;
  display: flex;
  justify-content: space-between;
  padding: 1rem 1.25rem;
}

.viewer-count[b-3wmogxrv51] {
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.viewer-main[b-3wmogxrv51] {
  align-items: center;
  display: flex;
  justify-content: center;
  min-block-size: 0;
  padding-inline: 4.5rem;
  position: relative;
}

.viewer-stage[b-3wmogxrv51] {
  block-size: 100%;
  inline-size: 100%;
}

.viewer-stage[b-3wmogxrv51]  img {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: contain;
}

.viewer-step[b-3wmogxrv51] {
  inset-block-start: 50%;
  position: absolute;
  transform: translateY(-50%);
}

.viewer-back[b-3wmogxrv51] {
  inset-inline-start: 1.25rem;
}

.viewer-on[b-3wmogxrv51] {
  inset-inline-end: 1.25rem;
}

.viewer-strip[b-3wmogxrv51] {
  display: flex;
  gap: .5rem;
  justify-content: safe center;
  overflow-x: auto;
  padding: 1rem 1.25rem 1.25rem;
  scrollbar-width: none;
}

.viewer-strip .thumb[b-3wmogxrv51] {
  flex-basis: 6.5rem;
}

/* The view's thumbnail of the picture it shows, as game-gallery.js marks it. */
.thumb[aria-current="true"][b-3wmogxrv51] {
  --thumb-opacity: 1;
  box-shadow: 0 0 0 2px var(--accent);
}

.viewer-strip .thumb:focus-visible[b-3wmogxrv51] {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Only a pointer that hovers lifts and lights a thumbnail: on a touch screen
   the tapped one would stay raised after the tap, like a second choice. */
@media (hover: hover) {
  .thumb:hover[b-3wmogxrv51] {
    --thumb-opacity: 1;
    transform: translateY(-3px);
  }
}

@media (hover: none) {
  .edge[b-3wmogxrv51] {
    opacity: .6;
  }

  .stage-zoom[b-3wmogxrv51] {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .edge[b-3wmogxrv51],
  .stage-zoom[b-3wmogxrv51],
  .strip-step[b-3wmogxrv51],
  .viewer-button[b-3wmogxrv51],
  .thumb[b-3wmogxrv51],
  .thumb-image[b-3wmogxrv51] {
    transition: none;
  }

  .thumb:hover[b-3wmogxrv51] {
    transform: none;
  }
}

@media (max-width: 620px) {
  .game-gallery[b-3wmogxrv51] {
    padding: .9rem;
  }

  .thumb[b-3wmogxrv51] {
    flex-basis: calc((100% - 2 * .5rem) / 3.4);
  }

  .viewer-main[b-3wmogxrv51] {
    padding-inline: .75rem;
  }

  .viewer-step[b-3wmogxrv51] {
    display: none;
  }

  .viewer-strip .thumb[b-3wmogxrv51] {
    flex-basis: 5rem;
  }
}
/* /Components/Public/Games/GameReport.razor.rz.scp.css */
/* One panel holding the subject and the form, kept to a reading measure as a
   legal page's text is. Tokens for every colour and logical properties for
   every side, so the page reads in both flavors and mirrors under dir="rtl". */

.report-page[b-w7uuftjcir] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.6);
  display: grid;
  gap: 1.25rem;
  max-inline-size: 40rem;
  padding: clamp(1.25rem, 4vw, 2.5rem);
}

/* The game the report is about, above the heading, and the way back to it. */
.report-game[b-w7uuftjcir] {
  font-weight: 700;
  overflow-wrap: anywhere;
}

.report-page h1[b-w7uuftjcir] {
  color: var(--text);
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  font-weight: 800;
  line-height: 1.15;
  margin: 0;
}

.report-page textarea[b-w7uuftjcir] {
  min-block-size: 7rem;
  resize: vertical;
}

.report-hint[b-w7uuftjcir] {
  color: var(--text-muted);
  font-size: .8rem;
  margin-block: 0 .4rem;
}
/* /Components/Public/Games/GameSection.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the part
   reads in both flavors and mirrors under dir="rtl". The name is the shared
   .section-label; in a summary the space under it is the fold's. */

.game-section[b-rk4pagjv8j] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
}

.section-title[b-rk4pagjv8j] {
  margin-block-end: .8rem;
}

/* The name and what stands at the end of its line, on one baseline. */
.section-head[b-rk4pagjv8j] {
  align-items: baseline;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-block-end: .8rem;
}

.section-head .section-label[b-rk4pagjv8j] {
  margin: 0;
}

@media (max-width: 620px) {
  .game-section[b-rk4pagjv8j] {
    padding: .95rem;
  }
}
/* /Components/Public/Games/JoiPlayMark.razor.rz.scp.css */
.joiplay-mark[b-t665atxxyx] {
  background: var(--accent-soft);
  border-radius: 999px;
  color: var(--accent-text);
  font-size: .74rem;
  font-weight: 800;
  line-height: 1.4;
  padding: .2rem .55rem;
  white-space: nowrap;
}
/* /Components/Public/Games/OtherGameList.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the list
   reads in both flavors and mirrors under dir="rtl". The rows are the home
   page's recently updated games: a thumbnail, then the title and one quiet
   line under it. */

.other-games[b-nfe8dvdp5j] {
  display: flex;
  flex-direction: column;
  gap: .6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The title's link is stretched over the row, thumbnail included. */
.other-game[b-nfe8dvdp5j] {
  align-items: center;
  border-radius: var(--radius-sm);
  display: flex;
  gap: .75rem;
  position: relative;
}

.other-game:focus-within[b-nfe8dvdp5j] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.thumb[b-nfe8dvdp5j] {
  align-items: center;
  aspect-ratio: 16 / 10;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--cover-from) 55%, var(--surface)),
    color-mix(in srgb, var(--cover-to) 55%, var(--surface)));
  border-radius: var(--radius-sm);
  display: flex;
  flex: none;
  inline-size: 5.5rem;
  justify-content: center;
  overflow: hidden;
}

.thumb .cover-image[b-nfe8dvdp5j] {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: cover;
}

.thumb .cover-initials[b-nfe8dvdp5j] {
  color: var(--text);
  font-size: .85rem;
  font-weight: 800;
  opacity: .85;
}

.other-copy[b-nfe8dvdp5j] {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  min-inline-size: 0;
}

.other-link[b-nfe8dvdp5j] {
  color: var(--text);
  font-size: .9rem;
  font-weight: 700;
  line-height: 1.25;
  overflow-wrap: anywhere;
  text-decoration: none;
}

.other-link[b-nfe8dvdp5j]::after {
  content: "";
  inset: 0;
  position: absolute;
}

.other-link:focus-visible[b-nfe8dvdp5j] {
  outline: none;
}

.other-game:hover .other-link[b-nfe8dvdp5j] {
  color: var(--accent-text);
}

.other-date[b-nfe8dvdp5j] {
  color: var(--text-subtle);
  font-size: .76rem;
}
/* /Components/Public/Games/ReportEntry.razor.rz.scp.css */
/* Reporting a link is a quiet link on its mirror. Reporting the file is a
   ghost button, outlined and unfilled, so it is found under the download
   without competing with it. Tokens for every
   colour and logical properties for every side, so the entry point reads the
   same way in a right-to-left page. */

.report-trigger[b-gb4uh36vt6] {
  align-items: center;
  /* On the raised surface a mirror row sits on, the subtle role falls under AA. */
  color: var(--text-on-raised);
  display: inline-flex;
  font-size: .76rem;
  gap: .3rem;
  margin-block-start: .6rem;
  text-decoration: none;
}

.report-trigger:hover[b-gb4uh36vt6] {
  color: var(--danger-text);
  text-decoration: underline;
}

.report-button[b-gb4uh36vt6] {
  align-items: center;
  display: flex;
  gap: .45rem;
  justify-content: center;
  margin-block-start: .75rem;
}

.report-button > span[aria-hidden="true"][b-gb4uh36vt6] {
  color: var(--danger-text);
}

.report-answer[b-gb4uh36vt6] {
  margin-block-start: .65rem;
}
/* /Components/Public/Legal/LegalDocument.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the text
   reads in both flavors and mirrors under dir="rtl". The text keeps to a
   reading measure rather than the shell's whole width. */

.legal[b-zt3q0lrnyc] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.6);
  color: var(--text);
  line-height: 1.6;
  max-inline-size: 48rem;
  padding: clamp(1.25rem, 4vw, 2.5rem);
}

.legal h1[b-zt3q0lrnyc] {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  line-height: 1.15;
  margin-block: 0 .5rem;
}

.legal-updated[b-zt3q0lrnyc] {
  color: var(--text-muted);
  font-size: .95rem;
  margin-block: 0 1.5rem;
}

.legal[b-zt3q0lrnyc]  h2 {
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1.25;
  margin-block: 2rem .75rem;
}

.legal[b-zt3q0lrnyc]  h3 {
  font-size: 1.05rem;
  font-weight: 700;
  margin-block: 1.25rem .5rem;
}

.legal[b-zt3q0lrnyc]  p,
.legal[b-zt3q0lrnyc]  ul {
  margin-block: 0 .85rem;
}

.legal[b-zt3q0lrnyc]  ul {
  padding-inline-start: 1.5rem;
}

.legal[b-zt3q0lrnyc]  li + li {
  margin-block-start: .35rem;
}

.legal[b-zt3q0lrnyc]  .legal-email a {
  font-weight: 700;
}
/* /Components/Public/PublicHome.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side, so the page
   reads in both flavors and mirrors under dir="rtl". The parts are set apart
   by spacing alone, never by a rule. */

/* The page's heading, above everything it names. */
.home-title[b-humefq4b1r] {
  color: var(--text);
  font-size: clamp(1.5rem, 4vw, 2rem);
  font-weight: 800;
  line-height: 1.15;
  margin-block: 0 1.2rem;
}

/* ---- the top block: one large cover beside four small ones ---- */

/* The large tile takes the inline start and both rows; the four others fill
   two columns beside it. A catalog of one game draws it alone, full width. */
.home-top[b-humefq4b1r] {
  display: grid;
  gap: 1rem;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: repeat(2, minmax(11rem, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.home-top:has(> :only-child)[b-humefq4b1r] {
  grid-template-columns: minmax(0, 1fr);
}

/* The cover fills the tile behind the words, and a shade rises from its floor
   so the title reads on any picture. Both sit under the tile's own content in
   a stacking context of its own, so the link stretched over the tile is on
   top of everything and the tile is one link and one focus stop. */
.tile[b-humefq4b1r] {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--cover-from) 55%, var(--surface)),
    color-mix(in srgb, var(--cover-to) 55%, var(--surface)));
  border-radius: calc(var(--radius) * 1.6);
  display: flex;
  flex-direction: column;
  isolation: isolate;
  justify-content: flex-end;
  min-block-size: 0;
  overflow: hidden;
  position: relative;
}

.tile:first-child[b-humefq4b1r] {
  grid-row: span 2;
}

.tile[b-humefq4b1r]::after {
  background: linear-gradient(to top, color-mix(in srgb, var(--picture-shade) 88%, transparent), transparent 60%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
  z-index: -1;
}

.tile .cover-image[b-humefq4b1r] {
  block-size: 100%;
  inline-size: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  transition: transform .5s cubic-bezier(.2, .7, .2, 1);
  z-index: -1;
}

.tile .cover-initials[b-humefq4b1r] {
  align-items: center;
  color: var(--text);
  display: flex;
  font-size: 2rem;
  font-weight: 800;
  inset: 0;
  justify-content: center;
  letter-spacing: -.03em;
  opacity: .85;
  position: absolute;
  z-index: -1;
}

.tile-copy[b-humefq4b1r] {
  color: var(--on-picture);
  display: flex;
  flex-direction: column;
  gap: .25rem;
  padding: 1rem 1.1rem;
}

.tile:first-child .tile-copy[b-humefq4b1r] {
  padding: 1.5rem;
}

.tile-link[b-humefq4b1r] {
  color: var(--on-picture);
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.2;
  text-decoration: none;
}

.tile:first-child .tile-link[b-humefq4b1r] {
  font-size: clamp(1.35rem, 3vw, 1.9rem);
}

.tile-link[b-humefq4b1r]::after {
  content: "";
  inset: 0;
  position: absolute;
}

.tile-link:focus-visible[b-humefq4b1r] {
  outline: none;
}

.tile:focus-within[b-humefq4b1r] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.tile-engine[b-humefq4b1r] {
  font-size: .78rem;
  opacity: .85;
}

/* Only where a pointer can rest: on a touch screen a hover state sticks. */
@media (hover: hover) {
  .tile:hover .cover-image[b-humefq4b1r] {
    transform: scale(1.05);
  }

  .tile:hover .tile-link[b-humefq4b1r] {
    text-decoration: underline;
  }
}

/* ---- New, beside the recently updated games and the tags ---- */

.home-split[b-humefq4b1r] {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr) 300px;
  margin-block-start: 2.6rem;
}

.home-split-alone[b-humefq4b1r] {
  grid-template-columns: minmax(0, 1fr);
}

.home-section[b-humefq4b1r] {
  margin-block-start: 2.6rem;
}

.home-heading[b-humefq4b1r] {
  align-items: baseline;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-block-end: .9rem;
}

.home-heading h2[b-humefq4b1r] {
  color: var(--text);
  font-size: 1.3rem;
  font-weight: 800;
  margin: 0;
}

.see-all[b-humefq4b1r] {
  align-items: center;
  color: var(--accent-text);
  display: inline-flex;
  font-size: .88rem;
  font-weight: 600;
  gap: .3rem;
  text-decoration: none;
  white-space: nowrap;
}

.see-all:hover[b-humefq4b1r] {
  text-decoration: underline;
}

/* Points the way the line reads, so it turns round under RTL. */
.arrow[b-humefq4b1r] {
  block-size: 1em;
  fill: none;
  flex: none;
  inline-size: 1em;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.arrow:dir(rtl)[b-humefq4b1r] {
  transform: scaleX(-1);
}

/* As many cards as fit at a readable width, as in the catalog. */
.home-grid[b-humefq4b1r] {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The column stays in view beside a long grid, in its own track, so it never
   lies over anything. */
.home-side[b-humefq4b1r] {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  inset-block-start: 1rem;
  position: sticky;
}

.side-title[b-humefq4b1r] {
  margin-block-end: .7rem;
}

.updated[b-humefq4b1r] {
  display: flex;
  flex-direction: column;
  gap: .55rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The title's link is stretched over the row, thumbnail included. */
.updated-game[b-humefq4b1r] {
  align-items: center;
  border-radius: var(--radius-sm);
  display: flex;
  gap: .7rem;
  position: relative;
}

.updated-game:focus-within[b-humefq4b1r] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.thumb[b-humefq4b1r] {
  align-items: center;
  aspect-ratio: 16 / 10;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--cover-from) 55%, var(--surface)),
    color-mix(in srgb, var(--cover-to) 55%, var(--surface)));
  border-radius: var(--radius-sm);
  display: flex;
  flex: none;
  inline-size: 4.6rem;
  justify-content: center;
  overflow: hidden;
}

.thumb .cover-image[b-humefq4b1r],
.mosaic .cover-image[b-humefq4b1r] {
  block-size: 100%;
  display: block;
  inline-size: 100%;
  object-fit: cover;
}

.thumb .cover-initials[b-humefq4b1r] {
  color: var(--text);
  font-size: .85rem;
  font-weight: 800;
  opacity: .85;
}

.updated-copy[b-humefq4b1r] {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: .25rem;
  min-inline-size: 0;
}

.updated-link[b-humefq4b1r] {
  color: var(--text);
  font-size: .86rem;
  font-weight: 700;
  line-height: 1.25;
  text-decoration: none;
}

.updated-link[b-humefq4b1r]::after {
  content: "";
  inset: 0;
  position: absolute;
}

.updated-link:focus-visible[b-humefq4b1r] {
  outline: none;
}

.updated-game:hover .updated-link[b-humefq4b1r] {
  color: var(--accent-text);
}

/* The version as the administrator wrote it, never cut short of a whole line. */
.version[b-humefq4b1r] {
  background: var(--success-soft);
  border-radius: 999px;
  color: var(--success-text);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .03em;
  max-inline-size: 100%;
  overflow: hidden;
  padding: .2rem .55rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tags[b-humefq4b1r] {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.tags a[b-humefq4b1r] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  display: inline-block;
  font-size: .88rem;
  font-weight: 600;
  padding: .45rem .9rem;
  text-decoration: none;
}

.tags a:hover[b-humefq4b1r] {
  border-color: var(--accent);
  color: var(--accent-text);
}

/* ---- the categories, each a mosaic of its newest covers ---- */

.categories[b-humefq4b1r] {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.category[b-humefq4b1r] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.4);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

.category:hover[b-humefq4b1r] {
  border-color: var(--accent);
}

.category:focus-within[b-humefq4b1r] {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The newest cover takes the inline start and both rows, the next two share
   the rest; fewer covers take the room the missing ones leave. */
.mosaic[b-humefq4b1r] {
  block-size: 9rem;
  display: grid;
  gap: 2px;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: 1fr 1fr;
}

.mosaic-piece[b-humefq4b1r] {
  background: var(--surface-raised);
  overflow: hidden;
}

.mosaic-piece:first-child[b-humefq4b1r] {
  grid-row: span 2;
}

.mosaic-piece:only-child[b-humefq4b1r] {
  grid-column: span 2;
}

.mosaic-piece:nth-child(2):last-child[b-humefq4b1r] {
  grid-row: span 2;
}

.mosaic .cover-image[b-humefq4b1r] {
  transition: transform .5s cubic-bezier(.2, .7, .2, 1);
}

.category-foot[b-humefq4b1r] {
  align-items: center;
  color: var(--text-subtle);
  display: flex;
  gap: .5rem;
  justify-content: space-between;
  padding: .8rem 1rem;
}

.category-link[b-humefq4b1r] {
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 700;
  text-decoration: none;
}

.category-link[b-humefq4b1r]::after {
  content: "";
  inset: 0;
  position: absolute;
}

.category-link:focus-visible[b-humefq4b1r] {
  outline: none;
}

.category:hover .category-foot[b-humefq4b1r] {
  color: var(--accent-text);
}

@media (hover: hover) {
  .category:hover .cover-image[b-humefq4b1r] {
    transform: scale(1.05);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tile .cover-image[b-humefq4b1r],
  .mosaic .cover-image[b-humefq4b1r] {
    transition: none;
  }

  .tile:hover .cover-image[b-humefq4b1r],
  .category:hover .cover-image[b-humefq4b1r] {
    transform: none;
  }
}

/* ---- a catalog with nothing published ---- */

.home-state[b-humefq4b1r] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.6);
  padding: clamp(1.5rem, 4vw, 3rem);
  text-align: center;
}

.home-state h2[b-humefq4b1r] {
  color: var(--text);
  font-size: 1.5rem;
  font-weight: 700;
  margin-block: 0 .75rem;
}

.home-state p[b-humefq4b1r] {
  color: var(--text-muted);
  margin: 0 auto;
  max-inline-size: 46ch;
}

/* ---- narrower screens ---- */

/* The column goes under the grid, and stays where it is laid. */
@media (max-width: 960px) {
  .home-split[b-humefq4b1r] {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-side[b-humefq4b1r] {
    position: static;
  }
}

/* The large tile across the top, the four others two by two under it. */
@media (max-width: 860px) {
  .home-top[b-humefq4b1r] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: none;
  }

  .tile[b-humefq4b1r] {
    aspect-ratio: 1;
  }

  .tile:first-child[b-humefq4b1r] {
    aspect-ratio: 16 / 12;
    grid-column: span 2;
    grid-row: auto;
  }

  .tile:not(:first-child) .tile-copy[b-humefq4b1r] {
    padding: .75rem;
  }

  .tile:not(:first-child) .tile-link[b-humefq4b1r] {
    font-size: .92rem;
  }
}

@media (max-width: 760px) {
  .categories[b-humefq4b1r] {
    grid-template-columns: minmax(0, 1fr);
  }

  .mosaic[b-humefq4b1r] {
    block-size: 7rem;
  }
}

@media (max-width: 560px) {
  .home-grid[b-humefq4b1r] {
    gap: .75rem;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  }
}
/* /Components/Public/PublicNotFound.razor.rz.scp.css */
/* Tokens for every colour and logical properties for every side. */

.not-found[b-n7jhvj3tqx] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) * 1.6);
  padding: clamp(1.5rem, 4vw, 3rem);
}

.eyebrow[b-n7jhvj3tqx] {
  color: var(--accent-text);
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: calc(.12em * var(--label-tracking));
  margin: 0;
  text-transform: uppercase;
}

.not-found h1[b-n7jhvj3tqx] {
  color: var(--text);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  line-height: 1.15;
  margin-block: .75rem 1rem;
}

.lead[b-n7jhvj3tqx] {
  color: var(--text-muted);
  font-size: 1.05rem;
  margin-block: 0 1.5rem;
  max-inline-size: 42rem;
}
/* /Components/Shared/Badge.razor.rz.scp.css */
.badge[b-qivvn9lrmj] {
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: calc(.06em * var(--label-tracking));
  padding: .15rem .5rem;
  text-transform: uppercase;
}

.badge-neutral[b-qivvn9lrmj] {
  background: var(--surface-high);
  color: var(--text);
}

.badge-accent[b-qivvn9lrmj] {
  background: var(--accent);
  color: var(--accent-contrast);
}

.badge-success[b-qivvn9lrmj] {
  background: var(--success-soft);
  color: var(--success-text);
}
/* /Components/Shared/Callout.razor.rz.scp.css */
.callout[b-fstr0e57t3] {
  border: 1px solid;
  border-radius: var(--radius-sm);
  font-size: .9rem;
  padding: .75rem .9rem;
}

.callout-danger[b-fstr0e57t3] {
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
  color: var(--danger-text);
}

.callout-warning[b-fstr0e57t3] {
  background: var(--warning-soft);
  border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
  color: var(--warning-text);
}

.callout-success[b-fstr0e57t3] {
  background: var(--success-soft);
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
  color: var(--success-text);
}
/* /Components/Shared/DeleteConfirmation.razor.rz.scp.css */
/* The question takes the whole row, whatever columns the listing gives its
   other rows: it replaces the row's cells rather than filling one of them. The
   buttons stay on the right, where the row's own buttons were. */
.confirm-delete[b-4mgsgz8ksx] {
  align-items: center;
  column-gap: 1rem;
  display: flex;
  flex-wrap: wrap;
  grid-column: 1 / -1;
  justify-content: space-between;
  row-gap: .6rem;
}

.confirm-question[b-4mgsgz8ksx] {
  font-size: .95rem;
  line-height: 1.3;
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

.confirm-question strong[b-4mgsgz8ksx] {
  font-weight: 600;
}

.confirm-consequence[b-4mgsgz8ksx] {
  color: var(--text-muted);
  display: block;
  font-size: .82rem;
  margin-top: .2rem;
}

.confirm-actions[b-4mgsgz8ksx] {
  display: flex;
  gap: .4rem;
  margin-left: auto;
}

@media (max-width: 560px) {
  .confirm-actions[b-4mgsgz8ksx] {
    width: 100%;
  }

  .confirm-actions .btn[b-4mgsgz8ksx] {
    flex: 1;
  }
}
/* /Components/Shared/Fold.razor.rz.scp.css */
/* Logical properties only: the summary's reach mirrors under dir="rtl" without a
   rule of its own. The caret itself is the shared .disclosure-caret primitive in
   controls.css, because the report queue's rows draw the same mark. */

.fold > summary[b-362uc7tay2] {
  align-items: center;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  gap: .55rem;
  list-style: none;
  margin-block: -.35rem;
  margin-inline: -.5rem;
  padding-block: .35rem;
  padding-inline: .5rem;
}

.fold > summary[b-362uc7tay2]::-webkit-details-marker {
  display: none;
}

.fold > summary:hover[b-362uc7tay2] {
  background: var(--surface-raised);
}

.fold > summary:focus-visible[b-362uc7tay2] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.fold-body[b-362uc7tay2] {
  margin-block-start: .9rem;
}
/* /Components/Shared/FormField.razor.rz.scp.css */
.field-row + .field-row[b-d5t7rinyc5] {
  margin-top: 1rem;
}
/* /Components/Shared/ListingFoot.razor.rz.scp.css */
.listing-foot[b-b3gpkcjhjf] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1rem;
  justify-content: space-between;
  margin-top: 1.5rem;
}

.showing[b-b3gpkcjhjf] {
  color: var(--text-subtle);
  font-size: .82rem;
  margin: 0;
}
/* /Components/Shared/ListingTab.razor.rz.scp.css */
.tab[b-cjic1ib0qu] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted);
  font-size: .88rem;
  font-weight: 600;
  padding: .4rem .95rem;
  text-decoration: none;
}

/* A tab answers the pointer, the keyboard and "this is where you are" the same
   way a page link does. */
.tab:hover[b-cjic1ib0qu] {
  background: var(--surface-raised);
  color: var(--text);
}

.tab:focus-visible[b-cjic1ib0qu] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.tab[aria-current="page"][b-cjic1ib0qu] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.count[b-cjic1ib0qu] {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  margin-left: .25rem;
}
/* /Components/Shared/ListingTabs.razor.rz.scp.css */
/* Separate pills, each its own link: a tab is a filter the reader can leave,
   and the one being read is filled. */
.tabs[b-9ja77yhj6k] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}
/* /Components/Shared/Pagination.razor.rz.scp.css */
/* One capsule holding the arrows and the numbers, pushed to the far end of the
   row it sits in, across from the count of what is shown. A caller that wants
   it elsewhere, such as the public catalog centring it under the cards, moves
   the capsule as a whole. */
.pagination[b-p9a2afdsgr] {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 1.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0 0 0 auto;
  max-width: 100%;
  padding: 5px;
  position: relative;
  width: fit-content;
}

.pagination a[b-p9a2afdsgr],
.pagination span:not(.rover)[b-p9a2afdsgr] {
  align-items: center;
  border-radius: 999px;
  color: var(--text-muted);
  display: flex;
  font-size: .88rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  height: 2.25rem;
  justify-content: center;
  min-width: 2.35rem;
  padding: 0 .6rem;
  position: relative;
  text-decoration: none;
  transition: background-color .25s ease, box-shadow .25s ease, color .2s ease;
  z-index: 1;
}

/* The highlight that rides to the link under the pointer or the keyboard, drawn
   behind the numbers. pagination.js places it and shows it; without the script
   it is never drawn, and a link lights up on its own instead. */
.pagination .rover[b-p9a2afdsgr] {
  background: var(--surface-high);
  border-radius: 999px;
  height: var(--rover-height, 0);
  left: var(--rover-left, 0);
  opacity: 0;
  pointer-events: none;
  position: absolute;
  top: var(--rover-top, 0);
  transition:
    left .28s cubic-bezier(.3, 1.4, .5, 1),
    top .28s cubic-bezier(.3, 1.4, .5, 1),
    width .28s cubic-bezier(.3, 1.4, .5, 1),
    opacity .2s ease;
  width: var(--rover-width, 0);
}

.pagination[data-rover] .rover[b-p9a2afdsgr] {
  opacity: 1;
}

.pagination[data-rover="still"] .rover[b-p9a2afdsgr] {
  transition: none;
}

.pagination a:hover[b-p9a2afdsgr],
.pagination a:focus-visible[b-p9a2afdsgr] {
  color: var(--text);
}

.pagination:not([data-rover]) a:not([aria-current="page"]):hover[b-p9a2afdsgr] {
  background: var(--surface-high);
}

.pagination a:focus-visible[b-p9a2afdsgr] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.pagination a[aria-current="page"][b-p9a2afdsgr] {
  background: var(--accent);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent-contrast);
}

.pagination .gap[b-p9a2afdsgr] {
  color: var(--text-subtle);
}

/* The arrow that leads nowhere keeps its place, so the bar does not shift on
   the first and last page, and says by its tone that it is not a link. */
.pagination .edge[b-p9a2afdsgr] {
  color: var(--text-subtle);
}

@media (max-width: 560px) {
  /* Seven numbers and both arrows still fit across a 320px phone; a bar too
     long even then, such as one with four-digit numbers, wraps instead of
     pushing the page sideways. */
  .pagination[b-p9a2afdsgr] {
    gap: 0;
    margin: 0 auto;
    padding: 4px;
  }

  .pagination a[b-p9a2afdsgr],
  .pagination span:not(.rover)[b-p9a2afdsgr] {
    min-width: 1.8rem;
    padding: 0 .25rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pagination a[b-p9a2afdsgr],
  .pagination .rover[b-p9a2afdsgr] {
    transition: none;
  }
}
/* /Components/Shared/Panel.razor.rz.scp.css */
.panel[b-zetcagkxvs] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.6rem;
}

.eyebrow[b-zetcagkxvs] {
  color: var(--accent-text);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: calc(.12em * var(--label-tracking));
  text-transform: uppercase;
}

h1[b-zetcagkxvs] {
  font-size: 1.4rem;
  line-height: 1.25;
  margin: .5rem 0 1.4rem;
}

/* A section under the page's own heading: a step smaller, and closer to what
   follows it, because it names one part of the screen rather than the screen. */
h2[b-zetcagkxvs] {
  font-size: 1.1rem;
  line-height: 1.3;
  margin: .25rem 0 .75rem;
}

/* The row takes the heading's own spacing, so a panel reads the same with or
   without something beside its title. */
.title-row[b-zetcagkxvs] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin: .5rem 0 1.4rem;
}

.title-row h1[b-zetcagkxvs] {
  margin: 0;
}

@media (max-width: 880px) {
  .panel[b-zetcagkxvs] {
    padding: 1.1rem;
  }
}
/* /Components/Shared/PlatformIcon.razor.rz.scp.css */
/* The size of the text it sits in, and the colour its host gives it through
   --platform-icon-color, or the text's own colour where the host gives none,
   so it follows the theme and the host's state without a rule of its own. */
.platform-icon[b-8wuap9bsz7] {
  block-size: 1em;
  color: var(--platform-icon-color, currentColor);
  fill: currentColor;
  flex: none;
  inline-size: 1em;
  vertical-align: -.125em;
}
/* /Components/Shared/PlatformIconSprite.razor.rz.scp.css */
/* Holds the symbols and draws nothing, without taking a line of its own. */
.platform-icon-sprite[b-t31ldstyl8] {
  position: absolute;
}
/* /Components/Shared/PlatformMarks.razor.rz.scp.css */
/* A row that wraps, set by gap rather than by a margin on one side, so it
   reads the same in either direction. Each mark takes the surface and colours
   of a tag (TagList), as a square around its glyph rather than a pill around a
   name. */

.platform-marks[b-wv3qj0g8r0] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.platform-mark[b-wv3qj0g8r0] {
  align-items: center;
  background: var(--surface-high);
  border-radius: var(--radius-sm);
  color: var(--text);
  display: inline-flex;
  font-size: .95rem;
  justify-content: center;
  padding: .4rem;
}

/* Among other small text, such as a catalog card's: the glyph alone, in the
   muted text colour, at the size of the text beside it. */
.platform-marks-quiet[b-wv3qj0g8r0] {
  gap: .5rem;
}

.platform-marks-quiet .platform-mark[b-wv3qj0g8r0] {
  background: none;
  color: var(--text-muted);
  font-size: .85rem;
  padding: 0;
}
/* /Components/Shared/PlatformName.razor.rz.scp.css */
/* The glyph and the name are one unit: a line may break before or after the
   pair, never between them. */
.platform-name[b-pw06b13mx9] {
  white-space: nowrap;
}

.platform-name[b-pw06b13mx9]  .platform-icon {
  margin-inline-end: .45em;
}
/* /Components/Shared/StatTile.razor.rz.scp.css */
/* A tile is the same physical thing on every metrics screen, so its surface,
   its label treatment and its figure are declared once here. The row the tiles
   sit in belongs to the screen, which decides how many fit. */

.stat[b-t72cp3828c] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  gap: .35rem;
  padding: 1rem 1.1rem;
}

.stat-label[b-t72cp3828c] {
  color: var(--text-muted);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: calc(.04em * var(--label-tracking));
  text-transform: uppercase;
}

.stat-value[b-t72cp3828c] {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
}

/* Pushed to the floor of the tile, so the numbers of a row stay on one baseline
   however many of them carry a line. */
.stat-foot[b-t72cp3828c] {
  color: var(--text-subtle);
  font-size: .78rem;
  margin-top: auto;
  padding-top: .3rem;
}

/* A comparison, where the line is a second figure rather than a caption. The
   color only agrees with the arrow and the word the line already carries. */
.stat-foot.up[b-t72cp3828c] {
  color: var(--up-text);
  font-weight: 700;
}

.stat-foot.down[b-t72cp3828c] {
  color: var(--danger-text);
  font-weight: 700;
}

.stat-foot.flat[b-t72cp3828c] {
  color: var(--text-muted);
  font-weight: 700;
}

@media (max-width: 880px) {
  .stat[b-t72cp3828c] {
    padding: .8rem .9rem;
  }

  .stat-value[b-t72cp3828c] {
    font-size: 1.55rem;
  }
}
/* /Components/Shared/StoreIconImage.razor.rz.scp.css */
/* Drawn at 16 pixels wherever it is shown, so what the administrator sees on
   the store listing is what a visitor sees on a game page. */
.store-icon[b-n48hpl4tbl] {
  flex: none;
  height: 16px;
  object-fit: contain;
  width: 16px;
}

.store-icon-none[b-n48hpl4tbl] {
  border: 1px dashed var(--border);
  border-radius: 3px;
}

.store-initial[b-n48hpl4tbl] {
  align-items: center;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text-muted);
  display: inline-flex;
  font-size: .62rem;
  font-weight: 800;
  justify-content: center;
}
/* /Components/Shared/TagList.razor.rz.scp.css */
/* A row that wraps, set by gap rather than by a margin on one side, so it
   reads the same in either direction. */

.tags[b-w2t4ba9ek4] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.tags li[b-w2t4ba9ek4] {
  background: var(--surface-high);
  border-radius: 999px;
  color: var(--text);
  font-size: .8rem;
  font-weight: 600;
  line-height: 1.4;
  padding: .2rem .65rem;
}

.tags-accent li[b-w2t4ba9ek4] {
  background: var(--accent-soft);
  color: var(--accent-text);
}
/* /Components/Shared/ThemeToggle.razor.rz.scp.css */
/* theme.js marks the document as soon as it runs, in <head>. Until then — and
   forever, without JavaScript — the control is not offered, because pressing it
   would do nothing. How it looks is the frame's bare button, in controls.css. */
.theme-toggle[b-qwc3sa4y90] {
  display: none;
}

html.js .theme-toggle[b-qwc3sa4y90] {
  display: inline-flex;
}

/* Drawn in outline, in the button's own colour, so the mark follows the hover
   and focus states. */
.theme-mark[b-qwc3sa4y90] {
  block-size: 1.1rem;
  fill: none;
  flex: none;
  inline-size: 1.1rem;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.4;
}

/* The moon while the page is light, the sun while it is dark: the visitor's
   override when there is one, the system's preference when there is not. */
.to-light[b-qwc3sa4y90] {
  display: none;
}

:root[data-theme="dark"] .to-light[b-qwc3sa4y90] {
  display: block;
}

:root[data-theme="dark"] .to-dark[b-qwc3sa4y90] {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .to-light[b-qwc3sa4y90] {
    display: block;
  }

  :root:not([data-theme="light"]) .to-dark[b-qwc3sa4y90] {
    display: none;
  }
}

/* theme.js marks the button as it flips the theme, so the mark that comes in
   turns in. Only then: on a page load it simply stands there. */
@media (prefers-reduced-motion: no-preference) {
  .theme-toggle.is-turning .theme-mark[b-qwc3sa4y90] {
    animation: theme-turn-b-qwc3sa4y90 .45s ease;
  }
}

@keyframes theme-turn-b-qwc3sa4y90 {
  from {
    opacity: .2;
    transform: rotate(-120deg) scale(.6);
  }

  to {
    opacity: 1;
    transform: none;
  }
}
/* /Components/Shared/Topbar.razor.rz.scp.css */
.topbar[b-iw341uogs3] {
  background: var(--bg-deep);
  border-bottom: 1px solid var(--border);
}

.topbar-inner[b-iw341uogs3] {
  align-items: center;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  min-height: 3.5rem;
}

.brand-group[b-iw341uogs3] {
  align-items: center;
  display: flex;
  gap: .5rem;
}

.topbar-content[b-iw341uogs3] {
  align-items: center;
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  gap: .6rem 1.25rem;
}
