:root{
  --bg:#F1ECDC; --panel:#FBF9F1; --ink:#26261D; --ink-soft:#6B6A5A;
  --green:#1F3B2C; --green-light:#3F6650; --gold:#B8912A; --rust:#A23F29;
  --line:#D3CDB6; --line-strong:#B9B29C; --teal:#3E6E8E;
}
*{ box-sizing:border-box; }

/* Locks the page down so it behaves like a native app screen rather than a
   web page -- no rubber-band dragging in any direction, even by a
   sub-pixel. `overflow-y:auto` on .scrollarea alone leaves overflow-x
   computed as "auto" too (that's CSS's own rule for a non-visible/visible
   axis pairing), which combined with the scorecard's edge-to-edge bleed
   was just enough sub-pixel horizontal overflow for iOS to rubber-band
   against. overscroll-behavior is the belt-and-suspenders browser-level
   switch for the bounce itself. */
html{
  height:100%; overflow:hidden; overscroll-behavior:none;
}

body{
  margin:0; background:var(--bg); color:var(--ink); font-family:'IBM Plex Sans',sans-serif;
  display:flex; justify-content:center; height:100vh; height:100dvh; overflow:hidden; overscroll-behavior:none;
}

.app{ width:100%; max-width:440px; height:100%; display:flex; flex-direction:column; position:relative; overflow:hidden; }
.scrollarea{ flex:1 1 auto; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch;
  overscroll-behavior-y:contain; padding:18px 16px 28px; }

h1{ font-family:'Barlow Condensed',sans-serif; font-weight:700; font-size:26px; color:var(--green); margin:4px 0 2px; }
.sub{ font-size:12px; color:var(--ink-soft); margin-bottom:16px; }

.screen{ display:none; }
.screen.active{ display:block; }

.hidden{ display:none !important; }

/* ---------- Sign-in card (embedded, not a full-screen gate) ---------- */
.signin-card{ background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:14px; margin-bottom:16px; }
.signin-card .whoami{ font-size:13px; margin-bottom:8px; }
.signin-card .error-text{ color:var(--rust); font-size:11px; margin-top:8px; }
.signout-link{ background:none; border:none; color:var(--ink-soft); font-size:11px; text-decoration:underline; cursor:pointer; padding:0; margin-top:8px; }

/* ---------- Fields ---------- */
.field{ margin-bottom:12px; }
.field label{ display:block; font-family:'Barlow Condensed',sans-serif; font-size:11px; letter-spacing:1.1px;
  text-transform:uppercase; color:var(--ink-soft); margin-bottom:5px; }
.field-row{ display:flex; gap:10px; }
.field-row .field{ flex:1; }

.tee-rating-note{ font-size:11.5px; color:var(--ink-soft); margin-top:6px; }
.tee-rating-note.away-rating-hint{ margin-top:-4px; margin-bottom:12px; }

/* font-size must stay >=16px on every real <input>/<textarea> -- iOS Safari
   auto-zooms the whole page in when a smaller input receives focus, and the
   zoomed viewport sticks around after (that's the "zooms in and doesn't
   fit" bug). The chip/toggle "pills" are plain divs, not inputs, so they
   can still be as compact as we like without triggering this. */
input[type="text"], input[type="date"], input[type="number"], textarea{
  width:100%; background:var(--panel); border:1.5px solid var(--line-strong); border-radius:9px;
  padding:9px 12px; font-family:'IBM Plex Sans',sans-serif; font-size:16px; color:var(--ink);
}
input[type="date"], input[type="number"]{ font-family:'IBM Plex Mono',monospace; font-size:16px; }
input:focus, textarea:focus{ outline:none; border-color:var(--green); }
textarea{ resize:vertical; min-height:60px; }

/* ---------- Chips (single & multi select) ---------- */
.chiprow{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px; }
.chip{ padding:6px 11px; border-radius:16px; border:1.5px solid var(--line-strong); background:var(--panel);
  font-size:12px; font-weight:500; cursor:pointer; color:var(--ink); }
.chip.active{ background:var(--green); border-color:var(--green); color:#fff; }

.staterow{ display:flex; gap:6px; margin-bottom:12px; }
.staterow .chip{ flex:1; text-align:center; padding:8px 6px; font-size:12px; }
.staterow .chip.active.won{ background:var(--green); border-color:var(--green); }
.staterow .chip.active.lost{ background:var(--rust); border-color:var(--rust); }
.staterow .chip.active.halved{ background:var(--gold); border-color:var(--gold); }

.togglechip{ display:inline-flex; align-items:center; gap:7px; padding:7px 13px; border-radius:16px;
  border:1.5px solid var(--line-strong); background:var(--panel); font-size:13px; font-weight:600; color:var(--ink);
  cursor:pointer; margin-bottom:12px; }
.togglechip.active{ background:var(--green); border-color:var(--green); color:#fff; }

/* Tag / people picker -- reuses .chip visuals with a remove affordance */
.people-picker{ position:relative; display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-bottom:16px; }
.people-picker input{ border:none; background:transparent; flex:1 1 120px; min-width:100px; padding:9px 2px;
  font-family:'IBM Plex Sans',sans-serif; font-size:16px; }
.people-picker input:focus{ outline:none; }
.person-chip{ padding:8px 8px 8px 15px; border-radius:20px; background:var(--green); color:#fff; font-size:13px;
  font-weight:500; display:flex; align-items:center; gap:6px; }
.person-chip button{ background:none; border:none; color:#fff; font-weight:bold; cursor:pointer; padding:0 4px; line-height:1; opacity:0.8; }
.person-chip button:active{ opacity:1; }

/* Tap-to-select suggestion dropdown -- replaces a native <datalist>, whose
   suggestion UI doesn't reliably show up on iOS Safari. Anchored to the
   whole picker (not just the input) so it doesn't jump around as chips
   wrap onto new lines. */
.people-suggestions{ position:absolute; left:0; right:0; top:100%; margin-top:4px; z-index:20;
  background:var(--panel); border:1.5px solid var(--line-strong); border-radius:10px;
  box-shadow:0 6px 16px rgba(38,38,29,0.18); max-height:190px; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.suggestion-row{ padding:11px 14px; font-family:'IBM Plex Sans',sans-serif; font-size:15px; color:var(--ink);
  border-bottom:1px solid var(--line); cursor:pointer; }
.suggestion-row:last-child{ border-bottom:none; }
.suggestion-row:active{ background:var(--bg); }

/* ---------- Scorecard (front/back nine, hole-by-hole, Out/In totals) ---------- */
/* Bleeds out to the screen edge (cancelling .scrollarea's 16px side
   padding) rather than sitting inset like the rest of the form -- that's
   what was leaving dead space to the left of hole 1 and left too little
   width for 9 holes + a total to fit an iPhone screen. A small 3px inner
   gutter keeps the numbers off the literal edge. */
.scorecard{ margin:0 -16px 16px; padding:0 3px; }
.nine-block{ background:var(--panel); border:1px solid var(--line); border-radius:10px; overflow:hidden; margin-bottom:8px; }

/* Flexbox, not CSS Grid -- grid's `minmax(0,1fr)` still lets a WebKit
   input's intrinsic content size win the sizing fight on some iOS
   versions. flex:1 1 0 + min-width:0 on every cell is the bulletproof
   equal-width pattern and is what actually keeps 9 columns + a total on
   screen. */
.nine-row{ display:flex; align-items:center; }
.nine-row.header{ background:var(--green); }
.nine-row.header span{ color:#fff; }
.nine-row.parrow{ border-bottom:1px solid var(--line); }
/* The score row's circles/squares sit flush against nine-block's
   overflow:hidden boundary with no cushion, so their bottom edge (and the
   eagle/double-bogey rings, which extend a few px past the input's own box
   via box-shadow) get clipped. A little vertical padding here keeps them
   clear of that edge. */
.nine-row.scorerow{ padding:4px 0; }
.nine-row > span{ flex:1 1 0%; min-width:0; text-align:center; font-family:'IBM Plex Mono',monospace; }

.holenum{ font-size:10.5px; font-weight:600; padding:6px 0; }
.ninelabel{ font-size:9.5px; font-weight:700; letter-spacing:0.3px; text-transform:uppercase; padding:6px 0; flex:1.15 1 0% !important; }

.parval{ font-size:11px; color:var(--ink-soft); padding:5px 0; }
.partotal{ font-size:11px; color:var(--ink-soft); font-weight:600; padding:5px 0; flex:1.15 1 0% !important; }

/* Each score cell is a flexible slot (same width-share as the hole-number
   /par columns above it, so everything lines up) that just centers a
   FIXED-SIZE circle inside itself. Keeping the circle's own box a constant
   26x26px -- instead of stretching an <input> to fill a variable-width
   column -- is what makes it render as an actual circle instead of an
   oval, and keeps its size identical regardless of how narrow the column
   ends up being on a given phone. */
.scorecell{ flex:1 1 0%; min-width:0; display:flex; justify-content:center; }

/* No visible box until a hole is entered and scores to a
   birdie/eagle/bogey/double-bogey -- just the digit on its own, sitting on
   the panel background. */
/* input.scoreinput (not just .scoreinput) so this beats the generic
   input[type="text"] rule above on specificity -- otherwise that rule's
   var(--line-strong) border and var(--panel) background win and every
   empty cell shows a faint box, which is the "circles look like squares"
   bug. */
/* font-size is 16px (not smaller) for the same iOS auto-zoom reason as the
   rule above -- these cells get focused over and over via auto-advance, so
   they're the biggest offender for that bug. Bumped to 30px so the circle
   still has comfortable room around a 16px digit; the column math above
   has margin to spare at this size on a real iPhone's minimum width. */
input.scoreinput{ width:30px; height:30px; flex:0 0 30px; border:1.5px solid transparent; background:transparent;
  padding:0; margin:0; font-family:'IBM Plex Mono',monospace; font-size:16px; font-weight:700; color:var(--ink);
  text-align:center; line-height:30px; border-radius:50%; box-sizing:border-box; caret-color:var(--green);
  -webkit-appearance:none; appearance:none; }
input.scoreinput:focus{ outline:none; background:var(--bg); }
.scoretotal{ font-size:13px; font-weight:700; color:var(--green); padding:8px 0; background:var(--bg); overflow:hidden; text-overflow:clip; flex:1.15 1 0%; }

/* Score-vs-par notation: circle = birdie, double circle = eagle or better,
   square = bogey, double square = double-bogey or worse. Par (and empty)
   holes get no mark at all -- the transparent border above keeps every
   cell's box size identical so a mark appearing/disappearing never shifts
   the layout. The double-ring marks use a card-colored gap so they read as
   two concentric rings against the nine-block's background. */
input.scoreinput.mark-birdie{ border-radius:50% !important; border-color:var(--green); }
input.scoreinput.mark-eagle{ border-radius:50% !important; border-color:var(--green); box-shadow:0 0 0 2px var(--panel), 0 0 0 3.5px var(--green); }
input.scoreinput.mark-bogey{ border-radius:6px !important; border-color:var(--rust); }
input.scoreinput.mark-dbogey{ border-radius:6px !important; border-color:var(--rust); box-shadow:0 0 0 2px var(--panel), 0 0 0 3.5px var(--rust); }

.scorecard-summary{ display:flex; justify-content:space-around; background:var(--panel); border:1px solid var(--line);
  border-radius:12px; padding:10px; font-size:13px; color:var(--ink-soft); }
.scorecard-summary strong{ color:var(--green); font-family:'IBM Plex Mono',monospace; font-size:15px; }

/* ---------- Buttons ---------- */
.savebtn{ width:100%; padding:15px 0; border:none; border-radius:12px; background:var(--green); color:#fff;
  font-family:'Barlow Condensed',sans-serif; font-weight:600; font-size:17px; letter-spacing:0.5px; cursor:pointer; }
.savebtn:active{ background:var(--green-light); }
.savebtn:disabled{ opacity:0.5; }
.startbtn{ background:none; border:1.5px solid var(--line-strong); border-radius:8px; padding:9px 14px;
  font-family:'Barlow Condensed',sans-serif; font-weight:600; font-size:13px; color:var(--green); cursor:pointer; width:100%; }
.toast{ text-align:center; font-size:12px; color:var(--ink-soft); margin-top:10px; min-height:14px; }

/* Tapping a card in History (edit) drops the Delete button below Save --
   an outline rust button rather than a filled one, so it doesn't visually
   compete with the primary Save/Update action just above it. */
.deletebtn{ width:100%; padding:13px 0; border:1.5px solid var(--rust); border-radius:12px; background:none;
  color:var(--rust); font-family:'Barlow Condensed',sans-serif; font-weight:600; font-size:14px;
  letter-spacing:0.3px; cursor:pointer; margin-top:10px; }
.deletebtn:active{ background:var(--rust); color:#fff; }
.deletebtn:disabled{ opacity:0.5; }

/* Edit-mode banner -- shown at the top of Add Round/Add Other Round
   whenever the form is populated from an existing History card rather
   than starting blank, so it's unmistakable that Save will overwrite that
   round rather than create a new one. Cancel lives here (top, easy to
   reach without scrolling past the whole form) rather than next to
   Delete at the bottom, which is for the rarer, more deliberate action. */
.editbanner{ display:flex; justify-content:space-between; align-items:center; gap:10px;
  background:var(--teal); color:#fff; border-radius:12px; padding:10px 14px; margin-bottom:16px;
  font-family:'Barlow Condensed',sans-serif; font-weight:600; font-size:14px; letter-spacing:0.3px; }
.editbanner-cancel{ background:rgba(255,255,255,0.22); color:#fff; border:none; border-radius:8px;
  padding:7px 12px; font-family:'Barlow Condensed',sans-serif; font-weight:600; font-size:12.5px; cursor:pointer; }

.detail-output{ margin-top:10px; padding:10px 12px; background:var(--panel); border:1px solid var(--line);
  border-radius:10px; font-family:'IBM Plex Mono',monospace; font-size:11.5px; line-height:1.6; color:var(--ink);
  white-space:pre-wrap; word-break:break-word; max-height:340px; overflow-y:auto; }

/* ---------- Section headers / cards ---------- */
.sectiontitle{ font-family:'Barlow Condensed',sans-serif; font-size:14px; letter-spacing:1.2px; text-transform:uppercase;
  color:var(--ink-soft); margin:20px 0 10px; font-weight:600; }
.sectiontitle:first-child{ margin-top:0; }

.card{ background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:14px 16px; margin-bottom:12px; }
/* Every History card opens that round for editing on tap -- :active gives
   a quick press flash since cursor:pointer means nothing on a touch
   screen. */
.roundcard{ cursor:pointer; }
.roundcard:active{ background:var(--bg); }
.roundcard .toprow{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:6px; }
.roundcard .datelabel{ font-family:'IBM Plex Mono',monospace; font-size:14px; color:var(--ink-soft); }
.roundcard .score{ font-family:'Barlow Condensed',sans-serif; font-weight:700; font-size:25px; color:var(--green); }
.roundcard .meta{ font-size:14.5px; color:var(--ink-soft); }
.roundcard .meta-names{ margin-top:2px; }
.roundcard .score-breakdown{ font-size:12.5px; color:var(--ink-soft); opacity:.8; margin-top:4px; }
.roundcard .score-achievements{ font-size:12.5px; font-weight:700; color:var(--ink-soft); opacity:.8; margin-top:2px; }
.roundcard .badgerow{ display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.badge{ font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.5px; color:#fff;
  border-radius:8px; padding:4px 9px; }
.badge.gold{ background:var(--gold); }
.badge.rust{ background:var(--rust); }
.badge.teal{ background:var(--teal); }
.badge.green{ background:var(--green); }

.empty{ font-size:12px; color:var(--ink-soft); padding:6px 0 14px; text-align:center; }
.loading-text{ font-size:12px; color:var(--ink-soft); padding:6px 0 14px; text-align:center; }

/* ---------- Stats / Analysis report tables ---------- */

/* Rounds by Tee (Analysis) -- plain 5-column table (Tee, Rds, Front, Back,
   18). Unlike .yeargrid/.holescore-table this never needs horizontal
   scroll or a frozen column -- five columns fit a phone screen fine -- so
   it's just a normal table with right-aligned numeric columns and a
   highlighted Total row (pale gold tint, matches the spreadsheet this is
   modeled on). */
.tee-breakdown-table{ width:100%; border-collapse:collapse; font-size:13px; }
.tee-breakdown-table th, .tee-breakdown-table td{ padding:7px 6px; text-align:right; border-bottom:1px solid var(--line); }
.tee-breakdown-table th:first-child, .tee-breakdown-table td:first-child{ text-align:left; }
.tee-breakdown-table th{ font-family:'Barlow Condensed',sans-serif; font-size:11px; letter-spacing:0.6px; text-transform:uppercase; color:var(--ink-soft); font-weight:600; }
.tee-breakdown-table .tee-breakdown-name{ font-weight:600; }
.tee-breakdown-table tr.tee-breakdown-total{ background:rgba(184,145,42,0.16); font-weight:700; }
.tee-breakdown-table tr.tee-breakdown-total td{ border-bottom:none; }
/* Played With's Rounds/Avg Score headers are click-to-sort, same visual
   treatment as the yeargrid sortable headers above. */
.tee-breakdown-table th.sortable{ cursor:pointer; }
.tee-breakdown-table th.sort-active{ color:var(--green); font-weight:800; text-decoration:underline; text-decoration-thickness:2px; text-underline-offset:2px; }
.playedwith-toggle{ text-align:center; margin-top:10px; font-size:13px; }
.playedwith-toggle a{ color:var(--green); font-weight:600; text-decoration:none; }
.playedwith-toggle a:active{ opacity:.7; }
.match-overall{ font-family:'Barlow Condensed',sans-serif; font-size:16px; font-weight:700; color:var(--ink); margin-bottom:10px; }

/* Score Distribution (Analysis) -- three independent Score|Count histograms
   (Front 9, Back 9, Total) side by side in one table, six columns total.
   Still fits a phone screen without horizontal scroll. The Count cell's
   background comes from countHeatStyle() in app.js (inline style, a green
   intensity scaled to that column's own max count) -- the Score cell next
   to it stays plain so the number reads clearly against every count's
   shade. */
.score-distribution-table{ width:100%; border-collapse:collapse; font-size:12.5px; text-align:center; }
.score-distribution-table th, .score-distribution-table td{ padding:5px 4px; }
.score-distribution-table thead th{ font-family:'Barlow Condensed',sans-serif; font-size:11px; letter-spacing:0.6px; text-transform:uppercase; color:var(--ink-soft); font-weight:600; border-bottom:1px solid var(--line-strong); padding-bottom:6px; }
.score-distribution-table tbody tr:nth-child(even){ background:rgba(211,205,182,0.18); }
.score-distribution-table tbody td:nth-child(odd){ color:var(--ink-soft); }
.score-distribution-table tbody td:nth-child(even){ font-weight:600; }

/* Handicap row (History tab) -- a point-in-time reading, not a counted
   stat, so it lives above the round list rather than on the Stats page.
   Flexbox with equal-width cells (same pattern as the scorecard) so
   however many tiles exist (2 up through all six: 18 Hole/White/Silver/
   Slate/Blue/Other) always fit on one row instead of wrapping. */
.handicap-row{ display:flex; gap:4px; margin-bottom:14px; }
.handicap-tile{ flex:1 1 0%; min-width:0; background:var(--panel); border:1px solid var(--line);
  border-radius:9px; padding:7px 2px; text-align:center; }
.handicap-tile .value{ font-family:'Barlow Condensed',sans-serif; font-size:16px; font-weight:700; color:var(--green); line-height:1.15; }
.handicap-tile .label{ font-size:8px; color:var(--ink-soft); margin-top:2px; text-transform:uppercase;
  letter-spacing:0.2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Stats filters -- compact dropdowns side by side in one row (most
   reports have two; Holes: Year vs Year has three -- Year A/Year B/Tee).
   A native select collapses to just its current value, which is what
   keeps an open-ended list (every year played) from ever needing to wrap
   the way a chip row would. flex-wrap + a min flex-basis is a no-op for
   the common two-select row (both already fit) and only kicks in for a
   three-select row on a narrow phone, wrapping to 2-up + 1 rather than
   squeezing three illegibly-thin dropdowns onto one line. */
.stats-filters{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:14px; }
.stats-filters select{ flex:1 1 96px; min-width:0; background:var(--panel); border:1.5px solid var(--line-strong);
  border-radius:9px; padding:8px 10px; font-family:'IBM Plex Sans',sans-serif; font-size:13px; font-weight:500;
  color:var(--ink); }
.stats-filters select:focus{ outline:none; border-color:var(--green); }

/* ---------- Handicap Over Time chart ---------- */
/* A single-series line chart, so no legend (the section title already
   names what's plotted) -- see the dataviz method's "a single series
   needs no legend box" rule. Card-like wrapper (border/radius/background)
   matches .card/.holescore-wrap so the chart reads as its own panel
   rather than floating on the page background. touch-action:none on the
   svg lets a finger drag the crosshair across the chart without the page
   trying to scroll underneath it at the same time. */
.trend-chart-wrap{ position:relative; background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:10px 8px 4px; }
.trend-chart{ width:100%; height:auto; display:block; touch-action:none; }
.trend-grid{ stroke:var(--line); stroke-width:1; }
.trend-axis{ font-size:9px; fill:var(--ink-soft); font-family:'IBM Plex Sans',sans-serif; }
.trend-area{ fill:var(--green); fill-opacity:.1; }
.trend-line{ fill:none; stroke:var(--green); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.trend-enddot{ fill:var(--green); stroke:var(--panel); stroke-width:2; }
.trend-endlabel{ font-size:11px; font-weight:700; fill:var(--green); font-family:'IBM Plex Mono',monospace; }
.trend-crosshair{ stroke:var(--ink-soft); stroke-width:1; stroke-dasharray:3 3; }
.trend-crosshair-dot{ fill:var(--green); stroke:var(--panel); stroke-width:2; }
.trend-tooltip{ position:absolute; top:6px; transform:translateX(-50%); background:var(--ink); color:var(--panel);
  font-size:11px; font-weight:600; padding:4px 8px; border-radius:6px; white-space:nowrap; pointer-events:none; }
.trend-summary{ font-size:12px; color:var(--ink-soft); margin-top:8px; text-align:center; }

/* Settings section (Analysis tab, bottom) -- a single labeled field,
   styled like the rest of the app's form inputs. */
.settings-field{ display:flex; flex-direction:column; gap:6px; }
.settings-field label{ font-size:13px; font-weight:600; color:var(--ink-soft); }
.settings-field input[type="number"]{ width:100%; }

/* ---------- Analysis tab ---------- */
/* Collapsed by default -- clicking the title (the whole row, not just the
   text) toggles its .collapsible-body. The chevron rotates as the one
   visual hint that this title is tappable at all. */
.analysis-block{ margin-bottom:4px; }
.collapsible-title{ display:flex; align-items:center; justify-content:space-between; cursor:pointer; user-select:none; }
.collapsible-title .chevron{ font-size:11px; color:var(--ink-soft); transition:transform 0.15s ease; flex:0 0 auto; margin-left:8px; }
.collapsible-title.expanded .chevron{ transform:rotate(90deg); }

/* Eagle log -- one box per year (most recent year first, since entries
   arrive pre-sorted most-recent-date-first and a year's box is created the
   first time an entry for it is seen) rather than one box per eagle. */
.sectioncount{ font-weight:400; text-transform:none; letter-spacing:0; margin-left:6px; font-size:13px; color:var(--ink-soft); }
.eagle-year-box{ background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:12px 14px; margin-bottom:12px; }
.eagle-year-header{ font-family:'Barlow Condensed',sans-serif; font-weight:700; font-size:18px; color:var(--green);
  margin-bottom:8px; display:flex; align-items:baseline; }
.eagle-row{ display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  padding:9px 0; border-bottom:1px solid var(--line); }
.eagle-row:last-child{ border-bottom:none; padding-bottom:0; }
.eagle-row .eagle-date{ font-family:'IBM Plex Mono',monospace; font-size:14px; color:var(--ink-soft); white-space:nowrap; }
.eagle-row .eagle-detail{ font-size:15px; font-weight:600; color:var(--green); text-align:right; }

/* Shared frozen-column grid -- used by both Birdie Tracker and Score by
   Year. Hole/Par/... are frozen on the left (position:sticky; each cell's
   `left` offset is set inline by freezeCell() in app.js, since the two
   grids don't freeze the same number of leading columns), a scrolling
   column per year to the right. The wrap is the only thing that scrolls
   horizontally; the table itself is exactly as wide as its columns demand.
   A tfoot totals row sits below the 18 hole rows, set off by a top border
   instead of the row-by-row bottom border the body rows use. */
.stats-section-note{ text-align:left; margin:-4px 0 10px; }
.yeargrid-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; border:1px solid var(--line);
  border-radius:10px; background:var(--panel); margin-bottom:6px; }
.yeargrid{ border-collapse:collapse; font-family:'IBM Plex Mono',monospace; }
/* Column width is sized for the font, not the other way around -- bumping
   font-size without widening the column just clips/wraps the text. Wider
   columns mean more horizontal scrolling to see the same span of years,
   which is the deliberate tradeoff for readability on a phone. Row padding
   (8px vs the old 5px) is what actually gives "more space between rows". */
.yeargrid th, .yeargrid td{ width:38px; min-width:38px; max-width:38px; box-sizing:border-box;
  text-align:center; font-size:14px; padding:8px 3px; border-bottom:1px solid var(--line); white-space:nowrap; }
.yeargrid thead th{ font-weight:700; color:var(--ink-soft); font-size:12px; text-transform:uppercase;
  letter-spacing:0.2px; padding-bottom:8px; background:var(--panel); }
.yeargrid td.hole-cell{ font-weight:700; color:var(--green); }
.yeargrid th.freeze, .yeargrid td.freeze{ position:sticky; background:var(--panel); z-index:2; }
.yeargrid th.last-freeze, .yeargrid td.last-freeze{ border-right:1.5px solid var(--line-strong); }
.yeargrid tbody tr:last-child td{ border-bottom:none; }
.yeargrid tfoot td{ font-weight:700; border-top:1.5px solid var(--line-strong); border-bottom:none; }

/* Sortable column headers -- tapping Total/Avg/Eagles or any year header
   re-sorts the 18 hole rows by that column (Score by Year: closest to par
   first; Birdie Tracker: most birdies first -- see sortScoreByYearHoles()/
   sortBirdieTrackerHoles() in app.js). The "Hole" header is also sortable,
   as a way back to plain 1-18 order. Bold+underline+green marks whichever
   column is currently driving the sort, since narrow columns don't have
   room to spare for an arrow glyph without risking overflow into the next
   column (cells have no text-overflow clipping). */
.yeargrid th.sortable{ cursor:pointer; }
.yeargrid th.sort-active{ color:var(--green); font-weight:800; text-decoration:underline; text-decoration-thickness:2px; text-underline-offset:2px; }

/* Score by Year gets extra breathing room between columns on top of the
   shared width above -- decimal averages ("70.5") need more room than the
   Birdie Tracker's integer counts do. */
.yeargrid.wide th, .yeargrid.wide td{ width:48px; min-width:48px; max-width:48px; }

/* Hole Scores per Round -- a different shape than the two grids above
   (5 short rows instead of 18, a two-row grouped header, one wide frozen
   label column instead of several narrow ones, plus a static reference
   block at the end), so it gets its own small ruleset rather than being
   forced through .yeargrid -- but matches its look and sticky mechanics.
   Only one column is ever frozen here, so a plain `left:0` covers it --
   no per-cell inline offset needed the way the multi-column grids require. */
.holescore-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; border:1px solid var(--line);
  border-radius:10px; background:var(--panel); margin-bottom:6px; }
.holescore-table{ border-collapse:collapse; font-family:'IBM Plex Mono',monospace; }
.holescore-table th, .holescore-table td{ width:46px; min-width:46px; max-width:46px; box-sizing:border-box;
  text-align:center; font-size:14px; padding:8px 3px; border-bottom:1px solid var(--line); white-space:nowrap; }
.holescore-table th.label-col, .holescore-table td.label-col{ width:108px; min-width:108px; max-width:108px;
  text-align:left; padding-left:10px; font-family:'Barlow Condensed',sans-serif; font-size:14px; font-weight:600;
  text-transform:uppercase; letter-spacing:0.3px; color:var(--green); }
.holescore-table thead th{ font-weight:700; color:var(--ink-soft); font-size:12px; text-transform:uppercase; letter-spacing:0.2px; background:var(--panel); }
.holescore-table thead tr:first-child th{ border-bottom:1px solid var(--line); padding-bottom:6px; }
.holescore-table th.freeze, .holescore-table td.freeze{ position:sticky; left:0; background:var(--panel);
  z-index:2; border-right:1.5px solid var(--line-strong); }
.holescore-table th.divider, .holescore-table td.divider{ border-left:1.5px solid var(--line-strong); }
.holescore-table tbody tr:last-child td{ border-bottom:none; }
.holescore-table tfoot td{ font-weight:700; border-top:1.5px solid var(--line-strong); border-bottom:none; }

/* Rounds per Year (Stats) -- same .holescore-table shape (frozen label
   column, years across the top) but with a wider label column since these
   row labels ("CB Front 9 Rounds") run longer than Hole Scores per
   Round's ("Birdies +", "To Par"). Wraps to two lines rather than
   truncating -- there's vertical room to spare and a legible full label
   beats a clipped one. */
.rounds-per-year-table th.label-col, .rounds-per-year-table td.label-col{ width:126px; min-width:126px; max-width:126px;
  font-size:11.5px; line-height:1.2; white-space:normal; }

/* Hole by Hole (Stats) -- the transposed shape of the grids above: one
   frozen row-label column on the left, then a column PER HOLE (1-18)
   instead of per year, since this table is about a single Year/Tee slice
   (whatever's picked in the Stats filters) rather than comparing years
   side by side. A "Total" column closes it out instead of the spreadsheet
   this is modeled on's separate Front/Back/Total trio, and the Eagles/
   Birdies/Pars/Bogeys/Double+ rows' Total is a plain count with no
   percentage alongside it -- both simplifications trade a little of the
   original sheet's density for a narrower table. Column width (44px, up
   from an initial 36px) trades more horizontal scrolling for more room
   between the numbers -- the deliberate tradeoff, same as every other
   grid in this app. Blank spacer rows between the four row-groups
   (score, counts, percentages, ringer) are plain <tr> with a single
   colspan cell -- see renderHoleByHole() in app.js. The Avg / Par or
   Better / Double+ / Ringer rows get a per-row heatmap background
   (green=good, gold=mid, red=bad, computed relative to that row's own 18
   values) via an inline background-color from heatColor() in app.js -- a
   continuous gradient isn't practical as a fixed set of CSS classes. The
   Avg and Ringer rows' heatmaps are keyed off score-relative-to-par
   rather than the raw value they display (average / best-ever score), so
   par-5s don't just read as permanently worse than par-3s. Ringer, at the
   very bottom, is the best score ever posted on each hole composited into
   one "round" -- not tied to any single actual round played. */
.holebyhole-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; border:1px solid var(--line);
  border-radius:10px; background:var(--panel); margin-bottom:6px; }
.holebyhole-table{ border-collapse:collapse; font-family:'IBM Plex Mono',monospace; }
.holebyhole-table th, .holebyhole-table td{ width:44px; min-width:44px; max-width:44px; box-sizing:border-box;
  text-align:center; font-size:14px; padding:8px 3px; border-bottom:1px solid var(--line); white-space:nowrap; }
.holebyhole-table th.label-col, .holebyhole-table td.label-col{ width:132px; min-width:132px; max-width:132px;
  text-align:left; padding-left:10px; font-family:'Barlow Condensed',sans-serif; font-size:13px; font-weight:600;
  text-transform:uppercase; letter-spacing:0.2px; color:var(--green); overflow:hidden; text-overflow:ellipsis; }
.holebyhole-table thead th{ font-weight:700; color:var(--ink-soft); font-size:12px; text-transform:uppercase; letter-spacing:0.2px; background:var(--panel); }
.holebyhole-table th.freeze, .holebyhole-table td.freeze{ position:sticky; left:0; background:var(--panel);
  z-index:2; border-right:1.5px solid var(--line-strong); }
.holebyhole-table td.total-col{ font-weight:700; border-left:1.5px solid var(--line-strong); }
.holebyhole-table tr.spacer-row td{ border-bottom:none; padding:5px 0; }
.holebyhole-table tbody tr:last-child td{ border-bottom:none; }

/* ---------- Tab bar ---------- */
.tabbar{ flex:0 0 auto; background:var(--panel); border-top:1px solid var(--line); display:flex;
  padding:8px 6px calc(8px + env(safe-area-inset-bottom)); }
.tabbtn{ flex:1; display:flex; flex-direction:column; align-items:center; gap:3px; background:none; border:none;
  color:var(--ink-soft); font-family:'Barlow Condensed',sans-serif; font-size:11px; font-weight:600;
  letter-spacing:0.4px; text-transform:uppercase; cursor:pointer; padding:6px 0; }
.tabbtn.active{ color:var(--green); }
.tabbtn svg{ width:20px; height:20px; }
