/* Gunman Airsoft — public stylesheet.

   Linked after public/assets/theme.css whenever `theme.active = 'gunman'`.
   core-foundation.css is first and unconditional, core's public sheet follows
   it, and this file is third — so the resets, the design tokens, the protective
   notices and the whole of core's public design language are already in the
   document before the first rule here, and everything here outranks them at
   equal specificity.

   ## Why this file no longer opens with an @import

   It used to. A theme's sheet replaced core's rather than joining it, and core's
   public sheet is not only the marketing pages a theme owns — it is also every
   transactional public screen: the booking flow, the checkout outcomes, the
   player account, the ticket pages, gift cards, waiver signing, the login and
   registration forms, the public error pages. Those are core-component and
   core-behavior templates in docs/theme-contract/view-ownership.json; a theme
   may not touch them, and there are 149 of them against the 15 it may own. A
   theme that shipped only its own rules would leave every one of them unstyled,
   which is a broken site rather than a differently-styled one. So this file
   opened with `@import url("/assets/theme.css")`, same-origin, the one way to
   reach a second sheet from inside a stylesheet under `style-src 'self'`.

   That import had no cache version and could not be given one: a stylesheet is
   bytes, there is no build step to rewrite the URL, and this tree denies
   execution. Every `<link>` views/layout.php writes is keyed on its file's
   modification time; this was the one URL in a Gunman document that never
   changed when its contents did, against a host serving it
   `public, max-age=604800`. The booking summary's totals lost their padding and
   "Due today" reverted to footnote type for returning players for up to a week
   after those rules were added to core's sheet.

   views/layout.php now links core's public sheet itself, versioned like the
   other three, and the import is gone with the problem it caused. The cascade is
   unchanged — the import was the first rule here, so core's rules arrived before
   this file's then and arrive before it now.

   The honest limitation is still worth recording: Gunman's pages and core's
   transactional pages are styled by two authors, and the tokens are the only
   thing holding them together. The fix for that is for the sheet split to grow a
   further entry point — a public *component* sheet a theme always gets, beside
   the marketing sheet it replaces — which is a core change and not a theme's to
   make. Linking core's sheet is a step toward it, not a substitute for it:
   layout.php is now the one place deciding what a themed document loads.

   ## Contrast

   Every foreground and background this file pairs is computed rather than
   eyeballed, and asserted in tests/checks/gunman-theme.php with the ratio in
   the message. `#1e3b1c` and `#3f5c3d` are Gunman's brand greens and are used
   only in roles where they pass: `#3f5c3d` is 6.76:1 on the paper ground and
   7.47:1 on white, so it carries secondary text; it is never put on the forest
   ground, where it would be 1.6:1.

   Four rules from core-foundation.css are restated below, and the four are not
   all the same kind of change. Two are repairs the token overrides make
   necessary: the focus ring inside a dark band would be `var(--signal)` on the
   brand forest at 1.66:1, and the staff return tab's arrow would be the same
   colour on `var(--ink)` at 2.41:1 — both under the 3:1 a non-text indicator
   needs. Two are strengthenings of rules that already pass: the focus ring on
   the paper ground is 6.76:1 as inherited and is taken to forest at 11.18:1, and
   the skip link is 7.47:1 as inherited and is taken to 12.37:1. Each says which
   it is where it sits, because a comment that called a strengthening a repair
   would be a number nobody could check.

   Two rules from core's public sheet are repaired the same way (Gunman 1.6.1):
   the primary button and the booking summary's event code, whose `var(--ink)`
   text is 2.41:1 on the mid green once `--signal` is Gunman's, and two labels
   core sets in `var(--signal)` on the booking page's dark surfaces. */

/* ---------------------------------------------------------------------------
   Tokens

   Overriding core's `:root` rather than declaring a parallel palette, because
   the 147 templates this theme does not own read these names and nothing else.
   Values an operator sets on the design-token screen arrive in
   /assets/appearance.css, which views/layout.php links after this sheet, so an
   operator still outranks the theme — which is the right way round.

   The ground is the clearest single difference from Forward Element: theirs is
   warm sand, #d8d1bf. Gunman's is a cool off-white with the green pulled
   through it, so the brand greens read as structure on it rather than as a
   second warm tone beside it.
   --------------------------------------------------------------------------- */

:root {
    /* Core token names, revalued. */
    --ink: #14180f;
    --ink-2: #1e3b1c;
    --ink-3: #2b3f28;
    --paper: #f2f4f1;
    --paper-2: #e4e8e2;
    --paper-3: #cfd6cc;
    --muted: #4a5f47;
    --olive: #1e3b1c;
    --olive-light: #3f5c3d;
    --signal: #3f5c3d;
    --signal-dark: #1e3b1c;
    --tan: #6b7f68;
    --line: rgb(30 59 28 / 22%);
    --shell: min(1320px, calc(100vw - 56px));

    /* Typography. Both stacks are self-hosted-free and deliberately unlike
       core's `"Arial Narrow", "Roboto Condensed"` condensed sans: a monospace
       display face because this site's spine is a timetable, and every date,
       place count and price in it is data that should line up in a column; and a
       neo-grotesque body face rather than system-ui, so the body metric differs
       too. fonts are `font-src 'self'` here and there is no font file to ship,
       so a system stack is the choice the content security policy leaves. */
    --display: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --body: "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;

    /* Gunman's own names, for the roles core has no token for. Literal values
       rather than `var(--paper)` indirection, so that an operator revaluing a
       core token cannot silently move a pair this theme has proved. */
    --gm-paper: #f2f4f1;
    --gm-panel: #e4e8e2;
    --gm-band: #eaeee8;
    --gm-white: #ffffff;
    --gm-ink: #14180f;
    --gm-muted: #4a5f47;
    --gm-forest: #1e3b1c;
    --gm-mid: #3f5c3d;
    --gm-rule: #6b7f68;
    --gm-hairline: rgb(30 59 28 / 20%);
    --gm-on-dark: #f2f4f1;
    --gm-on-dark-dim: #c9d3c6;
    --gm-on-dark-rule: rgb(242 244 241 / 26%);
    --gm-focus: #1e3b1c;
    --gm-focus-dark: #c9d3c6;
    /* The warning red: a field error, a strict dress code, a paused team, and
       a full ticket or day. 8.26:1 on white, 6.67:1 on the panel. */
    --gm-warning: #8c2f1f;
    --gm-shell: min(1320px, calc(100vw - 56px));
}

/* ---------------------------------------------------------------------------
   Restated foundation rules

   Two repairs and two strengthenings, marked as such. The repairs are the two
   places where changing the tokens above and leaving the rule alone would put an
   indicator under its threshold.
   --------------------------------------------------------------------------- */

/* Strengthening. core-foundation.css draws the ring in `var(--signal)`, which is
   Gunman's mid green at 6.76:1 on the paper ground — already over the 3:1 a focus
   indicator needs. Forest is 11.18:1, and a ring should not be the weakest thing
   on the page. */
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--gm-focus);
    outline-offset: 3px;
}

/* Repair. Inside a dark band the inherited ring is `var(--signal)` on the brand
   forest: 1.66:1, which is no indicator at all. This one is 8.02:1.

   The list is exactly the dark surfaces. The header itself is not one of them —
   it is a paper deck, because the mark sits in it — so a ring there keeps the
   light value above, and putting `.gm-header` in this list would have made the
   nav's ring 1.31:1 on paper.

   `summary` is in the rail's list because the rail's disclosure is one. It is
   not a `button`, so `:is(a, button)` walked straight past the only control in
   the band and left the one element a keyboard user has to find there wearing
   the 1.66:1 ring. */
.gm-next :is(a, button, input, select, textarea):focus-visible,
.gm-cta :is(a, button, input, select, textarea):focus-visible,
.gm-footer :is(a, button, input, select, textarea):focus-visible,
.gm-site-rail :is(a, button, summary):focus-visible,
.gm-social-bar :is(a, button):focus-visible {
    outline-color: var(--gm-focus-dark);
}

/* Strengthening. `.skip-link` is white on `var(--signal)` in the foundation:
   7.47:1, which passes — but it sits over whatever is beneath it, and forest
   reads as a deliberate object rather than a tint. 12.37:1. */
.skip-link {
    color: var(--gm-white);
    background: var(--gm-forest);
}

/* Repair. The staff return tab is foundation furniture drawn on a public
   document, and its arrow is `var(--signal)` on `var(--ink)` — 2.41:1 once both
   are Gunman's. This one is 11.67:1. */
.staff-return-tab-icon {
    color: var(--gm-on-dark-dim);
}

/* Repair, from core's public sheet rather than the foundation. Core draws its
   primary button and the booking summary's event code as `var(--ink)` on
   `var(--signal)`: right on core's sand, 2.41:1 on Gunman's mid green, and the
   button's hover fill, `var(--signal-dark)`, is the forest at 1.45:1. These
   are the main action on every page core still renders under this theme — the
   error pages, the booking flow, sign-in, tickets, gift cards. The fills stay
   the brand greens and only the text changes, to the white Gunman's own
   buttons use: 7.47:1 at rest, 12.37:1 hovered. Focus keeps the resting
   colours and takes the forest ring above, 9.98:1 on the error page's card. */
.button-primary,
.event-code {
    color: var(--gm-white);
}

/* Repair, the same pairing the other way round. Core sets two labels on the
   booking page's dark surfaces in `var(--signal)`: the summary's "Due today"
   and its amount on `var(--ink)`, 2.41:1, and a team's "Required:" uniform
   label on its #242a22 panel, 1.97:1. Gunman's pale on-dark green is 11.67:1
   and 9.53:1; the amount still differs from the white ticket price above it. */
.summary-pay-now,
.team-camo-rule > b {
    color: var(--gm-on-dark-dim);
}

/* ---------------------------------------------------------------------------
   Base
   --------------------------------------------------------------------------- */

body {
    color: var(--gm-ink);
    background: var(--gm-paper);
    font-family: var(--body);
    font-size: 16px;
    line-height: 1.6;
}

.gm-shell {
    width: var(--gm-shell);
    margin-inline: auto;
}

h1,
h2,
h3 {
    margin: 0;
    font-family: var(--display);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.04;
    text-wrap: balance;
}

h1 {
    font-size: clamp(34px, 5.2vw, 62px);
}

h2 {
    font-size: clamp(26px, 3.4vw, 40px);
}

h3 {
    font-size: clamp(16px, 1.5vw, 19px);
    letter-spacing: -0.01em;
}

/* The one recurring typographic device: a small uppercase monospace label with
   a notched block before it, echoing the hexagonal mark. Forward Element's
   equivalent is a numbered "01 / Intent" section index in a condensed sans. */
.gm-label {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 14px;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1;
    text-transform: uppercase;
}

.gm-label::before {
    width: 10px;
    height: 11px;
    background: currentColor;
    clip-path: polygon(50% 0, 100% 27%, 100% 73%, 50% 100%, 0 73%, 0 27%);
    content: "";
    flex: 0 0 auto;
}

.gm-section-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    gap: 22px 40px;
    align-items: end;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--gm-rule);
    margin-bottom: 0;
}

/* Two children rather than three, for a section head that carries a heading and
   its action and no explanatory note between them. Without it the button lands
   in the note's column and the `auto` track sits empty on the right, so the
   action reads as centred. Declared immediately after the rule it narrows so
   that the single-column rule in the narrow-viewport band below, which carries
   the same specificity, still wins on a phone. */
.gm-section-head-tight {
    grid-template-columns: minmax(0, 1fr) auto;
}

.gm-section-note {
    max-width: 52ch;
    margin: 0;
    color: var(--gm-muted);
    font-size: 14px;
    line-height: 1.6;
}

.gm-masthead-note {
    max-width: 62ch;
    margin: 18px 0 0;
    color: var(--gm-muted);
    font-size: clamp(15px, 1.5vw, 17px);
}

.gm-empty {
    margin: 0;
    padding: 34px 0;
    border-bottom: 1px solid var(--gm-hairline);
    color: var(--gm-muted);
    font-family: var(--display);
    font-size: 14px;
}

/* ---------------------------------------------------------------------------
   Buttons and links

   Square, hairline-bordered, monospace, uppercase. No radius anywhere in this
   theme and no drop shadow: Forward Element's buttons are pill-adjacent rounded
   blocks with a shadow on hover, and the difference is meant to be visible at a
   glance.
   --------------------------------------------------------------------------- */

.gm-button {
    display: inline-flex;
    min-height: 50px;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 22px;
    border: 1px solid transparent;
    color: var(--gm-white);
    background: var(--gm-forest);
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.1em;
    line-height: 1;
    text-align: center;
    text-transform: uppercase;
    transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
    cursor: pointer;
}

.gm-button-primary:hover {
    background: var(--gm-mid);
}

.gm-button-outline {
    border-color: var(--gm-rule);
    color: var(--gm-forest);
    background: transparent;
}

.gm-button-outline:hover {
    border-color: var(--gm-forest);
    background: var(--gm-panel);
}

.gm-button-light {
    color: var(--gm-forest);
    background: var(--gm-paper);
}

.gm-button-light:hover {
    background: var(--gm-on-dark-dim);
}

.gm-button-ghost {
    border-color: var(--gm-on-dark-rule);
    color: var(--gm-on-dark);
    background: transparent;
}

.gm-button-ghost:hover {
    border-color: var(--gm-on-dark);
}

.gm-button-disabled {
    border-color: var(--gm-rule);
    color: var(--gm-muted);
    background: var(--gm-panel);
    cursor: not-allowed;
}

.gm-button-full {
    width: 100%;
}

.gm-text-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0;
    border: 0;
    color: var(--gm-forest);
    background: none;
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-transform: uppercase;
    text-underline-offset: 4px;
    cursor: pointer;
}

.gm-text-link:hover {
    color: var(--gm-mid);
}

/* ---------------------------------------------------------------------------
   Header

   In flow, and three decks where Forward Element's is one: an optional social
   strip, the masthead, then the site rail. Theirs is `position: absolute` and
   transparent, floating over a photographic hero. This one cannot float — the
   rail beneath it is content, and a five-site club's visitor should see the five
   names before they scroll.

   The masthead deck is paper rather than dark, which is the mark's doing: two of
   its thirteen shapes are filled `#1e3b1c` and `#3f5c3d`, so on the brand ground
   the artwork half disappears. Light masthead, near-black rail, forest band
   beneath it — three steps down rather than one flat dark bar.
   --------------------------------------------------------------------------- */

.gm-header {
    position: relative;
    z-index: 50;
    color: var(--gm-ink);
    background: var(--gm-paper);
}

.gm-social-bar {
    color: var(--gm-on-dark);
    background: var(--gm-ink);
}

/* Sized from the variables `body.has-social-bar` carries, so an operator's
   small/medium/large choice on the social-bar screen still reaches this theme.
   The fallbacks are core's own small values, for the case where the bar renders
   without that body class. */
.gm-social-bar-inner {
    display: flex;
    min-height: var(--social-bar-height, 34px);
    align-items: center;
    gap: 14px;
}

.gm-social-bar-inner > span {
    color: var(--gm-on-dark-dim);
    font-family: var(--display);
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gm-social-links {
    display: flex;
    gap: 6px;
}

/* The containing block for the mobile menu panel, which is positioned against
   this deck rather than against the whole header so that it opens below the
   masthead and over the site rail. */
.gm-header-bar {
    position: relative;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-header-inner {
    display: flex;
    min-height: 82px;
    align-items: center;
    gap: 20px;
}

.gm-brand {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-right: auto;
}

/* Referenced, never inlined: the file colours its thirteen shapes from a
   <style> block and the policy here is `style-src 'self'` with no
   'unsafe-inline'. Intrinsic width and height are on the element because the
   file carries neither. */
.gm-brand-mark {
    width: 48px;
    height: auto;
    flex: 0 0 auto;
}

/* The mark, wherever it lands on a dark surface. A tile rather than a recolour:
   the artwork is the client's and is not this theme's to repaint. */
.gm-mark-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    background: var(--gm-paper);
}

.gm-mark-tile img {
    width: 100%;
    height: auto;
}

.gm-brand-name {
    font-family: var(--display);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.12em;
    line-height: 1.1;
    text-transform: uppercase;
}

.gm-nav {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Written at (0,1,1), the same specificity core's `.site-nav a` has, and later
   in the document, so these win without a specificity fight. Every property
   core's rule sets is set here, including the ones this design does not want —
   see the reflow band at the bottom for why that matters. */
.gm-nav a {
    display: inline-flex;
    min-height: 44px;
    align-items: center;
    padding: 8px 12px;
    border-bottom: 2px solid transparent;
    color: var(--gm-ink);
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    opacity: 1;
    text-transform: uppercase;
}

.gm-nav a:hover {
    border-bottom-color: var(--gm-forest);
}

/* Core draws a sliding underline on `.site-nav a::after` in `var(--signal)`.
   This theme's nav marks itself with a border on the element instead, and two
   indicators for one state is one too many. */
.gm-nav a::after {
    content: none;
}

.gm-nav-account {
    margin-left: 10px;
    border: 1px solid var(--gm-rule);
}

.gm-nav-account:hover {
    border-color: var(--gm-forest);
}

.gm-nav-toggle {
    display: none;
    width: 46px;
    height: 46px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0;
    border: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: none;
    cursor: pointer;
}

.gm-nav-toggle > span:not(.sr-only) {
    display: block;
    width: 20px;
    height: 2px;
    margin: 0;
    background: currentColor;
}

/* The rail. The information-architecture signature of this theme: the
   operator's place names on every page, in the chrome.

   It used to be five short labels a file in this theme package chose, so its
   width was known when these rules were written. It reads the `locations` rows
   now, and a name on a row is the operator's: "Gunman Eversley Alpha
   (Hampshire)" is what the database holds, because a site is named once for
   the postal address, the insurance schedule and the public page, and that one
   name has to serve all three. Nothing about a rail entitles it to a short
   name, and shortening one here — dropping a leading brand word, cutting a
   trailing county — would be this stylesheet editing the operator's own copy
   on a guess that holds for five names and fails on the sixth.

   So the rail takes whatever it is given. Every rule below exists because some
   count and some length has to be composed for, and none of them is tuned to
   the five names this customer happens to have.

   Above core's 820px menu band these rules are the whole rail and it is one
   line. Inside the band it becomes a disclosure, which is the third answer
   this band has had and is explained where those rules are, at the bottom of
   this sheet. Nothing here is conditional on that: the disclosure is switched
   on by the band and is off everywhere else, so the desktop rail is composed
   by exactly the rules it was composed by before there was one. */
.gm-site-rail {
    color: var(--gm-on-dark);
    background: var(--gm-ink);
}

/* Off above the menu band, and off with no stylesheet at all in the sense that
   matters: a document rendering with none of this would show the summary and
   the list together, which is a heading over a list of sites and is readable.
   Switched on in the band at the bottom of this sheet. */
.gm-site-rail-disclosure {
    display: none;
}

/* One line, above the menu band. The rail wrapped when the names outgrew it,
   which put "OUR SITES" on a row of its own above the sites it labels and read
   as two bands of chrome rather than one strip. A roster is a strip: it stays
   on its line and the line scrolls when it runs out of room. */
.gm-site-rail-inner {
    display: flex;
    min-height: 46px;
    align-items: center;
    gap: 0 20px;
    flex-wrap: nowrap;
}

/* The rail keeps the shell's left edge, so the label lines up with the
   wordmark above it, and then runs to the right edge of the window instead of
   stopping at the shell's right margin. The band is already full-bleed; this
   lets the roster use the width the band occupies. It buys back the margin the
   shell would have taken -- 60px at 1440 -- which is the difference between
   Gunman's five names fitting and the last one being cut in half. */
.gm-site-rail .gm-site-rail-inner {
    width: auto;
    max-width: none;
    margin-inline: 0;
    padding-inline: max(28px, calc((100% - var(--gm-shell)) / 2)) 0;
}

/* Given a rail link's height rather than left as a 10px line box. When the
   names beside it are too wide to sit on one line the label takes a flex line
   of its own, and a line as tall as its own text put the label hard against
   the header above it — which is what shipped: on the live site "OUR SITES"
   read as clipped against the white bar, and it was not clipped, it was a
   10px line with nothing to centre it in. At 44px it is centred in its line at
   any count, and on the one-line case it changes nothing, because it was
   already being centred against 44px links. */
.gm-site-rail-label {
    display: inline-flex;
    /* Never squeezed and never carried onto a row of its own. */
    flex: 0 0 auto;
    min-height: 44px;
    align-items: center;
    color: var(--gm-on-dark-dim);
    font-family: var(--display);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.gm-site-rail-list {
    display: flex;
    gap: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    /* The affordance. A hairline in the rail's own rule colour says there is
       more to the right; without it a reader who is not already swiping has no
       way to know the roster continues. */
    scrollbar-width: thin;
    scrollbar-color: var(--gm-on-dark-rule) transparent;
    /* The 1px that `.gm-site-rail-list li` takes back below, so that the first
       name on every row starts on the shell's left edge rather than one pixel
       outside it. */
    margin: 0 0 0 1px;
    padding: 0;
    list-style: none;
    /* A flex item will not shrink below its content by default, and one long
       name is wider than the shell. Without this the rail pushed the document
       wider than the viewport and the whole page scrolled sideways — the nav
       toggle included. */
    min-width: 0;
}

/* Hairlines on both sides of every name, overlapped a pixel so that two
   neighbours still share one rule. The rail used to put a border on the left
   of each name and on the right of the last one, which draws correctly on one
   line and only on one line: wrap it and the last name on every row but the
   final one ends in mid-air with nothing closing it. Bordering both sides
   closes every row wherever it happens to break. */
.gm-site-rail-list li {
    margin-left: -1px;
    /* Allowed to give way, so that a name wider than the strip breaks inside
       its own box instead of carrying the document off the side of the screen
       — which is what it did on a phone, taking the navigation toggle with it.

       Flex only calls this in when the line is genuinely over-full, so a rail
       with one site in it is not squeezed by it. `max-width: 100%` was the
       other way to write this and is the wrong one: the percentage is resolved
       against a width the flex layout has not settled yet, and Chrome answers
       it by breaking "Forward Element Main Site" over two lines with the whole
       shell free beside it. */
    flex: 0 0 auto;
    min-width: auto;
}

.gm-site-rail-list a {
    display: inline-flex;
    white-space: nowrap;
    min-height: 44px;
    align-items: center;
    padding: 6px 11px;
    border-inline: 1px solid var(--gm-on-dark-rule);
    color: var(--gm-on-dark);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.04em;
}

.gm-site-rail-list a:hover {
    background: var(--gm-forest);
}

.gm-header-minimal .gm-header-inner {
    min-height: 70px;
}

/* ---------------------------------------------------------------------------
   The next game, and the page mastheads
   --------------------------------------------------------------------------- */

.gm-next {
    color: var(--gm-on-dark);
    background: var(--gm-forest);
}

.gm-next-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 40px;
    align-items: center;
    padding: clamp(44px, 6vw, 84px) 0;
}

.gm-next .gm-label {
    color: var(--gm-on-dark-dim);
}

.gm-next-date {
    margin: 0 0 14px;
    font-family: var(--display);
    font-size: clamp(15px, 1.8vw, 20px);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.gm-next-where {
    display: flex;
    gap: 0;
    flex-wrap: wrap;
    margin: 18px 0 0;
}

.gm-next-where span {
    padding: 6px 14px;
    border: 1px solid var(--gm-on-dark-rule);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-next-where span + span {
    border-left: 0;
}

.gm-next-lead {
    max-width: 54ch;
    margin: 18px 0 0;
    color: var(--gm-on-dark-dim);
}

/* The operator's own line, from site_branding_settings.public_tagline. It
   replaces a dashed `[PLACEHOLDER]` box that told the operator to replace it
   from a staff panel that had no such control, so it is styled as prose now
   that it is real copy rather than as a flagged gap. No empty-state rule is
   needed: the template emits no element at all when the field is unset, so
   there is nothing here to hide. `--gm-on-dark-dim` on `--gm-forest` is the
   same pairing `.gm-next-lead` uses and is measured in the contrast table. */
.gm-next-tagline {
    max-width: 56ch;
    margin: 18px 0 0;
    color: var(--gm-on-dark-dim);
    font-family: var(--display);
    font-size: clamp(14px, 1.3vw, 16px);
    line-height: 1.5;
}

.gm-next-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 28px;
}

.gm-next-mark {
    width: clamp(132px, 16vw, 208px);
    flex: 0 0 auto;
}

.gm-masthead {
    padding: clamp(40px, 5vw, 76px) 0 clamp(30px, 3.5vw, 46px);
    border-bottom: 1px solid var(--gm-rule);
}

.gm-back {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-bottom: 6px;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.gm-back:hover {
    color: var(--gm-forest);
}

/* ---------------------------------------------------------------------------
   The schedule

   The component this theme is recognisable by. A date stamp, then the game,
   then the price and the places. Full width, hairline separated, no image.
   --------------------------------------------------------------------------- */

.gm-schedule,
.gm-sites,
.gm-types,
.gm-steps,
.gm-board,
.gm-rules,
.gm-legal,
.gm-site-detail,
.gm-limits,
.gm-facilities,
.gm-team-index,
.gm-team-about,
.gm-command,
.gm-dress,
.gm-about,
.gm-tools,
.gm-game-detail {
    padding: clamp(44px, 5.5vw, 84px) 0;
}

.gm-game-list {
    display: block;
}

.gm-game {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) 190px;
    gap: 0 28px;
    align-items: start;
    padding: 26px 0;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-game:hover {
    background: var(--gm-band);
    box-shadow: -14px 0 0 var(--gm-band), 14px 0 0 var(--gm-band);
}

.gm-game-stamp {
    display: grid;
    justify-items: center;
    gap: 2px;
    padding: 12px 6px 14px;
    color: var(--gm-on-dark);
    background: var(--gm-forest);
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%);
    font-family: var(--display);
}

.gm-game-stamp-weekday {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gm-on-dark-dim);
}

.gm-game-stamp-day {
    font-size: 34px;
    font-weight: 700;
    line-height: 1;
}

.gm-game-stamp-month {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.gm-game-where {
    display: flex;
    gap: 6px 10px;
    flex-wrap: wrap;
    margin: 0 0 10px;
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.gm-game-type {
    color: var(--gm-white);
    background: var(--gm-mid);
    padding: 3px 8px;
}

.gm-game-site {
    color: var(--gm-forest);
    border: 1px solid var(--gm-rule);
    padding: 2px 8px;
}

.gm-game-terrain {
    align-self: center;
    color: var(--gm-muted);
}

.gm-game-title {
    margin: 0 0 8px;
    font-size: clamp(19px, 2vw, 25px);
}

.gm-game-title a:hover {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
}

.gm-game-summary {
    max-width: 62ch;
    margin: 0;
    color: var(--gm-muted);
    font-size: 14px;
}

.gm-game-when {
    margin: 10px 0 0;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-game-book {
    display: grid;
    gap: 6px;
    justify-items: end;
    text-align: right;
}

.gm-game-price {
    font-family: var(--display);
    font-size: 21px;
    font-weight: 700;
}

.gm-game-places {
    color: var(--gm-muted);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-game-book .gm-button {
    margin-top: 6px;
    min-width: 128px;
}

/* ---------------------------------------------------------------------------
   Sites
   --------------------------------------------------------------------------- */

.gm-sites {
    background: var(--gm-panel);
}

.gm-site-list {
    display: grid;
    /* 240 rather than 210, which is a cell wide enough for a name an operator
       wrote for a postal address. At the 1320px shell the floor decides how
       many tracks `auto-fit` makes: 210 makes six of 220, and "Gunman Anzio
       (Northamptonshire)" in 220 is four wrapped lines. 240 makes five of 264,
       which is exactly what five sites already got — the roster this customer
       has is unchanged by it — and it is what six or nine now get as well,
       over as many rows as they need. */
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--gm-rule);
    /* On the grid rather than on its first cell, which is the same correction
       the rail needed and for the same reason. `.gm-site:first-child` closes
       the left of the grid only while the grid is one row: five sites at this
       width, which is what it was written against. Six sites, or five on a
       narrower window, start a second row whose first cell then opens on
       nothing. The grid's own edge is an edge at every row. */
    border-left: 1px solid var(--gm-rule);
}

.gm-site {
    border-bottom: 1px solid var(--gm-rule);
    border-right: 1px solid var(--gm-rule);
}

.gm-site a {
    display: grid;
    /* `minmax(0, 1fr)` for the name, not `1fr`. A `1fr` track will not go below
       its own min-content, so a cell holding "Gunman Anzio (Northamptonshire)"
       pushed its arrow out through the right-hand border and over the cell
       beside it. The name gives way instead. */
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 12px;
    align-items: baseline;
    min-height: 92px;
    align-content: center;
    padding: 20px 18px;
}

.gm-site a:hover {
    background: var(--gm-white);
}

.gm-site-number {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.1em;
}

.gm-site-name {
    font-family: var(--display);
    font-size: clamp(15px, 1.5vw, 19px);
    font-weight: 700;
    letter-spacing: -0.01em;
    /* A name is broken between words wherever it can be, and inside one when it
       cannot: a single word wider than the cell would otherwise draw straight
       through the border. `anywhere` rather than `break-word` because only
       `anywhere` lets the track shrink to match. */
    overflow-wrap: anywhere;
}

.gm-site-go {
    color: var(--gm-mid);
    font-family: var(--display);
}

/* The sites index: rows, because each one has a summary and a count. */
.gm-sites-index {
    background: none;
}

.gm-site-rows {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--gm-rule);
}

.gm-site-row {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr) 210px;
    gap: 0 26px;
    align-items: start;
    padding: 28px 0;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-site-row-number {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
}

.gm-site-row-body h2 {
    margin: 0 0 10px;
    font-size: clamp(21px, 2.2vw, 28px);
}

.gm-site-row-body h2 a:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.gm-site-row-summary {
    max-width: 62ch;
    margin: 0;
    color: var(--gm-ink);
    font-size: 15px;
}

.gm-site-row-terrain {
    max-width: 62ch;
    margin: 8px 0 0;
    color: var(--gm-muted);
    font-size: 14px;
}

.gm-site-row-actions {
    display: grid;
    gap: 8px;
    justify-items: stretch;
}

.gm-site-row-count {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

/* ---------------------------------------------------------------------------
   Game types, booking steps, closing band
   --------------------------------------------------------------------------- */

.gm-types-inner {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: 34px 48px;
    align-items: center;
}

.gm-type-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* A column rather than a row, because a tile with no dates on the board carries
   a second line under its name. `justify-content: flex-end` keeps every tile's
   name on the same baseline whether or not that line is there, which is what
   `align-items: flex-end` did while the tile held one child. */
.gm-type-list a {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 7px;
    min-height: 118px;
    padding: 18px;
    border: 1px solid var(--gm-rule);
    font-family: var(--display);
    font-size: clamp(17px, 2vw, 23px);
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* Inherited colour, not a token of its own: the tile inverts to white on forest
   on hover, and a note fixed to `--gm-muted` would be unreadable on it. */
.gm-type-note {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: inherit;
    opacity: 0.66;
}

.gm-type-list li + li a {
    border-left: 0;
}

.gm-type-list a:hover {
    color: var(--gm-white);
    background: var(--gm-forest);
    border-color: var(--gm-forest);
}

/* Panel, so the homepage alternates paper and panel down its length — schedule,
   sites, game types, steps — rather than running one flat ground from the
   forest band to the closing one. */
.gm-steps {
    background: var(--gm-panel);
}

.gm-step-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.gm-step-list > li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 16px;
    padding: 28px 24px 30px 0;
    border-top: 1px solid var(--gm-hairline);
}

.gm-step-number {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.14em;
}

.gm-step-list h3 {
    margin: 0 0 8px;
}

.gm-step-list p {
    margin: 0;
    color: var(--gm-muted);
    font-size: 14px;
}

.gm-cta {
    color: var(--gm-on-dark);
    background: var(--gm-forest);
}

.gm-cta-inner {
    display: flex;
    gap: 26px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    padding: clamp(36px, 4.5vw, 62px) 0;
}

.gm-cta .gm-label {
    color: var(--gm-on-dark-dim);
}

/* ---------------------------------------------------------------------------
   Games board: the filters

   Core's `.event-filter-bar` is a dark panel drawn for core's palette: its
   current-filter chip fills with `var(--olive)` and underlines itself in
   `var(--signal)`, which under Gunman's tokens is forest on forest. Gunman's
   bar is light, so the three colours core sets for a dark bar are restated.
   --------------------------------------------------------------------------- */

.gm-filter-bar.event-filter-bar {
    padding: clamp(20px, 3vw, 30px);
    border: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: var(--gm-white);
}

.gm-filter-bar h2 {
    font-size: clamp(15px, 1.4vw, 18px);
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.gm-filter-bar .quick-filter {
    border-color: var(--gm-rule);
    color: var(--gm-forest);
    background: transparent;
}

.gm-filter-bar .quick-filter:hover {
    border-color: var(--gm-forest);
    background: var(--gm-panel);
}

.gm-filter-bar .quick-filter[aria-current="true"] {
    border-color: var(--gm-forest);
    box-shadow: inset 0 -4px 0 var(--gm-forest);
    color: var(--gm-white);
    background: var(--gm-forest);
}

/* The field labels and the controls themselves. Core draws all three for a dark
   bar: the labels are the sand `rgb(216 209 191 / 72%)`, which is 1.36:1 on this
   one, and the select borders are the same sand at 42%, which is no boundary at
   all. Written at (0,2,1) and (0,2,2) so they outrank core's without needing to
   be later as well. */
.gm-filter-bar .event-filter-fields > label,
.gm-filter-bar .event-filter-custom label {
    color: var(--gm-mid);
    font-family: var(--display);
    font-weight: 700;
}

.gm-filter-bar .event-filter-fields select,
.gm-filter-bar .event-filter-custom input {
    border: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: var(--gm-white);
}

.gm-filter-bar > .field-error,
.gm-filter-bar .event-filter-custom .field-error,
.gm-filter-bar .field-error {
    color: var(--gm-warning);
}

.gm-filter-bar > .gm-text-link {
    display: flex;
    width: fit-content;
    min-height: 50px;
    margin: 14px 0 -8px auto;
}

.gm-filter-bar .event-filter-custom summary {
    color: var(--gm-forest);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.gm-board-count {
    display: flex;
    gap: 6px 16px;
    flex-wrap: wrap;
    align-items: baseline;
    padding: 26px 0 8px;
}

.gm-board-count strong {
    font-family: var(--display);
    font-size: 20px;
    font-weight: 700;
}

.gm-board-count span {
    color: var(--gm-muted);
    font-size: 14px;
}

/* ---------------------------------------------------------------------------
   One game

   The booking panel is light, not dark. Core's — and Forward Element's — is a
   dark aside, which also means every value in it is drawn for a dark ground:
   the team indicator classes resolve to tints chosen against `var(--ink)`. A
   light panel needs them restated, and they are, below. (Since theme API 0.6
   the aside carries no uniform notice or team requirements: one line of
   minimum age and uniform links to the dress code, as core's card does.)
   --------------------------------------------------------------------------- */

.gm-game-facts {
    border-bottom: 1px solid var(--gm-rule);
    background: var(--gm-panel);
}

.gm-game-facts-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0;
    /* margin-block, not margin. This element also carries .gm-shell, whose
       margin-inline: auto is what centres it inside the full-bleed band. A
       shorthand `margin: 0` here is a later rule of equal specificity, so it
       silently won and pinned the strip to the viewport edge while every
       other section stayed inset -- the date sat hard against the left of
       the page. Only the dl's own block margin needs clearing. */
    margin-block: 0;
}

.gm-game-facts-list > div {
    padding: 20px 20px 22px 0;
}

.gm-game-facts-list dt {
    margin: 0 0 6px;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gm-game-facts-list dd {
    margin: 0;
    font-family: var(--display);
    font-size: 15px;
    font-weight: 700;
}

.gm-game-facts-list dd a {
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* "May vary slightly on the day" under Game on to End of play (theme API 0.6):
   a note in body type under the bold value, muted, at 5.6:1 on the panel. */
.gm-game-facts-list dd small {
    display: block;
    margin-top: 4px;
    color: var(--gm-muted);
    font-family: var(--body);
    font-size: 12px;
    font-weight: 400;
}

.gm-game-image {
    padding: 30px 0 0;
}

.gm-game-image img {
    width: 100%;
    height: clamp(180px, 26vw, 330px);
    object-fit: cover;
}

.gm-game-detail-grid {
    display: grid;
    grid-template-columns: 370px minmax(0, 1fr);
    gap: 44px;
    align-items: start;
}

.gm-booking {
    padding: 26px 24px 30px;
    border: 1px solid var(--gm-rule);
    background: var(--gm-white);
}

.gm-booking-price {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: baseline;
    margin: 0 0 20px;
}

.gm-booking-price strong {
    font-family: var(--display);
    font-size: clamp(30px, 3.6vw, 42px);
    font-weight: 700;
    line-height: 1;
}

.gm-booking-price span {
    color: var(--gm-muted);
    font-family: var(--display);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.gm-ticket-options {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--gm-hairline);
}

.gm-ticket-options li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px 12px;
    padding: 13px 0;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-ticket-options strong {
    font-family: var(--display);
    font-size: 14px;
}

.gm-ticket-options b {
    font-family: var(--display);
    font-size: 15px;
    text-align: right;
}

.gm-ticket-options span,
.gm-ticket-options small {
    grid-column: 1 / -1;
    color: var(--gm-muted);
    font-size: 12.5px;
    line-height: 1.5;
}

.gm-booking-availability {
    margin: 18px 0;
    padding: 11px 13px;
    border-left: 4px solid var(--gm-forest);
    background: var(--gm-panel);
    font-family: var(--display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Places per ticket and per game day (theme API 0.5). The words say the
   state; colour only repeats it: muted when open, ink when low, the warning
   red when full or sold out. A sold-out ticket's name and price fade to 0.7,
   which is 6.7:1 on the white card; tests/checks/gunman-theme.php measures
   every one of these. */
.gm-ticket-places {
    font-family: var(--display);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-ticket-options .gm-ticket-places.is-low {
    color: var(--gm-ink);
}

.gm-ticket-options .gm-ticket-places.is-out {
    color: var(--gm-warning);
}

.gm-ticket-options li.is-sold-out > strong,
.gm-ticket-options li.is-sold-out > b {
    opacity: 0.7;
}

.gm-day-places p {
    margin: 0;
}

.gm-day-places ul {
    display: grid;
    gap: 4px;
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
}

.gm-day-places li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
}

.gm-day-places b {
    color: var(--gm-muted);
}

.gm-day-places b.is-low {
    color: var(--gm-ink);
}

.gm-day-places b.is-out {
    color: var(--gm-warning);
}

.gm-team-availability .gm-team-days {
    grid-column: 2 / -1;
    color: var(--gm-warning);
    font-family: var(--body);
    font-size: 12px;
    font-weight: 700;
}

.gm-team-availability {
    display: grid;
    gap: 7px;
    margin: 0 0 20px;
    padding: 0;
    list-style: none;
}

/* The team indicator classes `team_class()` emits set a `color` chosen for a
   dark panel, and that colour is inherited by the team's name. On a light panel
   `#afb0aa` and `#8ba5b0` are 2.1:1 and 2.4:1, so the text takes the ink and the
   colour is moved to the dot alone, where it is a 3:1 graphic rather than 4.5:1
   text. */
.gm-team-availability > li {
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr) auto;
    gap: 9px;
    align-items: center;
    padding: 11px 13px;
    border: 1px solid var(--gm-hairline);
    color: var(--gm-ink);
    font-size: 13px;
}

.gm-team-availability > li > i {
    width: 8px;
    height: 8px;
    background: var(--gm-forest);
}

.gm-team-availability > li.team-olive > i {
    background: #3f5c3d;
}

.gm-team-availability > li.team-tan > i {
    background: #6b7f68;
}

.gm-team-availability > li.team-black > i {
    background: #14180f;
}

.gm-team-availability > li.team-blue > i {
    background: #3d5a63;
}

/* Red joined the core identifier allowlist after this sheet was written, and a
   theme replaces core's public sheet rather than adding to it, so without this
   a team called Red fell through to var(--gm-forest) and rendered green.
   6.85:1 on --gm-paper and 6.12:1 on --gm-panel, which is where these dots sit:
   the olive and blue beside it are 6.76 and 6.68, and the forest default is
   1.00:1 on the forest band, so the light grounds are the real ones. */
.gm-team-availability > li.team-red > i {
    background: #8c3a34;
}

.gm-team-availability > li > span {
    font-family: var(--display);
    font-size: 13px;
}

.gm-team-availability > li > span a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.gm-team-availability .team-booking-public-state {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-team-availability .team-booking-public-state.is-paused {
    color: var(--gm-warning);
}

.gm-team-availability .team-booking-reopens,
.gm-team-availability .team-sniper-availability {
    grid-column: 2 / -1;
    color: var(--gm-muted);
    font-family: var(--body);
    font-size: 12px;
    font-weight: 400;
}

.gm-booking .gm-button {
    margin-top: 9px;
}

.gm-booking-note,
.gm-booking-policy {
    margin: 16px 0 0;
    color: var(--gm-muted);
    font-size: 12.5px;
    line-height: 1.55;
}

/* The one line of minimum age and uniform (S7): ink rather than the notes'
   muted, because it is a condition of booking, with its link underlined. */
.gm-booking-meta {
    color: var(--gm-ink);
}

.gm-booking-meta a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* "Ticket and refund policy", folded. A native disclosure: the summary keeps
   its marker, is 44 pixels tall, and takes the forest focus ring the global
   `summary:focus-visible` rule above gives it on this light panel. */
.gm-booking-policy summary {
    display: list-item;
    min-height: 44px;
    padding: 12px 0;
    box-sizing: border-box;
    color: var(--gm-forest);
    font-family: var(--display);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

.gm-booking-policy p {
    margin: 0;
}

/* ---------------------------------------------------------------------------
   A scheduled game's teaser (theme API 0.7)

   The game page reduced: Date, Site and Tickets on sale in the facts row, and
   the Coming soon panel in the booking panel's slot, as light and as boxed as
   the booking panel. Core's `.teaser-panel` rules, linked before this sheet,
   draw the panel and Notify me for a dark ground (white text, sand labels, a
   pale error red); each is restated here for the white card, at (0,2,0) and
   above so they outrank core's without depending on order. Every colour is a
   pair this file already proves in tests/checks/gunman-theme.php: ink, muted
   and mid on white, the rule as a control border on white, the warning on
   white, and white on the forest fill.
   --------------------------------------------------------------------------- */

.gm-game-facts-list--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.gm-booking.teaser-panel {
    color: var(--gm-ink);
    background: var(--gm-white);
}

.gm-booking.teaser-panel > .gm-label {
    margin: 0 0 14px;
    color: var(--gm-mid);
}

.gm-booking.teaser-panel h2 {
    margin: 0 0 12px;
    font-size: clamp(24px, 2.6vw, 30px);
    font-weight: 700;
    text-transform: none;
}

.gm-booking.teaser-panel > p {
    margin: 0 0 8px;
    color: var(--gm-muted);
}

.gm-booking.teaser-panel > .teaser-time {
    margin: 0 0 10px;
    color: var(--gm-ink);
    font-size: clamp(20px, 2.2vw, 24px);
    font-weight: 700;
    letter-spacing: 0.02em;
}

.gm-booking.teaser-panel .notify-me-field label {
    color: var(--gm-mid);
    font-family: var(--display);
    font-weight: 700;
}

.gm-booking.teaser-panel .notify-me-field input {
    border: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: var(--gm-white);
}

.gm-booking.teaser-panel .notify-me-field input[aria-invalid="true"] {
    border: 2px solid var(--gm-warning);
    box-shadow: inset 4px 0 0 var(--gm-warning);
}

.gm-booking.teaser-panel .notify-me-field .field-error {
    color: var(--gm-warning);
}

.gm-booking.teaser-panel .notify-me-hint {
    color: var(--gm-muted);
}

.gm-booking.teaser-panel .notify-me-hint a {
    color: var(--gm-forest);
}

/* Notify me's buttons in this theme's button language: square, monospace,
   the forest fill, no lift on hover. */
.gm-booking.teaser-panel .notify-me .button {
    min-height: 52px;
    font-family: var(--display);
    font-weight: 700;
    letter-spacing: 0.1em;
}

.gm-booking.teaser-panel .notify-me .button:hover {
    transform: none;
}

.gm-booking.teaser-panel .notify-me .button-primary {
    color: var(--gm-white);
    background: var(--gm-forest);
}

.gm-booking.teaser-panel .notify-me .button-primary:hover {
    background: var(--gm-mid);
}

.gm-booking.teaser-panel .notify-me .button-outline {
    border-color: var(--gm-rule);
    color: var(--gm-forest);
    background: transparent;
}

.gm-booking.teaser-panel .notify-me .button-outline:hover {
    border-color: var(--gm-forest);
    background: var(--gm-panel);
}

.gm-briefing .teaser-note {
    margin: 0;
    color: var(--gm-muted);
    font-size: 14px;
}

/* "Coming soon" where a schedule row's price, places and Book stand: words in
   the label's type, outlined like the row's site, never colour alone. */
.gm-game-soon {
    padding: 3px 8px;
    border: 1px solid var(--gm-rule);
    color: var(--gm-forest);
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1.4;
    text-transform: uppercase;
}

.gm-briefing h2 {
    margin: 0 0 18px;
}

.gm-briefing .rich-text {
    max-width: 70ch;
}

/* Terrain and Standard, as text tags under the briefing's heading: outlined
   like a game row's site, never colour alone. */
.gm-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 18px;
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.gm-tags span {
    padding: 3px 8px;
    border: 1px solid var(--gm-rule);
    color: var(--gm-forest);
}

/* "On the day": each game day's Arrive from, Game on and End of play, three
   values in a row that stack on a phone. */
.gm-day-times {
    max-width: 70ch;
    margin: 30px 0 0;
    padding-top: 22px;
    border-top: 1px solid var(--gm-hairline);
}

.gm-day-times h4 {
    margin: 18px 0 8px;
}

.gm-day-times dl {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    margin: 0;
}

.gm-day-times dl div {
    display: grid;
    gap: 2px;
}

.gm-day-times dt {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gm-day-times dd {
    margin: 0;
    font-family: var(--display);
    font-size: 15px;
    font-weight: 700;
}

.gm-day-times p {
    margin: 16px 0 0;
    color: var(--gm-muted);
    font-size: 13px;
}

/* "On the day" with public itinerary entries (core 0.6.0): a day with
   entries reads as one list in time order, the time first, then what
   happens, an entry's note under it in body type, as the closing note. A
   day without keeps its row of three. */
.gm-day-times dl.gm-day-times-timeline {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
}

.gm-day-times .gm-day-times-timeline div {
    grid-template-columns: 5.5rem minmax(0, 1fr);
    gap: 2px 16px;
    padding: 8px 0;
    border-top: 1px solid var(--gm-hairline);
}

.gm-day-times .gm-day-times-timeline div:last-child {
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-day-times .gm-day-times-timeline dt {
    grid-column: 2;
    grid-row: 1;
    color: var(--gm-ink);
    font-size: 15px;
    letter-spacing: 0;
    text-transform: none;
}

.gm-day-times .gm-day-times-timeline dd {
    grid-column: 1;
    grid-row: 1;
    white-space: nowrap;
}

.gm-day-times .gm-day-times-timeline .gm-day-times-note {
    grid-column: 2;
    grid-row: 2;
    color: var(--gm-muted);
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    white-space: normal;
}

/* ---------------------------------------------------------------------------
   Dress code
   --------------------------------------------------------------------------- */

.gm-dress {
    background: var(--gm-panel);
}

.gm-dress-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 0;
    margin-top: 0;
}

.gm-dress-card {
    padding: 24px 24px 28px;
    border-bottom: 1px solid var(--gm-rule);
    border-right: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: var(--gm-white);
}

.gm-dress-card header {
    display: grid;
    grid-template-columns: 9px minmax(0, 1fr) auto;
    gap: 10px;
    align-items: center;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-dress-card header > i {
    width: 9px;
    height: 9px;
    background: var(--gm-forest);
}

.gm-dress-card.team-olive header > i {
    background: #3f5c3d;
}

.gm-dress-card.team-tan header > i {
    background: #6b7f68;
}

.gm-dress-card.team-black header > i {
    background: #14180f;
}

.gm-dress-card.team-blue header > i {
    background: #3d5a63;
}

.gm-dress-card.team-red header > i {
    background: #8c3a34;
}

.gm-dress-card header h3 {
    margin: 0;
}

.gm-dress-card header strong {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* The team's name links to its team page, underlined as the aside's team
   names are. */
.gm-dress-card header h3 a {
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* The team's places, moved here from the booking aside (theme API 0.6
   layout): its days with room in the aside's state type, its full days in the
   warning colour, its sniper places muted. Words carry every state. */
.gm-dress-places {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: baseline;
    margin: -4px 0 14px;
}

.gm-dress-places .team-booking-public-state {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-dress-places .gm-team-days {
    color: var(--gm-warning);
    font-size: 12px;
    font-weight: 700;
}

.gm-dress-places .team-sniper-availability {
    color: var(--gm-muted);
    font-size: 12px;
}

.gm-dress-card section + section {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--gm-hairline);
}

.gm-dress-recommended {
    margin: 12px 0 0;
    color: var(--gm-muted);
    font-size: 13px;
}

.gm-dress-recommended ul {
    margin: 6px 0 0;
    padding-left: 18px;
}

.gm-dress + .gm-team-about,
.gm-dress > .gm-shell > .gm-button {
    margin-top: 24px;
}

/* ---------------------------------------------------------------------------
   Teams
   --------------------------------------------------------------------------- */

.gm-team-rows {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--gm-rule);
}

.gm-team-row {
    display: grid;
    grid-template-columns: 78px minmax(0, 1fr) auto;
    gap: 0 24px;
    align-items: start;
    padding: 26px 0;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-team-tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    padding: 6px 8px;
    color: var(--gm-white);
    background: var(--gm-forest);
    font-family: var(--display);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.gm-team-row.gm-team-tan .gm-team-tag {
    background: var(--gm-mid);
}

.gm-team-row.gm-team-black .gm-team-tag {
    background: var(--gm-ink);
}

.gm-team-row.gm-team-blue .gm-team-tag {
    background: #2d444b;
}

/* White at 12px bold needs 4.5:1, not 3:1. #6e2b28 gives 10.30:1, matching the
   blue tag beside it at 10.29 rather than merely clearing the floor. */
.gm-team-row.gm-team-red .gm-team-tag {
    background: #6e2b28;
}

.gm-team-row-body h2 {
    margin: 0 0 8px;
    font-size: clamp(19px, 2vw, 25px);
}

.gm-team-row-body p {
    max-width: 66ch;
    margin: 0;
    color: var(--gm-muted);
    font-size: 14px;
}

.gm-team-row-dress {
    margin-top: 8px !important;
}

.gm-team-about-grid,
.gm-facilities-grid,
.gm-about-grid {
    display: grid;
    grid-template-columns: minmax(0, 0.55fr) minmax(0, 1.45fr);
    gap: 26px 48px;
    align-items: start;
}

.gm-command-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0;
    margin: 24px 0 0;
    padding: 0;
    list-style: none;
}

.gm-commander {
    display: grid;
    gap: 4px;
    padding: 0 0 20px;
    border-top: 1px solid var(--gm-rule);
    border-right: 1px solid var(--gm-rule);
}

.gm-commander img,
.gm-commander-blank {
    display: block;
    width: 100%;
    height: clamp(210px, 22vw, 290px);
    margin-bottom: 14px;
    object-fit: cover;
    background: var(--gm-panel);
}

.gm-commander-role,
.gm-commander-name {
    padding: 0 16px;
    font-family: var(--display);
}

.gm-commander-role {
    color: var(--gm-mid);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.gm-commander-name {
    font-size: 16px;
}

/* ---------------------------------------------------------------------------
   Site detail
   --------------------------------------------------------------------------- */

.gm-site-detail-grid {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 44px;
    align-items: start;
}

.gm-address {
    padding: 24px 22px 26px;
    border: 1px solid var(--gm-rule);
    background: var(--gm-white);
}

.gm-address strong {
    display: block;
    font-family: var(--display);
    font-size: 18px;
}

.gm-address p {
    margin: 8px 0 18px;
    color: var(--gm-muted);
    font-size: 14px;
}

.gm-site-flags {
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
}

.gm-site-flags li {
    padding: 7px 0;
    border-top: 1px solid var(--gm-hairline);
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.gm-site-prose {
    max-width: 72ch;
}

.gm-site-terrain {
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--gm-rule);
}

.gm-limits {
    background: var(--gm-panel);
}

.gm-limit-table {
    width: 100%;
    margin-top: 26px;
    border-collapse: collapse;
    font-family: var(--display);
    font-size: 14px;
}

.gm-limit-table th,
.gm-limit-table td {
    padding: 13px 14px;
    border-bottom: 1px solid var(--gm-rule);
    text-align: left;
}

.gm-limit-table thead th {
    border-bottom: 1px solid var(--gm-forest);
    color: var(--gm-mid);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gm-limit-table tbody th {
    font-weight: 700;
}

.gm-class-rules {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0;
    margin-top: 30px;
}

.gm-class-rules article {
    padding: 22px;
    border-top: 1px solid var(--gm-rule);
    border-right: 1px solid var(--gm-rule);
    background: var(--gm-white);
}

.gm-class-rules h3 {
    margin: 0 0 10px;
}

/* ---------------------------------------------------------------------------
   Rules and legal: sticky index rails
   --------------------------------------------------------------------------- */

.gm-rules-layout,
.gm-legal-layout {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 48px;
    align-items: start;
}

.gm-rules-index,
.gm-legal-index {
    position: sticky;
    top: 24px;
    display: grid;
    padding-right: 22px;
    border-right: 1px solid var(--gm-rule);
}

.gm-rules-index a,
.gm-legal-index a {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 8px;
    align-items: baseline;
    min-height: 44px;
    align-content: center;
    padding: 9px 0;
    border-top: 1px solid var(--gm-hairline);
    color: var(--gm-ink);
    font-family: var(--display);
    font-size: 12.5px;
    line-height: 1.35;
}

.gm-rules-index a > span,
.gm-legal-index a > span {
    color: var(--gm-mid);
    font-size: 11px;
    font-weight: 700;
}

.gm-rules-index a:hover,
.gm-legal-index a:hover {
    color: var(--gm-mid);
}

.gm-rules-index .gm-label:not(:first-child),
.gm-legal-index .gm-label:not(:first-child) {
    margin-top: 24px;
}

.gm-rules-content > section,
.gm-legal-content {
    max-width: 74ch;
}

.gm-rules-content > section + section {
    margin-top: 44px;
    padding-top: 36px;
    border-top: 1px solid var(--gm-rule);
}

.gm-rules-number {
    margin: 0 0 6px;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.14em;
}

.gm-rules-content h2 {
    margin-bottom: 14px;
}

.gm-rules-content p,
.gm-rules-content li {
    color: var(--gm-ink);
}

.gm-rules-dress {
    margin-top: 26px;
    padding: 22px;
    border: 1px solid var(--gm-rule);
    background: var(--gm-white);
}

.gm-rules-dress header {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--gm-hairline);
}

.gm-rules-dress header strong {
    font-family: var(--display);
    font-size: 16px;
}

.gm-legal-head {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 26px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--gm-rule);
}

.gm-legal-head > span {
    color: var(--gm-muted);
    font-family: var(--display);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ---------------------------------------------------------------------------
   About and tools
   --------------------------------------------------------------------------- */

.gm-about-lead {
    margin: 0 0 16px;
    font-size: clamp(17px, 1.8vw, 21px);
}

.gm-about-body p {
    max-width: 70ch;
    color: var(--gm-ink);
}

.gm-about-links {
    display: grid;
    gap: 0;
    margin: 24px 0 0;
    padding: 0;
    list-style: none;
}

.gm-about-links li {
    padding: 13px 0;
    border-top: 1px solid var(--gm-hairline);
}

.gm-tool {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 44px;
    align-items: start;
}

.gm-tool-copy p {
    max-width: 58ch;
    color: var(--gm-ink);
}

.gm-tool-warning {
    margin: 18px 0 0;
    padding: 13px 15px;
    border-left: 4px solid var(--gm-warning);
    background: #fae9e4;
    color: #5d2418;
    font-size: 13.5px;
}

.gm-tool-formula {
    margin: 18px 0 0;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 13px;
}

.gm-converter {
    padding: 24px 22px 26px;
    border: 1px solid var(--gm-rule);
    background: var(--gm-white);
}

.gm-converter label {
    display: grid;
    gap: 7px;
}

.gm-converter label > span {
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gm-converter select,
.gm-converter input {
    width: 100%;
    min-height: 50px;
    padding: 12px 13px;
    border: 1px solid var(--gm-rule);
    color: var(--gm-ink);
    background: var(--gm-white);
    font-family: var(--display);
    font-size: 16px;
}

.gm-converter-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 14px;
    align-items: end;
    margin-top: 20px;
}

.gm-converter-fields > i {
    padding-bottom: 14px;
    color: var(--gm-mid);
    font-family: var(--display);
    font-size: 19px;
    font-style: normal;
}

.gm-converter-input {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
}

.gm-converter-input > b {
    display: flex;
    align-items: center;
    padding: 0 12px;
    border: 1px solid var(--gm-rule);
    border-left: 0;
    color: var(--gm-white);
    background: var(--gm-forest);
    font-family: var(--display);
    font-size: 11px;
    letter-spacing: 0.1em;
}

/* ---------------------------------------------------------------------------
   Social icons
   --------------------------------------------------------------------------- */

.gm-social-icon {
    display: inline-flex;
    width: 32px;
    height: 32px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--gm-on-dark-rule);
    color: var(--gm-on-dark);
}

.gm-social-icon svg {
    width: 16px;
    height: 16px;
    fill: currentColor;
}

/* Instagram is drawn as outlines, as core's .social-link draws it: filled, its
   rounded square and lens merge into one solid block. The dot stays filled. */
.gm-social-icon svg rect,
.gm-social-icon svg circle:first-of-type {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
}

.gm-social-icon:hover {
    border-color: var(--gm-on-dark);
    color: var(--gm-forest);
    background: var(--gm-on-dark);
}

.gm-social-link {
    width: 28px;
    height: 28px;
}

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */

.gm-footer {
    color: var(--gm-on-dark);
    background: var(--gm-forest);
}

.gm-footer-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) repeat(3, minmax(0, 1fr));
    gap: 34px 40px;
    padding: clamp(40px, 5vw, 70px) 0 clamp(28px, 3vw, 44px);
}

/* Three columns, for an installation that has entered no sites: the shell
   draws no Sites column at all rather than an empty one, and the fixed
   four-column track above would leave its width behind as a gap on the right.
   Declared immediately after the rule it narrows so that the single-column
   rule in the narrow-viewport band below, which carries the same specificity,
   still wins on a phone. */
.gm-footer-grid-compact {
    grid-template-columns: minmax(0, 1.2fr) repeat(2, minmax(0, 1fr));
}

.gm-footer-mark {
    width: 72px;
    margin-bottom: 16px;
    padding: 9px;
}

.gm-footer-name {
    display: block;
    font-family: var(--display);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.gm-footer-legal {
    margin: 10px 0 0;
    color: var(--gm-on-dark-dim);
    font-size: 13px;
}

.gm-footer-mail {
    display: inline-block;
    margin-top: 12px;
    color: var(--gm-on-dark);
    font-family: var(--display);
    font-size: 13px;
    text-decoration: underline;
    text-underline-offset: 4px;
}

.gm-footer-social {
    display: flex;
    gap: 6px;
    margin-top: 18px;
}

.gm-footer-column {
    display: grid;
    align-content: start;
    gap: 0;
}

.gm-footer-column strong {
    margin-bottom: 8px;
    color: var(--gm-on-dark-dim);
    font-family: var(--display);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.gm-footer-column a,
.gm-footer-cookie-settings {
    display: inline-flex;
    min-height: 40px;
    align-items: center;
    padding: 0;
    border: 0;
    color: var(--gm-on-dark);
    background: none;
    font-family: var(--body);
    font-size: 13.5px;
    text-align: left;
    cursor: pointer;
}

.gm-footer-column a:hover,
.gm-footer-cookie-settings:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.gm-footer-base {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    padding: 18px 0 24px;
    border-top: 1px solid var(--gm-on-dark-rule);
    color: var(--gm-on-dark-dim);
    font-family: var(--display);
    font-size: 12px;
}

/* "Powered by AirsoftOS". The shape of it — the flex row, the gap, the mark's
   height — is core's and is imported with the rest of theme.css; the colour is
   not, because core's is var(--paper-3), a warm sand meant for var(--ink), and
   this footer is the brand forest. var(--gm-on-dark-dim) is 8.02:1 on #1e3b1c
   and is what every other word in this footer base is already painted, which is
   the point: the attribution should read as part of this footer rather than as
   a fragment of another club's palette that wandered in.

   `.gm-footer-base .powered-by` and not `.powered-by` alone. The two selectors
   never meet — Gunman's footer base is not `.footer-base` — so this states a
   colour for this footer rather than for every `.powered-by` anywhere, which is
   what a bare class selector arriving in a later sheet would have done. */
.gm-footer-base .powered-by {
    color: var(--gm-on-dark-dim);
}

/* ---------------------------------------------------------------------------
   Reflow

   Three bands, chosen to match the widths the release gate measures — 1400,
   1280 and 560 — plus the 1180 the grids actually need.
   --------------------------------------------------------------------------- */

@media (max-width: 1180px) {
    :root {
        --gm-shell: min(100% - 40px, 960px);
        --shell: min(100% - 40px, 960px);
    }

    .gm-game-detail-grid,
    .gm-site-detail-grid,
    .gm-tool,
    .gm-types-inner,
    .gm-team-about-grid,
    .gm-facilities-grid,
    .gm-about-grid,
    .gm-rules-layout,
    .gm-legal-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 30px;
    }

    .gm-rules-index,
    .gm-legal-index {
        position: static;
        padding-right: 0;
        padding-bottom: 20px;
        border-right: 0;
        border-bottom: 1px solid var(--gm-rule);
    }

    .gm-section-head {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
    }

    .gm-section-head > .gm-button {
        justify-self: start;
    }
}

/* The menu band is core's 820px, not a width of this theme's choosing. The two
   sheets both style the same two elements — `.nav-toggle` and `.site-nav` are
   `public/assets/site.js`'s hooks and cannot be renamed — so a second breakpoint
   would leave a band where core has collapsed the nav and this theme has not
   shown the button to open it.

   Every property core's mobile `.site-nav` rule sets is set again here, because
   equal specificity is decided by source order and these rules win that way
   rather than by escalating. Four of them matter: core hides the panel with
   `visibility: hidden` and `opacity: 0`, which a `display: none` of this
   theme's own would not have undone on `.is-open`, and it gives the panel a
   full-viewport height against `var(--ink)`, which is not this header's ground. */
@media (max-width: 820px) {
    .gm-nav-toggle {
        display: inline-flex;
    }

    .gm-nav {
        position: absolute;
        inset: 100% 0 auto;
        display: none;
        height: auto;
        align-items: stretch;
        padding: 8px 20px 20px;
        flex-direction: column;
        gap: 0;
        border-bottom: 1px solid var(--gm-rule);
        visibility: visible;
        color: var(--gm-ink);
        background: var(--gm-paper);
        opacity: 1;
        transform: none;
        transition: none;
    }

    .gm-nav.is-open {
        display: flex;
        visibility: visible;
        opacity: 1;
        transform: none;
    }

    .gm-nav a {
        border-bottom: 1px solid var(--gm-hairline);
        font-size: 13px;
    }

    .gm-nav-account {
        margin: 12px 0 0;
        border: 1px solid var(--gm-rule);
    }

    .gm-header-bar {
        position: relative;
    }

    /* The rail, in the band where the header is already a button and a panel.
     *
     * Third answer. It wrapped first, which put one site per row: five rows of
     * chrome for this customer and nine for an operator with nine, on top of
     * every page before anything the visitor came for, and "OUR SITES" on a
     * row of its own above the sites it labels. Then it was one line that ran
     * off the right, which is the ordinary way a phone carries more chips than
     * fit — and on a phone it is a 46px strip with no edge you can see, so a
     * reader who is not already swiping is told there are sites and shown two
     * of them. Neither is wrong about the other: a roster this long is either
     * too tall or too wide for a phone, and both answers spent the first
     * screen arguing about which.
     *
     * So it spends a row. One row, always the same height whatever the roster
     * is, saying what the band holds and how many — and the roster is there
     * when it is asked for. Collapsed it costs what the strip cost, 46px, and
     * unlike the strip it is legible at a glance: "OUR SITES  9 SITES". Open,
     * it is the wrapped list that was rejected as a default, which is the
     * right shape for a roster and was only ever wrong about when to appear.
     *
     * 820px is core's menu band and not a width chosen here, for the reason
     * given above it: a second breakpoint would leave a band where the header
     * had collapsed into a button and the rail had not. It is also the honest
     * line for this — the rail is header chrome, and this is where this
     * theme's header stops being a desktop header.
     *
     * No script. `public/assets/site.js` opens the menu above, and nothing in
     * this band waits for it: `<details>` is the browser's own disclosure, so
     * the rail works on a page whose scripts have not loaded, are blocked, or
     * failed — which matters more here than for the menu, because the content
     * security policy is `style-src 'self'` and this is chrome on every page.
     * The summary is a button to a keyboard and announces itself expanded or
     * collapsed to a screen reader, both without a line of author code. */
    .gm-site-rail-inner {
        flex-direction: column;
        align-items: stretch;
    }

    /* The band already has its label: the summary is it. Two elements carry
     * that word and `display: none` keeps each out of the accessibility tree
     * where it is not the one in use, so one is ever announced. */
    .gm-site-rail-label {
        display: none;
    }

    .gm-site-rail-disclosure {
        display: block;
    }

    /* Symmetric, in place of the `… 0` the one-line rail runs with. That rail
     * gives up its right margin on purpose, to buy the width that decides
     * whether the last name fits; a list that wraps has no use for the width
     * and every use for a right edge to align to. */
    .gm-site-rail .gm-site-rail-inner {
        padding-inline: max(28px, calc((100% - var(--gm-shell)) / 2));
    }

    /* 46px, the height the strip was, and it stays that height at one site and
     * at nine — which is the whole claim this treatment makes. The label's own
     * type, because it is the same label. */
    .gm-site-rail-summary {
        display: flex;
        min-height: 46px;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        color: var(--gm-on-dark-dim);
        font-family: var(--display);
        font-size: 10px;
        font-weight: 700;
        letter-spacing: 0.18em;
        text-transform: uppercase;
        /* Both are needed to drop the default triangle: the standard property
         * and WebKit's pseudo-element, which older Safari answers to and
         * nothing else does. The marker is replaced below rather than kept,
         * because a UA triangle in the corner of a near-black band is drawn in
         * whatever ink the UA picked and sits where the UA put it. */
        list-style: none;
        /* A disclosure is tapped, often twice. Without this the second tap
         * selects the label instead of closing the band. */
        user-select: none;
    }

    .gm-site-rail-summary::-webkit-details-marker {
        display: none;
    }

    /* The count. The one thing a collapsed band can say that the strip could
     * not: how much is behind it. Read off the roster in the template, so an
     * operator who opens a sixth site is told six. */
    .gm-site-rail-summary-count {
        margin-left: auto;
        color: var(--gm-on-dark);
    }

    .gm-site-rail-summary::after {
        content: '';
        flex: 0 0 auto;
        width: 6px;
        height: 6px;
        border-right: 1px solid currentColor;
        border-bottom: 1px solid currentColor;
        transform: translateY(-2px) rotate(45deg);
    }

    .gm-site-rail-disclosure[open] > .gm-site-rail-summary::after {
        transform: translateY(1px) rotate(-135deg);
    }

    /* The list is the disclosure's sibling, not its child, so its visibility
     * is these two rules and not the `<details>` element's own behaviour. That
     * is what lets the desktop rail keep the list with no disclosure involved
     * at all: above this band both selectors are simply unmatched, because
     * `.gm-site-rail-disclosure` is `display: none` and the list is drawn by
     * the rules it has always been drawn by. */
    .gm-site-rail-disclosure:not([open]) ~ .gm-site-rail-list {
        display: none;
    }

    /* Open: the wrap, with columns when there is width for columns. `auto-fill`
     * rather than a count, so the same rule gives a 390px phone one column and
     * a 760px tablet three, and so nothing here is tuned to a roster size. The
     * `min(100%, …)` is the guard that stops a track wider than the band from
     * pushing the document sideways, which is how a name once took the
     * navigation toggle off the right of a phone. */
    .gm-site-rail-disclosure[open] ~ .gm-site-rail-list {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
        column-gap: 18px;
        overflow-x: visible;
        margin: 0;
        padding-bottom: 8px;
        border-top: 1px solid var(--gm-on-dark-rule);
    }

    /* The one-line rail overlaps its entries by a pixel so two neighbours share
     * one vertical hairline. In a grid there are no shared vertical hairlines
     * to make, and the overlap would drag every cell a pixel left of its
     * track. */
    .gm-site-rail-disclosure[open] ~ .gm-site-rail-list li {
        margin-left: 0;
    }

    /* A row, not a chip: the name runs to the edge of its track and the rule
     * under it closes the row. On every entry rather than between them, because
     * where this list breaks is decided by the operator's names and the width
     * of the phone, and a rule that knows which entry is last does not survive
     * either.
     *
     * `white-space: normal` is the one property the strip cannot share. On one
     * line a name must not break, or it breaks mid-word on a line that was
     * going to scroll anyway; in a track 190px wide a name that must not break
     * simply leaves it. `overflow-wrap: anywhere` is for the name with no space
     * in it to break at, which is not a name Gunman holds and is not a name
     * this sheet gets to rule out. */
    .gm-site-rail-disclosure[open] ~ .gm-site-rail-list a {
        display: flex;
        min-height: 40px;
        align-items: center;
        padding: 10px 0;
        border-inline: 0;
        border-bottom: 1px solid var(--gm-on-dark-rule);
        white-space: normal;
        overflow-wrap: anywhere;
        font-size: 12px;
        line-height: 1.35;
    }

    .gm-next-inner {
        grid-template-columns: minmax(0, 1fr);
        gap: 26px;
    }

    .gm-next-mark {
        order: -1;
    }

    .gm-game {
        grid-template-columns: 80px minmax(0, 1fr);
        gap: 0 20px;
    }

    .gm-game-book {
        grid-column: 2;
        justify-items: start;
        margin-top: 14px;
        text-align: left;
    }

    .gm-site-row,
    .gm-team-row {
        grid-template-columns: 52px minmax(0, 1fr);
    }

    .gm-site-row-actions,
    .gm-team-row > .gm-button {
        grid-column: 2;
        margin-top: 14px;
        justify-items: start;
    }

    .gm-team-row > .gm-button {
        justify-self: start;
    }
}

@media (max-width: 620px) {
    :root {
        --gm-shell: min(100% - 28px, 560px);
        --shell: min(100% - 28px, 560px);
    }

    /* No rail rules. This band used to hold the mobile rail — a tighter gap
     * and smaller chips on the strip, and before that the stack — and every
     * one of them is now dead here, because the 820px band above has already
     * turned the rail into a disclosure by the time this band is read: closed,
     * the list is `display: none` and nothing about a chip applies; open, the
     * `[open] ~` rules outrank anything written on the bare selectors. A rule
     * that cannot take effect is worse than no rule, because the next person
     * to change the rail reads it as something the rail does.
     *
     * The reasoning that was recorded here — why a phone is one name wide, and
     * why five rows of chrome above the fold was the wrong answer to it — is
     * kept where it now applies, in the 820px band. */
    .gm-game {
        grid-template-columns: 64px minmax(0, 1fr);
        gap: 0 16px;
        padding: 22px 0;
    }

    .gm-game:hover {
        box-shadow: none;
    }

    .gm-game-stamp {
        padding: 9px 4px 11px;
        clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%);
    }

    .gm-game-stamp-day {
        font-size: 25px;
    }

    .gm-game-stamp-weekday,
    .gm-game-stamp-month {
        font-size: 10px;
    }

    .gm-site-list,
    .gm-type-list,
    .gm-step-list,
    .gm-dress-grid,
    .gm-class-rules,
    .gm-command-list {
        grid-template-columns: minmax(0, 1fr);
    }

    .gm-type-list li + li a {
        border-left: 1px solid var(--gm-rule);
        border-top: 0;
    }

    .gm-footer-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .gm-converter-fields {
        grid-template-columns: minmax(0, 1fr);
        align-items: stretch;
    }

    .gm-converter-fields > i {
        padding: 0;
        text-align: center;
    }

    .gm-game-facts-list > div {
        padding: 16px 0 18px;
        border-bottom: 1px solid var(--gm-hairline);
    }

    .gm-game-facts-list--three {
        grid-template-columns: minmax(0, 1fr);
    }

    .gm-day-times dl {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media print {
    .gm-header,
    .gm-footer,
    .gm-cta,
    .gm-site-rail {
        display: none;
    }
}
