/* The starter's look: one column, one heading, plain native controls, no
   decoration. Every colour, face, size and space is a --sw-* token from the
   sprue.works brand theme (https://sprue.works/brand/v1/theme.css), linked
   before this file. That theme is cross-origin, so every var() carries the
   starter's light-scheme value as a literal fallback: without it the page is
   plain but readable. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* ---- Colours ----
   The theme's semantic colours, remapped so the starter uses no brown:
   Eerie Black where the theme uses Coffee Bean (the dark background, the
   light text, and the gray mixed from them), and orange accents: Bronze
   Spice in the light scheme (4.5:1 on Floral White, where Pumpkin Spice is
   2.6:1) and Pumpkin Spice in the dark. This file sets them itself, so both
   schemes keep them if the theme is unreachable. index.html's theme-color
   metas mirror --sw-bg. */
:root {
  --sw-fg: var(--sw-eerie-black, #1f1d1c);
  --sw-muted: #797470; /* Eerie Black 60% over Floral White */
  /* Bronze Spice as sprue-works/website#26 sets it, written out: a theme
     served or cached from before that change has #c2571b (4.2:1), which a
     var() would pick up over this value. */
  --sw-accent: #bd5205;
}

@media (prefers-color-scheme: dark) {
  :root {
    --sw-bg: var(--sw-eerie-black, #1f1d1c);
    --sw-fg: var(--sw-floral-white, #fff7ed);
    --sw-muted: #9a958f; /* Floral White 55% over Eerie Black */
    --sw-accent: var(--sw-pumpkin-spice, #f97316);
  }
}

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh; /* for browsers without dvh */
  min-height: 100dvh;
  background: var(--sw-bg, #fff7ed);
  color: var(--sw-fg, #1f1d1c);
  font-family: var(--sw-font-body, system-ui, -apple-system, "Segoe UI", sans-serif);
  font-size: var(--sw-text-md, 1rem);
  line-height: var(--sw-leading-normal, 1.5);
  /* Checkboxes, radios, range and progress take the brand accent. */
  accent-color: var(--sw-accent, #bd5205);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---- The column ---- */
main {
  flex: 1;
  width: 100%;
  max-width: 36rem;
  margin-inline: auto;
  padding: var(--sw-space-7, 3rem) var(--sw-space-4, 1rem) var(--sw-space-6, 2rem);
}

/* One per screen. The brand's display face, as on mari.guerrieri.codes. */
h1 {
  margin: 0 0 var(--sw-space-6, 2rem);
  font-family: var(--sw-font-sprue, "Quicksand", system-ui, -apple-system, "Segoe UI", sans-serif);
  font-weight: var(--sw-weight-sprue, 700);
  font-size: var(--sw-text-3xl, 2rem);
  line-height: var(--sw-leading-tight, 1.2);
  text-wrap: balance;
}

a {
  color: var(--sw-accent, #bd5205);
}

/* ---- Native controls ----
   Left as the platform draws them; they only take the page's face and size.
   The theme's color-scheme gives them their dark look. */
input,
button,
select,
textarea {
  font: inherit;
}

form {
  display: grid;
  justify-items: start;
  gap: var(--sw-space-2, 0.5rem);
}

form button {
  margin-top: var(--sw-space-2, 0.5rem);
}

/* ---- Footer ----
   A centred row that wraps whole items. Spacing is gap only, so a wrapped
   line leaves no orphan separator. */
footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: var(--sw-space-2, 0.5rem) var(--sw-space-5, 1.5rem);
  padding: var(--sw-space-5, 1.5rem) var(--sw-space-4, 1rem) var(--sw-space-6, 2rem);
  font-size: var(--sw-text-sm, 0.875rem);
}

footer a {
  color: var(--sw-fg, #1f1d1c);
  text-decoration: underline;
  text-decoration-color: var(--sw-muted, #797470);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

footer a:hover,
footer a:focus-visible {
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}

/* ---- The admin pages (lib/home.js, lib/editor.js; #878) ----
   Desktop-first (DESIGN.md §5.1): a game's editor widens the column for its
   grid, and on a phone the grid scrolls sideways in its own box. */
main.wide {
  max-width: 72rem;
}

h2 {
  margin: var(--sw-space-6, 2rem) 0 var(--sw-space-2, 0.5rem);
  font-size: var(--sw-text-md, 1rem);
}

.paste textarea {
  justify-self: stretch;
}

.note,
.flag,
.adjusted {
  color: var(--sw-muted, #797470);
  font-size: var(--sw-text-sm, 0.875rem);
}

.note:empty {
  display: none;
}

.warnings {
  padding-left: var(--sw-space-5, 1.5rem);
}

/* position: relative makes the box the containing block of the absolutely
   positioned .visually-hidden text inside the table, which would otherwise
   escape its scroll clip and widen the whole page on a phone. */
.grid-wrap {
  position: relative;
  overflow-x: auto;
  margin-block: var(--sw-space-4, 1rem);
}

/* The grid fills the column, and the item column takes what the tag columns
   leave. */
table.grid {
  min-width: 100%;
  border-collapse: collapse;
}

.grid td.item {
  width: 100%;
}

/* A new tag's name and emoji on one row. */
.add-tag {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.add-tag button {
  margin-top: 0;
}

.add-tag .note {
  flex-basis: 100%;
}

.grid th,
.grid td {
  padding: var(--sw-space-2, 0.5rem);
  border-bottom: 1px solid var(--sw-muted, #797470);
  text-align: left;
  vertical-align: top;
}

.grid th.tag {
  white-space: nowrap;
}

.grid td.check {
  text-align: center;
}

.grid td.footer span {
  display: block;
}

.item-text {
  width: 100%;
  min-width: 16rem;
}

.field {
  display: flex;
  align-items: center;
  gap: var(--sw-space-2, 0.5rem);
  margin-block: var(--sw-space-2, 0.5rem);
}

.tally {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--sw-space-2, 0.5rem) var(--sw-space-4, 1rem);
}

.tally dd {
  margin: 0;
}

/* The Share section's two buttons on one row (lib/sharing.js, #881). */
.share {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sw-space-2, 0.5rem);
}

/* Empty, it takes no room but stays in the page, so a screen reader still hears what's
   written into it next. */
.share-status:empty {
  margin: 0;
}

.share-link input {
  max-width: 100%;
}

/* The footer's account slot: a label and its button, on one line. */
#account,
.account-body {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sw-space-2, 0.5rem);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The hidden attribute must win over any display rule above. */
[hidden] {
  display: none !important;
}

/* ---- Printed cards (lib/print.js, lib/printing.js; #879) ----
   A card is laid out in em of its own font size, which is a 40th of the width
   it's given (the print document's, or the looked-up card's box), so a card
   always fills the width and its shape never changes: 40em wide and at most
   44.5em tall (the head 11em, the grid's rows 6em, the legend at most 2.5em,
   two gaps of 0.5em), 1.11 high for 1 wide. Its squares are 8em by 6em.

   The shape is what fits a page, not the size. Printing on iOS lays a page
   out at the phone's width and scales its widest content to fill the paper's
   printable width, so a card wider than the phone printed at the paper's full
   width: a 6.33in card came out 7.5in wide and 10.4in tall, onto two pages
   (Mari, on #891, 2026-11-02). At the full printable width of US Letter
   (7.7in), a card is 8.6in tall: inside Letter's 10.2in, and inside the about
   9.3in Firefox on iOS prints beside its own header and footer. On A4 it's
   7.47in by 8.3in. One card per page, and the print dialog's four pages per
   sheet halve it legibly (DESIGN.md §8).

   Squares step their text down a size (data-size) until it fits, and text
   that still overflows a square, the name or the legend shrinks on
   (lib/print.js' fitCards()). The sizes are in em, and the glyphs scale with
   them (text-rendering, below), so a fit made at one width holds at the
   others a card is laid out at, up to whole-pixel rounding
   (test/editor/print.test.js checks them). On paper a card is black on
   white, whatever the screen's scheme. */
@page {
  margin: 0.4in;
}

.card {
  width: 40em;
  display: grid;
  gap: 0.5em;
  font-family: var(--sw-font-body, system-ui, -apple-system, "Segoe UI", sans-serif);
  line-height: 1.15;
}

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1em;
  height: 11em;
  overflow: hidden;
}

.card-title {
  min-width: 0;
}

.card-game {
  margin: 0;
  font-size: 1.3em;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.card-number {
  margin: 0.25em 0 0;
  display: flex;
  align-items: baseline;
  gap: 0.3em;
}

.card-number-label {
  font-size: 1.25em;
}

.card-number-value {
  font-size: 5em;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.card-qr {
  flex: none;
  width: 11em;
  height: 11em;
}

.card-grid {
  display: grid;
  /* The card's width, its left border included: five columns of 8em. */
  grid-template-columns: repeat(5, minmax(0, 1fr));
  grid-auto-rows: 6em;
  border-top: 0.08em solid;
  border-left: 0.08em solid;
}

/* A square is a column: its tags' emoji at the top right, then its text,
   centred in the room the emoji leave. Both are in the flow, so a long run
   of emoji takes room from the text rather than lying over it. */
.square {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.25em 0.35em 0.35em;
  overflow: hidden;
  border-right: 0.08em solid;
  border-bottom: 0.08em solid;
  text-align: center;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.square-text {
  margin-block: auto;
}

.square-tags {
  flex: none;
  align-self: stretch;
  text-align: right;
  line-height: 1;
}

/* The default, FREE, in bold capitals. The owner's own text (#901) is set as they wrote it,
   in an item's type: capitals would change what was written, and in an item's type it's
   fitted as an item's text is. */
.square.free:not(.own) .square-text {
  font-weight: 700;
  text-transform: uppercase;
}

.square[data-size="0"] .square-text {
  font-size: 1.5em;
}

.square[data-size="1"] .square-text {
  font-size: 1.25em;
}

.square[data-size="2"] .square-text {
  font-size: 1.05em;
}

.square[data-size="3"] .square-text {
  font-size: 0.9em;
}

.square[data-size="4"] .square-text {
  font-size: 0.78em;
}

.square[data-size="5"] .square-text {
  font-size: 0.68em;
}

/* The space between entries is each entry's own, in its em, so it shrinks with
   them when fitCards() fits a long legend into its 2.5em. */
.card-legend {
  display: flex;
  flex-wrap: wrap;
  max-height: 2.5em;
  overflow: hidden;
  margin: 0;
  padding: 0;
  list-style: none;
}

.card-legend li {
  margin: 0 1.25em 0.25em 0;
}

/* A card looked up, on screen: the same card, as wide as its box. */
.lookup-card {
  container-type: inline-size;
  max-width: 40rem;
}

.lookup-card .card {
  font-size: calc(100cqi / 40);
  margin-block: var(--sw-space-4, 1rem);
}

/* A card fitted at one width and shown at another (on paper, whatever the
   paper; a looked-up card on screen) has to keep its lines. Its sizes are in
   em, but its glyphs needn't scale with them: Chromium on Linux set the CJK
   fallback font (WenQuanYi Zen Hei) at whole-pixel advances, so a square of
   CJK fitted at Letter's width lost a line at A4's (#903). geometricPrecision
   asks for advances in proportion to the size. */
.print-doc .card,
.lookup-card .card {
  text-rendering: geometricPrecision;
}

/* The print documents: a card as wide as the page. */
.print-doc {
  container-type: inline-size;
}

.print-doc .card {
  font-size: calc(100cqi / 40);
  color: #000;
  background: #fff;
}

/* On screen, each print document is laid out unseen, at Letter's printable
   width, so the squares can be measured before the print dialog opens: in a
   fixed box of no height that clips its cards, so a hundred of them add
   nothing to the page's scroll. */
@media screen {
  .print-doc {
    position: fixed;
    top: 0;
    left: 0;
    width: 7.7in;
    height: 0;
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
  }
}

@media print {
  .print-doc {
    display: none;
  }

  /* While a print document prints, it's all there is: one card per page. */
  html.printing body {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  html.printing body > :not(.print-doc--active) {
    display: none !important;
  }

  html.printing .print-doc--active {
    display: block;
  }

  .print-doc .card {
    break-inside: avoid;
  }

  .print-doc .card:not(:last-child) {
    break-after: page;
  }
}

/* ---- The guest warning (lib/guest-warning.js) ---- */
.guest-warning {
  max-width: 32rem;
  padding: var(--sw-space-5, 1.5rem);
  border: 1px solid var(--sw-muted, #797470);
  background: var(--sw-bg, #fff7ed);
  color: var(--sw-fg, #1f1d1c);
}

.guest-warning h2 {
  margin-top: 0;
}

.guest-warning-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sw-space-2, 0.5rem);
}

.guest-warning-message:empty {
  display: none;
}
