/* ========================================================================= */
/* WHAT THIS FILE IS (in plain English):                                     */
/*                                                                           */
/* The house style for every Waygate web page. Think of it as the uniform:   */
/* one set of colours, one set of letter sizes, one way a button, a card or  */
/* a heading looks. Each page wears this first, then adds only what is truly */
/* its own (the Runecast's slot grid, the Bazaar's price tags) in its own    */
/* <style> block.                                                            */
/*                                                                           */
/* Before this file existed, every page carried a private copy of the same   */
/* rules, and the copies drifted: some labels shrank to 7 pixels, headings   */
/* sat in three different places, and the Hub button covered titles on a     */
/* phone. One copy cannot drift from itself.                                 */
/*                                                                           */
/* This is CSS ("Cascading Style Sheets"), the language for how a page       */
/* LOOKS. A rule is a "selector" (which things) and a block in { } (how they */
/* look). Comments are the text between slash-star and star-slash.           */
/*                                                                           */
/* The rules a page must follow are checked in CI by                          */
/* tools/check_web_style.py, and written out in docs/web-style.md.           */
/* ========================================================================= */


/* ── 1. THE TOKENS ─────────────────────────────────────────────────────────
   Names starting with -- are "CSS variables" (here called tokens): a value
   given a name once, then used everywhere by name. Change one here and every
   page follows. ":root" is the whole document, so these names reach every
   rule on every page. */
:root {
  /* Colours. Hex codes mix Red, Green and Blue, two digits each. */
  --void: #06080c;          /* the page background: nearly black */
  --obsidian: #0d1015;      /* a raised surface: cards, slots */
  --well: #0a0d12;          /* a sunken surface: inputs, inner boxes */
  --line: #1a2330;          /* hairline borders */
  --parchment: #e9e7df;     /* main text */
  --ash: #8a93a2;           /* quieter text: hints, labels */
  --gold: #c9a24b;          /* the accent: buttons, section names */
  --gold-bright: #e6c479;   /* the accent at its brightest: titles */
  --rune: #3f93c4;          /* the second accent: links, magic */
  --rune-bright: #6ab8e6;
  --rune-deep: #1c567c;
  --ember: #c98a6b;         /* warnings and apologies */
  --heal: #7fb069;          /* success */
  --blood: #b8564f;         /* danger */
  --blood-bright: #e0776e;
  --tint: 63,147,196;       /* the rune blue as bare numbers, for see-through mixes */

  /* The two typefaces, each with fallbacks if the download fails. A serif
     has little feet on its letters (storybook); a sans has none (labels). */
  --serif: "Cormorant Garamond", Georgia, serif;
  --sans: "Archivo", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* THE TYPE SCALE — the only letter sizes a page should use. "rem" means
     "times the browser's base size", which is 16 pixels unless the player
     has asked their browser for bigger text (and then everything grows
     with it, which is the point of rem). The floor is 12 pixels: nothing on
     a page is ever smaller than --fs-tiny. */
  --fs-tiny: 0.75rem;       /* 12px — dense data only: table heads, slot numbers */
  --fs-label: 0.8125rem;    /* 13px — the small capitals above things */
  --fs-small: 0.875rem;     /* 14px — secondary text, hints, badges */
  --fs-body: 1rem;          /* 16px — ordinary text, buttons, inputs */
  --fs-read: 1.125rem;      /* 18px — serif reading text (the serif runs small) */
  --fs-h3: 1.25rem;         /* 20px — names inside a card */
  --fs-h2: 1.5rem;          /* 24px — card and section titles */
  /* clamp(smallest, preferred, largest): grows with the screen width (vw is
     1% of it) but never past either end. */
  --fs-h1: clamp(2rem, 6vw, 2.6rem);
  --fs-display: clamp(2.4rem, 9vw, 3.6rem);  /* the front door's title only */

  /* Letter spacing for small capitals. Wide spacing looks grand on a big
     sign and unreadable on a small label, so it is capped here. */
  --track: 0.12em;

  /* Shape and space. */
  --radius: 10px;           /* corner rounding for cards */
  --radius-sm: 8px;         /* corner rounding for controls */
  --tap: 44px;              /* the smallest comfortable finger target */
  --wrap: 60rem;            /* how wide the reading column may grow (960px) */
  --bar-h: 56px;            /* the height of the top bar (section 3) */
}


/* ── 2. THE PAGE ───────────────────────────────────────────────────────── */

/* "*" means every element. border-box makes a stated width include padding
   and border, so "100 wide" really is 100 wide. */
*, *::before, *::after { box-sizing: border-box; }

/* Phones sometimes enlarge text on their own when turned sideways; this
   keeps the size the page chose. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* The canvas: nearly black with a faint gold glow at the top
   (radial-gradient is a soft circle of light that fades out). min-height
   100vh means "at least one screen tall", so a short page is dark to the
   bottom too. */
body {
  margin: 0; min-height: 100vh;
  background: var(--void);
  background-image: radial-gradient(1100px 560px at 50% -10%, color-mix(in srgb, var(--gold) 10%, transparent), transparent);
  color: var(--parchment);
  font-family: var(--sans); font-size: var(--fs-body); line-height: 1.5;
}

/* The reading column: centred, capped in width, with room at the sides so
   text never touches the edge of a phone. A page that needs more room (a
   wide table) sets --wrap on its own .wrap. (For :where, see the note
   before section 4.) */
:where(.wrap) { max-width: var(--wrap); margin: 0 auto; padding: 24px 16px 80px; }

/* Links: the rune blue, underlined only on hover so a paragraph of them
   stays calm. */
:where(a) { color: var(--rune-bright); text-decoration: none; }
:where(a:hover) { text-decoration: underline; }

/* A visible ring around whatever the keyboard is on (Tab key). Mouse clicks
   don't show it — that is what :focus-visible, rather than :focus, means. */
:where(:focus-visible) { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

/* Both spellings of "hide this", used by page scripts to switch screens.
   !important makes it win over anything else that sets display. */
[hidden], .hidden { display: none !important; }


/* ── 3. THE TOP BAR ────────────────────────────────────────────────────────
   app-auth.js adds a bar across the top of every signed-in page: the Hub
   button on the left, who you are on the right. It used to float over the
   page and sat on top of titles on a phone. Now the page makes room for it:
   app-auth.js marks the document "wg-bar" the moment it loads (before the
   page draws), and the rule below pushes the page down by the bar's height,
   so nothing jumps when the bar appears a moment later. */
html.wg-bar body { padding-top: var(--bar-h); }

/* The bar itself: pinned to the top (position:fixed), full width, and a
   little see-through with a blur behind it (backdrop-filter), so the page
   scrolls under it without clashing. z-index puts it above everything. */
#wg-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  height: var(--bar-h);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 12px;
  background: rgba(6,8,12,0.86);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
/* The Hub button: the one solid gold button on the page, so "home" is
   always the easiest thing to find. */
#wg-hub-btn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 14px;
  font-family: var(--sans); font-size: var(--fs-body); font-weight: 700; letter-spacing: 0.04em;
  color: var(--void); text-decoration: none;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold));
  border: 1px solid var(--gold-bright); border-radius: var(--radius-sm);
}
#wg-hub-btn:hover { text-decoration: none; filter: brightness(1.08); }
/* Who is signed in. margin-left:auto keeps it on the right even when there
   is no Hub button beside it. The ellipsis ("…") trims a very long name. */
#wg-handle-badge {
  margin-left: auto; max-width: 50%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--sans); font-size: var(--fs-small); font-weight: 600;
  color: var(--gold-bright);
}


/* ── WHY THE REST OF THIS FILE IS WRAPPED IN :where( … ) ───────────────────
   When two rules disagree about the same thing, the browser picks the more
   SPECIFIC one: a rule naming a class (".cell") beats one naming only an
   element ("button"), and a rule with extra conditions (":hover") beats one
   without. That is a problem for a shared style: a page's own game tile,
   say a <button class="cell">, would lose its look to the house button rule
   below whenever the house rule happened to be more specific.

   :where( … ) fixes it. Whatever is inside it counts as having NO
   specificity at all, so any rule a page writes for itself wins over the
   house style, every time, without tricks. The house style becomes a
   default, which is exactly what it should be. */


/* ── 4. THE PAGE HEADING ───────────────────────────────────────────────────
   Every page opens the same way, left-aligned:

     SMALL CAPITALS          ← .eyebrow (or h1 .sub): where you are
     The Page Title          ← h1
     A line or two of what   ← p.lede
     this page is for.

   h1 .sub is the small capitals written inside the title, first:
   <h1><span class="sub">Waygate · the bazaar</span>The Bazaar</h1>.
   display:block puts it on its own line over the title. */
:where(.eyebrow, h1 .sub) {
  display: block; margin: 0 0 6px;
  font-family: var(--sans); font-size: var(--fs-label); font-weight: 500;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--gold);
}
:where(h1) {
  margin: 0 0 8px;
  font-family: var(--serif); font-size: var(--fs-h1); font-weight: 600; line-height: 1.1;
  color: var(--gold-bright);
}
:where(.lede) { margin: 0 0 16px; font-size: var(--fs-body); color: var(--ash); max-width: 42rem; }

/* Section headings between cards: small gold capitals. */
:where(h2) {
  margin: 24px 0 10px;
  font-family: var(--sans); font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--gold);
}


/* ── 5. CARDS ──────────────────────────────────────────────────────────────
   A card is a raised panel holding one job (a form, a list, your standing).
   Its title is the serif, larger and warmer than a section heading. */
:where(.card) {
  margin: 0 0 14px; padding: 16px;
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent), var(--obsidian);
  border: 1px solid var(--line); border-radius: var(--radius);
}
/* The last thing in a card never adds space below itself: the card's own
   padding is the gap. (Without this, a card ending in an empty message line
   has a blank strip at the bottom.) */
:where(.card > :last-child) { margin-bottom: 0; }
:where(.card h2) {
  margin: 0 0 10px;
  font-family: var(--serif); font-size: var(--fs-h2); font-weight: 600;
  letter-spacing: normal; text-transform: none; color: var(--gold-bright);
}
:where(.card h3) { margin: 0 0 6px; font-family: var(--serif); font-size: var(--fs-h3); font-weight: 600; }


/* ── 6. FORMS ──────────────────────────────────────────────────────────────
   A .row lays fields side by side and wraps them onto the next line when
   the screen runs out. A .field stacks a label over its box. max-width 100%
   stops a field with a long option in it from pushing past the edge of a
   phone. */
:where(.row) { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
:where(.field) { display: flex; flex-direction: column; gap: 4px; max-width: 100%; }
:where(label) {
  font-size: var(--fs-label); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ash);
}

/* Text boxes and drop-downs. 16px text matters on a phone: an iPhone zooms
   the whole page into any box whose text is smaller, and does not zoom back. */
:where(input, select, textarea, .nameinput) {
  max-width: 100%; min-height: var(--tap); padding: 8px 12px;
  font-family: var(--sans); font-size: var(--fs-body);
  color: var(--parchment); background: var(--well);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
/* Tick boxes and radio dots keep their natural small size. */
:where(input[type="checkbox"], input[type="radio"]) { min-height: 0; padding: 0; }
:where(textarea) { line-height: 1.45; }
:where(input:focus, select:focus, textarea:focus, .nameinput:focus) { outline: none; border-color: var(--gold); }
/* The "type your handle" box used by the older pages. */
:where(.nameinput) { min-width: 14rem; }
:where(.namebox) { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* Buttons. Every page used two looks: the main gold action, and a quiet
   "ghost" for secondary things like Refresh. The class names differed
   (.act / .ghostbtn / .ghost); all of them are styled here the same.
   A link can wear the look too (<a class="act">); inline-flex gives it the
   same height and centring as a real button. Only buttons and links take
   the look from a class: a <div class="act"> is left alone, because some
   pages use that name for the row that HOLDS a card's buttons. */
:where(button, a.act, a.ghost, a.ghostbtn, .ghostbtn) {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--tap); padding: 8px 16px;
  font-family: var(--sans); font-size: var(--fs-body); font-weight: 600; line-height: 1.2;
  color: var(--gold-bright); background: color-mix(in srgb, var(--gold) 14%, transparent);
  border: 1px solid var(--gold); border-radius: var(--radius-sm);
  text-decoration: none; cursor: pointer; transition: background 0.15s;
}
:where(button:hover:not(:disabled), a.act:hover) { background: color-mix(in srgb, var(--gold) 28%, transparent); text-decoration: none; }
:where(button.ghost, a.ghost, .ghostbtn) { color: var(--ash); background: transparent; border-color: var(--line); }
:where(button.ghost:hover:not(:disabled), a.ghost:hover, .ghostbtn:hover:not(:disabled)) { color: var(--parchment); background: rgba(255,255,255,0.04); text-decoration: none; }
:where(button:disabled) { opacity: 0.5; cursor: default; }


/* ── 7. SMALL THINGS ───────────────────────────────────────────────────── */

/* A chip or pill: a small rounded tag of status text. If a long one has to
   wrap onto two lines, it stays inside the screen. */
:where(.chip, .pill, .badge) {
  display: inline-block; max-width: 100%; padding: 3px 10px;
  font-family: var(--sans); font-size: var(--fs-small); letter-spacing: 0.04em;
  color: var(--ash); border: 1px solid var(--line); border-radius: 999px;
}
/* A .bar is a row of chips or buttons. Pages often fill one in later from
   a script; until then (":empty") it takes no room, so it doesn't leave a
   blank gap under the heading. */
:where(.bar) { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 14px; }
:where(.bar:empty) { display: none; }

/* Messages: a quiet helper line, an empty list, and an apology when
   something went wrong (#msg and #apology are the ids pages use for it). */
:where(.hint, .muted, .empty) { font-size: var(--fs-small); color: var(--ash); }
:where(.empty) { font-style: italic; }
:where(.apology, #apology, #msg) { min-height: 1.4em; margin: 6px 0 14px; font-style: italic; color: var(--ember); }

/* Tables: data in rows. The wrapper lets a wide table scroll sideways by
   itself instead of pushing the whole page off the side of a phone. */
:where(.tablewrap) { overflow-x: auto; }
:where(table) { border-collapse: collapse; width: 100%; font-size: var(--fs-small); }
:where(th) {
  text-align: left; padding: 8px; border-bottom: 1px solid var(--line);
  font-size: var(--fs-tiny); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ash); font-weight: 500;
}
:where(td) { padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; }

/* The row of links at the foot of a page. Each link is tall enough to tap. */
:where(.backlink) { display: flex; flex-wrap: wrap; gap: 0 20px; margin-top: 32px; }
:where(.backlink a) {
  display: inline-flex; align-items: center; min-height: var(--tap);
  font-family: var(--sans); font-size: var(--fs-label); letter-spacing: var(--track);
  text-transform: uppercase; color: var(--ash);
}
:where(.backlink a:hover) { color: var(--rune-bright); text-decoration: none; }
