/* ──────────────────────────────────────────────────────────
   Wild Geese — shared shell.
   ONE place for tokens, the header and the primitives every Goose surface
   uses (hub, gathering, admin). Page-specific CSS loads after this and only
   adds what is unique to that page.

   BRAND: Meadow — chosen 2026-09-08 from /brand. Green-led rather than the
   borrowed festival navy, because Wild Geese is its own thing now. Paper
   #F7F4E9, ink #1C2B24, accent #2F5D50, olive and ochre beside it.

   Every pair below was checked with the WCAG formula, in BOTH themes, before
   it shipped — not chosen by eye. Light: body 13.43, muted 5.17, accent 6.81,
   white-on-accent 7.49. Dark: 15.35 / 8.18 / 9.75 / 10.20. If you change a
   value here, re-run those numbers; a palette swap is the single easiest way
   to make half a site unreadable without noticing.

   --goose-navy keeps its NAME so nothing downstream has to be renamed, but it
   now holds the meadow accent. Renaming it would touch every stylesheet for
   no benefit.
   ────────────────────────────────────────────────────────── */

:root{
  color-scheme: light dark;
  --goose-navy:#2F5D50; --goose-navy-deep:#1F4438; --goose-navy-light:#4A7D6D;
  --goose-sky:#8FCBB6;
  --bg:#F7F4E9; --bg-lighter:#FCFAF3; --surface:#FFFFFF; --surface-sunk:#EFEDDF;
  --text:#1C2B24; --muted:#586B60;
  --outline:rgba(47,93,80,.18); --outline-strong:rgba(47,93,80,.38);
  --ochre:#8A6224; --ochre-text:#845D22; --oxblood:#7A2E30; --sage:#5F7347;
  --accent:var(--goose-navy); --on-accent:#fff;
  /* The ink that may sit ON each of those fills (2026-09-09). Read the trap
     before you put a word inside a coloured pill: --ochre, --oxblood and --sage
     FLIP with the theme, because in the dark they are lifted to be readable as
     TEXT. So `background:var(--oxblood);color:#fff` is 9.29 on paper and 2.23
     in the dark — the same white label on a light rose. Measured, not guessed.
     Pair every fill with its companion: background:var(--oxblood);
     color:var(--on-oxblood). Light 9.29 / 5.45 / 5.21, dark 8.45 / 9.15 / 9.49,
     and the pill itself stands off a dark card at 7.31 / 7.91 / 8.20.
     This is the --accent/--on-accent pattern, NOT the --role-*-fill one: a fill
     that stays dark in both schemes is right for the six roles, which must read
     as the same six on a map and in an email, but wrong here — a #7A2E30 pill
     on the dark card measures 1.75 and its edge disappears. */
  --on-ochre:#fff; --on-oxblood:#fff; --on-sage:#fff;
  --over:var(--oxblood); --under:var(--sage);
  --radius:12px; --radius-sm:8px; --gap:18px;
  --transition:.3s cubic-bezier(.25,.1,.25,1);
  --shadow-1:0 1px 2px rgba(34,48,58,.06),0 2px 8px rgba(34,48,58,.04);
  --shadow-2:0 2px 6px rgba(34,48,58,.08),0 12px 28px rgba(34,48,58,.10);
  /* presence colours must be defined wherever JS reads them — an undefined
     custom property resolves to transparent, silently. */
  /* All six carry white initials — every one clears 4.5:1 against white. */
  /* The six stripes (2026-09-08). Baker's rainbow, each colour deepened until
     it holds as TEXT on the paper (all six clear 4.5:1 on #F7F4E9, measured)
     and carries white on a fill. Green is the Meadow accent, so it leads: it is
     the first presence colour, the wordmark's WILD, every heading and link.
     Yellow on paper is an ochre by necessity; it is a yellow in the dark and in
     the mark. The published flag hexes live on /brand, not here. */
  --stripe-red:#B5121B; --stripe-orange:#B34700; --stripe-yellow:#8A6A00;
  --stripe-green:#2F5D50; --stripe-blue:#1F4E8C; --stripe-purple:#6A2C86;
  --p1:var(--stripe-green); --p2:var(--stripe-red); --p3:var(--stripe-blue);
  --p4:var(--stripe-yellow); --p5:var(--stripe-purple); --p6:var(--stripe-orange);
  /* Libre Baskerville sets small, so anything using --serif at body size
     wants a touch more size than Garamond needed. */
  /* The six geese (ROLE_COLORS in src/signups.ts) plus Other. Text use on the
     light ground; in the dark each is pulled 45% toward white, the mix that
     measured 5.07-5.96 on the card for the signup pills. Read these, never
     the hex: a hard-coded #7A2E30 measured 1.75:1 on The Plan in the dark. */
  /* Each role is one stripe (Justin's mapping, 2026-09-08): Ranger red,
     Connector green, Singer orange, Storyteller yellow, Host purple, Gatherer
     blue. Connector's green sits a step off the accent so a chosen pill is
     not a link. */
  --role-ranger:var(--stripe-red); --role-gatherer:var(--stripe-blue); --role-singer:var(--stripe-orange);
  --role-storyteller:var(--stripe-yellow); --role-host:var(--stripe-purple); --role-connector:#2F6B45; --role-other:#6B6560;
  /* The same six as FILLS under white text: never lifted, in either scheme
     (white on the lifted singer measured 2.17). Text token for text, fill
     token for a solid button or swatch. */
  --role-ranger-fill:#B5121B; --role-gatherer-fill:#1F4E8C; --role-singer-fill:#B34700;
  --role-storyteller-fill:#8A6A00; --role-host-fill:#6A2C86; --role-connector-fill:#2F6B45; --role-other-fill:#6B6560;
  --serif:'Libre Baskerville',ui-serif,Georgia,serif;
  --sans:'Inter',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
}

/* ── dark mode ────────────────────────────────────────
   Only the tokens flip. Two things are deliberately NOT a straight
   inversion: the navy is lifted to --goose-sky for TEXT use (the deep navy
   is unreadable on a dark field), while a separate --accent-fill keeps a
   dark-enough colour for white text sitting ON it. One variable cannot
   serve both roles once the background goes dark — verified with the WCAG
   luminance formula, not by eye. */
@media (prefers-color-scheme: dark){
  :root{
    --bg:#121815; --bg-lighter:#171F1B; --surface:#1A221E; --surface-sunk:#141A17;
    --text:#E7EFE9; --muted:#A2B3A8;
    --outline:rgba(143,203,182,.20); --outline-strong:rgba(143,203,182,.42);
    --goose-navy:#8FCBB6;            /* heading/text use — lifted for contrast */
    --goose-navy-deep:#AEDCCB;
    --goose-navy-light:#6FB49D;
    --accent:#8FCBB6; --on-accent:#0C1310;
    --ochre:#D9AE6B; --ochre-text:#D9AE6B; --oxblood:#E39B9C; --sage:#A9C089;
    /* Lifted fills take dark ink, the same ink --on-accent uses. */
    --on-ochre:#0C1310; --on-oxblood:#0C1310; --on-sage:#0C1310;
    --shadow-1:0 1px 2px rgba(0,0,0,.34),0 2px 8px rgba(0,0,0,.24);
    --shadow-2:0 2px 6px rgba(0,0,0,.40),0 12px 28px rgba(0,0,0,.34);
    /* The stripes lifted for the dark: every one measured 7.5-12 on #121815. */
    --stripe-red:#F08A8C; --stripe-orange:#F5A55A; --stripe-yellow:#F2D24B;
    --stripe-green:#8FCBB6; --stripe-blue:#95BEE8; --stripe-purple:#CFA3DA;
    --p1:var(--stripe-green); --p2:var(--stripe-red); --p3:var(--stripe-blue);
    --p4:var(--stripe-yellow); --p5:var(--stripe-purple); --p6:var(--stripe-orange);
    --role-ranger:color-mix(in srgb,#B5121B 55%,#fff); --role-gatherer:color-mix(in srgb,#1F4E8C 55%,#fff);
    --role-singer:color-mix(in srgb,#B34700 55%,#fff); --role-storyteller:color-mix(in srgb,#8A6A00 55%,#fff);
    --role-host:color-mix(in srgb,#6A2C86 55%,#fff); --role-connector:color-mix(in srgb,#2F6B45 55%,#fff);
    --role-other:color-mix(in srgb,#6B6560 55%,#fff);
  }
  /* The lattice has to be redrawn in the dark ink; the light one vanishes. */
  body{ background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20viewBox%3D%220%200%2072%2072%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%238FCBB6%22%20stroke-width%3D%221%22%20opacity%3D%220.035%22%3E%3Cpath%20d%3D%22M0%2036%20L36%200%20L72%2036%20L36%2072%20Z%22%2F%3E%3Cpath%20d%3D%22M36%200%20V72%22%2F%3E%3Cpath%20d%3D%22M0%2036%20H72%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); }
}

*{box-sizing:border-box}
/* Backstop only — the root causes are fixed at each site (min-width:0 on flex
   children, max-width on centred fixed elements). This guarantees a missed one
   can never make the page slide sideways. */
html,body{margin:0;max-width:100%;overflow-x:hidden}
/* The trellis. 3.5%% — chosen 2026-09-08 after 20%% read as wallpaper. It is
   texture in the paper: you find it leaning into the screen and never see it
   from across a room. background-attachment:fixed would jitter on iOS, so it
   simply repeats. */
body{
  background-color:var(--bg);
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20viewBox%3D%220%200%2072%2072%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%232F5D50%22%20stroke-width%3D%221%22%20opacity%3D%220.035%22%3E%3Cpath%20d%3D%22M0%2036%20L36%200%20L72%2036%20L36%2072%20Z%22%2F%3E%3Cpath%20d%3D%22M36%200%20V72%22%2F%3E%3Cpath%20d%3D%22M0%2036%20H72%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  background-repeat:repeat;
  color:var(--text);font:16px/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;min-height:100dvh;
  padding-bottom:env(safe-area-inset-bottom);
}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;z-index:99;background:var(--surface);padding:10px 14px;
  border-radius:var(--radius-sm);box-shadow:var(--shadow-2)}
a{color:var(--goose-navy)}

/* ── header, shared by every Goose page ──────────────── */
.bar-l{display:flex;align-items:center;gap:16px;min-width:0}
.bar-r{display:flex;align-items:center;gap:12px;flex:none}

/* The real Wild Goose Festival lockup, used unmodified. It is a wide
   wordmark, so it needs real width — a 34px square would render
   "FESTIVAL" as mud. */
.mark{flex:none;display:block;line-height:0;border-radius:4px}
.mark img{width:132px;height:auto;display:block}
.mark:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

h1{margin:0;font:600 clamp(1.25rem,2.6vw,1.6rem)/1.15 var(--serif);
  color:var(--goose-navy);letter-spacing:.1px}
.titles{min-width:0}
.when{margin:1px 0 0;font-size:.83rem;color:var(--muted)}

/* ── the masthead: a floating bar, always centred ───────
   Code foundation: AESTHETICS/1-organic-naturalism (.nav-outer / nav) —
   a fixed bar 16px from the top, centred, capped at 1200px, warm matte
   frosted glass rather than a full-width strip, with an inner highlight so
   it reads as a pane sitting on the page. Adapted to Meadow: cream glass
   tinted with the paper colour, the site's own outline token, 18px radius.
   Site-level only — the page's title lives in .pagehead below it.
   It stays as you scroll but goes quiet: smaller, a touch more transparent
   (NN/g: persistent headers earn their place only if unobtrusive). */
.bar{
  position:fixed;top:calc(12px + env(safe-area-inset-top));left:50%;transform:translateX(-50%);
  z-index:50;width:calc(100% - 32px);max-width:1200px;
  display:flex;align-items:center;gap:6px;
  padding:8px 10px 8px 16px;
  background:rgba(252,250,243,.78);
  -webkit-backdrop-filter:blur(28px) saturate(1.4) brightness(1.04);backdrop-filter:blur(28px) saturate(1.4) brightness(1.04);
  border:1px solid rgba(255,255,250,.6);border-radius:18px;
  box-shadow:0 1px 0 rgba(255,255,250,.8) inset,0 2px 20px rgba(0,0,0,.07),0 0 0 1px rgba(47,93,80,.06);
  transition:padding .3s cubic-bezier(.25,.1,.25,1),background .3s,box-shadow .3s,top .3s;
}
@media (prefers-color-scheme:dark){
  .bar{background:rgba(26,34,30,.72);border-color:rgba(143,203,182,.14);
    box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 2px 20px rgba(0,0,0,.35),0 0 0 1px rgba(143,203,182,.08)}
}
.bar-l{display:flex;align-items:center;gap:16px;min-width:0}
.bar .mark{min-height:44px;display:inline-flex;align-items:center}
.bar .mark img{width:88px;transition:width .3s}
/* Scrolled: quieter. Tighter, smaller mark, glass a shade more see-through. */
.bar.bar-stuck{padding:5px 8px 5px 12px;background:rgba(252,250,243,.66);
  box-shadow:0 1px 0 rgba(255,255,250,.6) inset,0 2px 14px rgba(0,0,0,.05),0 0 0 1px rgba(47,93,80,.05)}
.bar.bar-stuck .mark img{width:72px}
@media (prefers-color-scheme:dark){ .bar.bar-stuck{background:rgba(26,34,30,.6)} }
@media (prefers-reduced-motion:reduce){ .bar,.bar .mark img{transition:none} }
/* The bar is out of flow, so the page starts below it. */
body{padding-top:calc(74px + env(safe-area-inset-top))}

.gnav{display:flex;align-items:center;gap:2px;margin-left:auto;flex-wrap:nowrap}
.gnav a{
  /* .70, not the foundation's .60: on this glass over this paper .62 measured
     4.24:1 — under AA. .70 composites to 5.4. */
  font:500 .9rem/1 var(--sans);text-decoration:none;color:rgba(28,43,36,.70);
  padding:11px 12px;border-radius:9px;position:relative;white-space:nowrap;
  transition:color .15s,background .15s;
}
@media (prefers-color-scheme:dark){ .gnav a{color:rgba(231,239,233,.62)} }
.gnav a::after{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:44px}
.gnav a:hover{color:var(--text);background:rgba(0,0,0,.04)}
@media (prefers-color-scheme:dark){ .gnav a:hover{background:rgba(255,255,255,.06)} }
/* Current page — decided 2026-09-09: a soft green wash behind the word, and
   beneath it the mark itself, tiny and low and faint. Hover is a grey wash;
   the chevron only ever belongs to the page you are on. */
.gnav a[aria-current=page]{color:var(--goose-navy);background:rgba(47,93,80,.08)}
.gnav a[aria-current=page]::before{
  content:"";position:absolute;left:50%;bottom:2px;width:4px;height:4px;
  border-left:1.25px solid var(--goose-navy);border-top:1.25px solid var(--goose-navy);
  transform:translateX(-50%) rotate(45deg);opacity:.55;
}
/* A masthead item with the sections inside it. The menu is a small pane in the
   same glass as the bar; it opens on hover on a desk and on a tap anywhere. */
.gnav-has-menu{position:relative;display:flex;align-items:center}
.gnav-has-menu > a{display:inline-flex;align-items:center;gap:7px}
.gnav-caret{width:5px;height:5px;flex:none;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:translateY(-2px) rotate(45deg);opacity:.55;transition:transform .2s}
.gnav-has-menu.open .gnav-caret{transform:translateY(1px) rotate(-135deg)}
/* The 8px gap is bridged by a transparent strip, so the pointer never leaves
   the hover area on its way down into the menu. */
.gnav-has-menu.open::after{content:"";position:absolute;top:100%;left:0;right:0;height:12px}
.gnav-menu{position:absolute;top:calc(100% + 8px);left:0;min-width:190px;z-index:60;
  display:flex;flex-direction:column;gap:2px;padding:8px;border-radius:14px;
  background:rgba(252,250,243,.96);border:1px solid var(--outline);
  -webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);
  box-shadow:0 8px 30px rgba(0,0,0,.12)}
.gnav-menu[hidden]{display:none}
.gnav-menu a{white-space:nowrap;padding:10px 12px;border-radius:9px;font-size:.9rem;color:var(--text)}
.gnav-menu a:hover{background:rgba(47,93,80,.08);color:var(--goose-navy)}
.gnav-menu a[aria-current=page]{color:var(--goose-navy);background:rgba(47,93,80,.10)}
@media (prefers-color-scheme:dark){
  .gnav-menu{background:rgba(26,34,30,.96);border-color:rgba(143,203,182,.16)}
  .gnav-menu a{color:var(--text)} .gnav-menu a:hover{color:var(--goose-sky)}
}
/* the phone panel: the same children, indented under their parent */
.gnav-panel .gnav-panel-sub a{font-size:1rem;padding-left:22px;min-height:44px;display:flex;align-items:center;color:rgba(255,255,255,.62)}
.gnav-panel .gnav-panel-sub a:hover{color:#fff}
@media (prefers-color-scheme:dark){.gnav-panel .gnav-panel-sub a{color:rgba(236,233,221,.62)}}

.gnav .gnav-action{
  margin-left:8px;background:var(--accent);color:var(--on-accent);
  padding:10px 16px;border-radius:99px;font-weight:600;
}
.gnav .gnav-action:hover{background:var(--goose-navy-deep);color:var(--on-accent)}

/* ── the page's own head: title, tools, parts ─────── */
.pagehead{
  display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px 18px;
  padding:18px clamp(14px,3vw,28px) 4px;max-width:1200px;margin:0 auto;
}
.pagehead .titles{flex:1 1 320px;min-width:0}
.pagehead h1{font:600 clamp(1.7rem,3.4vw,2.3rem)/1.1 var(--serif);letter-spacing:-.01em}
.pagehead .when{margin:6px 0 0;font-size:.95rem;max-width:60ch}
.pagehead .dbar,.pagehead .bar-r{margin-left:auto;align-self:center}

/* A second row for a page that has parts — Planning's three documents,
   The Brand's tentative/concepts. A segmented control on paper: one hairline
   box, the current part filled in ink, everything else quiet. Full width on
   a phone with equal segments; its own width on a desk. */
.subnav{
  display:inline-flex;flex-basis:100%;margin-top:6px;
  padding:3px;border:1px solid var(--outline-strong);border-radius:99px;
  background:var(--surface);align-self:flex-start;width:fit-content;max-width:100%;
}
.subnav a{
  /* 0.875rem is the floor for a word in a pill that is uppercase or
     letter-spaced (2026-09-09); this was .74rem = 11.8px on a desk and
     .68rem = 10.9px on a phone. Capitals and tracking take away the
     word-shape a reader scans by, which is the whole job of a section
     switcher. Measured at 14px in a 343px phone row: three chips 114, 117
     and 104 wide, 44 tall, no row overflow and no clipped label; the widest
     pair we have, Tentative brand and Concepts, comes to 197 and 138. */
  flex:1 1 auto;text-align:center;white-space:nowrap;
  font:500 .875rem/1 var(--sans);letter-spacing:.12em;text-transform:uppercase;
  text-decoration:none;color:var(--muted);padding:11px 16px;border-radius:99px;
  position:relative;transition:color .2s,background .2s;
}
.subnav a:hover{color:var(--goose-navy)}
.subnav a[aria-current=page]{background:var(--accent);color:var(--on-accent)}
/* The phone gets the 44px floor here rather than more padding: three chips
   share one row, so padding would make the row taller than it can hold.
   min-height with a centred flex box grows the target, not the layout.
   On a desk these stay 34px by choice — a pointer target, not a thumb one,
   and 34 clears the 24px minimum. Recorded so it reads as a decision. */
@media (max-width:900px){ .subnav{width:100%;display:flex}
  .subnav a{padding:11px 6px;letter-spacing:.08em;
    display:flex;align-items:center;justify-content:center;min-height:44px} }

/* ── narrow: the menu button and the page-stack panel ── */
.gnav-burger{
  display:none;width:44px;height:44px;margin-left:auto;padding:0;border:0;border-radius:8px;
  background:none;cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:5px;
  position:relative;z-index:60;
}
.gnav-burger span{display:block;width:22px;height:2px;background:var(--goose-navy);border-radius:1px;
  transition:transform .3s cubic-bezier(.25,.1,.25,1),opacity .2s}
/* With the menu open the bar goes clear — only its close button remains —
   so the frosted glass never covers the top of the panel beneath it. */
.nav-open .bar{background:transparent;box-shadow:none;border-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
.nav-open .bar > :not(.gnav-burger){visibility:hidden}
.nav-open .gnav-burger span{background:#fff}
.nav-open .gnav-burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-open .gnav-burger span:nth-child(2){opacity:0}
.nav-open .gnav-burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

.gnav-panel{
  position:fixed;top:0;right:0;bottom:0;width:min(300px,84vw);z-index:45;
  background:var(--goose-navy);color:#fff;padding:calc(72px + env(safe-area-inset-top)) 28px 28px;
  display:flex;flex-direction:column;
  transform:translateX(24px);opacity:0;transition:transform .4s cubic-bezier(.25,.1,.25,1),opacity .3s;
}
/* display:flex above beats the hidden attribute, which left the CLOSED panel
   in the page as an invisible, clickable 300px layer down the right edge of
   every page — "Reset" on the map opened The Story because the panel's
   "Planning" link sat over it (Justin, 2026-09-09). Hidden means gone. */
.gnav-panel[hidden]{display:none !important}
body:not(.nav-open) .gnav-panel{pointer-events:none}
.nav-open .gnav-panel{transform:none;opacity:1}
.gnav-panel ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.gnav-panel a{
  display:block;padding:11px 8px;border-radius:8px;text-decoration:none;color:rgba(255,255,255,.82);
  font:400 1.25rem/1.2 var(--serif);
  opacity:0;transform:translateX(30px);transition:opacity .35s,transform .35s cubic-bezier(.25,.1,.25,1);
}
.nav-open .gnav-panel a{opacity:1;transform:none}
.gnav-panel li:nth-child(1) a{transition-delay:.05s} .gnav-panel li:nth-child(2) a{transition-delay:.13s}
.gnav-panel li:nth-child(3) a{transition-delay:.21s} .gnav-panel li:nth-child(4) a{transition-delay:.29s}
.gnav-panel li:nth-child(5) a{transition-delay:.37s} .gnav-panel li:nth-child(6) a{transition-delay:.45s}
.gnav-panel li:nth-child(7) a{transition-delay:.53s} .gnav-panel li:nth-child(8) a{transition-delay:.61s}
.gnav-panel li:nth-child(9) a{transition-delay:.69s}
.gnav-panel a:hover{color:#fff;background:rgba(255,255,255,.08)}
.gnav-panel a[aria-current=page]{color:#fff}
.gnav-panel a[aria-current=page]::after{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--ochre);margin-left:10px;vertical-align:middle}
.gnav-panel .gnav-panel-action{margin-top:14px}
.gnav-panel .gnav-panel-action a{background:#fff;color:var(--goose-navy);text-align:center;
  font:600 .875rem var(--sans);letter-spacing:.12em;text-transform:uppercase;padding:14px}
.gnav-panel-foot{margin:auto 0 0;font:400 .8rem var(--sans);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.45)}
.gnav-panel a:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media (prefers-color-scheme:dark){
  .gnav-panel{background:#0F1A16;color:var(--text)}
  .gnav-panel .gnav-panel-action a{background:var(--accent);color:var(--on-accent)}
}

/* The page steps aside for the menu. Everything that is not the panel
   slides left and shrinks a little, so the menu reads as a layer under the
   page rather than a sheet on top of it. max(), not min(): with two negative
   lengths min() picks the MORE negative one, which shoved the whole page
   84vw off-screen on every phone wider than 357px (seen live, 2026-09-08). */
body > *:not(.gnav-panel):not(.bar){transition:transform .4s cubic-bezier(.25,.1,.25,1)}
.nav-open > *:not(.gnav-panel):not(.bar){transform:translateX(max(-300px,-84vw)) scale(.96);
  transform-origin:right center;pointer-events:none}
.nav-open{overflow:hidden}
@media (prefers-reduced-motion:reduce){
  body > *:not(.gnav-panel),.gnav-panel,.gnav-panel a,.gnav-burger span{transition:none}
}

@media (max-width:900px){
  .gnav{display:none}
  .gnav-burger{display:flex;order:5}
  /* The logo block takes what is left of the row so the menu button stays
     on the same line as the title rather than dropping under it. */
  .bar{width:calc(100% - 20px);top:calc(8px + env(safe-area-inset-top));padding:6px 6px 6px 12px}
  .bar .mark img{width:80px}
  body{padding-top:calc(66px + env(safe-area-inset-top))}
  .pagehead{padding-top:18px}
  .pagehead .dbar,.pagehead .bar-r{margin-left:0;flex-basis:100%}
}

/* ── primitives ──────────────────────────────────────── */
input,textarea,select,button{font-family:inherit}
input,textarea,select{font-size:16px}

/* A long-press on chrome shouldn't raise the iOS selection callout; real
   reading content stays selectable. */
.bar,.gnav,.btn,button{-webkit-user-select:none;user-select:none}
p,li,blockquote,td,h1,h2,h3{-webkit-user-select:text;user-select:text}

.card{background:var(--surface);border:1px solid var(--outline);
  border-radius:var(--radius);box-shadow:var(--shadow-1);padding:18px}
/* 44px floor, 2026-09-09. This computed to 43px — one pixel short of the
   touch target, everywhere a button appears, because the height came from
   11px padding on a .95rem line rather than being stated. inline-flex with
   min-height states it. The same three lines are already proven in
   signup-map.css, which has been on inline-flex + min-height:44px all along.
   justify-content is here because a flex box does not inherit text-align. */
.btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:11px 18px;border:0;border-radius:var(--radius-sm);
  background:var(--accent);color:var(--on-accent);font:600 .95rem var(--sans);
  cursor:pointer;text-decoration:none}
.btn:hover{background:var(--goose-navy-deep)}
.btn-quiet{background:none;border:1px solid var(--outline-strong);color:var(--goose-navy)}
.btn-quiet:hover{background:rgba(1,66,106,.05)}
.muted{color:var(--muted)}

@media (max-width:860px){
  .bar{padding:12px 14px;gap:10px;flex-wrap:wrap}
  .bar-l{gap:10px}
  .mark img{width:96px}
  .when{font-size:.72rem;line-height:1.35}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ── iOS zoom floor ──────────────────────────────────────
   Below 16px, iOS Safari zooms the whole page when a field takes focus and
   never zooms back out. Several fields here are deliberately compact
   (a minutes box, an owner chip, a note in a narrow rail) and sat at
   11–15px. Scoped to coarse pointers so the desktop keeps its compact
   sizing and phones get the correctness. */
@media (pointer: coarse){
  input, textarea, select,
  .b-text, .i-title, .i-detail, .i-owner, .mins, .note .b-text{ font-size:16px }
}

/* ── 44px touch targets ──────────────────────────────────
   The visible chip stays small; the hit area does not. */
@media (pointer: coarse){
  button.pill{position:relative}
  button.pill::after{content:"";position:absolute;left:-6px;right:-6px;
    top:50%;transform:translateY(-50%);height:44px}
  .kind, .n-kill, .kill{position:relative;min-height:32px}
  .kind::after,.n-kill::after,.kill::after{content:"";position:absolute;
    inset:-8px;min-height:44px}
}

/* ── icons ────────────────────────────────────────────
   Sized in em so an icon always matches the text it sits beside, and
   currentColor so a role icon is automatically that role's colour. */
[data-icon]{display:inline-flex;align-items:center;justify-content:center;flex:none}
.wgi{width:1em;height:1em;display:block}
[data-icon].big .wgi{width:1.6em;height:1.6em}
.tile [data-icon]{color:var(--goose-navy);margin-bottom:9px;font-size:1.35rem;display:block}
