/* Golf Trip — one stylesheet, no build step.
   Reads as printed matter: thin rules, tabular figures, generous margins. */

/* ---------------------------------------------------------------- brand
   Golf Idiots. Colours are taken from the FINAL GRAPHICS artwork, not from the
   concept deck's palette page: the deck swatches green as #1B423B, but every
   delivered logo is drawn in #213F2A, and the UI has to sit flush against the
   real logo. Red #B43F35, cream #F3F2E0 and ink #161110 agree in both.

   Type is Saira, standing in for Eurostile. Eurostile is the licensed brand face
   and is not on any free CDN; Saira shares the squared-off letterforms and holds
   up at UI sizes. Swap it for a self-hosted Eurostile when there's a licence.
   The script is the LOGO, never a text face — it ships as SVG and is never set. */

:root {
  --pine:    #213F2A;
  --pine-dk: #16291C;
  --fairway: #35603F;
  --brass:   #B43F35;
  --brass-lt:#C9564A;
  --paper:   #F3F2E0;
  --card:    #FFFDF6;
  --ink:     #161110;
  --muted:   #6E6A5C;
  --rule:    #DEDBC5;
  --rule-sf: #EAE7D6;
  --ok:      #2E6B46;
  --warn:    #9A6508;
  --bad:     #B43F35;
  --radius:  10px;
  --shadow:  0 1px 2px rgba(22,17,16,.06), 0 8px 24px -12px rgba(22,17,16,.18);
  --ui: Saira, "Eurostile", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root {
    --pine:    #16291C;
    --pine-dk: #0E1A12;
    --fairway: #5B9A6C;
    --brass:   #D4675A;
    --brass-lt:#E08578;
    --paper:   #12140F;
    --card:    #1A1D15;
    --ink:     #EDEBDB;
    --muted:   #9A9784;
    --rule:    #2E3327;
    --rule-sf: #24281E;
    --ok:      #6FBF8E;
    --warn:    #D6A23A;
    --bad:     #E08578;
    --shadow:  0 1px 2px rgba(0,0,0,.3), 0 8px 24px -12px rgba(0,0,0,.6);
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 15.5px/1.55 var(--ui);
  font-feature-settings: "kern" 1;
}

h1, h2, h3, .display {
  font-family: var(--ui);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.18;
  margin: 0;
}
h1 { font-size: clamp(1.6rem, 4.5vw, 2.3rem); }
h2 { font-size: 1.22rem; }
h3 { font-size: 1.02rem; }

a { color: var(--fairway); text-underline-offset: 2px; }
a:hover { color: var(--brass); }

.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---------- shell ---------- */
.topbar {
  background: var(--pine);
  color: #F2EFE6;
  border-bottom: 3px solid var(--brass);
  /* Not sticky. On a laptop the strip underneath is what pins, and on a phone
     the bar along the bottom does; this one scrolls away with the page. It is
     still layered above the strip, because it holds the year menu and the later
     sibling would otherwise paint over that. */
  position: relative; z-index: var(--z-sticky);
  padding-top: env(safe-area-inset-top);
}
.topbar-inner {
  max-width: 1080px; margin: 0 auto;
  padding: .55rem max(1rem, env(safe-area-inset-right)) .55rem max(1rem, env(safe-area-inset-left));
  display: flex; align-items: center; gap: .85rem;
}
.brand {
  display: flex; align-items: center; gap: .6rem;
  margin-right: auto; min-width: 0; text-decoration: none;
}
.brand .mark { height: 40px; width: auto; display: block; flex: none; }
.brand .wordmark { height: 40px; width: auto; display: block; flex: none; }
@media (max-width: 760px) { .brand .mark, .brand .wordmark { height: 34px; } }
@media (max-width: 560px) {
  /* Logo and wordmark both, even on a phone: the monogram alone reads as an
     app icon, not as Golf Idiots. */
  .brand { gap: .5rem; }
  .brand .mark { height: 32px; }
  .brand .wordmark { height: 31px; }
}
/* The trip, out on the right of the bar where the name used to be: a pill, and
   a menu when there is more than one year to switch between. */
.yr {
  display: inline-flex; align-items: center; flex: none; white-space: nowrap;
  font-size: .82rem; font-weight: 600; line-height: 1.2; color: #F2EFE6;
  padding: .38rem .85rem; border-radius: 999px;
  border: 1px solid rgba(243,242,224,.26); background: rgba(243,242,224,.06);
}
.yr .num { font-variant-numeric: tabular-nums; }
/* On only one trip there is nothing to switch to: the label stays, the button
   look does not, so it never invites a tap that does nothing. */
span.yr { border-color: transparent; background: transparent; padding-right: .1rem; }
.yr-sep { color: var(--brass-lt); padding: 0 .38rem; }
@media (max-width: 560px) {
  .yr { font-size: .8rem; padding: .34rem .7rem; }
  .yr-tail { display: none; }   /* 2026 · Scottsdale, without ", Arizona" */
}

nav.tabs {
  background: var(--pine-dk);
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  position: sticky; top: 0; z-index: var(--z-dropdown);
}
nav.tabs::-webkit-scrollbar { display: none; }
nav.tabs ul {
  max-width: 1080px; margin: 0 auto; padding: 0 .5rem; list-style: none;
  display: flex; gap: .15rem;
}
nav.tabs a {
  display: block; padding: .62rem .8rem; white-space: nowrap;
  color: #AFC0B2; text-decoration: none; font-size: .87rem; font-weight: 500;
  border-bottom: 2px solid transparent;
}
nav.tabs a:hover { color: #F2EFE6; background: rgba(255,255,255,.04); }
nav.tabs a[aria-current="page"] { color: #FFF; border-bottom-color: var(--brass-lt); }

main {
  max-width: 1080px; margin: 0 auto;
  padding: 1.15rem max(1rem, env(safe-area-inset-right)) 4rem max(1rem, env(safe-area-inset-left));
}
/* Focus lands on <main> after an in-place page change, for screen readers.
   It is not something to draw a ring round. */
main[tabindex]:focus, main[tabindex]:focus-visible { outline: none; box-shadow: none; }

/* ---------- cards ---------- */
.card {
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 1.05rem 1.1rem; margin-bottom: 1rem;
}
.card.slim { padding: .7rem 1.1rem; }
.card > header {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: -.15rem 0 .8rem;
}
.card > header h2 { margin-right: auto; }
.card.flush { padding: 0; overflow: hidden; }
.card.flush > header { padding: 1rem 1.1rem 0; margin-bottom: .6rem; }

.eyebrow {
  font-size: .68rem; letter-spacing: .15em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.tiny  { font-size: .76rem; }

.grid { display: grid; gap: 1rem; }
/* A grid item's min-width is auto, so one nowrap line inside it (an ellipsised
   subtitle, a table header) sets a floor the column cannot go under and the
   whole page widens past the phone. Nothing here wants that floor. */
.grid > * { min-width: 0; }
@media (min-width: 720px) {
  .grid.two   { grid-template-columns: 1fr 1fr; }
  .grid.side  { grid-template-columns: 1.6fr 1fr; }
}

/* ---------- hero ---------- */
.hero {
  background: linear-gradient(135deg, var(--pine) 0%, var(--fairway) 135%);
  color: #F4F1E8; border-radius: var(--radius); padding: 1.4rem 1.25rem;
  margin-bottom: 1rem; box-shadow: var(--shadow); position: relative; overflow: hidden;
}
.hero h1 { color: #FFF; }
.hero .dest { color: var(--brass-lt); font-size: .95rem; margin-top: .3rem; }
.hero .dates { color: #CBD9CC; font-size: .9rem; margin-top: .1rem; }
.hero .intro { margin: .9rem 0 0; max-width: 58ch; color: #E4E8DF; font-size: .93rem; }
.countdown {
  display: flex; gap: 1.35rem; margin-top: 1.1rem;
  border-top: 1px solid rgba(255,255,255,.17); padding-top: .9rem;
}
.countdown div { line-height: 1.1; }
.countdown .n {
  font-family: var(--ui); font-size: 1.85rem; font-weight: 600;
  font-variant-numeric: tabular-nums; display: block; color: #FFF;
}
.countdown .l { font-size: .67rem; letter-spacing: .13em; text-transform: uppercase; color: #A9BFAC; }

/* ---------- tables ---------- */
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th {
  text-align: left; font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; padding: .5rem .7rem;
  border-bottom: 1px solid var(--rule); white-space: nowrap;
}
td { padding: .62rem .7rem; border-bottom: 1px solid var(--rule-sf); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: rgba(45,106,79,.035); }
td.r, th.r { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Let a narrow screen scroll the table rather than shredding the description
   column into one word per line. */
.table-wrap table { min-width: 26rem; }
.table-wrap td:first-child { min-width: 9.5rem; }
/* On a phone, fold the low-value column into the subtitle instead of scrolling. */
.only-sm { display: none; }
@media (max-width: 560px) {
  .hide-sm { display: none; }
  .only-sm { display: inline; }
  .table-wrap table { min-width: 0; }
  .table-wrap td:first-child { min-width: 9.5rem; }
  td, th { padding: .55rem .38rem; }
  th { letter-spacing: .07em; }
}

/* ---------- pills ---------- */
.pill {
  display: inline-block; font-size: .7rem; font-weight: 600; letter-spacing: .04em;
  padding: .16rem .52rem; border-radius: 999px; border: 1px solid;
  white-space: nowrap; vertical-align: baseline;
}
.pill.in      { color: var(--ok);    border-color: color-mix(in srgb, var(--ok) 40%, transparent);    background: color-mix(in srgb, var(--ok) 9%, transparent); }
.pill.out     { color: var(--bad);   border-color: color-mix(in srgb, var(--bad) 40%, transparent);   background: color-mix(in srgb, var(--bad) 9%, transparent); }
.pill.maybe   { color: var(--warn);  border-color: color-mix(in srgb, var(--warn) 42%, transparent);  background: color-mix(in srgb, var(--warn) 10%, transparent); }
.pill.invited { color: var(--muted); border-color: var(--rule); background: transparent; }
.pill.admin   { color: var(--brass); border-color: color-mix(in srgb, var(--brass) 45%, transparent); background: color-mix(in srgb, var(--brass) 10%, transparent); }
.pill.paid    { color: var(--ok);    border-color: color-mix(in srgb, var(--ok) 40%, transparent);    background: color-mix(in srgb, var(--ok) 9%, transparent); }
.pill.issued  { color: var(--warn);  border-color: color-mix(in srgb, var(--warn) 42%, transparent);  background: color-mix(in srgb, var(--warn) 10%, transparent); }
.pill.void    { color: var(--muted); border-color: var(--rule); text-decoration: line-through; }

/* ---------- forms ---------- */
label { display: block; font-size: .78rem; font-weight: 600; color: var(--muted); margin-bottom: .22rem; }
input[type=text], input[type=date], input[type=time], input[type=number],
input[type=email], input[type=tel], input[type=url], select, textarea {
  width: 100%; padding: .5rem .6rem; font: inherit; font-size: .92rem;
  color: var(--ink); background: var(--card);
  border: 1px solid var(--rule); border-radius: 7px;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid color-mix(in srgb, var(--fairway) 55%, transparent); outline-offset: 1px;
  border-color: var(--fairway);
}
textarea { min-height: 4.5rem; resize: vertical; }
.field { margin-bottom: .8rem; }
.fields { display: grid; gap: .8rem 1rem; }
@media (min-width: 620px) { .fields.two { grid-template-columns: 1fr 1fr; } .fields.three { grid-template-columns: repeat(3,1fr); } }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer;
  padding: .5rem .95rem; border-radius: 7px; border: 1px solid var(--pine);
  background: var(--pine); color: #F4F1E8; text-decoration: none; white-space: nowrap;
}
.btn:hover { background: var(--fairway); border-color: var(--fairway); color: #FFF; }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { background: rgba(45,106,79,.07); color: var(--ink); border-color: var(--fairway); }
.btn.brass { background: var(--brass); border-color: var(--brass); color: #1A1508; }
.btn.brass:hover { background: var(--brass-lt); border-color: var(--brass-lt); }
.btn.sm { font-size: .78rem; padding: .3rem .6rem; }
.btn.danger { background: transparent; color: var(--bad); border-color: color-mix(in srgb, var(--bad) 35%, transparent); }
.btn.danger:hover { background: color-mix(in srgb, var(--bad) 10%, transparent); color: var(--bad); border-color: var(--bad); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* In-place confirmation: the trigger slides aside, a red verb button slides out.
   Replaces window.confirm, which interrupts, names the hostname instead of the
   action, and reads like a browser malfunction. */
.ci { display: inline-flex; align-items: center; vertical-align: middle; }
.ci .ci-go {
  max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap;
  padding-left: 0; padding-right: 0; border-width: 0; margin-right: 0;
  background: var(--bad); border-color: var(--bad); color: #fff;
  transition: max-width .2s cubic-bezier(.4,0,.2,1), opacity .14s ease,
              padding .2s cubic-bezier(.4,0,.2,1), margin .2s cubic-bezier(.4,0,.2,1);
}
.ci .ci-go:hover { background: #86271F; border-color: #86271F; color: #fff; }
.ci.armed .ci-go {
  max-width: 11rem; opacity: 1; padding: .3rem .62rem; border-width: 1px; margin-right: .32rem;
}
.ci.armed .ci-trigger { opacity: .45; }
.ci .ci-trigger { transition: opacity .14s ease; }
@media (prefers-reduced-motion: reduce) { .ci .ci-go { transition: none; } }

/* ---------- itinerary ---------- */
.day { margin-bottom: 1.3rem; }
.day-head {
  /* Anchors the day's own + insert. Without it that button was positioned off
     the page itself: all five days' pluses sat in one pile at the bottom right
     of the first screen, and on a phone pushed the page 6px wider than it. */
  position: relative;
  display: flex; align-items: baseline; gap: .6rem;
  border-bottom: 2px solid var(--pine); padding-bottom: .3rem; margin-bottom: .1rem;
}
.day-head .dow { font-family: var(--ui); font-size: 1.15rem; font-weight: 600; }
.day-head .dt { font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.slot {
  display: flex; gap: .85rem; padding: .72rem .25rem;
  border-bottom: 1px solid var(--rule-sf);
  position: relative; /* anchors the inline + on the divider below */
}
/* Golf blocks drop the time gutter and run full width, because the three groups
   underneath each carry their own tee time. */
.slot-golf > .b { flex: 1 1 100%; }

/* The + that hangs on the right end of a divider. Quiet until the row is under
   the cursor, so twelve of them do not read as decoration. */
.ins { position: absolute; right: .1rem; bottom: -.72rem; z-index: 2; line-height: 0; }
.day-head .ins { bottom: -.66rem; }
.ins button {
  all: unset; cursor: pointer; width: 1.15rem; height: 1.15rem;
  display: grid; place-items: center; border-radius: 999px;
  font-size: .85rem; line-height: 1; font-weight: 600;
  color: var(--muted); background: var(--card); border: 1px solid var(--rule);
  opacity: .38; transition: opacity .12s ease-out, color .12s ease-out, border-color .12s ease-out;
}
/* Faint but always there. A + that only exists on hover is invisible on a phone
   and undiscoverable on a laptop. */
.slot:hover .ins button, .day-head:hover .ins button,
.ins button:focus-visible { opacity: 1; }
.ins button:hover { opacity: 1; color: var(--fairway); border-color: var(--fairway); }
@media (prefers-reduced-motion: reduce) { .ins button { transition: none; } }

/* The format being played, sitting with the round's name. */
.game {
  margin-left: .5rem; font-size: .7rem; font-weight: 600; letter-spacing: .02em; white-space: nowrap;
  padding: .08rem .4rem .12rem; border-radius: 999px; vertical-align: .08em;
  color: var(--brass); background: color-mix(in srgb, var(--brass) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass) 26%, transparent);
}
.game.none { display: none; }

/* How a round is scored, from its round_setup: the format, one line on how it
   counts, and for Stableford the points as chips. Compact on the itinerary,
   where it sits inside a block among the foursomes. */
.rules {
  margin: .7rem 0 .2rem; padding: .6rem .75rem; border-radius: 8px;
  background: color-mix(in srgb, var(--fairway) 7%, var(--card));
  border: 1px solid color-mix(in srgb, var(--fairway) 22%, transparent);
}
.rules.compact { margin: .45rem 0 .5rem; padding: .45rem .6rem; }
.rules-h { display: flex; align-items: center; gap: .35rem; font-size: .9rem; color: var(--ink); }
.rules-h .ic { width: 1rem; height: 1rem; color: var(--fairway); }
.rules-how { margin: .2rem 0 0; font-size: .82rem; color: var(--muted); line-height: 1.4; }
.rules.compact .rules-how { font-size: .78rem; }
.pts { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .45rem; }
.pt {
  display: inline-flex; align-items: baseline; gap: .3rem; padding: .15rem .5rem .18rem;
  border-radius: 999px; font-size: .74rem; color: var(--muted);
  background: var(--card); border: 1px solid var(--rule);
}
.pt b { font-size: .9rem; color: var(--fairway); font-variant-numeric: tabular-nums; }

/* Three groups abreast, each stacking its own players. Below a tablet they go
   back to one per row rather than squeezing four names into a third of a phone. */
.foursomes {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .5rem; margin-top: .5rem;
}
@media (max-width: 720px) { .foursomes { grid-template-columns: 1fr; } }
.slot:last-child { border-bottom: 0; }
.slot .t {
  flex: none; width: 4.4rem; font-variant-numeric: tabular-nums;
  font-size: .82rem; font-weight: 600; color: var(--muted); padding-top: .1rem;
}
.slot .b { min-width: 0; flex: 1; }
.slot .ttl { font-weight: 600; font-size: .96rem; }
.slot .meta { font-size: .82rem; color: var(--muted); margin-top: .08rem; }
.kind {
  display: inline-block; width: 8px; height: 8px; border-radius: 2px;
  margin-right: .3rem; vertical-align: 1px;
}
.kind.golf { background: var(--fairway); }
.kind.meal { background: var(--brass); }
.kind.travel { background: #6B8AA6; }
.kind.activity { background: #8A6BA6; }
.kind.other { background: var(--muted); }

/* A tee group: a quiet header and a row of player pills. Everything that used
   to be a form field in this row now lives in the group's drawer. */
/* No overflow:hidden here. The add-golfer menu is absolutely positioned inside
   this box, and clipping it left a 272px list showing 4px. The header rounds
   its own top corners instead. */
.foursome { margin-top: .5rem; border: 1px solid var(--rule); border-radius: 8px; }
.foursome + .foursome { margin-top: .4rem; }
.foursome .fh {
  background: rgba(45,106,79,.06); padding: .28rem .5rem .28rem .6rem; border-radius: 7px 7px 0 0;
  font-size: .76rem; font-weight: 700; letter-spacing: .05em;
  display: flex; gap: .5rem; align-items: center;
}
.fh-name { color: inherit; text-decoration: none; }
a.fh-name:hover { color: var(--fairway); }
.foursome .fh .tt {
  margin-left: .45rem; font-variant-numeric: tabular-nums;
  color: var(--muted); font-weight: 600; letter-spacing: 0;
}
.foursome .fh .ci { margin-left: auto; }
.golfers {
  display: flex; flex-direction: column; align-items: stretch; gap: .28rem;
  padding: .45rem .5rem .5rem;
}
.foursome { margin-top: 0; display: flex; flex-direction: column; }
.foursome + .foursome { margin-top: 0; }

/* The pill. Light enough to read as a name on a card rather than as a button,
   with the handicap along for the ride because that is what the pairing is
   actually chosen on. */
.gpill {
  position: relative; display: flex; align-items: center; gap: .3rem;
  font-size: .82rem; line-height: 1.5; min-width: 0;
  padding: .1rem .3rem .14rem .5rem; border-radius: 999px;
  background: color-mix(in srgb, var(--fairway) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--fairway) 20%, transparent);
}
.gpill.me { font-weight: 600; border-color: var(--fairway); }
.gpill > :first-child, .gpill { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gpill em { font-style: normal; font-size: .74rem; color: var(--muted);
  font-variant-numeric: tabular-nums; margin-left: auto; flex: none; }
.gpill form { flex: none; }
.gpill form { display: inline-flex; }
.gpill button {
  all: unset; cursor: pointer; color: var(--muted); line-height: 1;
  padding: 0 .16rem; border-radius: 999px; font-size: .95em;
}
.gpill button:hover { color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, transparent); }
.gpill:not(:hover) button { opacity: .45; }

/* Add golfer. A <details> so the browser owns open/close and the keyboard; the
   click-away handler in layout() closes it like the year picker. */
.addg { position: relative; display: inline-block; }
.addg > summary { list-style: none; cursor: pointer; }
.addg > summary::-webkit-details-marker { display: none; }
.addg ul {
  position: absolute; top: calc(100% + .3rem); left: 0; z-index: var(--z-dropdown);
  margin: 0; padding: var(--pop-inset); list-style: none; min-width: 12rem; max-height: 17rem; overflow-y: auto;
  background: var(--pop-bg); border: 1px solid var(--pop-line); border-radius: var(--pop-radius);
  box-shadow: var(--pop-shadow);
}
.addg li form { display: block; }
.addg li button {
  all: unset; box-sizing: border-box; cursor: pointer; display: flex; gap: .5rem; align-items: baseline;
  width: 100%; padding: var(--item-pad); border-radius: var(--item-radius); font-size: var(--item-size); white-space: nowrap;
}
.addg li button em { font-style: normal; font-size: .74rem; color: var(--muted); margin-left: auto; }
.addg li button:hover, .addg li button:focus-visible { background: var(--item-hover); outline: none; }

.gnew { margin-top: .55rem; padding-top: .55rem; border-top: 1px dashed var(--rule); }

@media (max-width: 560px) {
  .slot { gap: .5rem; }
  .slot .t { width: 3.4rem; font-size: .76rem; }
  .addg ul { min-width: 10rem; }
}

/* ---------- misc ---------- */
.stat { display: flex; align-items: baseline; gap: .45rem; }
.stat .v {
  font-family: var(--ui); font-size: 1.5rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.stat .k { font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.statrow { display: grid; grid-template-columns: repeat(auto-fit,minmax(118px,1fr)); gap: .9rem; }

.flash {
  border-radius: 8px; padding: .6rem .85rem; margin-bottom: 1rem;
  font-size: .88rem; border: 1px solid;
}
.flash.ok  { background: color-mix(in srgb, var(--ok) 9%, transparent);  border-color: color-mix(in srgb, var(--ok) 35%, transparent);  color: var(--ok); }
.flash.err { background: color-mix(in srgb, var(--bad) 9%, transparent); border-color: color-mix(in srgb, var(--bad) 35%, transparent); color: var(--bad); }

.empty { text-align: center; padding: 2rem 1rem; color: var(--muted); font-size: .9rem; }
.checkline { display: flex; align-items: center; gap: .55rem; padding: .42rem .2rem; border-bottom: 1px solid var(--rule-sf); }
.checkline:last-child { border-bottom: 0; }
.checkline.done .nm { text-decoration: line-through; color: var(--muted); }
.checkline .nm { flex: 1; min-width: 0; font-size: .93rem; }
.checkline input[type=checkbox] { width: 1.05rem; height: 1.05rem; accent-color: var(--fairway); flex: none; }
/* The tick: a drawn box inside a real button, so it is one thumb-sized target
   and a screen reader hears a toggle rather than a form. */
.tickf { display: flex; flex: none; }
.tickb {
  all: unset; box-sizing: border-box; cursor: pointer; display: grid; place-items: center;
  width: 2.2rem; height: 2.2rem; margin: -.5rem -.35rem -.5rem -.4rem; border-radius: 8px;
}
.tickb:focus-visible { box-shadow: var(--ring); }
.tick {
  flex: none; width: 1.25rem; height: 1.25rem; border-radius: 5px;
  border: 1.5px solid var(--rule); background: var(--card); position: relative;
}
.tick.on { background: var(--fairway); border-color: var(--fairway); }
.tick.on::after {
  content: ""; position: absolute; left: .38rem; top: .14rem; width: .3rem; height: .62rem;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.tickf.working .tick { opacity: .5; }
/* A dozen red boxes down the list read as a dozen alarms. The × stays red and
   keeps its target; the box only appears under the pointer. */
.checkline .btn.danger { border-color: transparent; }
.checkline .btn.danger:hover, .checkline .btn.danger:focus-visible { border-color: color-mix(in srgb, var(--bad) 35%, transparent); }

/* Editable roster row: name, email, phone, home, save — wraps as it narrows. */
/* ---------- admin: clickable listings ---------- */
table.clickable tbody tr { cursor: pointer; }
table.clickable tbody tr:hover { background: rgba(45,106,79,.06); }
table.clickable tbody tr.open { background: rgba(166,124,46,.12); }
.rowlink { color: inherit; text-decoration: none; font-weight: 600; display: inline-block; }
.rowlink:hover { color: var(--fairway); }
.admin-flag:not(:empty) { margin-left: .35rem; }

.addbar { padding: .85rem 1.1rem 1.05rem; border-top: 1px solid var(--rule); }
.inline-add { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.inline-add input { width: auto; flex: 1 1 9rem; min-width: 0; padding: .34rem .5rem; font-size: .86rem; }
.inline-add button { flex: none; }

/* ---------- admin: edit drawer ----------
   Opened by :target, so a row is a real link and the whole surface still works
   with JavaScript off. JS only smooths it (no scroll jump, live saving). */
.panel {
  position: fixed; top: 0; right: 0; z-index: var(--z-drawer);
  width: min(32rem, 100%); height: 100dvh;
  background: var(--card); border-left: 1px solid var(--rule);
  box-shadow: -18px 0 40px -24px rgba(20,52,43,.5);
  display: flex; flex-direction: column;
  transform: translateX(102%); visibility: hidden;
  transition: transform .24s cubic-bezier(.4,0,.2,1), visibility .24s;
}
/* :target is the no-JS way in. With JS the `.open` class owns the drawer, so
   :target is switched off entirely — otherwise the close button removes .open
   while the fragment keeps the panel on screen and nothing appears to happen. */
html:not(.js) .panel:target,
.panel.open { transform: none; visibility: visible; }
.panel-head {
  display: flex; align-items: center; gap: .6rem;
  padding: .85rem 1rem; border-bottom: 1px solid var(--rule);
  background: var(--pine); color: #F2EFE6; flex: none;
}
.panel-title { font-family: var(--ui); font-size: 1.05rem; font-weight: 600; }
.panel-head .tiny { color: #A9BFAC; }
.panel-head > div:first-child { margin-right: auto; min-width: 0; }
.panel-x {
  color: #F2EFE6; text-decoration: none; font-size: 1.5rem; line-height: 1;
  padding: 0 .25rem; flex: none; opacity: .8;
}
.panel-x:hover { opacity: 1; color: #fff; }
.panel-body { padding: 1rem; overflow-y: auto; flex: 1; -webkit-overflow-scrolling: touch; }
.panel-sep { margin: 1.15rem 0 .55rem; padding-top: .8rem; border-top: 1px solid var(--rule); }
.panel-body .field { margin-bottom: .7rem; }
/* A row of two fields spaces itself with the grid gap, not with each field's
   own margin as well, or the pair sits twice as far from its neighbours. */
.panel-body .fields { gap: .7rem 1rem; margin-bottom: .7rem; }
.panel-body .fields > .field { margin-bottom: 0; }

.save-state { font-size: .74rem; letter-spacing: .04em; flex: none; white-space: nowrap; }
.save-state.saving { color: #A9BFAC; }
.save-state.ok { color: #8FD3B0; }
.save-state.err { color: #F0A9A9; }

.switch { display: flex; align-items: center; gap: .5rem; font-weight: 400; font-size: .9rem; color: var(--ink); margin-bottom: .7rem; }
.switch input { width: 1.05rem; height: 1.05rem; accent-color: var(--fairway); flex: none; }
.switch em { font-style: normal; margin-left: auto; text-align: right; }

.panel-scrim {
  position: fixed; inset: 0; z-index: var(--z-scrim); display: block;
  background: rgba(12,31,25,.42); opacity: 0; pointer-events: none;
  transition: opacity .24s ease;
}
html:not(.js) .panel:target ~ .panel-scrim,
.panel.open ~ .panel-scrim { opacity: 1; pointer-events: auto; }
@media (max-width: 560px) { .panel { width: 100%; } }
@media (prefers-reduced-motion: reduce) {
  .panel, .panel-scrim { transition: none; }
}
.archived-banner {
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 38%, transparent);
  color: var(--warn); border-radius: 8px; padding: .55rem .85rem;
  font-size: .85rem; margin-bottom: 1rem;
}
hr.rule { border: 0; border-top: 1px solid var(--rule); margin: 1rem 0; }

/* ---------- invoice ---------- */
.invoice {
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.6rem 1.5rem; box-shadow: var(--shadow); max-width: 760px; margin: 0 auto 1rem;
}
.inv-head { display: flex; gap: 1rem; align-items: flex-start; border-bottom: 2px solid var(--pine); padding-bottom: .9rem; }
.inv-head .who2 { margin-left: auto; text-align: right; font-size: .84rem; }
.inv-title { font-family: var(--ui); font-size: 1.5rem; font-weight: 600; }
.inv-no { font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; letter-spacing: .06em; }
.inv-tot {
  display: flex; align-items: baseline; gap: .7rem; justify-content: flex-end;
  border-top: 2px solid var(--pine); margin-top: .3rem; padding-top: .7rem;
}
.inv-tot .lbl { font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.inv-tot .amt { font-family: var(--ui); font-size: 1.8rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.invoice tr.inv-group td { padding-top: .9rem; font-size: .74rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--pine); border-bottom: 1px solid var(--rule); }
.inv-note { margin-top: 1rem; font-size: .84rem; color: var(--muted); border-top: 1px solid var(--rule); padding-top: .8rem; }

@media print {
  .topbar, nav.tabs, .tabbar, .no-print { display: none !important; }
  /* Undo the phone's app shell, or printing from a phone prints one screenful. */
  html, body { height: auto; overflow: visible; display: block; }
  body { background: #fff; color: #000; }
  main { padding: 0; max-width: none; overflow: visible; }
  .invoice { box-shadow: none; border: 0; padding: 0; max-width: none; }
  a { color: #000; text-decoration: none; }
  .print-only { display: block !important; }
}
.print-only { display: none; }

/* ---------- lodging ---------- */
.house-hero {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg, var(--pine) 0%, var(--fairway) 140%);
  color: #F4F1E8; border-radius: var(--radius); padding: 1.5rem 1.35rem;
  margin-bottom: 1rem; box-shadow: var(--shadow);
}
.house-hero h1 { color: #FFF; margin-top: .15rem; }
.house-seal {
  position: absolute; right: -2.2rem; top: 50%; transform: translateY(-50%);
  width: 190px; height: 190px; opacity: .1; pointer-events: none;
}
.house-addr { color: var(--brass-lt); font-size: .95rem; margin-top: .35rem; max-width: 42ch; }
.house-when {
  display: flex; gap: 1.6rem; flex-wrap: wrap;
  margin-top: 1.1rem; padding-top: .9rem; border-top: 1px solid rgba(255,255,255,.18);
}
.house-when .l {
  display: block; font-size: .66rem; letter-spacing: .13em;
  text-transform: uppercase; color: #A9BFAC;
}
.house-when .v { display: block; font-size: 1.05rem; font-weight: 600; color: #FFF; margin-top: .1rem; }
.btn.ghost.onhero { color: #F4F1E8; border-color: rgba(255,255,255,.4); }
.btn.ghost.onhero:hover { background: rgba(255,255,255,.12); color: #FFF; border-color: #FFF; }
.housenote p { font-size: .93rem; color: var(--ink); }

/* The same house notes on the home tile: the door code and the Wi-Fi are what
   a man wants at the door with his bags, and home is where the app opens. */
.house-codes {
  margin-top: .7rem; padding: .55rem .7rem; border-radius: 8px;
  background: color-mix(in srgb, var(--brass) 8%, var(--card));
  border: 1px solid color-mix(in srgb, var(--brass) 30%, transparent);
}
.house-codes .hc-l {
  display: flex; align-items: center; gap: .35rem; margin-bottom: .15rem;
  font-size: .68rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--brass);
}
.house-codes .hc-l .ic { width: .95rem; height: .95rem; }
.house-codes p { margin: 0; font-size: .95rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }

.shots { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.shot { margin: 0; border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; background: var(--rule-sf); }
.shot img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  background: var(--rule-sf); transition: transform .25s ease;
}
.shot a:hover img { transform: scale(1.03); }
.shot figcaption {
  display: flex; align-items: center; gap: .4rem;
  padding: .35rem .5rem; font-size: .78rem; color: var(--muted); background: var(--card);
}
.shot figcaption span { flex: 1; min-width: 0; }

.roomrow {
  display: flex; gap: .85rem; align-items: baseline;
  padding: .55rem 0; border-bottom: 1px solid var(--rule-sf);
}
.roomrow:last-of-type { border-bottom: 0; }
.roomrow.unplaced .roomname { color: var(--warn); }
.roomname {
  flex: none; width: 8.5rem; font-weight: 600; font-size: .9rem;
  overflow-wrap: anywhere;
}
.roompeople { display: flex; flex-wrap: wrap; gap: .3rem; }
.who-chip {
  font-size: .8rem; padding: .12rem .5rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card); white-space: nowrap;
}
.who-chip.me { border-color: var(--fairway); font-weight: 600; }
@media (max-width: 560px) {
  .roomrow { flex-direction: column; gap: .3rem; }
  .roomname { width: auto; }
  .house-seal { width: 130px; height: 130px; right: -1.6rem; opacity: .08; }
}

/* Lead photo behind the lodging hero. The gradient carries most of its weight on
   the left so the heading stays legible whatever the photo is doing. */
.house-hero.shot-hero {
  background-image:
    linear-gradient(100deg, rgba(22,41,28,.95) 0%, rgba(22,41,28,.86) 42%, rgba(22,41,28,.40) 100%),
    var(--hero);
  background-size: cover;
  background-position: center 58%;
  min-height: 310px;
  display: flex; flex-direction: column; justify-content: flex-end;
}
@media (max-width: 560px) {
  .house-hero.shot-hero {
    min-height: 260px;
    background-image:
      linear-gradient(180deg, rgba(22,41,28,.72) 0%, rgba(22,41,28,.93) 62%),
      var(--hero);
  }
}

/* ---------- sortable columns ---------- */
table.sortable thead th[data-sort] {
  cursor: pointer; user-select: none; white-space: nowrap;
}
table.sortable thead th[data-sort]:hover { color: var(--ink); }
table.sortable thead th[data-sort]::after {
  content: "\2195"; margin-left: .28rem; opacity: .32; font-size: .95em;
}
table.sortable thead th[aria-sort="ascending"]::after  { content: "\2191"; opacity: 1; color: var(--fairway); }
table.sortable thead th[aria-sort="descending"]::after { content: "\2193"; opacity: 1; color: var(--fairway); }
table.sortable thead th[data-sort]:focus-visible {
  outline: 2px solid var(--fairway); outline-offset: -2px;
}

/* ---------- landing (idiots.golf) ----------
   Its own shell: no nav, no trip, nothing signed in. The photo carries the page
   and a deep brand-green wash keeps the type legible whatever the sky is doing. */
body.landing {
  min-height: 100dvh; margin: 0; color: #F3F2E0;
  background-color: #16291C;
  background-image: url('/img/links-sunset-2000.jpg');
  background-image: image-set(
    url('/img/links-sunset-2000.webp') type('image/webp'),
    url('/img/links-sunset-2000.jpg') type('image/jpeg'));
  background-size: cover; background-position: center 62%;
  background-repeat: no-repeat; background-attachment: fixed;
}
@media (max-width: 700px) {
  body.landing {
    background-attachment: scroll;
    background-image: url('/img/links-sunset-1100.jpg');
    background-image: image-set(
      url('/img/links-sunset-1100.webp') type('image/webp'),
      url('/img/links-sunset-1100.jpg') type('image/jpeg'));
  }
}
body.landing .gate {
  /* Column, with the card taking `margin:auto` so it centres in whatever space
     is left over and the credit can never ride up over the copy. */
  min-height: 100dvh; display: flex; flex-direction: column;
  padding: 1.5rem 1.25rem 0; position: relative;
  overflow: hidden; /* the seal deliberately hangs off the corner */
  background: radial-gradient(125% 95% at 50% 46%, rgba(22,41,28,.50) 0%, rgba(22,41,28,.79) 60%, rgba(12,20,14,.93) 100%);
}
.gate-card { width: 100%; max-width: 30rem; margin: auto; text-align: center; position: relative; z-index: 2; } /* landing: above the wash, below everything global */
.gate-wordmark {
  width: min(24rem, 78vw); height: auto; display: block; margin: 0 auto .6rem;
  filter: drop-shadow(0 2px 14px rgba(0,0,0,.45));
}
.gate-tag {
  margin: 0 0 2rem; font-size: .72rem; letter-spacing: .3em; text-transform: uppercase;
  color: #B9C9BC;
}
.gate-form label {
  display: block; text-align: left; font-size: .7rem; letter-spacing: .16em;
  text-transform: uppercase; color: #B9C9BC; margin-bottom: .4rem; font-weight: 600;
}
.gate-row { display: flex; gap: .5rem; }
.gate-row input {
  flex: 1; min-width: 0; padding: .7rem .85rem; font-size: 1rem; font-family: var(--ui);
  color: #F3F2E0; background: rgba(12,20,14,.55); border: 1px solid rgba(243,242,224,.32);
  border-radius: 8px;
}
.gate-row input::placeholder { color: rgba(243,242,224,.45); }
.gate-row input:focus {
  outline: 2px solid var(--brass); outline-offset: 1px;
  border-color: var(--brass); background: rgba(12,20,14,.75);
}
.gate-row .btn { flex: none; padding: .7rem 1.1rem; font-size: .92rem; }
.gate-help {
  margin: .85rem 0 0; font-size: .82rem; line-height: 1.5;
  color: #A9BFAC; text-align: left; max-width: 34ch;
}
.gate-err {
  margin: 0 0 1rem; padding: .6rem .85rem; border-radius: 8px; font-size: .88rem;
  background: rgba(180,63,53,.22); border: 1px solid rgba(201,86,74,.6); color: #F6D9D5;
  text-align: left;
}
.gate-years {
  margin: 2.2rem 0 0; font-size: .8rem; letter-spacing: .12em;
  display: flex; gap: .7rem; justify-content: center; align-items: center;
}
.gate-years a { color: #B9C9BC; text-decoration: none; font-variant-numeric: tabular-nums; }
.gate-years a:hover { color: #FFF; }
.gate-years span { color: rgba(185,201,188,.4); }
.gate-seal {
  position: absolute; bottom: -1.5rem; right: -1.5rem;
  width: 230px; height: 230px; opacity: .085; pointer-events: none; z-index: 1;
}
@media (max-width: 560px) {
  .gate-row { flex-direction: column; }
  .gate-row .btn { width: 100%; }
  .gate-seal { width: 150px; height: 150px; bottom: -1rem; right: -1rem; }
}

/* ---------- room cards under Who's where ---------- */
.rooms { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.room {
  margin: 0; border: 1px solid var(--rule); border-radius: 9px; overflow: hidden;
  background: var(--card); display: flex; flex-direction: column;
}
.room img, .room-nophoto {
  display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; background: var(--rule-sf);
}
.room-b { padding: .6rem .7rem .7rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.room-h { display: flex; align-items: baseline; gap: .5rem; }
.room-n { font-weight: 600; font-size: .95rem; }

/* One row per bed. The card's height tells you how many places there are,
   which the old line of subtext never did. */
/* Beds sit under the room name, not pushed to the foot of the card. A card
   with one bed should show one row right where you are already looking; the
   slack belongs at the bottom. */
.beds { display: flex; flex-direction: column; gap: .3rem; }
.bedrow { display: flex; }
.bedrow > form, .bedrow > .bedpill { flex: 1; min-width: 0; }
.bedadd select {
  width: 100%; min-height: 2rem; padding: .25rem 1.8rem .25rem .5rem;
  font-size: .84rem; background-position: right .4rem center; background-size: .95rem;
}
.bedpill {
  display: flex; align-items: center; gap: .4rem;
  min-height: 2rem; padding: .25rem .35rem .25rem .6rem;
  border: 1px solid var(--rule); border-radius: 8px;
  background: color-mix(in srgb, var(--fairway) 10%, var(--card));
  font-size: .86rem; font-weight: 500;
}
.bedpill > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bedpill.me { border-color: var(--fairway); font-weight: 600; }
.bedpill.empty {
  background: transparent; border-style: dashed; color: var(--muted); font-weight: 400;
}
.bedpill form { display: flex; flex: none; }
.bedpill button {
  all: unset; cursor: pointer; flex: none;
  width: 1.4rem; height: 1.4rem; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 1rem; line-height: 1;
  transition: background-color .14s var(--ease), color .14s var(--ease);
}
.bedpill button:hover { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
.bedpill button:focus-visible { box-shadow: var(--ring); }
.who-chip form { display: inline; }
.who-chip button {
  all: unset; cursor: pointer; margin-left: .3rem; color: var(--muted);
  font-size: .85em; line-height: 1;
}
.who-chip button:hover { color: var(--bad); }
.who-chip em { font-style: normal; }
.shot figcaption:empty { display: none; }

/* ---------- polls on undecided meals ---------- */
/* Outline pills before a vote. After it, each pill carries its share as a quiet
   fill from the left and a count, and your own pick is outlined in green. */
.poll { margin-top: .5rem; }
.poll-opts { display: flex; flex-wrap: wrap; gap: .35rem; }
.poll-opts form { display: contents; }
.poll-opt {
  font: inherit; font-size: .8rem; line-height: 1.2; color: var(--ink); cursor: pointer;
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .32rem .75rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card);
  transition: border-color .12s var(--ease), background-color .12s var(--ease);
}
.poll-opt:hover:not(:disabled) { border-color: var(--fairway); }
.poll-opt:focus-visible { outline: none; box-shadow: var(--ring); }
.poll-opt:disabled { cursor: default; opacity: .6; }
.poll.voted .poll-opt {
  background: linear-gradient(to right,
    color-mix(in srgb, var(--fairway) 15%, transparent) var(--pct, 0%), var(--card) var(--pct, 0%));
}
.poll-opt.mine { border-color: var(--fairway); font-weight: 600; }
.po-n { font-size: .74rem; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.poll-opt.mine .po-n { color: var(--fairway); }
.poll-foot { margin-top: .35rem; }
@media (prefers-reduced-motion: reduce) { .poll-opt { transition: none; } }

/* ---------- arrivals and departures ---------- */
/* Worked out from people's own travel, one row per time, everyone on it as a
   chip. The flight goes beside the title when they all share one, and on each
   chip only when they do not. */
.who-row { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .4rem; }
.who-row .who-chip em { font-style: normal; color: var(--muted); margin-left: .35rem; font-size: .92em; }
.travel-via {
  margin-left: .45rem; font-size: .72rem; font-weight: 600; letter-spacing: .02em;
  color: var(--muted); font-variant-numeric: tabular-nums;
}

/* ---------- the meal board ---------- */
.mday + .mday { margin-top: 1rem; }
.mrow {
  display: flex; gap: .85rem; align-items: center;
  padding: .5rem 0; border-top: 1px solid var(--rule-sf);
}
.mrow:first-of-type { border-top: 0; }
.m-slot {
  flex: none; width: 4.6rem; font-weight: 600; text-transform: capitalize;
  color: var(--muted); letter-spacing: .01em;
}
.m-b { flex: 1; min-width: 0; }
.m-t { font-size: .9rem; font-weight: 600; }
.m-t a { color: inherit; text-decoration: none; }
.m-t a:hover { color: var(--fairway); }
.m-where { font-weight: 500; color: var(--fairway); }
.m-r { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: .15rem; }

/* The plan is the whole point of the row, so it is the one coloured thing in
   it. Undecided reads as a gap to fill rather than as a status. */
.mplan {
  font-size: .68rem; font-weight: 600; white-space: nowrap;
  padding: .12rem .45rem .16rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card); color: var(--muted);
}
/* Modifiers are prefixed because the bare words collide: `.course` is the golf
   course card (display:grid, which stretched this pill to 256px) and `.out` is
   an attendee status. */
.mplan.plan-cook { border-color: var(--fairway); color: var(--fairway);
  background: color-mix(in srgb, var(--fairway) 10%, transparent); }
.mplan.plan-course { border-color: color-mix(in srgb, var(--ink) 22%, transparent); color: var(--ink); }
.mplan.plan-out, .mplan.plan-delivery { border-color: var(--brass); color: var(--brass);
  background: color-mix(in srgb, var(--brass) 8%, transparent); }
.mplan.plan-tbd { border-style: dashed; }
.mrow.open .m-t { color: var(--muted); }

@media (max-width: 560px) {
  .mrow { flex-wrap: wrap; gap: .3rem .6rem; }
  .m-slot { width: auto; }
  .m-b { flex: 1 0 100%; order: 3; }
  .m-r { flex-direction: row; align-items: center; gap: .4rem; margin-left: auto; }
}

/* ---------- receipts ---------- */
/* A quiet marker beside the description. It has to read as "there is evidence
   here" at a glance without competing with the expense itself. */
.rcpt {
  margin-left: .45rem; font-size: .66rem; font-weight: 600; letter-spacing: .01em;
  padding: .06rem .34rem .1rem; border-radius: 4px; white-space: nowrap;
  color: var(--fairway); background: color-mix(in srgb, var(--fairway) 11%, transparent);
  border: 1px solid color-mix(in srgb, var(--fairway) 24%, transparent);
  text-decoration: none; vertical-align: .05em;
}
.rcpt:hover { background: color-mix(in srgb, var(--fairway) 20%, transparent); text-decoration: none; }
.rcpt-have { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-bottom: .8rem; }
.rcpt-have form { display: inline; }

/* The subset ticks. Two columns: at three, a name like "Jonathan Ortiz-Myers"
   wraps and the rows go ragged. Twelve names over two columns still fits the
   drawer without scrolling. */
.share-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  gap: .1rem .8rem; margin: .5rem 0 .3rem;
}
.share-grid .switch { margin: 0; align-items: center; }

/* File inputs are native and ugly by default; this makes the button match ours
   without replacing the control, which would cost the keyboard and screen
   reader behaviour that comes free with it. */
input[type="file"] {
  width: 100%; font-size: .84rem; color: var(--muted);
  padding: .45rem .55rem; border: 1px dashed var(--rule); border-radius: 8px;
  background: var(--card); cursor: pointer;
}
input[type="file"]:hover { border-color: var(--fairway); }
input[type="file"]::file-selector-button {
  font: inherit; font-weight: 600; color: var(--ink); cursor: pointer;
  margin-right: .6rem; padding: .3rem .7rem;
  border: 1px solid var(--rule); border-radius: 6px; background: var(--paper);
}
input[type="file"]::file-selector-button:hover { border-color: var(--fairway); color: var(--fairway); }

/* ---------- statement import ---------- */
.qual { font-size: .74rem; font-weight: 600; white-space: nowrap; }
.qual.ok    { color: var(--ok); }
.qual.warn  { color: var(--warn); }
.qual.err   { color: var(--bad); }
.qual.muted { color: var(--muted); }
tr.dim { opacity: .5; }
tr.dim:hover { background: transparent; }

/* code entry on the front door */
.gate-code {
  font-size: 1.35rem; letter-spacing: .38em; text-align: center;
  font-variant-numeric: tabular-nums;
}
.gate-again { margin-top: .8rem; text-align: left; }
.gate-again button {
  all: unset; cursor: pointer; font-size: .8rem; color: #A9BFAC;
  text-decoration: underline; text-underline-offset: 3px;
}
.gate-again button:hover { color: #FFF; }

/* ---------- year switcher in the top bar ---------- */
.yearpick { position: relative; flex: none; min-width: 0; }
.yearpick > summary { list-style: none; cursor: pointer; user-select: none; }
.yearpick > summary::-webkit-details-marker { display: none; }
.yearpick > summary::after {
  content: ""; flex: none; width: .4rem; height: .4rem; margin-left: .55rem;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: translateY(-.1rem) rotate(45deg); opacity: .75;
  transition: transform .15s var(--ease);
}
.yearpick[open] > summary::after { transform: translateY(.12rem) rotate(-135deg); }
.yearpick > summary:hover { color: #FFF; border-color: rgba(243,242,224,.55); }
.yearpick ul {
  position: absolute; top: calc(100% + .45rem); right: 0; left: auto; z-index: var(--z-drawer);
  margin: 0; padding: var(--pop-inset); list-style: none; min-width: 15rem;
  background: var(--pop-bg); color: var(--ink);
  border: 1px solid var(--pop-line); border-radius: var(--pop-radius);
  box-shadow: var(--pop-shadow);
}
.yearpick li a {
  display: flex; align-items: baseline; gap: .5rem;
  padding: var(--item-pad); border-radius: var(--item-radius);
  color: var(--ink); text-decoration: none; font-size: var(--item-size); white-space: nowrap;
}
.yearpick li a:hover, .yearpick li a:focus-visible { background: var(--item-hover); color: var(--ink); outline: none; }
.yearpick li a[aria-current="page"] { font-weight: 600; background: rgba(166,124,46,.12); }
.yearpick li a em { font-style: normal; font-size: .72rem; color: var(--muted); margin-left: auto; }
/* .brand carries margin-right:auto, so the picker sits hard against the right
   edge and its menu hangs from that edge rather than running off it. */
@media (max-width: 760px) {
  .yearpick ul { min-width: 11rem; max-width: calc(100vw - 1.5rem); }
}
@media (max-width: 560px) {
  .yearpick li a { font-size: .84rem; white-space: normal; }
}

/* ---------- one person, one year ---------- */
.legrow {
  display: flex; gap: .85rem; align-items: baseline;
  padding: .5rem 0; border-bottom: 1px solid var(--rule-sf);
}
.legrow:last-child { border-bottom: 0; }
.legrow .l {
  flex: none; width: 5.5rem; font-size: .7rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.legrow .v { flex: 1; min-width: 0; font-size: .93rem; }
.goals { font-size: .97rem; line-height: 1.6; white-space: pre-line; max-width: 68ch; }
@media (max-width: 560px) {
  .legrow { flex-direction: column; gap: .15rem; }
  .legrow .l { width: auto; }
}

/* =====================================================================
   Controls, toasts and motion
   ===================================================================== */

/* A real z-index scale. Nothing here invents a number. */
:root {
  --z-dropdown: 40;
  --z-sticky:   50;
  --z-drawer:   60;
  --z-scrim:    59;
  --z-toast:    80;
  --ring: 0 0 0 2px var(--paper), 0 0 0 4px color-mix(in srgb, var(--fairway) 65%, transparent);
  --ease: cubic-bezier(.22,.61,.36,1);
  /* Every menu in the app opens the same surface: the year picker, Add golfer,
     each <select>, and the category combobox. Shared here so none can drift. */
  --pop-bg: var(--card);
  --pop-line: var(--rule);
  --pop-radius: 8px;
  --pop-inset: .25rem;
  --pop-shadow: 0 12px 32px -12px rgba(12,20,14,.45), 0 2px 6px -1px rgba(12,20,14,.1);
  --item-pad: .42rem .6rem;
  --item-radius: 6px;
  --item-size: .88rem;
  --item-hover: color-mix(in srgb, var(--fairway) 12%, transparent);
  /* Chevron for selects. Baked per theme because a data URI cannot read a token. */
  --chev: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6A5C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
}
@media (prefers-color-scheme: dark) {
  :root {
    --ring: 0 0 0 2px var(--paper), 0 0 0 4px color-mix(in srgb, var(--fairway) 70%, transparent);
    --chev: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239AA684' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  }
}

/* One control spec: same height, radius, border and focus for every field. */
input[type=text], input[type=date], input[type=time], input[type=number],
input[type=email], input[type=tel], input[type=url], input[type=password],
select, textarea {
  min-height: 2.25rem;
  border-radius: 8px;
  border: 1px solid var(--rule);
  background-color: var(--card);
  transition: border-color .14s var(--ease), box-shadow .14s var(--ease);
}
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--fairway) 45%, var(--rule));
}
input:focus-visible, select:focus-visible, textarea:focus-visible,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--fairway);
  box-shadow: var(--ring);
}
select {
  appearance: none; -webkit-appearance: none;
  background-image: var(--chev);
  background-repeat: no-repeat;
  background-position: right .5rem center;
  background-size: 1.05rem;
  padding-right: 2rem;
  cursor: pointer;
}
select:disabled { cursor: not-allowed; opacity: .55; }

/* The open <select> menu, styled with the platform's customizable select rather
   than a script: keyboard, type-ahead and screen readers keep working because it
   is still a real <select>. Chrome and Edge draw it; every other browser falls
   back to its own native menu, which on a phone is the better control anyway.
   ::picker(select) is kept out of any selector list shared with other rules: an
   engine that does not know it would throw away the whole rule. */
@supports (appearance: base-select) {
  select, ::picker(select) { appearance: base-select; }
  select::picker-icon { display: none; }            /* --chev already draws it */
  select:open { border-color: var(--fairway); box-shadow: var(--ring); }
  ::picker(select) {
    /* The default placement takes whichever side has MORE room, so a select in
       the lower half of the page opened upwards. Prefer below, flip only when
       it will not fit - the way shadcn's Select behaves. */
    position-try-order: normal;
    margin-top: .3rem; padding: var(--pop-inset);
    background: var(--pop-bg); color: var(--ink);
    border: 1px solid var(--pop-line); border-radius: var(--pop-radius);
    box-shadow: var(--pop-shadow);
    opacity: 0; translate: 0 -4px;
    transition: opacity .12s var(--ease), translate .12s var(--ease),
                display .12s allow-discrete, overlay .12s allow-discrete;
  }
  select:open::picker(select) { opacity: 1; translate: 0 0; }
  @starting-style { select:open::picker(select) { opacity: 0; translate: 0 -4px; } }
  option {
    padding: var(--item-pad); border-radius: var(--item-radius);
    font-size: var(--item-size); cursor: pointer; gap: .6rem;
  }
  option:hover, option:focus-visible { background: var(--item-hover); outline: none; }
  option:checked { font-weight: 600; }
  option::checkmark { order: 1; margin-left: auto; color: var(--fairway); }
}
@media (prefers-reduced-motion: reduce) {
  @supports (appearance: base-select) { ::picker(select) { transition: none; translate: none; } }
}

/* The category combobox's list. It is a popover, so it sits in the top layer
   and nothing it opens inside can clip it. */
.combo-list {
  position: fixed; inset: auto; margin: 0; z-index: var(--z-dropdown);
  list-style: none; padding: var(--pop-inset); max-height: 15rem; overflow-y: auto;
  background: var(--pop-bg); color: var(--ink);
  border: 1px solid var(--pop-line); border-radius: var(--pop-radius);
  box-shadow: var(--pop-shadow);
}
.combo-opt {
  padding: var(--item-pad); border-radius: var(--item-radius);
  font-size: var(--item-size); cursor: pointer; white-space: nowrap;
}
.combo-opt:hover, .combo-opt.active { background: var(--item-hover); }
.combo-opt[aria-selected="true"] { font-weight: 600; }
::placeholder { color: color-mix(in srgb, var(--muted) 78%, transparent); }

.btn { transition: background-color .14s var(--ease), border-color .14s var(--ease), color .14s var(--ease); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn:active:not([disabled]) { transform: translateY(0.5px); }
a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: none; box-shadow: var(--ring); border-radius: 6px;
}

/* A form mid-flight: dimmed, inert, no spinner theatre. */
form.working { opacity: .55; pointer-events: none; }

/* Toasts. Actions used to announce themselves by rewriting the URL and
   shoving a banner into the layout; they now say their piece and leave. */
#toasts {
  position: fixed; z-index: var(--z-toast);
  left: 50%; transform: translateX(-50%); bottom: 1.1rem;
  display: flex; flex-direction: column; gap: .4rem; align-items: center;
  pointer-events: none; padding: 0 1rem; width: max-content; max-width: calc(100vw - 2rem);
}
.toast {
  background: var(--pine); color: #F3F2E0;
  border: 1px solid color-mix(in srgb, #F3F2E0 22%, transparent);
  border-radius: 9px; padding: .55rem .9rem; font-size: .88rem; line-height: 1.35;
  box-shadow: 0 12px 30px -12px rgba(12,20,14,.65);
  opacity: 0; transform: translateY(8px) scale(.98);
  transition: opacity .2s var(--ease), transform .24s var(--ease);
  max-width: 34rem;
}
.toast.in { opacity: 1; transform: none; }
.toast.err { background: var(--bad); border-color: color-mix(in srgb, #fff 26%, transparent); }
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity .12s linear; transform: none; }
  .toast.in { transform: none; }
  .btn:active:not([disabled]) { transform: none; }
  input, select, textarea { transition: none; }
}
@media (max-width: 560px) { #toasts { bottom: .8rem; } }
/* On a phone the bottom is taken by the tab bar and, on Your Details, the Save
   bar, so a toast drops in from the top instead of landing on either. */
@media (max-width: 760px) {
  #toasts { bottom: auto; top: calc(env(safe-area-inset-top) + 3.9rem); }
  .toast { transform: translateY(-8px) scale(.98); }
  .toast.in { transform: none; }
}

/* =====================================================================
   Section headings
   Small uppercase tracked labels were doing the work of headings all over
   this app. They are a kicker, not a heading, and using one above every
   block reads as scaffolding rather than design. Sections now get a real
   heading: sentence case, weight contrast, a hairline rule to separate.
   `.eyebrow` survives only on the invoice, where "Billed to" / "Issued" /
   "Due" are genuinely small field labels on a document.
   ===================================================================== */
.section-h {
  font-family: var(--ui);
  font-size: .96rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--ink); line-height: 1.3;
  margin: 1.5rem 0 .75rem; padding-top: 1.05rem;
  border-top: 1px solid var(--rule);
}
.section-h:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.panel-body .section-h { margin: 1.3rem 0 .65rem; }
.legend-h { padding: 0 .4rem; font-size: .86rem; font-weight: 600; color: var(--ink); }
.slot-label {
  font-size: .86rem; font-weight: 600; color: var(--ink);
  margin: .85rem 0 .15rem;
}
.slot-label:first-child { margin-top: .2rem; }

/* Photo delete sits on the image, out of the way, organisers only. */
.shot { position: relative; }
.shot-x { position: absolute; top: .4rem; right: .4rem; z-index: 2; }
/* Only the trigger gets overlay chrome. Styling `.shot-x .btn` also hit the
   collapsed confirm button, whose padding then leaked past its own max-width:0
   clip and showed as a sliver of the word "Delete". */
.shot-x .ci-trigger {
  background: rgba(12,20,14,.62); border-color: rgba(243,242,224,.34); color: #F3F2E0;
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  padding: .08rem .42rem; font-size: .95rem; line-height: 1.3;
  opacity: .85; transition: opacity .14s var(--ease), background-color .14s var(--ease);
}
.shot-x .ci-trigger:hover { background: var(--bad); border-color: var(--bad); color: #fff; }
.shot-x .ci.armed .ci-go {
  background: var(--bad); border-color: var(--bad); color: #fff;
  padding: .12rem .5rem; font-size: .78rem; max-width: 5rem;
}
@media (hover: hover) {
  .shot-x .ci-trigger { opacity: 0; }
  .shot:hover .shot-x .ci-trigger,
  .shot-x .ci-trigger:focus-visible,
  .shot-x .ci.armed .ci-trigger { opacity: .95; }
}

/* =====================================================================
   Lightbox
   Native <dialog>, so focus trapping, Esc and the top layer come from the
   platform rather than from a stacking-context fight.
   ===================================================================== */
dialog.lightbox {
  border: 0; padding: 0; margin: 0; max-width: 100vw; max-height: 100dvh;
  width: 100vw; height: 100dvh; background: transparent; overflow: hidden;
  color: #F3F2E0;
}
dialog.lightbox::backdrop { background: rgba(8,14,10,.93); }
.lb-stage {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 3.4rem 1rem 3.2rem;
}
.lb-stage img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; border-radius: 6px; display: block;
  box-shadow: 0 24px 70px -30px rgba(0,0,0,.9);
  -webkit-user-select: none; user-select: none; -webkit-user-drag: none;
}
.lb-btn {
  position: absolute; z-index: 2; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; border-radius: 999px;
  background: rgba(243,242,224,.12); color: #F3F2E0;
  border: 1px solid rgba(243,242,224,.3);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  font: inherit; font-size: 1.15rem; line-height: 1;
  transition: background-color .14s var(--ease), border-color .14s var(--ease);
}
.lb-btn:hover { background: rgba(243,242,224,.24); border-color: rgba(243,242,224,.55); }
.lb-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(243,242,224,.55); }
.lb-prev { left: .75rem; top: 50%; transform: translateY(-50%); }
.lb-next { right: .75rem; top: 50%; transform: translateY(-50%); }
.lb-close { top: .75rem; right: .75rem; }
.lb-count {
  position: absolute; bottom: .95rem; left: 50%; transform: translateX(-50%);
  font-size: .8rem; letter-spacing: .1em; color: rgba(243,242,224,.72);
  font-variant-numeric: tabular-nums;
}
.lb-cap {
  position: absolute; bottom: 2.4rem; left: 50%; transform: translateX(-50%);
  font-size: .86rem; color: rgba(243,242,224,.9); text-align: center;
  max-width: min(46rem, 88vw);
}
@media (max-width: 620px) {
  .lb-stage { padding: 3.2rem .5rem 3.4rem; }
  .lb-prev, .lb-next { top: auto; bottom: .9rem; transform: none; }
  .lb-prev { left: 1rem; } .lb-next { right: 1rem; }
  .lb-count { bottom: 1.6rem; }
  .lb-cap { bottom: 3.5rem; font-size: .8rem; }
}
@media (prefers-reduced-motion: reduce) { .lb-btn { transition: none; } }

/* ---------- the house, on the front page ---------- */
.house-tile { overflow: hidden; }
.house-shot { display: block; }
.house-shot img {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  background: var(--rule-sf);
}
.house-body { padding: .95rem 1.05rem 1.05rem; }
/* This header is a child of .house-body, not of .card, so it never picked up
   the card-header flex rules and the link stacked under the heading. */
.house-body > header {
  display: flex; align-items: center; gap: .5rem; flex-wrap: nowrap;
  margin: -.1rem 0 .55rem;
}
.house-body > header h2 { margin-right: auto; }
.house-body > header .btn { flex: none; }
.house-rooms {
  margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--rule);
  display: flex; flex-direction: column; gap: .42rem;
}
/* Label left, room right, both on one optical line. The label sizes to its own
   text rather than a fixed column: there is only ever one of these rows, so a
   fixed width buys no alignment and only forces the label to wrap. */
.hr-row { display: flex; gap: .6rem; align-items: center; }
.hr-name {
  flex: none; font-size: .78rem; font-weight: 600; color: var(--muted);
  overflow-wrap: anywhere;
}
.hr-who {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: .25rem .45rem;
  align-items: center; justify-content: flex-end; text-align: right; font-size: .84rem;
}
.hr-open .hr-who { color: var(--muted); font-size: .8rem; }
.hr-who .who-chip { font-size: .76rem; padding: .08rem .42rem; }
@media (max-width: 560px) {
  /* Stays a row down here rather than stacking: the label now sizes to its text
     and the room chip wraps inside its own half, so both still fit on one line. */
  .hr-row { gap: .5rem; }
  .hr-name { font-size: .76rem; }
}

/* ---------- the week, on the front page ---------- */
.agenda { padding: 0 1.1rem 1rem; }
.agday {
  display: flex; gap: .9rem; align-items: flex-start;
  padding: .6rem 0; border-bottom: 1px solid var(--rule-sf);
}
.agday:last-child { border-bottom: 0; }
.agday-when { flex: none; width: 4.4rem; line-height: 1.25; }
.agday-dow { display: block; font-weight: 600; font-size: .88rem; }
.agday-date { display: block; font-size: .74rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.agday-what { flex: 1; min-width: 0; }
.agday-golf { display: flex; gap: .6rem; align-items: baseline; }
.agday-golf + .agday-golf { margin-top: .15rem; }
.agday-course { flex: 1; min-width: 0; font-weight: 600; font-size: .92rem; }
.agday-tee {
  flex: none; font-size: .82rem; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.agday-tee.mine { color: var(--fairway); font-weight: 600; }
.agday-rest { font-size: .82rem; color: var(--muted); margin-top: .12rem; }
.agday-golf + .agday-rest { margin-top: .2rem; }
@media (max-width: 560px) {
  .agday { gap: .7rem; }
  .agday-when { width: 3.6rem; }
}

/* ---------- the courses ---------- */
.courses { display: flex; flex-direction: column; gap: 1rem; }
.course {
  margin: 0; background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
  display: grid; grid-template-columns: minmax(0, 15rem) 1fr;
}
.course-fig { margin: 0; position: relative; min-width: 0; }
.course-shot { display: block; width: 100%; height: 100%; min-height: 12rem; object-fit: cover; background: var(--rule-sf); }
/* Attribution for Creative Commons photos. Legible but never competing with the
   picture: it sits in the shadow at the foot of the frame. */
.course-credit {
  position: absolute; inset: auto 0 0 0; padding: 1.4rem .6rem .35rem;
  font-size: .62rem; line-height: 1.3; text-align: right; color: rgba(255, 255, 255, .78);
  background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent);
  pointer-events: none;
}
.course-noshot {
  background:
    repeating-linear-gradient(135deg, var(--rule-sf) 0 12px, var(--card) 12px 24px);
}
.course-b { padding: 1.05rem 1.15rem 1.1rem; display: flex; flex-direction: column; gap: .6rem; }
.course-h { display: flex; gap: 1rem; align-items: flex-start; }
.course-h > div:first-child { flex: 1; min-width: 0; }
.course-club { font-size: .76rem; font-weight: 600; color: var(--muted); }
.course-name { font-size: 1.28rem; margin-top: .05rem; }
.course-when { flex: none; text-align: right; line-height: 1.3; }
.cw-day { display: block; font-size: .8rem; font-weight: 600; }
.cw-tee { display: block; font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.cw-tee.mine { color: var(--fairway); font-weight: 600; }
.course-blurb { margin: 0; font-size: .93rem; line-height: 1.55; max-width: 62ch; }
.course-facts { display: flex; flex-wrap: wrap; gap: .3rem 1.6rem; margin: 0; }
.course-facts > div { min-width: 0; }
.course-facts dt {
  font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.course-facts dd { margin: 0; font-size: .85rem; }
.course-you {
  margin: 0; font-size: .86rem; color: var(--ink);
  background: color-mix(in srgb, var(--fairway) 9%, transparent);
  border-radius: 7px; padding: .4rem .6rem;
}
/* A round with nothing filled in yet: no photo column, no hatched frame. */
.course.bare { grid-template-columns: 1fr; }
.course.bare .course-b { padding-bottom: .95rem; }
@media (max-width: 720px) {
  .course { grid-template-columns: 1fr; }
  .course-shot { min-height: 0; aspect-ratio: 16 / 9; }
  .course-h { flex-direction: column; gap: .3rem; }
  .course-when { text-align: left; }
  .cw-day, .cw-tee { display: inline; margin-right: .5rem; }
}


/* =====================================================================
   The phone shell
   A bar along the bottom of the screen, where a thumb reaches. Every
   section is in it and it scrolls sideways, so nothing hides behind a
   menu. Above 760px the strip under the header does the job instead.
   ===================================================================== */
:root { --tabbar-h: 3.75rem; }
.ic { display: block; flex: none; width: 1.25rem; height: 1.25rem; }
.tabbar { display: none; }

@media (max-width: 760px) {
  nav.tabs { display: none; }

  /* The phone gets an app shell rather than a long document: the screen is
     exactly the viewport, the page scrolls inside <main>, and the bar is the
     last row of the screen rather than a fixed element floating over it.
     position:fixed anchors to iOS Safari's LARGE viewport, so a bar pinned
     that way hides behind the toolbar until you scroll, and the space
     reserved for it reads as dead space at the foot of the page. */
  html { height: 100%; }
  /* --app-h is measured from visualViewport, which is the only number that is
     reliably what the phone is SHOWING. 100dvh is the fallback and is close,
     but iOS counts its own floating toolbars differently between versions, so
     on its own it leaves the bar hovering above the bottom edge. */
  body { height: var(--app-h, 100dvh); display: flex; flex-direction: column; overflow: hidden; }
  /* The bar is before <main> in the markup, so that a screen reader and the
     keyboard meet the navigation first; order puts it last on the screen. */
  .topbar { flex: none; order: 1; }
  main {
    order: 2; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch; padding-bottom: 1.6rem;
    /* Pinned to the screen's width, or a wide table's headers stretch it past
       the edge and the overflow is clipped by the shell instead of scrolling
       inside its own .table-wrap. */
    width: 100%; min-width: 0;
  }

  .tabbar {
    display: block; flex: none; order: 3; margin-top: auto;
    /* The inset is capped. On iOS 26 safe-area-inset-bottom also covers the
       floating browser bar, and the shell has already stopped above that, so
       taking the whole inset lifts the tabs a thumb's width off the bottom.
       This keeps clearance for the home indicator and nothing more. */
    padding: .3rem 0 calc(.3rem + min(env(safe-area-inset-bottom), .7rem));
    background: var(--pine-dk);
    border-top: 1px solid rgba(243,242,224,.1);
    box-shadow: 0 -10px 30px -18px rgba(0,0,0,.55);
  }
  /* Ten sections do not fit across a phone, so the bar scrolls sideways and
     the page you are on is scrolled into view. The mask sits on the scroller
     rather than the bar, so the tabs fade out at the edges, as a hint that
     there are more of them, while the bar's own colour runs edge to edge. */
  .tabbar-scroll {
    display: flex; overflow-x: auto; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding-left: max(.35rem, env(safe-area-inset-left));
    padding-right: max(.35rem, env(safe-area-inset-right));
    mask-image: linear-gradient(to right, transparent 0, #000 .85rem, #000 calc(100% - 1rem), transparent 100%);
  }
  .tabbar-scroll::-webkit-scrollbar { display: none; }
  .tabbar a {
    all: unset; box-sizing: border-box; position: relative; cursor: pointer;
    flex: 0 0 auto; min-width: 4.5rem; padding: 0 .4rem;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .24rem;
    min-height: calc(var(--tabbar-h) - .6rem); border-radius: 12px;
    color: #A3B7A6; font: 600 .68rem/1 var(--ui); letter-spacing: .015em; white-space: nowrap;
    -webkit-tap-highlight-color: transparent; touch-action: manipulation;
    transition: color .15s var(--ease), background-color .15s var(--ease);
  }
  .tabbar .ic { width: 1.45rem; height: 1.45rem; }
  .tabbar a[aria-current="page"] { color: #FFF; }
  /* The red mark the laptop strip underlines with, moved to the bar's top edge. */
  .tabbar a[aria-current="page"]::before {
    content: ""; position: absolute; top: -.3rem; left: 50%;
    width: 1.75rem; height: 3px; margin-left: -.875rem;
    border-radius: 0 0 3px 3px; background: var(--brass-lt);
  }
  .tabbar a:active { background: rgba(243,242,224,.07); }
  .tabbar a:focus-visible { box-shadow: inset 0 0 0 2px var(--brass-lt); }
}

/* Waiting on a page. Only shown if the swap takes longer than a blink. */
html.nav-wait body::before {
  content: ""; position: fixed; z-index: var(--z-toast); top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--brass-lt) 50%, transparent) no-repeat;
  background-size: 40% 100%; animation: nav-wait 1.1s linear infinite;
}
@keyframes nav-wait { from { background-position: -67% 0; } to { background-position: 167% 0; } }
@media (prefers-reduced-motion: reduce) {
  html.nav-wait body::before { animation: none; background-size: 100% 100%; opacity: .6; }
}
/* The page swap crossfades rather than cuts. Short: it is a tab change. */
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: .18s; animation-timing-function: cubic-bezier(.22,.61,.36,1);
}

/* Bigger targets wherever the pointer is a finger. */
@media (pointer: coarse) {
  /* Not the folded-away confirm verb: padding it would open a blank gap beside
     every × while it is meant to be zero wide. */
  .btn.sm:not(.ci-go) { min-height: 2.25rem; padding-left: .75rem; padding-right: .75rem; }
  .ci.armed .ci-go { min-height: 2.25rem; }
  /* Except on a photo, where a finger-sized box would cover a third of the
     thumbnail. It keeps a finger-sized target through the ::before below. */
  .shot-x .btn.sm.ci-trigger { position: relative; min-height: 1.7rem; padding: 0 .5rem; }
  .shot-x .btn.sm.ci-trigger::before { content: ""; position: absolute; inset: -.4rem; }
  .ins button { position: relative; }
  .ins button::before, .gpill button::before { content: ""; position: absolute; inset: -.55rem; }
  .gpill button { position: relative; }
}

/* =====================================================================
   Itinerary on a phone, and the meal's place as a pill
   ===================================================================== */
.ttl-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: .3rem .6rem; }
.ttl-row > .ttl { flex: 1 1 auto; min-width: 0; }
.locp {
  flex: none; margin-left: auto; max-width: 16rem;
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .76rem; font-weight: 600; line-height: 1.25; color: var(--ink);
  padding: .2rem .62rem .22rem .45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--brass) 6%, var(--card));
  border: 1px solid color-mix(in srgb, var(--brass) 24%, transparent);
}
.locp .ic { width: .85rem; height: .85rem; color: var(--brass); }
.locp b { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.locp:has(b:empty) { display: none; }

.panel-foot { margin-top: 1.4rem; padding-top: 1rem; border-top: 1px solid var(--rule); }
.panel-body { padding-bottom: calc(1rem + env(safe-area-inset-bottom)); }

.gpill .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gpill .nm-short { display: none; }

@media (max-width: 560px) {
  /* Delete lives in the block's drawer on a phone: the × column was taking a
     sixth of the row from every title. */
  .slot > form.ci { display: none; }
  /* Two to a row, first name and initial: a group reads as one short block. */
  .golfers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .3rem; }
  .golfers > .addg, .golfers > .tiny { grid-column: 1 / -1; }
  .gpill .nm-full {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .gpill .nm-short { display: inline; }
  /* The poll as a tidy two-by-two rather than a ragged wrap. */
  .poll-opts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .poll-opt { justify-content: center; gap: .35rem; padding: .5rem .6rem; white-space: nowrap; }
  .poll.voted .poll-opt { justify-content: space-between; }
  .locp { max-width: 100%; }
}

.courses { margin-bottom: 1rem; }

/* =====================================================================
   Lodging on a phone: a photo grid, and rooms as a list
   ===================================================================== */
@media (max-width: 560px) {
  .shots { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem; }
  .shot { border: 0; border-radius: 6px; }
  .shot img { aspect-ratio: 1; }
  .rooms { grid-template-columns: minmax(0, 1fr); gap: .55rem; }
  .room { flex-direction: row; }
  .room img, .room-nophoto {
    flex: none; width: 5.25rem; height: auto; min-height: 4.75rem; aspect-ratio: auto; align-self: stretch;
  }
  .room-b { padding: .55rem .65rem .6rem; gap: .4rem; }
}

/* =====================================================================
   Food
   ===================================================================== */
/* The meal board's detail line. It had no style of its own, so it rendered
   at body size in ink and outweighed the meal's name. */
.mrow .meta { font-size: .82rem; color: var(--muted); margin-top: .08rem; }
.mrow .meta.m-where { color: var(--fairway); }
.li-add {
  display: grid; grid-template-columns: minmax(0, 1fr) 6.5rem; gap: .7rem .6rem; align-items: end;
  margin-top: .9rem; padding-top: .85rem; border-top: 1px solid var(--rule);
}
.li-add label { margin-bottom: .22rem; }
.li-go .btn { width: 100%; min-height: 2.25rem; }

/* =====================================================================
   Money
   ===================================================================== */
/* Who splits it: each name a chip that fills when ticked. Chips wrap to their
   own widths, so "Jonathan Ortiz-Myers" never breaks across two lines the way
   it did in a fixed column. Still real checkboxes underneath. */
.share-pick { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.share-pick label {
  position: relative; display: inline-flex; align-items: center; margin: 0; cursor: pointer;
  min-height: 2.1rem; padding: .3rem .8rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card);
  font-size: .86rem; font-weight: 500; color: var(--ink); white-space: nowrap;
  transition: background-color .14s var(--ease), border-color .14s var(--ease);
}
.share-pick label:hover { border-color: var(--fairway); }
.share-pick input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.share-pick label:has(input:checked) {
  border-color: var(--fairway); font-weight: 600;
  background: color-mix(in srgb, var(--fairway) 13%, var(--card));
}
.share-pick label:has(input:checked)::before {
  content: ""; width: .32rem; height: .6rem; margin: -.15rem .45rem 0 -.1rem;
  border-right: 2px solid var(--fairway); border-bottom: 2px solid var(--fairway); transform: rotate(45deg);
}
.share-pick label:has(input:focus-visible) { box-shadow: var(--ring); }

/* =====================================================================
   Tables that fold on a phone
   A table.stack keeps its columns on a laptop. On a phone each row becomes
   two lines: the main cell and its amount on top, the rest underneath with
   their own labels, so nothing scrolls sideways and nothing wraps one word
   per line. Cells say what they are with c-main, c-amt, c-sub and c-act.
   ===================================================================== */
@media (max-width: 560px) {
  table.stack, table.stack tbody { display: block; width: 100%; }
  table.stack thead { display: none; }
  table.stack tr {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .22rem .85rem;
    padding: .72rem var(--stack-x, 0); border-bottom: 1px solid var(--rule-sf);
  }
  table.stack tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.stack td, table.stack td {
    display: block; min-width: 0; padding: 0; border: 0; text-align: left;
  }
  table.stack td.c-lead { order: 1; flex: none; font-weight: 600; }
  table.stack td.c-main { order: 1; flex: 1 1 0; }
  table.stack td.c-amt { order: 2; flex: none; text-align: right; }
  table.stack tr::after { content: ""; order: 3; flex: 1 0 100%; }
  table.stack td.c-sub { order: 4; font-size: .8rem; color: var(--ink); }
  table.stack td.c-sub[data-label]::before, table.stack td.c-amt[data-label]::before {
    content: attr(data-label) "\00a0"; font-size: .74rem; font-weight: 500; color: var(--muted);
  }
  table.stack td.c-wide { flex-basis: 100%; }
  table.stack td.c-act { order: 5; margin-left: auto; }
  table.stack td[data-empty], table.stack td.hide-sm { display: none; }
  table.stack td[colspan] { flex: 1 1 100%; }
  .card.flush > .table-wrap > table.stack { --stack-x: 1.1rem; }
  .table-wrap:has(> table.stack) { overflow: visible; }
}

/* =====================================================================
   Your details, as a bento
   Seven tiles on a six-column grid: who you are and whether you're coming,
   then contact, travel, golf, goals and the rest. Two columns on a tablet,
   one on a phone. One form and one Save behind all of it.
   ===================================================================== */
.me-form { margin: 0; }
.bento { display: grid; gap: 1rem; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-flow: dense; }
.tile {
  min-width: 0; background: var(--card); border: 1px solid var(--rule); border-radius: 14px;
  box-shadow: var(--shadow); padding: 1.1rem 1.15rem 1.2rem;
}
.tile > h2 { display: flex; align-items: center; gap: .5rem; font-size: 1rem; margin: 0 0 .85rem; }
.tile > h2 .ic { width: 1.1rem; height: 1.1rem; color: var(--fairway); }
.tile .field:last-child { margin-bottom: 0; }
.tile-note { margin: .75rem 0 0; font-size: .78rem; line-height: 1.45; color: var(--muted); }
.t-you { grid-column: span 2; }
.t-contact { grid-column: span 4; }
.t-travel { grid-column: span 4; }
.t-golf { grid-column: span 2; }
.t-goals { grid-column: span 4; grid-row: span 2; display: flex; flex-direction: column; }
.t-food { grid-column: span 2; }
.t-notes { grid-column: span 2; display: flex; flex-direction: column; }
.t-goals textarea { flex: 1; min-height: 16rem; font-size: .95rem; line-height: 1.6; }
.t-notes textarea { flex: 1; min-height: 6.5rem; }

/* You: the one dark tile, carrying your name now that the header doesn't. */
.t-you {
  display: flex; flex-direction: column;
  background: linear-gradient(150deg, var(--pine) 0%, var(--fairway) 175%);
  color: #F4F1E8; border-color: transparent;
}
.you-h { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.you-name { font-size: 1.45rem; color: #FFF; }
.you-pill { color: #F3F2E0; border-color: rgba(243,242,224,.42); background: rgba(243,242,224,.08); }
.you-sub { margin: .2rem 0 1rem; font-size: .85rem; color: #CBD9CC; }
.status-pick {
  border: 0; margin: auto 0 0; padding: 0; min-width: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .45rem;
}
.status-pick legend { padding: 0; margin-bottom: .5rem; font-size: .78rem; font-weight: 600; color: #CBD9CC; }
.status-pick label {
  position: relative; margin: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 2.6rem; padding: .35rem .5rem; border-radius: 10px;
  border: 1px solid rgba(243,242,224,.26); color: #E6EAE2;
  font-size: .86rem; font-weight: 600; line-height: 1.2;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.status-pick label:hover { border-color: rgba(243,242,224,.6); }
.status-pick input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.status-pick label:has(input:checked) { background: #F3F2E0; border-color: #F3F2E0; color: #213F2A; }
.status-pick label:has(input:focus-visible) { box-shadow: 0 0 0 2px var(--pine), 0 0 0 4px var(--brass-lt); }

.leg + .leg { margin-top: .95rem; padding-top: .95rem; border-top: 1px dashed var(--rule); }
.leg-h { font-size: .82rem; font-weight: 700; margin-bottom: .45rem; }
.leg-grid { display: grid; grid-template-columns: 1.25fr 1fr 1.25fr; gap: .6rem; }
.pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }

/* Save rides along the bottom of the form while you are in it, above the tab
   bar on a phone, so it is never a scroll away. */
.savebar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  margin: .6rem -.25rem 0; padding: .8rem .25rem;
  background: linear-gradient(to top, var(--paper) 70%, transparent);
}
.savebar .btn { min-height: 2.65rem; padding: 0 1.35rem; font-size: .93rem; }

@media (max-width: 900px) {
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .t-you, .t-golf, .t-food, .t-notes { grid-column: span 1; }
  .t-contact, .t-travel, .t-goals { grid-column: 1 / -1; }
  .t-goals { grid-row: auto; }
}
@media (max-width: 760px) {
  /* The bar is a row of the screen now, not a layer over the page, so Save
     sticks to the foot of the scrolling area rather than clearing anything. */
  .savebar { bottom: 0; margin-bottom: -1.6rem; padding-bottom: 1.6rem; }
}
@media (max-width: 620px) {
  .bento { grid-template-columns: minmax(0, 1fr); gap: .8rem; }
  .bento > .tile { grid-column: 1 / -1; }
  .t-goals textarea { min-height: 13rem; }
  .leg-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .leg-via { grid-column: 1 / -1; }
}

/* ---------- in or out, on an optional round ---------- */
.optin {
  margin: .2rem 0 0; padding: .7rem .8rem .75rem; border-radius: 10px;
  background: color-mix(in srgb, var(--fairway) 6%, var(--card));
  border: 1px solid color-mix(in srgb, var(--fairway) 18%, transparent);
}
.optin-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .6rem; }
.optin-q { font-size: .88rem; font-weight: 600; margin-right: auto; }
.optin-pick { display: flex; gap: .4rem; margin-top: .5rem; }
.optin-pick form { display: contents; }
.optin-btn {
  font: inherit; font-size: .84rem; font-weight: 600; cursor: pointer; flex: 1 1 0;
  min-height: 2.3rem; padding: .35rem .9rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card); color: var(--ink);
  transition: border-color .12s var(--ease), background-color .12s var(--ease);
}
.optin-btn:hover:not(:disabled) { border-color: var(--fairway); }
.optin-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.optin-btn:disabled { cursor: default; opacity: .55; }
.optin-btn.on { border-color: var(--fairway); color: #fff; background: var(--fairway); }
.optin .who-row { margin-top: .55rem; }
@media (prefers-reduced-motion: reduce) { .optin-btn { transition: none; } }

/* =====================================================================
   Live scoring
   A card you can keep with one thumb on a cart path, and a board that
   refreshes itself. Targets are deliberately large: this gets used in
   sunlight, in a glove, on a phone that is already sweaty.
   ===================================================================== */
.round-head h2 { font-size: 1.15rem; }
.course-live {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  margin: .2rem 0 0; font-size: .86rem;
}
.live-dot {
  width: .5rem; height: .5rem; border-radius: 999px; background: var(--ok); flex: none;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent);
  animation: live-pulse 2.4s ease-out infinite;
}
@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent); }
  70%, 100% { box-shadow: 0 0 0 .5rem transparent; }
}
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }

/* The one button anyone wants once a round starts: full width, thumb height,
   and loud enough to find in sunlight. Brass while a round is under way. */
.score-btn {
  display: flex; width: 100%; margin-top: .9rem;
  align-items: center; justify-content: center; gap: .55rem;
  min-height: 3.1rem; padding: .6rem 1.1rem; border-radius: 11px;
  font-size: 1.02rem; font-weight: 700; letter-spacing: .01em;
}
.score-btn .ic { width: 1.3rem; height: 1.3rem; }
.score-btn.live { background: var(--brass); border-color: var(--brass); color: #FFF4EE; }
.score-btn.live:hover { background: var(--brass-lt); border-color: var(--brass-lt); }
.score-btn .score-thru {
  font-size: .78rem; font-weight: 600; padding: .1rem .5rem .14rem; border-radius: 999px;
  background: rgba(255,255,255,.18);
}

/* The board, after the hand-hung one at Augusta. A heavy green frame round a
   white board; LEADERS in serif capitals across the top, with our GI where
   theirs has the map and flag; the HOLE and PAR rows lettered in green; one
   slat per man with his name in black serif capitals; and the running score to
   par in red under and green over. The board is white even in dark mode, as a
   real sign is, dimmed a shade so it does not glare, which is why it has its
   own colours instead of the page's: red and green have to read on white.
   Place and name stay pinned while the holes scroll sideways, so a phone shows
   who and how many before it shows where. Sticky cells need a solid fill. */
.ldr {
  --ldr-frame: #1E4A2E;
  --ldr-frame-dk: #163A23;
  --ldr-board: #FFFFFF;
  --ldr-mine: #F1F3E6;
  --ldr-ink: #111111;
  --ldr-sub: #6B6B63;
  --ldr-rule: #D9D9D2;
  --ldr-red: #C1272D;
  --ldr-green: #1E6B3A;
  --ldr-letter: #1E4A2E;
  --ldr-serif: "Times New Roman", Times, "Liberation Serif", serif;
  /* The frozen panes, left to right. Each has a fixed width so the next can be
     pinned exactly against it. */
  --w-pos: 2.4rem;
  --w-name: 11.5rem;
  --w-tp: 3.8rem;
  --w-thru: 3rem;
  --w-tot: 3.2rem;
  background: var(--ldr-frame); border-radius: 6px; padding: 0 6px 6px;
  box-shadow: var(--shadow); margin-bottom: 1rem;
}
@media (prefers-color-scheme: dark) {
  .ldr {
    --ldr-board: #E9E8E1;
    --ldr-mine: #DCDFCF;
    --ldr-rule: #C4C3BA;
    --ldr-sub: #5E5E57;
  }
}
.ldr .sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.ldr-band {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: .6rem;
  padding: .55rem .5rem .5rem; color: #FFFFFF;
}
/* The monogram's artwork sits well inside its viewBox, so it is drawn larger
   than it reads and pulled in so it does not heighten the band. */
.ldr-logo { height: 3.6rem; width: auto; justify-self: start; margin: -.6rem 0 -.6rem -.5rem; }
.ldr-band h2 {
  margin: 0; color: inherit; font-family: var(--ldr-serif); font-weight: 700;
  font-size: 1.9rem; line-height: 1; letter-spacing: .14em; text-transform: uppercase;
  padding-left: .14em;
}
.ldr-fmt {
  justify-self: end; text-align: right; font-size: .66rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .12em; color: rgba(255,255,255,.8);
}
.ldr-block { background: var(--ldr-board); border-radius: 2px; }
.ldr-block + .ldr-block { margin-top: 6px; }
.ldr-cap {
  margin: 0; padding: .55rem .8rem .35rem; font-family: var(--ldr-serif);
  font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .16em;
  color: var(--ldr-letter); border-bottom: 2px solid var(--ldr-frame);
}
.ldr-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.ldr-table {
  border-collapse: separate; border-spacing: 0; width: 100%;
  font-variant-numeric: tabular-nums lining-nums; color: var(--ldr-ink);
}
.ldr-table th, .ldr-table td {
  padding: .5rem .28rem; text-align: center; white-space: nowrap;
  border-bottom: 1px solid var(--ldr-rule); background: var(--ldr-board);
}
.ldr-table tbody tr:last-child > * { border-bottom: 0; }

/* HOLE and PAR, lettered in green on the white, as the board has them. */
.ldr-table thead th, .ldr-table thead td {
  font-family: var(--ldr-serif); font-weight: 700; font-size: .92rem;
  color: var(--ldr-ink); padding: .3rem .28rem;
}
.ldr-table thead .ldr-name, .ldr-table thead .ldr-tp, .ldr-table thead .ldr-thru,
.ldr-table thead .ldr-tot {
  color: var(--ldr-letter); font-size: .74rem; letter-spacing: .12em; text-transform: uppercase;
}
.ldr-table thead .ldr-par > * { border-bottom: 2px solid var(--ldr-frame); }

.ldr-pos, .ldr-name, .ldr-tp, .ldr-thru, .ldr-tot { position: sticky; z-index: 1; }
.ldr-pos  { left: 0; }
.ldr-name { left: var(--w-pos); text-align: left !important; }
.ldr-tp   { left: calc(var(--w-pos) + var(--w-name)); }
.ldr-thru { left: calc(var(--w-pos) + var(--w-name) + var(--w-tp)); }
.ldr-tot  { left: calc(var(--w-pos) + var(--w-name) + var(--w-tp) + var(--w-thru)); }
.ldr-pos  { width: var(--w-pos);  min-width: var(--w-pos);  max-width: var(--w-pos); }
.ldr-name { width: var(--w-name); min-width: var(--w-name); max-width: var(--w-name); }
.ldr-tp   { width: var(--w-tp);   min-width: var(--w-tp);   max-width: var(--w-tp); }
.ldr-thru { width: var(--w-thru); min-width: var(--w-thru); max-width: var(--w-thru); }
.ldr-tot  { width: var(--w-tot);  min-width: var(--w-tot);  max-width: var(--w-tot); }
/* The edge of the frozen panes: a green rule the holes slide under. */
.ldr-table .ldr-tot { box-shadow: inset -2px 0 0 var(--ldr-frame); }
.ldr-pos {
  font-family: var(--ldr-serif); font-weight: 700; font-size: 1rem; color: var(--ldr-ink);
}
tbody .ldr-name { font-weight: 400; }
.ldr-who {
  display: block; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--ldr-serif); font-weight: 700; font-size: 1.02rem;
  text-transform: uppercase; letter-spacing: .03em; color: var(--ldr-ink);
}
.ldr-who .nm-short { display: none; }
/* A foursome's name is four first names and is allowed to wrap. */
.ldr-teams .ldr-who { white-space: normal; }
.ldr-who .pill { font-family: var(--ui); text-transform: none; letter-spacing: 0; vertical-align: .15em; }
.ldr-sub { display: block; font-size: .68rem; color: var(--ldr-sub); overflow: hidden; text-overflow: ellipsis; }
.ldr .ldr-tp .tp { font-size: 1.25rem; }
.ldr-table thead th { white-space: normal; line-height: 1.1; }
.ldr-thru { font-family: var(--ldr-serif); font-weight: 700; font-size: .95rem; }
.ldr-h { min-width: 2.2rem; }
.ldr-turn { box-shadow: inset 1px 0 0 var(--ldr-rule); }
.ldr-tot { font-family: var(--ldr-serif); font-weight: 700; font-size: .95rem; }

/* The two switches under LEADERS: net or gross, to par or as played. Both
   views are in the markup and #board's classes pick one. */
.ldr-view { display: flex; justify-content: center; flex-wrap: wrap; gap: .5rem; padding: 0 .3rem .55rem; }
.ldr .seg { display: inline-flex; border: 1px solid rgba(255,255,255,.35); border-radius: 999px; overflow: hidden; }
.ldr .seg button {
  all: unset; box-sizing: border-box; cursor: pointer; padding: .32rem .85rem; min-height: 2rem;
  font-size: .74rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.8);
}
.ldr .seg button + button { border-left: 1px solid rgba(255,255,255,.35); }
.ldr .seg button[aria-pressed="true"] { background: #FFFFFF; color: var(--ldr-frame); }
.ldr .seg button:focus-visible { box-shadow: inset 0 0 0 2px #FFFFFF; }
.ldr-gross-only, .ldr .v-act { display: none; }
#board.show-gross .ldr-net-only { display: none; }
#board.show-gross .ldr-gross-only { display: block; }
#board.show-act .ldr .v-par { display: none; }
#board.show-act .ldr .v-act { display: inline; }
/* As played, a par is just a par: ink, not the green that means over. */
.ldr .v-act .tp.level { color: var(--ldr-ink); }

/* The numbers the board is known for: serif, bold, red or green. */
.ldr .tp { font-family: var(--ldr-serif); font-weight: 700; font-size: 1rem; }
.tp { font-weight: 700; }
.tp.red   { color: var(--ldr-red, var(--brass)); }
.tp.green { color: var(--ldr-green, var(--fairway)); }
.tp.level { color: var(--ldr-green, var(--fairway)); }

/* Your own row is the one you look for first. */
.ldr-table tr.mine > * { background: var(--ldr-mine); }
.ldr-table tr.mine .ldr-pos { box-shadow: inset 4px 0 0 var(--ldr-red); }

.ldr-empty { text-align: center !important; color: var(--ldr-sub); padding: 1.2rem !important; white-space: normal !important; }
.ldr-key {
  margin: 0; padding: .55rem .5rem .1rem; font-size: .72rem; color: rgba(255,255,255,.82);
}
.ldr .ldr-key .tp { font-family: var(--ui); font-size: inherit; }
.ldr-key .tp.red { color: #FFB3AE; }
.ldr-key .tp.green { color: #B9E3C3; }
@media (max-width: 520px) {
  .ldr { --w-pos: 1.7rem; --w-name: 7.6rem; --w-tp: 3rem; --w-thru: 2.3rem; --w-tot: 2.7rem;
         padding: 0 4px 4px; }
  .ldr-who .nm-long { display: none; }
  .ldr-who .nm-short { display: inline; }
  .ldr-who { font-size: .95rem; letter-spacing: .01em; }
  .ldr-teams .ldr-who { font-size: .8rem; }
  .ldr-sub { font-size: .62rem; letter-spacing: .02em; }
  .ldr-table th, .ldr-table td { padding-left: .18rem; padding-right: .18rem; }
  .ldr-name { padding-left: .3rem !important; }
  .ldr-table thead .ldr-name, .ldr-table thead .ldr-tp, .ldr-table thead .ldr-thru,
  .ldr-table thead .ldr-tot { font-size: .6rem; letter-spacing: .06em; }
  .ldr .ldr-tp .tp { font-size: 1.1rem; }
  .ldr-logo { height: 3rem; margin: -.5rem 0 -.5rem -.4rem; }
  .ldr-band h2 { font-size: 1.45rem; letter-spacing: .1em; }
  .ldr-fmt { font-size: .58rem; letter-spacing: .08em; }
}

/* The hole card wears the same green, lettered the same way. */
.card.scorecard { padding-top: 0; overflow: hidden; }
.card.scorecard > header {
  margin: 0 -1.1rem .9rem; padding: .65rem 1.1rem .6rem;
  background: #1E4A2E; color: #FFFFFF;
}
.card.scorecard > header h2 {
  color: inherit; font-family: "Times New Roman", Times, "Liberation Serif", serif; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; font-size: 1.3rem;
}
.card.scorecard > header .muted { color: inherit; opacity: .85; text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; }

/* The hole, and the eighteen chips that walk you round it. */
.sc-nav { display: flex; align-items: center; gap: .4rem; margin: .1rem 0 .9rem; }
.sc-strip {
  display: flex; gap: .25rem; overflow-x: auto; scrollbar-width: none; flex: 1; padding: .15rem 0;
}
.sc-strip::-webkit-scrollbar { display: none; }
.sc-chip {
  flex: 0 0 auto; min-width: 1.9rem; height: 1.9rem; border-radius: 7px;
  display: grid; place-items: center; text-decoration: none;
  font-size: .78rem; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--muted); background: var(--card); border: 1px solid var(--rule);
}
.sc-chip.part { border-color: color-mix(in srgb, var(--fairway) 45%, transparent); }
.sc-chip.done { color: var(--fairway); background: color-mix(in srgb, var(--fairway) 12%, transparent);
  border-color: color-mix(in srgb, var(--fairway) 30%, transparent); }
.sc-chip.on { color: #fff; background: var(--pine); border-color: var(--pine); }
.sc-arrow {
  flex: none; width: 2.1rem; height: 2.1rem; border-radius: 8px; display: grid; place-items: center;
  font-size: 1.3rem; line-height: 1; text-decoration: none; color: var(--ink);
  border: 1px solid var(--rule); background: var(--card);
}
.sc-arrow.off { opacity: .35; pointer-events: none; }

/* One man, one hole. */
.sc-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center;
  gap: .5rem .6rem; padding: .6rem 0; border-top: 1px solid var(--rule-sf);
}
.sc-row:first-child { border-top: 0; }
.sc-who { min-width: 0; font-size: .95rem; }
.sc-dots { color: var(--brass); font-size: .62rem; letter-spacing: .08em; vertical-align: .12em; }
.sc-in { display: flex; align-items: center; gap: .3rem; flex: none; }
.sc-step {
  all: unset; box-sizing: border-box; cursor: pointer; user-select: none;
  width: 2.5rem; height: 2.5rem; border-radius: 9px; display: grid; place-items: center;
  font-size: 1.25rem; font-weight: 600; color: var(--ink);
  border: 1px solid var(--rule); background: var(--card);
}
.sc-step:active { background: var(--item-hover); }
.sc-step:focus-visible { box-shadow: var(--ring); }
.sc-in input {
  width: 3.1rem; min-height: 2.5rem; text-align: center; font-size: 1.1rem; font-weight: 600;
  font-variant-numeric: tabular-nums; padding: .2rem;
  -moz-appearance: textfield; appearance: textfield;
}
.sc-in input::-webkit-outer-spin-button, .sc-in input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.sc-in input.saving, .sc-ball.saving { opacity: .55; }
.sc-drive { display: flex; gap: .2rem; grid-column: 2 / -1; justify-self: end; }
.sc-ball {
  all: unset; box-sizing: border-box; cursor: pointer;
  min-height: 1.9rem; padding: .2rem .6rem; border-radius: 999px;
  font-size: .76rem; font-weight: 600; color: var(--muted);
  border: 1px solid var(--rule); background: var(--card);
}
.sc-ball.on { color: #fff; background: var(--fairway); border-color: var(--fairway); }
.sc-ball:focus-visible { box-shadow: var(--ring); }
.sc-net {
  min-width: 3.4rem; text-align: right; font-size: .82rem; font-weight: 600; color: var(--fairway);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 420px) {
  .sc-row { grid-template-columns: minmax(0, 1fr) auto; }
  .sc-net { grid-column: 1 / -1; text-align: left; color: var(--muted); }
  .sc-drive { grid-column: 1 / -1; justify-self: start; }
}

/* ============================ POLLS ============================
   A questionnaire is a bento of tiles, one per question, sized by what the
   question actually asks: a Yes/No is a small cell and a fourteen-option list
   is a wide one. Inside a tile it is a row of pills, because a pill is a target
   you tap with a thumb rather than a checkbox you aim at. State comes from
   :has(input:checked), so a tick still shows with the script blocked and there
   is no class to keep in step with the DOM. */

/* The six-column bento is shared with Your Details; these are the spans the
   poll pages pick from. Two columns at tablet, one on a phone, which the
   .bento rules further up already handle for .tile. */
/* Ordered: the tiles are already packed into full rows by packSpans, and the
   dense flow would only be able to improve on that by moving a later tile in
   front of an earlier one. Questions have an order. */
.bento.ordered { grid-auto-flow: row; }
.bento > .span-2 { grid-column: span 2; }
.bento > .span-3 { grid-column: span 3; }
.bento > .span-4 { grid-column: span 4; }
.bento > .span-6 { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .bento > .span-2 { grid-column: span 1; }
  .bento > .span-3, .bento > .span-4 { grid-column: 1 / -1; }
}

.poll-top {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: .7rem 1.2rem; margin: 0 0 1rem;
}
.poll-top .pt-b { flex: 1 1 20rem; min-width: 0; }
.poll-top h1 { margin: 0 0 .25rem; font-size: 1.55rem; line-height: 1.15; text-wrap: balance; }
.poll-top .intro { margin: 0; color: var(--muted); font-size: .92rem; max-width: 65ch; }
.pt-r { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.pt-prog { display: flex; align-items: center; gap: .45rem; }
.pt-n { font-size: .82rem; color: var(--muted); white-space: nowrap; }
.pt-n b { color: var(--ink); font-size: 1.05rem; font-variant-numeric: tabular-nums; }

/* How far through it he is. A ring rather than a bar: it sits in the corner of
   a tile without taking a row of its own. */
.ring {
  flex: none; width: 1.7rem; height: 1.7rem; border-radius: 50%;
  background: conic-gradient(var(--fairway) calc(var(--pct, 0) * 1%), var(--rule-sf) 0);
  -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 4px), #000 calc(100% - 3.5px));
          mask: radial-gradient(farthest-side, #0000 calc(100% - 4px), #000 calc(100% - 3.5px));
}
.ring.big { width: 2.3rem; height: 2.3rem; }
.ring.full { background: var(--ok); }

/* ---------- a poll, as a tile ---------- */
.pcard { position: relative; display: flex; flex-direction: column; }
.pc-top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .7rem; }
.pc-h { margin: 0 0 .25rem; font-size: 1.12rem; line-height: 1.2; }
/* One real link, stretched over the whole tile, so the tile is one target and
   the Results button beside it is still its own. */
.pc-link { color: inherit; text-decoration: none; }
.pc-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.pcard:hover .pc-link { color: var(--fairway); }
.pc-link:focus-visible { outline: none; }
.pcard:has(.pc-link:focus-visible) { box-shadow: var(--ring); }
.pc-s { margin: 0; font-size: .87rem; line-height: 1.45; color: var(--muted); }
.pc-stat { margin: .5rem 0 0; }
.pc-foot { display: flex; align-items: center; gap: .6rem; margin-top: auto; padding-top: .9rem; }
.pc-go { font-size: .84rem; font-weight: 650; color: var(--fairway); margin-right: auto; }
.pcard.done .pc-go { color: var(--muted); font-weight: 500; }
.pc-res { position: relative; }

/* A tile the full width of the grid has room to read as one line rather than a
   stack: the ring, then what it is, then what to do about it. */
@media (min-width: 901px) {
  .pcard.span-6 {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center; column-gap: 1.3rem;
  }
  .pcard.span-6 .pc-top { grid-row: 1 / -1; margin-bottom: 0; flex-direction: column; gap: .5rem; }
  .pcard.span-6 .pc-h, .pcard.span-6 .pc-s, .pcard.span-6 .pc-stat { grid-column: 2; }
  .pcard.span-6 .pc-foot { grid-column: 3; grid-row: 1 / -1; margin-top: 0; padding-top: 0; }
  .pcard.span-6 .pc-go { margin-right: 0; }
}
.pnew .actions { margin-bottom: 0; }

/* ---------- one question, as a tile ---------- */
.q.answered { border-color: color-mix(in srgb, var(--fairway) 32%, var(--rule)); }
.q-h { display: flex; align-items: flex-start; gap: .4rem .7rem; flex-wrap: wrap; }
.q-p { flex: 1 1 13rem; min-width: 0; margin: 0; font-size: 1rem; line-height: 1.3; font-weight: 650; }
.q-p .rowlink { font-weight: inherit; }
/* Plain small caps, not pills. A pill here sits directly above a row of real
   pills you are meant to tap, and the eye reads the pair as one set of controls. */
.q-tags { flex: none; display: flex; align-items: baseline; gap: .45rem; padding-top: .25rem; }
.q-tag {
  font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap;
}
.q-tag + .q-tag::before { content: "\00b7"; margin-right: .45rem; color: var(--rule); }
.q-tag.req { color: var(--brass); }
.q-help { margin: .35rem 0 0; font-size: .84rem; color: var(--muted); }
.q-text { width: 100%; margin-top: .75rem; resize: vertical; }
.span-3 .q-text, .span-4 .q-text, .span-6 .q-text { min-height: 6rem; }

.q-opts { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .8rem; }
.opt {
  position: relative; display: inline-flex; align-items: center; gap: .4rem;
  cursor: pointer; appearance: none; -webkit-appearance: none;
  min-height: 2.4rem; padding: .35rem .8rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--card);
  font: 500 .88rem/1.25 var(--ui); color: var(--ink); text-align: left;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: border-color .14s var(--ease), background-color .14s var(--ease), color .14s var(--ease);
}
.opt input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: inherit; }
.opt:hover:not(:has(input:disabled)):not([disabled]) { border-color: color-mix(in srgb, var(--fairway) 45%, var(--rule)); }
.opt:has(input:checked), .opt.on {
  background: var(--fairway); border-color: var(--fairway); color: #fff; font-weight: 600;
}
.opt:has(input:focus-visible), .opt:focus-visible { outline: none; box-shadow: var(--ring); }
.opt:has(input:disabled), .opt[disabled] { opacity: .55; cursor: default; }

/* The rank badge. Hidden until it has a number to hold, so an unpicked option
   is the same shape as any other pill. */
.opt-n {
  flex: none; display: none; min-width: 1.2rem; height: 1.2rem; border-radius: 50%;
  align-items: center; justify-content: center; margin-left: -.2rem;
  font-size: .7rem; font-weight: 700; font-variant-numeric: tabular-nums;
  background: rgba(255,255,255,.24); color: #fff;
}
.opt.on .opt-n { display: inline-flex; }
/* All of them picked: the next tap replaces the first, and a dashed edge says
   so rather than a tap that appears to do nothing. */
.q-opts.rank.full .opt:not(.on) { border-style: dashed; }

/* ---------- what everyone said, one tile per question ---------- */
.qr-h { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.qr-h h2 { margin: 0; font-size: .97rem; font-weight: 650; line-height: 1.3; }
.qr-h .tiny { flex: none; }
.qr .empty { padding: 1.2rem .5rem; }
.bars { display: flex; flex-direction: column; gap: .28rem; margin-top: .7rem; }
.bar {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; padding: .4rem .6rem; border-radius: 7px; overflow: hidden;
  background: var(--rule-sf); font-size: .87rem;
}
.bar::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: var(--pct, 0%);
  background: color-mix(in srgb, var(--fairway) 30%, transparent);
}
.bar > * { position: relative; }
.b-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-n { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
.none-picked { margin: .5rem 0 0; }
.answers { display: flex; flex-direction: column; gap: .45rem; margin-top: .7rem; }
.ans { display: flex; gap: .7rem; align-items: baseline; font-size: .88rem; }
.ans-who { flex: none; width: 5.5rem; font-weight: 600; font-size: .8rem; color: var(--muted); }
.ans-what { min-width: 0; white-space: pre-wrap; }

.aq-req { display: flex; align-items: flex-end; padding-bottom: .3rem; }
/* An options list is the substance of the question, not a note about it. */
.panel-body textarea[name="options"] { min-height: 9.5rem; }

@media (max-width: 560px) {
  .poll-top h1 { font-size: 1.35rem; }
  .ans { flex-direction: column; gap: .05rem; }
  .ans-who { width: auto; }
}
.venmo-pay { margin-top: .8rem; text-align: right; }
.venmo-pay .btn { width: 100%; padding: .75rem 1rem; font-size: 1.05rem; }
/* Venmo's own blue and wordmark, so the button reads as Venmo at a glance. */
.btn.venmo { background: #008CFF; border-color: #008CFF; color: #FFF; }
.btn.venmo:hover { background: #0074D4; border-color: #0074D4; color: #FFF; }
.btn.venmo .venmo-mark { height: .95em; width: auto; margin-left: .1rem; transform: translateY(.06em); }
/* A Needs you line with a pay button: on a phone the words take the full width
   and the two buttons sit under them, rather than squeezing the text. */
@media (max-width: 760px) {
  .checkline.has-pay { flex-wrap: wrap; }
  .checkline.has-pay .nm { flex: 1 1 100%; }
  .checkline.has-pay .btn.venmo { margin-left: auto; }
}
/* A two-line Venmo button: what it does, then who it goes to. */
.btn.venmo.two { flex-direction: column; gap: .15rem; line-height: 1.2; }
.btn.venmo .venmo-line { display: inline-flex; align-items: center; gap: .35rem; }
.btn.venmo .venmo-sub { font-size: .76rem; font-weight: 500; opacity: .9; white-space: normal; }
/* A credit's amount never breaks from its minus sign. */
.invoice b.num { white-space: nowrap; }
