/* ============================================================
   GateIron — base.css: THE CHROME EVERY PAGE SHARES (code review C5, 2026-09-10).

   The palette, the buttons, the header, the footer, the account menu and the accessibility
   helpers - loaded first by every page on the site, marketing and game alike, so a page sheet
   only ADDS. Until today these lived in gateiron.css (the marketing pages) and again, sized
   down and scoped, in siteChrome.css (the games), and a change to the account menu had to be
   made twice. Jeff, 2026-08-24: "the same header and footer should be used everywhere."

   Two densities, one markup: a game page says <body class="gi-compact"> and the header tightens
   (the compact bar Jeff chose on 2026-08-18: translucent, a 28px logo, a 30px avatar) so the
   board keeps its height; everything else is the same rule. Fonts are linked per page.

   No global reset here. gateiron.css zeroes every margin and padding for the marketing pages;
   the games rely on the browser's defaults inside their dialogs, so only the chrome's own
   elements are boxed below.
   ============================================================ */

:root {
  /* ---- paper / surface tones (light → dark) ---- */
  --paper-lightest: #f9f5eb;
  --paper-lighter: #f8f3e8;
  --paper-light: #f6f1e5;
  --paper: #f5efe3;
  --paper-dark: #efe6d4;
  --paper-darker: #e5d6bb;
  --paper-darkest: #ddcaa8;

  --card-bg: #fbf7ee;

  /* ---- ink / text tones (base sits dark; only lighter rungs are needed) ---- */
  --ink: #2a2520;
  --ink-light: #4a443b;
  --ink-lighter: #7a7062;
  --ink-lightest: #aea69a;

  /* ---- clay accent (light → dark) ---- */
  --clay-lightest: #eed8c8;
  --clay-lighter: #e0b59f;
  --clay-light: #cf8c6d;
  --clay: #bb5a31;
  --clay-dark: #9b4623;
  --clay-darker: #74371e;
  --clay-darkest: #542b1a;

  /* ---- pine accent (light → dark) ---- */
  --pine-lightest: #d5d5ca;
  --pine-lighter: #acb0a3;
  --pine-light: #7b8474;
  --pine: #3f4e3b;
  --pine-dark: #2c3829;
  --pine-darker: #272e22;
  --pine-darkest: #22251c;

  /* ---- single-tone roles ---- */
  --sand: #dcc9a6;
  --border-color: rgba(42, 37, 32, 0.13);
  --shadow: 0 1px 2px rgba(42, 37, 32, 0.06), 0 12px 30px -12px rgba(42, 37, 32, 0.18);

  /* ---- swappable cover / about / CTA backgrounds (set the URL to change) ---- */
  --cover-img: url('../image/20231013_MtHoodSunset.jpg');  /* Mt. Hood, ~1600px wide */
  --cta-img: url('../image/BlackDragon_x16.jpg');   /* workshop / printing */
  /* There was a --about-img here naming about-gorge.jpg. No rule ever read it and the file has
     never existed in this repo, so it was three words of documentation for a picture nobody can
     look at. Removed 2026-09-15 (TODO 494). A Gorge photo for the about section is still a fine
     idea: add the file, then add the variable and the rule that uses it, in that order. */
}

/* The chrome boxes its own elements; the page decides for the rest. */
body > header, body > header *, body > footer, body > footer * { box-sizing: border-box; }

.wrap {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 28px;
}

/* ---------------- buttons ---------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  padding: 0.85em 1.5em;
  border-radius: 999px;
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
  border: 1.5px solid transparent;
  cursor: pointer;
}

.btn .arrow { transition: transform 0.18s ease; }

.btn:hover .arrow { transform: translateX(4px); }

.btn-primary {
  background: var(--clay);
  color: #fff;
  box-shadow: 0 8px 22px -8px rgba(155, 70, 35, 0.7);
}

.btn-primary:hover {
  background: var(--clay-dark);
  transform: translateY(-2px);
}

.btn-line {
  background: transparent;
  border-color: var(--border-color);
  color: var(--ink);
}

.btn-line:hover {
  border-color: var(--clay);
  color: var(--clay-dark);
  transform: translateY(-2px);
}

/* IN THE NAV, every button is the same small shape. The hero-sized padding and the primary's
   floating shadow belong to buttons standing in open page space; up in the bar they made the
   Shop button read "relatively big and round, not keeping the form of the other buttons"
   (Jeff, 2026-08-24) and squeezed upright phones. Colour still says which one is primary. */
.nav .btn {
  padding: 0.6em 1.15em;
  font-size: 0.92rem;
}
.nav .btn-primary {
  box-shadow: none;
}
.nav .btn-primary:hover {
  transform: none;
  box-shadow: none;
}

/* ---------------- header ---------------- */
body > header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(245, 239, 227, 0.82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-color);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Wrap rather than hide or overflow - Jeff, 2026-08-24: "Nothing on the bar should be hidden.
     Resized, relocated, wrapped, etc, but not hidden." */
  flex-wrap: wrap;
  row-gap: 8px;
  padding: 14px 28px;
  max-width: 1140px;
  margin: 0 auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  /* NEVER WRAP. Squeezed by the nav's buttons, "GateIron, LLC" used to break across two lines
     for the ~50px above the breakpoint that hides it (Jeff, 2026-08-24: "there is a width where
     it word wraps and gets ugly"). The breakpoint below is set well clear of that point, but a
     breakpoint is a guess about font metrics on one engine and this is a guarantee on all of
     them: the worst case is now merely tight, never broken. */
  white-space: nowrap;
}

.brand .logo {
  height: 40px;
  width: auto;
  flex: 0 0 auto;
  display: block;
}

footer .brand .logo { height: 44px; }

.brand small {
  display: block;
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 500;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-lighter);
  margin-top: 1px;
}

/* Wraps for the same reason .nav does: .nav's own flex-wrap moves this whole block below the
   brand, but cannot help if the buttons together are wider than the screen. Belt to that
   braces - the fallback has to hold on a browser nobody measured. */
.nav-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 8px;
  gap: 12px;
}

/* WHERE THE BRAND TEXT GOES, and the arithmetic behind the number, because a magic breakpoint
   is exactly how the last one ended up 148px too early.

   Measured in the browser at the real nav: the logo is 62px and "GateIron, LLC" is 139px, so the
   brand box is 210px - which is Jeff's own rule of thumb, 2026-08-24: "If 'GateIron, LLC' is
   really about 138 pixels wide, then the hide point needs to be in the ballpark of the button
   being 200 pixels from the edge." Add the buttons and the nav's 56px of padding and the two
   sides touch at 622px signed out, 579px signed in (the difference is the account chip: a
   "Sign in" button against a 36px avatar).

   660 is the worst of those plus a comfortable gap, and it hides the tagline with the name -
   they are one span, and the tagline is the NARROWER line (137px against 139px), so hiding it
   alone freed nothing at all. That was the obsolete rule Jeff caught. */
@media (max-width: 660px) {
  .nav .brand > span { display: none; }
}

@media (max-width: 520px) {
  .nav { padding: 12px 14px; }
  .wrap { padding: 0 20px; }
  /* What an upright phone adds is the buttons giving up whitespace on BOTH axes - Jeff,
     2026-08-24: "It should shrink whitespace in buttons vertically and wrap if it has to."
     Wrapping is .nav's flex-wrap, and it is the last resort rather than the first. */
  .nav .btn { padding: 0.34em 0.7em; font-size: 0.88rem; }
}

/* NOTHING ON THIS BAR IS EVER HIDDEN except the brand text, which Jeff asked for by name. Jeff:
   "Nothing on the bar should be hidden. Resized, relocated, wrapped, etc, but not hidden. There
   is nothing on the header bar that can go away." A navigation link that vanishes is a dead end
   for the person who needed it. */

/* ---------------- footer ---------------- */
body > footer {
  background: var(--ink);
  color: rgba(243, 236, 221, 0.7);
  padding: 54px 0 40px;
  font-size: 0.92rem;
  font-family: 'Hanken Grotesk', sans-serif;
  text-align: left;
}

footer .grid {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 30px;
  flex-wrap: wrap;
}

footer .brand { color: #f3ecdd; }
footer .brand small { color: rgba(243, 236, 221, 0.5); }

footer .links {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
}

footer a {
  color: rgba(243, 236, 221, 0.78);
  text-decoration: none;
  font-weight: 500;
}

footer a:hover { color: var(--clay); }

footer .fine-print {
  margin-top: 30px;
  padding-top: 22px;
  border-top: 1px solid rgba(243, 236, 221, 0.12);
  font-size: 0.82rem;
  color: rgba(243, 236, 221, 0.45);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

/* ---------------- accessibility helpers ---------------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -56px;
  z-index: 200;
  background: var(--clay);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  padding: 0.6em 1.1em;
  border-radius: 0 0 8px 8px;
  transition: top 0.18s ease;
}

.skip-link:focus { top: 0; }

:focus-visible {
  outline: 3px solid var(--clay);
  outline-offset: 2px;
}

main:focus { outline: none; }

/* ---------------- account (header avatar + dropdown menu) ---------------- */

.account-slot {
  display: flex;
  align-items: center;
  min-height: 39px; /* holds the header's height steady while /api/me loads */
}

.account-widget {
  position: relative;
  display: flex;
  align-items: center;
}

.account-avatar {
  display: block;
  width: 39px;  /* ~15% over the 34px original — reads closer in weight to the pill buttons beside it */
  height: 39px;
  border-radius: 50%;
  overflow: hidden;
  border: 1.5px solid var(--border-color);
  padding: 0;
  background: none;
  cursor: pointer;
  transition: border-color 0.18s ease, transform 0.18s ease;
}

.account-avatar:hover,
.account-avatar[aria-expanded="true"] {
  border-color: var(--clay);
  transform: translateY(-2px);
}

.account-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.account-avatar-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pine);
  color: #fff;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 1.05rem;
}

.account-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 230px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 16px;
  z-index: 200;
  text-align: left;
}

.account-menu[hidden] {
  display: none;
}

.account-menu-name {
  display: block;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--ink);
}

.account-menu-email {
  display: block;
  font-size: 0.88rem;
  color: var(--ink-lighter);
  margin-top: 2px;
  word-break: break-all;
}

/* The username, between the name and the address (the fly-down grew on 2026-09-10 - Jeff: "put
   the main info there"). */
.account-menu-user {
  display: block;
  font-family: 'Courier New', Courier, monospace;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--ink);
  margin-top: 2px;
}

.account-menu-divider {
  border: none;
  border-top: 1px solid var(--border-color);
  margin: 12px 0;
}

.account-menu-signout {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0.4em 0;
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 0.96rem;
  font-weight: 600;
  color: var(--clay-dark);
  cursor: pointer;
}

.account-menu-signout:hover {
  text-decoration: underline;
}

/* The admin notification badge on the avatar: word feedback waiting for review. Only ever
   rendered for an admin with an open queue (see /js/adminNotify.js), and it is itself the link. */
.admin-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--clay);
  color: #fff;
  font-family: 'Hanken Grotesk', Arial, Helvetica, sans-serif;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  text-decoration: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}
.admin-badge:hover { background: var(--clay-dark); }

/* ============================================================
   THE COMPACT DENSITY - game pages (<body class="gi-compact">). The same markup, tightened: a
   translucent bar (Jeff, 2026-08-18: the page's own background shows through a ~30% paper wash,
   so the bar reads as an overlay on the section rather than a wall above it; the blur keeps the
   text legible over busy backgrounds), a 28px logo, buttons at the size the old .gi-btn had, a
   30px avatar so the bar keeps its height. Every pixel of the bar's height is a pixel the board
   does not get.

   The bar and the footer claim the page's body margin back with negative margins of exactly
   the page's own value - the page says --page-margin on body - so the game content below keeps
   its spacing untouched. siteChrome.js used to compute this from getComputedStyle on every
   resize; a variable is the same fact stated once.
   ============================================================ */
body.gi-compact > header {
  margin: calc(-1 * var(--page-margin, 0px)) calc(-1 * var(--page-margin, 0px)) 8px;
  z-index: 1000;
  background: rgba(245, 239, 227, 0.30);
  font-family: 'Hanken Grotesk', Arial, Helvetica, sans-serif;
}
body.gi-compact .nav { padding: 7px 16px; gap: 10px; row-gap: 6px; }
body.gi-compact .brand { font-size: 1.02rem; gap: 0.5rem; font-family: 'Fraunces', Georgia, serif; }
body.gi-compact .brand .logo { height: 28px; }
body.gi-compact .brand small { font-size: 0.5rem; }
body.gi-compact .nav-actions { gap: 8px; row-gap: 6px; }
body.gi-compact .nav .btn { padding: 0.38em 0.85em; font-size: 0.8rem; }
body.gi-compact .nav .btn:hover { transform: none; }
body.gi-compact .account-slot { min-height: 30px; }
body.gi-compact .account-avatar { width: 30px; height: 30px; transition: none; }
body.gi-compact .account-avatar:hover,
body.gi-compact .account-avatar[aria-expanded="true"] { transform: none; }
body.gi-compact .account-avatar-fallback { font-size: 0.85rem; }
body.gi-compact .account-menu { min-width: 210px; padding: 14px; border-radius: 12px; z-index: 1100; }
body.gi-compact .account-menu-name { font-size: 0.95rem; }
body.gi-compact .account-menu-email { font-size: 0.8rem; }
body.gi-compact .account-menu-user { font-size: 0.85rem; }
body.gi-compact .account-menu-divider { margin: 10px 0; }
body.gi-compact .account-menu-signout { padding: 0.3em 0; font-size: 0.88rem; }

/* The footer under a game: clears Hangman's floated canvas (the wide layout floats #divCanvas
   left, and a block that follows a float flows up beside it unless it clears - the footer once
   sat across the bottom of the drawing), and the gap above it is PADDING, because a cleared
   block's top margin is swallowed into the clearance whenever the float runs past the content
   before it. The game sizes itself from the window, so a footer below the fold costs it
   nothing - the player scrolls to it (Jeff: "Tall is fine if the user has to scroll to see it"). */
body.gi-compact > footer {
  clear: both;
  margin: 0 calc(-1 * var(--page-margin, 0px)) calc(-1 * var(--page-margin, 0px));
  padding: 28px 0 24px;
  font-size: 0.85rem;
}
body.gi-compact > footer::before { content: ''; display: block; height: 4vh; min-height: 18px; margin-top: -28px; }
body.gi-compact footer .brand .logo { height: 32px; }
body.gi-compact footer .fine-print { margin-top: 16px; padding-top: 12px; font-size: 0.74rem; }

/* Buttons give up whitespace - BOTH ways - before anything has to disappear (Jeff, 2026-08-24:
   "shrink the left-right whitespace in the buttons", then "It should shrink whitespace in buttons
   vertically and wrap if it has to"). The brand shrinks too, rather than being first against the
   wall: a smaller face, a smaller logo, tighter gaps buy back more than the Contact button costs,
   so the name survives on a phone. */
@media (max-width: 480px) {
  body.gi-compact .nav .btn { padding: 0.28em 0.55em; }
  body.gi-compact .nav { padding: 5px 12px; gap: 6px; }
  body.gi-compact .brand { font-size: 0.88rem; gap: 0.35rem; }
  body.gi-compact .brand .logo { height: 24px; }
  body.gi-compact .brand small { font-size: 0.44rem; letter-spacing: 0.12em; }
}
/* Only when the shrinking above has run out of room, and sized for the SIGNED-IN bar: it needs
   387px, so 380 keeps the name on a 390-430px phone (Jeff's, and most); below that it goes. */
@media (max-width: 380px) {
  body.gi-compact .nav .brand > span { display: none; }
}

/* THE BOOLEAN SWITCH, site-wide (2026-09-11). Jeff: "All checkboxes on the site (unless there is
   a reason not to) should use a boolean mini slider control." A label with a hidden checkbox and
   a track: <label class="class-switch"><input type="checkbox"><span class="class-switchTrack"
   aria-hidden="true"></span> Words</label>. Born on Manage Class as the Advanced toggle (2026-09-09)
   and moved here from profile.css so every page has it - the game's dialogs included. */
.class-switch { display: inline-flex; align-items: center; gap: 0.4em; cursor: pointer; user-select: none; white-space: nowrap; }
.class-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.class-switchTrack {
    position: relative; display: inline-block; flex: none; width: 2.1em; height: 1.15em; border-radius: 1em;
    background: #cfc9bd; transition: background 0.15s;
}
.class-switchTrack::after {
    content: ""; position: absolute; top: 0.12em; left: 0.12em; width: 0.9em; height: 0.9em;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); transition: left 0.15s;
}
.class-switch input:checked + .class-switchTrack { background: #4A6B3D; }
.class-switch input:checked + .class-switchTrack::after { left: 1.07em; }
.class-switch input:focus-visible + .class-switchTrack { outline: 2px solid #9a7d00; outline-offset: 2px; }
.class-switch input:disabled + .class-switchTrack { opacity: 0.45; }
.class-switch-off { opacity: 0.45; cursor: default; }

/* The footer settles at the bottom of the window when the page is short, and follows the content
   down when it is long (Jeff, 2026-09-20). */
body { min-height: 100dvh; display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; }
