/* 7 Under Golf app styles. Mobile-first. */
:root {
  /* Core UI palette */
  --green-900: #1E3A34;   /* deep green: splash, handicap card, pressed states */
  --green-700: #2F7D5A;   /* medium green: buttons, active states, links */
  --green-500: #3E9670;   /* lighter green: accents, progress */
  --sage:      #A9B8A8;   /* muted green-grey */
  --accent:    #C9B79C;   /* warm tan: premium badge, brand mark on dark */
  --cream:     #F4F6F8;   /* page background: cool near-white, not pure white,
                             so white cards still read as cards */
  --surface:   #FFFFFF;   /* cards and raised surfaces */
  --ink:       #16191D;   /* body text (cool near-black) */
  --muted:     #667085;   /* secondary text */
  --line:      #E4E7EB;   /* hairlines, deliberately almost invisible */
  --danger:    #DC2626;
  --ok:        #16A34A;

  /* Scorecard / Data palette (categorical + light fills) for stats & charts */
  --data-blue:   #1D4ED8; --data-blue-50:   #DBEAFE;
  --data-green:  #16A34A; --data-green-50:  #DCFCE7;
  --data-violet: #6D28D9; --data-violet-50: #EDE9FE;
  --data-amber:  #D97706; --data-amber-50:  #FEF3C7;
  --data-red:    #DC2626; --data-red-50:    #FEE2E2;

  --radius:    18px;
  --tabbar-h:  64px;
  /* Cards lift off the page with shadow rather than outline. */
  --shadow:    0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --shadow-lg: 0 4px 12px rgba(16,24,40,.08), 0 2px 4px rgba(16,24,40,.04);
  /* One family: Nunito. Heavier weights (700/800) stand in for display type. */
  --font:      'Nunito', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --serif:     'Nunito', system-ui, sans-serif;  /* alias: existing display rules → Nunito */
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
}
button { font-family: inherit; cursor: pointer; }

/* Display elements (previously serif). Nunito needs weight to read as headings. */
.splash__mark, .appbar__brand, .auth__title, .section__title,
.wizard__title, .coach-hero__name, .pillar__title { font-weight: 800; letter-spacing: -0.01em; }

/* --- Splash / launch screen --- */
/* Launch screen. The timings here and SPLASH_MS in app.js are one sequence:
   the mark lands at 1.8s, the tagline at 2.5s, and the hold keeps it still for a
   beat after that. Change one and the tagline gets swept off as it arrives. */
.splash {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
  height: 100dvh; background: var(--green-900); text-align: center; padding: 24px;
  transition: opacity .48s ease;
}
.splash.is-out { opacity: 0; }
.splash__logo {
  width: 200px; max-width: 62%; height: auto;
  animation: splashLogoIn 1.5s cubic-bezier(.2,.7,.2,1) .3s both;
}
.splash__mark {
  font-weight: 800; font-size: 40px; color: var(--cream);
  letter-spacing: 1px; line-height: .9;
  animation: splashLogoIn 1.5s cubic-bezier(.2,.7,.2,1) .3s both;
}
.splash__mark span { display: block; font-weight: 600; font-size: 13px; letter-spacing: 6px; color: var(--accent); margin-top: 6px; }
.splash__tagline {
  margin: 0; font-size: 15px; font-weight: 500; letter-spacing: .3px;
  color: rgba(234,231,225,.82);
  animation: splashFadeUp 1s ease 1.5s both;
}
@keyframes splashLogoIn { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: none; } }
@keyframes splashFadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .splash__logo, .splash__mark, .splash__tagline { animation-duration: .01ms; animation-delay: 0ms; }
}

/* --- Inputs (shared, on light surfaces) --- */
.field-label { font-size: 13px; font-weight: 600; color: var(--muted); margin: 0; }
.field {
  width: 100%; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px;
  background: #fff; color: var(--ink); font-size: 16px; outline: none;
}
.field:focus { border-color: var(--green-500); box-shadow: 0 0 0 3px rgba(47,125,90,.16); }
.link { background: none; border: 0; color: var(--green-700); font-size: 14px; font-weight: 600; }

/* --- Welcome auth (rendered inside the dark-green splash) --- */
.authbox { width: 100%; max-width: 320px; margin-top: 6px; animation: splashFadeUp .8s ease 2.3s both; }
.authbox__form { display: flex; flex-direction: column; gap: 10px; }
.authbox .field { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.18); color: var(--cream); }
.authbox .field::placeholder { color: rgba(234,231,225,.55); }
.authbox .field:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(201,183,156,.22); background: rgba(255,255,255,.14); }
.authbox .btn--primary { background: var(--cream); color: var(--green-900); margin-top: 4px; }
.authbox .btn--primary:active { background: #fff; }
.auth-links { display: flex; flex-direction: column; align-items: center; gap: 9px; margin-top: 14px; }
.auth-links .link { color: var(--accent); }
.auth-links .link.subtle { color: rgba(234,231,225,.66); font-weight: 500; }

/* --- Buttons --- */
.btn { border: 0; border-radius: 12px; padding: 15px 18px; font-size: 16px; font-weight: 600; margin-top: 18px; }
.btn--primary { background: var(--green-700); color: #fff; }
.btn--primary:disabled { opacity: .6; }
.btn--primary:active { background: var(--green-900); }

/* --- App shell --- */
.shell { min-height: 100dvh; display: flex; flex-direction: column; padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom)); }
.appbar {
  position: sticky; top: 0; z-index: 5; display: flex; align-items: center; justify-content: space-between;
  padding: max(12px, env(safe-area-inset-top)) 18px 12px; background: var(--surface); color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.appbar__brand { font-family: var(--serif); font-weight: 700; font-size: 18px; letter-spacing: .5px; }
.appbar__brand { color: var(--green-900); }
.appbar__brand span { color: var(--green-700); font-family: var(--font); font-weight: 500; font-size: 11px; letter-spacing: 4px; margin-left: 6px; }
.outlet { flex: 1; padding: 18px 16px 24px; }
.outlet.is-leaving { opacity: .4; }

/* --- Section view --- */
.section__header { margin: 4px 2px 18px; }
.section__header--sub { display: grid; gap: 2px; }
.section__title { font-family: var(--serif); font-size: 26px; margin: 0 0 2px; }
/* A rung between the screen title and the small uppercase labels inside a block,
   so a screen made of several blocks says what each one is. */
.section__grouptitle {
  font-family: var(--serif); font-size: 19px; font-weight: 800; letter-spacing: -0.01em;
  margin: 4px 2px 12px; color: var(--ink);
}
.section__sub { color: var(--muted); margin: 0; }
/* The opening paragraph of a screen, in the flow rather than inside a card. A card
   around it makes it read as one more thing on the page to deal with, when it is
   the page explaining itself. */
.section__lede { color: var(--muted); font-size: 15px; line-height: 1.5; margin: -4px 2px 4px; }
.section__note { color: var(--muted); font-size: 13px; text-align: center; margin: 18px 8px 0; }
.backlink { align-self: start; background: none; border: 0; color: var(--green-700); font-size: 14px; font-weight: 500; padding: 0 0 6px; }
.feature-list { display: flex; flex-direction: column; gap: 12px; }
.card { background: var(--surface); border: 0; border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.feature__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.feature__title { font-size: 16px; margin: 0; }
.feature__desc { color: var(--muted); font-size: 14px; margin: 0; line-height: 1.45; }
.feature.is-locked { opacity: .85; }
.feature.is-link { cursor: pointer; }
.feature.is-link:active { background: #F7F8FA; }

/* --- Account footer (Me) --- */
.account { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
.account__row { display: flex; align-items: center; justify-content: space-between; padding: 4px 2px; }
.account__label { color: var(--muted); font-size: 14px; }
.btn--ghost { background: none; color: var(--danger); border: 1px solid var(--line); }
.btn--ghost:active { background: #FEF2F2; }

/* --- Coach section hero --- */
.coach-hero { text-align: center; padding: 12px 0 20px; }
.coach-hero__avatar { display: inline-grid; place-items: center; width: 60px; height: 60px; border-radius: 50%; background: var(--accent); color: var(--green-900); font-family: var(--serif); font-weight: 700; font-size: 26px; margin-bottom: 10px; }
.coach-hero__name { font-family: var(--serif); font-size: 24px; margin: 0 0 2px; }
.coach-hero__tagline { color: var(--muted); margin: 0; }

/* --- Badges --- */
.badge { font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 999px; line-height: 1; }
.badge--premium { background: rgba(201,183,156,.32); color: #6b5a3c; }
.badge--phase { background: #EFF1F4; color: var(--muted); margin-left: auto; }
.badge--free { background: #F1F3F5; color: var(--muted); border: 1px solid var(--line); }

/* --- Bottom tab bar --- */
.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 6; height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom); display: grid; grid-template-columns: repeat(5, 1fr);
  background: #fff; border-top: 1px solid var(--line);
}
.tab { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; text-decoration: none; color: var(--muted); font-size: 11px; }
.tab__icon { font-size: 24px; line-height: 1; }
.tab.is-active { color: var(--green-700); }
.tab.is-active .tab__icon { transform: translateY(-1px); }

/* --- Forms --- */
.form { display: flex; flex-direction: column; gap: 2px; }
.formrow { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.formrow:last-child { margin-bottom: 0; }
select.field { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236c7a72' d='M1 1l5 5 5-5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; padding-right: 40px; }
.field--area { resize: vertical; min-height: 76px; font-family: inherit; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { border: 1px solid var(--line); background: #fff; color: var(--ink); border-radius: 999px; padding: 9px 14px; font-size: 14px; }
.chip.is-on { background: var(--green-700); color: #fff; border-color: var(--green-700); }

.segmented { display: flex; background: #EFF1F4; border-radius: 12px; padding: 4px; margin-bottom: 14px; }
.segmented__btn { flex: 1; border: 0; background: none; color: var(--muted); font-size: 14px; font-weight: 500; padding: 10px; border-radius: 9px; }
.segmented__btn.is-on { background: #fff; color: var(--green-900); box-shadow: 0 1px 4px rgba(0,0,0,.1); }

.sticky-save { position: sticky; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 8px); margin-top: 16px; }
.sticky-save .btn { width: 100%; margin: 0; }

/* --- Onboarding wizard --- */
.wizard { min-height: 100dvh; display: flex; flex-direction: column; padding: max(16px, env(safe-area-inset-top)) 20px calc(24px + env(safe-area-inset-bottom)); max-width: 460px; margin: 0 auto; }
.wizard__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.wizard__progress { display: flex; gap: 6px; }
.wizard__dot { width: 22px; height: 4px; border-radius: 2px; background: var(--line); transition: .2s; }
.wizard__dot.is-on { background: var(--green-500); }
.wizard__skip { color: var(--muted); }
.wizard__step { flex: 1; }
.wizard__hero { display: grid; place-items: center; margin: 8px 0 18px; }
.wizard__hero .splash__mark { color: var(--green-900); }
.wizard__title { font-family: var(--serif); font-size: 26px; margin: 0 0 4px; }
.wizard__sub { color: var(--muted); margin: 0 0 22px; }
.wizard__nav { display: flex; gap: 12px; margin-top: 20px; }
.wizard__nav .btn { flex: 1; margin: 0; }
.wizard__back:disabled { opacity: .4; }

/* --- Onboarding nudge --- */
.nudge { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; border: 0; text-align: left;
  background: rgba(201,183,156,.26); color: #6b5a3c; padding: 12px 16px; font-size: 14px; font-weight: 600; }
.nudge__cta { color: var(--green-700); font-weight: 700; white-space: nowrap; }

/* --- Toasts --- */
.toasts { position: fixed; left: 12px; right: 12px; bottom: calc(var(--tabbar-h) + 84px); z-index: 20; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.toast { padding: 12px 16px; border-radius: 12px; color: #fff; font-size: 14px; box-shadow: 0 8px 24px rgba(0,0,0,.2); opacity: 0; transform: translateY(8px); transition: .22s; }
.toast.is-in { opacity: 1; transform: none; }
.toast--info { background: var(--green-700); }
.toast--success { background: var(--ok); }
.toast--error { background: var(--danger); }

/* ============================================================
   Albert: the conversation, rendered inside the sheet
   ============================================================
   The chat owns the full viewport: the log scrolls internally so the composer
   never drifts away from the thumb. Every other view keeps the normal page
   scroll, so the height chain is scoped to the shell that contains a .chat. */

/* The chat now lives in the Albert sheet, never in the outlet, so it fills its
   sheet rather than the shell. Scoping this to .sheet matters: a bare
   .shell:has(.chat) would match the sheet's chat and collapse every screen. */
.sheet .chat { height: 100%; display: flex; flex-direction: column; min-height: 0; }

.chat__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--surface);
}
.chat__head-id { display: flex; align-items: center; gap: 8px; }
.chat__avatar {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); color: var(--green-900); font-size: 14px;
}
.chat__name { font-weight: 700; font-size: 15px; }
.chat__reset {
  border: 0; background: none; color: var(--muted); font-size: 17px;
  padding: 4px 6px; border-radius: 8px; line-height: 1;
}
.chat__reset:active { background: #e2dfd7; }

.chat__log {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 16px; display: flex; flex-direction: column; gap: 10px;
}

/* --- Bubbles --- */
.chat__msg { display: flex; max-width: 100%; }
.chat__msg--user   { justify-content: flex-end; }
.chat__msg--albert { justify-content: flex-start; }

.chat__bubble {
  max-width: 85%; padding: 10px 14px; border-radius: 18px;
  font-size: 15px; line-height: 1.5; overflow-wrap: anywhere;
}
.chat__msg--user .chat__bubble {
  background: var(--green-700); color: #fff; border-bottom-right-radius: 6px;
}
.chat__msg--albert .chat__bubble {
  background: #F1F3F5; border: 0; color: var(--ink);
  border-bottom-left-radius: 6px;
}
.chat__bubble code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em;
  background: rgba(30,42,38,.07); padding: 1px 5px; border-radius: 5px;
}
.chat__msg--user .chat__bubble code { background: rgba(255,255,255,.2); }
.chat__bubble strong { font-weight: 700; }

/* --- Activity: Albert never narrates his own tool use, so the app shows it --- */
.chat__working { color: var(--muted); font-size: 14px; font-style: italic; }

.chat__typing { display: inline-flex; gap: 4px; padding: 3px 0; }
.chat__typing i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--sage);
  animation: chat-bounce 1.3s infinite ease-in-out;
}
.chat__typing i:nth-child(2) { animation-delay: .18s; }
.chat__typing i:nth-child(3) { animation-delay: .36s; }
@keyframes chat-bounce {
  0%, 70%, 100% { transform: translateY(0);    opacity: .45; }
  35%           { transform: translateY(-5px); opacity: 1;   }
}
@media (prefers-reduced-motion: reduce) {
  .chat__typing i { animation: none; opacity: .6; }
}

.chat__error { color: var(--danger); font-size: 14px; }

/* --- Empty state: the first thing a new golfer sees --- */
.chat__empty { margin: auto; text-align: center; padding: 20px 8px; }
.chat__empty-avatar {
  display: inline-grid; place-items: center; width: 60px; height: 60px; border-radius: 50%;
  background: var(--accent); color: var(--green-900); font-size: 30px; margin-bottom: 12px;
}
.chat__empty-title { font-size: 24px; margin: 0 0 4px; }
.chat__empty-sub { color: var(--muted); margin: 0 0 20px; }
.chat__starters { display: flex; flex-direction: column; gap: 8px; }
.chat__starter {
  border: 1px solid var(--line); background: #fff; color: var(--ink);
  border-radius: 14px; padding: 12px 16px; font-size: 14px; text-align: left; line-height: 1.4;
}
.chat__starter:active { background: #F1F3F5; }

/* --- Composer --- */
.chat__composer {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line); background: var(--surface);
}
.chat__input {
  flex: 1; resize: none; border: 1px solid var(--line); border-radius: 20px;
  padding: 11px 15px; font: inherit; line-height: 1.4;
  background: #fff; color: var(--ink); max-height: 140px; overflow-y: auto;
  /* 16px is a hard floor, not a design choice: iOS Safari zooms the whole page
     when you focus an input smaller than this. Do not drop it to 15 to match
     the bubbles. Every other focusable field in the app is 16 for the same
     reason. */
  font-size: 16px;
}
.chat__input:focus { outline: none; border-color: var(--green-500); }
.chat__send {
  flex: none; width: 42px; height: 42px; border: 0; border-radius: 50%;
  background: var(--green-700); color: #fff; font-size: 19px; line-height: 1;
}
.chat__send:active { background: var(--green-900); }
.chat.is-busy .chat__send { opacity: .45; }

/* --- Dev quick login (welcome screen, over the green splash) ---------------
   Draws nothing in a normal deployment: the API returns an empty list unless
   dev_login.enabled is on. */
.devlogin {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px; margin-top: 24px;
}
.devlogin__label {
  width: 100%; text-align: center; font-size: 11px; letter-spacing: .09em;
  text-transform: uppercase; color: rgba(234,231,225,.45);
}
.devlogin__btn {
  border: 1px solid rgba(234,231,225,.35); background: rgba(234,231,225,.08);
  color: var(--cream); border-radius: 999px; padding: 9px 18px;
  font-size: 13px; font-weight: 600;
}
.devlogin__btn:active { background: rgba(234,231,225,.22); }
.devlogin__btn:disabled { opacity: .45; }

/* ============================================================
   Rounds: history list and round detail
   ============================================================ */

.round-list { display: flex; flex-direction: column; gap: 10px; }

.round-card {
  background: var(--surface); border: 0; box-shadow: var(--shadow); border-radius: var(--radius);
  padding: 14px 16px; cursor: pointer;
}
.round-card:active { background: #F7F8FA; }
.round-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.round-card__meta { display: grid; gap: 2px; min-width: 0; }
.round-card__course { font-weight: 700; font-size: 15px; overflow-wrap: anywhere; }
.round-card__date { color: var(--muted); font-size: 13px; }
.round-card__score { display: flex; align-items: baseline; gap: 6px; flex: none; }
.round-card__total { font-size: 26px; font-weight: 800; line-height: 1; }

.round-card__nines { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.nine { display: inline-flex; align-items: baseline; gap: 5px; background: #F1F3F5; border-radius: 10px; padding: 5px 10px; }
.nine__label { font-size: 11px; font-weight: 700; letter-spacing: .06em; color: var(--muted); }
.nine__score { font-size: 15px; font-weight: 700; }
/* Score-relative colouring, judged by how it played rather than by beating par. */
.is-under { color: var(--data-blue); }
.is-level { color: var(--ok); }
.is-over  { color: var(--data-amber); }
.round-card__par, .nine__par, .round-head__par, .nineblock__par { font-weight: 700; font-size: 13px; }

/* --- Detail head --- */
.round-head { margin: 6px 0 18px; }
.round-head__course { font-size: 24px; margin: 0 0 2px; }
.round-head__meta { color: var(--muted); margin: 0 0 10px; font-size: 14px; }
.round-head__score { display: flex; align-items: baseline; gap: 8px; }
.round-head__total { font-size: 44px; font-weight: 800; line-height: 1; }
.round-head__par { font-size: 17px; }

/* --- The two nines, the headline of the screen --- */
.nineblocks { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.nineblock { background: var(--surface); border: 0; box-shadow: var(--shadow); border-radius: var(--radius); padding: 12px 14px; display: grid; gap: 2px; }
.nineblock__label { font-size: 11px; font-weight: 700; letter-spacing: .07em; color: var(--muted); }
.nineblock__score { font-size: 28px; font-weight: 800; line-height: 1.1; }
.nineblock__delta { font-size: 12px; color: var(--muted); }

/* --- Callouts: the thing worth noticing --- */
.callout {
  background: rgba(201,183,156,.24); border-left: 3px solid var(--accent);
  border-radius: 10px; padding: 12px 14px; margin-bottom: 12px;
}
.callout--quiet { background: #F1F3F5; border-left-color: var(--sage); }
.callout__text { margin: 0; font-size: 14px; line-height: 1.45; }

/* --- Supporting stats --- */
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr)); gap: 8px; margin-bottom: 16px; }
.stat { background: var(--surface); border: 0; box-shadow: var(--shadow); border-radius: 12px; padding: 10px; text-align: center; }
.stat__value { display: block; font-size: 19px; font-weight: 800; }
.stat__label { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; line-height: 1.3; }

/* --- Scorecard: scrolls sideways rather than forcing the page to --- */
/* Fits the width, always. Fixed 34px cells came to 398px, which overflows a 390px
   phone before you count any padding, so the hole columns now share whatever space
   there is and the card scales with the screen instead of scrolling. */
.scorecard { width: 100%; }
.card-half { width: 100%; }
.card-half + .card-half { margin-top: 20px; }
.card-row { display: grid; grid-template-columns: 40px repeat(9, minmax(0, 1fr)) 38px; }
.card-cell {
  height: 34px; display: grid; place-items: center; min-width: 0;
  font-size: 14px; font-variant-numeric: tabular-nums; border-bottom: 1px solid var(--line);
}
/* A doubled mark reaches 29px across, so the score row needs the clearance the
   other two rows do not. */
.card-row:last-child .card-cell { height: 38px; }
.card-cell--head { font-size: 9px; letter-spacing: .02em; font-weight: 700; text-transform: uppercase; color: var(--muted); justify-content: start; }
.card-cell--tot  { font-weight: 800; background: #F1F3F5; }
.card-cell--par  { color: var(--muted); }
.card-cell--score { font-weight: 700; }

/* Scorecard notation, the way it is drawn on a tour card and on television:
   circle under par, square over, doubled at two clear either way, par unmarked.
   The shape carries the meaning and the colour only reinforces it, so the card
   still reads at arm's length, in sunlight, and to a colour-blind golfer.

   Drawn with a border for the inner shape and a box-shadow for the outer ring,
   which keeps every mark the same 22px whatever it is: a scorecard where the
   numbers do not line up is not a scorecard. */
.mark {
  display: grid; place-items: center;
  width: 22px; height: 22px; box-sizing: border-box;
  border: 2px solid transparent; font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.mark--eagle, .mark--birdie { border-radius: 50%; }
.mark--bogey, .mark--double { border-radius: 3px; }

.mark--birdie {
  border-color: var(--data-blue); background: var(--data-blue-50); color: var(--data-blue);
}
.mark--eagle {
  border-color: var(--data-violet); background: var(--data-violet-50); color: var(--data-violet);
  /* The gap ring is painted in the card's own background, so the two rings read
     as two rings rather than one thick one. */
  box-shadow: 0 0 0 1.5px #fff, 0 0 0 3.5px var(--data-violet);
}
.mark--par { color: var(--ink); }
.mark--bogey {
  border-color: var(--data-amber); background: var(--data-amber-50); color: #7A4E13;
}
.mark--double {
  border-color: var(--data-red); background: var(--data-red-50); color: var(--data-red);
  box-shadow: 0 0 0 1.5px #fff, 0 0 0 3.5px var(--data-red);
}


/* --- Lifetime stats: scoring by par, and tee-shot dispersion --------------- */
.stats { display: flex; flex-direction: column; }
.stats__group {
  background: var(--surface); border: 0; box-shadow: var(--shadow);
  border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px;
}
.stats__title { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 10px; }
.stats__note { margin: 10px 0 0; font-size: 12px; color: var(--muted); line-height: 1.4; }

.bypar { display: grid; gap: 2px; }
.bypar__row {
  display: grid; grid-template-columns: 1fr auto auto 1fr; align-items: baseline;
  gap: 10px; padding: 7px 8px; border-radius: 8px;
}
.bypar__row.is-worst { background: var(--data-amber-50); }
.bypar__par   { font-weight: 700; font-size: 14px; }
.bypar__avg   { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bypar__rel   { font-size: 13px; font-weight: 700; color: var(--data-amber); font-variant-numeric: tabular-nums; }
.bypar__holes { font-size: 11px; color: var(--muted); text-align: right; }

.disp { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.disp__col { text-align: center; background: #F1F3F5; border-radius: 12px; padding: 12px 6px; }
/* Off the tee, coloured by outcome rather than by direction: straight is the shot
   you were trying to hit, either side is not. The side you miss most is called out
   because that is the one worth a lesson. */
.disp__col--straight { background: var(--data-green-50); }
.disp__col--straight .disp__pct { color: var(--data-green); }
.disp__col--left, .disp__col--right { background: var(--data-amber-50); }
.disp__col--left .disp__pct, .disp__col--right .disp__pct { color: var(--data-amber); }
.disp__col.is-most { background: var(--data-red-50); }
.disp__col.is-most .disp__pct { color: var(--data-red); }
.disp__col.is-most .disp__dir { font-weight: 800; }
.disp__pct { display: block; font-size: 22px; font-weight: 800; line-height: 1; }
.disp__dir { display: block; font-size: 12px; font-weight: 600; margin-top: 4px; }
.disp__fw  { display: block; font-size: 11px; color: var(--muted); margin-top: 3px; }

/* ============================================================
   Albert as a layer: floating button and bottom sheet
   ============================================================ */

.fab {
  position: fixed; right: 16px; z-index: 8;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 16px);
  width: 56px; height: 56px; border: 0; border-radius: 50%;
  background: var(--green-700); color: var(--cream);
  box-shadow: 0 6px 18px rgba(30,58,52,.32);
  display: grid; place-items: center;
}
.fab__mark { font-size: 28px; line-height: 1; }
.fab:active { background: var(--green-900); transform: translateY(1px); }
body.has-sheet .fab { opacity: 0; pointer-events: none; }

.sheet-backdrop {
  position: fixed; inset: 0; z-index: 9; background: rgba(30,42,38,.45);
  opacity: 0; pointer-events: none; transition: opacity .24s ease;
}
.sheet-backdrop.is-in { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
  height: 88dvh; max-height: 88dvh;
  background: var(--surface); border-radius: 22px 22px 0 0;
  box-shadow: 0 -8px 32px rgba(30,42,38,.28);
  display: flex; flex-direction: column; overflow: hidden;
  transform: translateY(100%); transition: transform .28s cubic-bezier(.32,.72,0,1);
}
.sheet.is-in { transform: translateY(0); }

/* Asking for one line of text. Sized to its content and lifted clear of the
   bottom, so the on-screen keyboard has somewhere to go and the sheet does not
   read as a page that happens to contain a field. */
.ask {
  height: auto; max-height: none;
  padding-bottom: calc(env(safe-area-inset-bottom) + 14px);
}
.ask__body { padding: 2px 18px 6px; display: grid; gap: 10px; }
.ask__title { margin: 0; font-size: 17px; font-weight: 800; }
.ask__input { width: 100%; font-size: 16px; }   /* 16px, or iOS zooms the page in */
.ask__foot { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.ask__hint { font-size: 12px; color: var(--muted); }
.ask__count { flex: none; font-size: 12px; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.ask__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 2px; }

/* The grab handle is the close button, so the gesture and the tap agree. */
.sheet__grab {
  flex: none; border: 0; background: none; padding: 10px 0 6px;
  display: grid; place-items: center;
}
.sheet__grab::before {
  content: ''; width: 40px; height: 4px; border-radius: 999px; background: var(--line);
}

@media (prefers-reduced-motion: reduce) {
  .sheet, .sheet-backdrop { transition: none; }
}

/* ============================================================
   Home
   ============================================================ */

.home { display: flex; flex-direction: column; gap: 12px; }
.home__head { margin: 4px 2px 16px; }
.home__greeting { font-size: 26px; margin: 0; }
.home__label {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 6px 2px 0;
}

.home__hc {
  background: var(--green-900); color: var(--cream); border-radius: var(--radius);
  padding: 18px 20px; display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.home__hc-main { display: flex; align-items: baseline; gap: 10px; }
.home__hc-value { font-size: 38px; font-weight: 800; line-height: 1; }
.home__hc-label { font-size: 13px; opacity: .75; }
.home__hc-target {
  font-size: 12px; text-align: right; opacity: .85; line-height: 1.35;
  border-left: 1px solid rgba(234,231,225,.25); padding-left: 12px;
}

/* --- Progress: the working-out behind the number, at the foot of Home ------- */
.prog {
  background: var(--green-900); color: var(--cream); border-radius: var(--radius);
  padding: 13px 16px 11px; display: grid; gap: 9px;
}
.prog__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.prog__head--bare { justify-content: flex-end; margin-bottom: -6px; }
.prog__title { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .7; }
.prog__link { border: 0; background: none; color: var(--accent); font-size: 12px; font-weight: 700; padding: 0; }

.prog__nums { display: flex; align-items: baseline; gap: 18px; }
.prog__num { display: grid; gap: 1px; }
.prog__numValue { font-family: var(--serif); font-size: 25px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.prog__numLabel { font-size: 11px; opacity: .7; }
.prog__num--estimate .prog__numValue { color: var(--accent); }
.prog__num--target { margin-left: auto; text-align: right; opacity: .75; }
.prog__num--target .prog__numValue { font-size: 17px; }

/* Better is up. In golf the number goes down as the golfer improves, so the
   y axis is inverted in chart.js; without that every line reads backwards. */
.chart { width: 100%; }
.chart__svg { width: 100%; height: 100%; display: block; overflow: visible; }
.chart__line { stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart__line--official { stroke: var(--cream); }
.chart__line--official[x1] { stroke-dasharray: 6 5; opacity: .8; }
.chart__line--estimate { stroke: var(--accent); }
.chart__band { stroke: rgba(234,231,225,.35); stroke-width: 1; stroke-dasharray: 3 4; }
.chart__key { display: flex; flex-wrap: wrap; gap: 14px; margin: 8px 2px 0; font-size: 12px; color: var(--muted); }
.chart__keyItem { display: inline-flex; align-items: center; gap: 6px; }
.chart__swatch { width: 14px; height: 3px; border-radius: 2px; background: currentColor; }
.chart__swatch--official { background: var(--ink); }
.chart__swatch--estimate { background: #B08A3E; }
.chart__swatch--target { background: repeating-linear-gradient(90deg, var(--muted) 0 3px, transparent 3px 7px); }

.prog__chips { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.prog__chip {
  background: rgba(244,246,248,.10); border-radius: 10px; padding: 6px 6px;
  display: grid; gap: 0; text-align: center;
}
.prog__chipValue { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.prog__chipLabel { font-size: 10px; opacity: .7; line-height: 1.3; }
.prog__chipDelta { font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; opacity: .85; }
.prog__chip.is-better .prog__chipDelta { color: #7FD1A0; }
.prog__chip.is-worse  .prog__chipDelta { color: #F2A9A9; }

.prog__cta {
  width: 100%; border: 0; background: none; color: var(--accent);
  border-radius: 10px; padding: 2px 0 0; font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; gap: 5px;
}
.prog__cta:active { color: var(--cream); }
.prog__chev { font-size: 17px; line-height: 1; }

/* --- Handicap screen ------------------------------------------------------- */
.hcnums { display: flex; gap: 22px; margin-bottom: 14px; }
.hcnum { display: grid; gap: 2px; }
.hcnum__value { font-family: var(--serif); font-size: 32px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.hcnum__label { font-size: 11px; font-weight: 600; color: var(--muted); }
.hcnum--estimate .hcnum__value { color: #B08A3E; }
.hcnum--target { margin-left: auto; text-align: right; }
.hcnum--target .hcnum__value { font-size: 22px; color: var(--muted); }

/* On the light screen the chart sits on white, so the two lines swap to the
   readable-on-white pair rather than the cream-on-green pair. */
.hc__caveat { margin: 10px 2px 18px; }
.hcnums ~ .chart .chart__line--official { stroke: var(--ink); }
.hcnums ~ .chart .chart__line--estimate { stroke: #B08A3E; }
.hcnums ~ .chart .chart__band { stroke: var(--muted); }

.hcform { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 6px; }
.hcform .btn { grid-column: 1 / -1; }

.hclist { display: grid; gap: 2px; }
.hcrow {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px;
  background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 11px 14px;
}
.hcrow__value { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; }
.hcrow__date { font-size: 13px; color: var(--muted); }
.hcrow__del { border: 0; background: none; color: var(--muted); font-size: 20px; line-height: 1; padding: 0 4px; }

.home__ask {
  display: flex; align-items: center; gap: 12px; text-align: left; width: 100%;
  background: var(--surface); border: 0; box-shadow: var(--shadow); border-radius: var(--radius); padding: 14px 16px;
}
.home__ask:active { background: #F7F8FA; }
.home__ask-avatar {
  flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: var(--accent); color: var(--green-900); font-size: 20px;
}
.home__ask-text { display: grid; gap: 2px; min-width: 0; }
.home__ask-title { font-weight: 700; font-size: 15px; }
.home__ask-sub { font-size: 13px; color: var(--muted); line-height: 1.35; }


/* --- Hero: a photo band with the heading laid over it ---------------------- */
.hero {
  position: relative; margin: 0 0 18px; border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
}
.hero__img { display: block; width: 100%; height: 132px; object-fit: cover; background: var(--sage); }
/* One size for every section hero. Home, Rounds and Planning sit next to each
   other in the tab bar, so a shorter one on any of them reads as a mistake rather
   than a choice. A hero with a button gets a little more room because its body is
   a line taller, not because it is a different kind of thing. */
.hero--tall .hero__img { height: 184px; }
.hero--action .hero__img { height: 196px; }
/* A band, not a picture: for a screen whose content needs the height back. */
.hero--short .hero__img { height: 96px; }
.hero--short .hero__body {
  padding: 12px 16px 14px;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.hero--short .hero__title { font-size: 20px; }
.hero__body {
  /* Extra padding at the foot lifts the block off the bottom edge, which matters
     most where a hero carries an action button. */
  position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 18px 24px; color: #fff;
  /* Scrim, not a flat tint: keeps the photo readable and the text legible. */
  background: linear-gradient(to top, rgba(12,20,17,.86) 0%, rgba(12,20,17,.5) 42%, rgba(12,20,17,0) 82%);
}
.hero__title { margin: 0; font-size: 23px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.15; }
.hero--tall .hero__title, .hero--action .hero__title { font-size: 27px; }
.hero__sub { margin: 3px 0 0; font-size: 13px; line-height: 1.4; color: rgba(255,255,255,.88); }
/* Inside the tagline, not under it: the story is a footnote to that sentence, and
   a button of its own was taking a row for one link. */
.hero__more {
  border: 0; background: none; padding: 0; font: inherit; font-weight: 800;
  color: #fff; text-decoration: underline; text-underline-offset: 2px;
}
.hero__more:active { color: var(--accent); }

/* --- Drawn icons ----------------------------------------------------------
   Each svg is 1em square and inherits currentColor, so a single file serves the
   13px avatar in the chat header and the 28px mark on the floating button, and
   goes green on an active tab without a second asset. Size with font-size. */
.icon { line-height: 0; }
.icon svg { display: block; width: 1em; height: 1em; }

/* --- App bar actions ------------------------------------------------------- */
.appbar__right { display: flex; align-items: center; gap: 10px; }
.appbar__btn {
  border: 0; background: none; color: var(--muted); font-size: 20px;
  padding: 4px; border-radius: 9px; line-height: 0;
}
.appbar__btn:active { background: #F1F3F5; color: var(--ink); }
.appbar__btn:disabled { opacity: .4; }

/* --- Score distribution ---------------------------------------------------- */
.spread {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 9px 12px;
}
.spread__label { font-size: 14px; color: var(--muted); }
.spread__track { height: 12px; border-radius: 999px; background: #EFF1F4; overflow: hidden; }
.spread__bar { display: block; height: 100%; border-radius: 999px; min-width: 0; }
.spread__count { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; min-width: 18px; }

/* A scoring scale, dark to light and cool to hot, so worse reads hotter. */
.spread__bar--eagle  { background: var(--data-violet); }
.spread__bar--birdie { background: var(--data-blue); }
.spread__bar--par    { background: var(--data-green); }
.spread__bar--bogey  { background: var(--data-amber); }
.spread__bar--double { background: #E07A3F; }
.spread__bar--triple { background: var(--data-red); }

/* --- Drive dispersion fan -------------------------------------------------- */
.fan { margin: 4px 0 2px; }
.fan svg { display: block; width: 100%; height: auto; }
.fan__wedge { stroke: var(--surface); stroke-width: 2; }
.fan__wedge--good  { fill: var(--data-green-50); }
.fan__wedge--mixed { fill: var(--data-amber-50); }
.fan__wedge--poor  { fill: var(--data-red-50); }
.fan__wedge--none  { fill: #F1F3F5; }
.fan__tee { fill: var(--ink); }
.fan__n {
  fill: var(--ink); font-size: 21px; font-weight: 800; text-anchor: middle;
  font-family: var(--font); font-variant-numeric: tabular-nums;
}
.fan__sub { font-size: 12px; font-weight: 700; text-anchor: middle; font-family: var(--font); fill: var(--muted); }
.fan__hit  { fill: var(--data-green); }
.fan__miss { fill: var(--data-red); }

/* --- Hero action: a way into a story from the picture ---------------------- */
.hero__action {
  margin-top: 10px; border: 1px solid rgba(255,255,255,.55); background: rgba(255,255,255,.14);
  color: #fff; border-radius: 999px; padding: 7px 15px; font-size: 13px; font-weight: 600;
  backdrop-filter: blur(3px);
}
/* On a band there is no room for a bordered pill, so the action is a plain link
   sharing the title's line. */
.hero__action--inline {
  margin: 0; flex: none; border: 0; background: none; backdrop-filter: none;
  padding: 0; font-size: 13px; font-weight: 700; color: var(--accent);
}
.hero__action:active { background: rgba(255,255,255,.28); }
.hero__action--inline:active { background: none; color: #fff; }

/* --- Story overlay --------------------------------------------------------
   Full screen and scrollable, because this is prose to be read rather than a
   dialog to be dismissed. Measure is capped so lines stay readable on a tablet. */
.story {
  position: fixed; inset: 0; z-index: 20; background: var(--cream);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  opacity: 0; transform: translateY(12px);
  transition: opacity .26s ease, transform .26s cubic-bezier(.32,.72,0,1);
}
.story.is-in { opacity: 1; transform: none; }
.story__panel {
  max-width: 560px; margin: 0 auto;
  padding: max(20px, env(safe-area-inset-top)) 22px calc(40px + env(safe-area-inset-bottom));
}
.story__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.story__title { font-size: 30px; font-weight: 800; letter-spacing: -0.015em; margin: 0; line-height: 1.1; }
.story__close {
  flex: none; border: 0; background: #EFF1F4; color: var(--muted);
  width: 34px; height: 34px; border-radius: 50%; font-size: 14px; line-height: 1;
}
.story__close:active { background: var(--line); color: var(--ink); }

/* The lede carries the argument, so it gets the weight. */
.story__lede { font-size: 19px; line-height: 1.45; font-weight: 600; margin: 0 0 8px; color: var(--ink); }
.story__section { margin-top: 26px; }
.story__heading { font-size: 17px; font-weight: 800; margin: 0 0 7px; }
.story__body { font-size: 15px; line-height: 1.62; color: var(--ink); margin: 0 0 10px; }
.story__body:last-child { margin-bottom: 0; }
.story__close-line {
  margin: 30px 0 0; padding: 18px 20px; border-radius: var(--radius);
  background: var(--green-900); color: var(--cream);
  font-size: 15px; line-height: 1.6; font-weight: 500;
}
.story__done { width: 100%; }

@media (prefers-reduced-motion: reduce) { .story { transition: none; } }

/* On the narrowest phones the hole columns come down to about 20px, where 14px
   digits start to touch. */
@media (max-width: 360px) {
  .card-cell { font-size: 13px; }
  .card-row { grid-template-columns: 34px repeat(9, minmax(0, 1fr)) 34px; }
  .mark { width: 20px; height: 20px; font-size: 12px; }
}

/* --- Stat tiles judged against the golfer's handicap ----------------------- */
.stat__bench { display: block; font-size: 10px; color: var(--muted); margin-top: 3px; }
.stat--good .stat__value { color: var(--data-green); }
.stat--ok   .stat__value { color: var(--ink); }
.stat--poor .stat__value { color: var(--data-red); }
/* A tinted foot rather than a tinted tile: the colour reads as a verdict on the
   number without turning a row of facts into a traffic light. */
.stat--good { box-shadow: var(--shadow), inset 0 -3px 0 var(--data-green); }
.stat--ok   { box-shadow: var(--shadow), inset 0 -3px 0 var(--data-amber); }
.stat--poor { box-shadow: var(--shadow), inset 0 -3px 0 var(--data-red); }

/* --- Albert's read on a round --------------------------------------------
   Deliberately not a .card. This is the one thing on the screen that is spoken
   rather than measured, so it is tinted and signed to look like someone talking
   rather than another panel of figures. */
.note {
  background: rgba(201,183,156,.22); border-radius: var(--radius);
  padding: 16px 18px 14px; margin-bottom: 16px;
}
.note__head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.note__avatar {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--green-700); color: var(--cream); font-size: 14px; flex: none;
}
.note__who {
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--green-700);
}
.note__text { margin: 0; font-size: 15px; line-height: 1.6; color: var(--ink); }
.note__more {
  border: 0; padding: 0; background: none; font: inherit;
  font-weight: 700; color: var(--green-700); white-space: nowrap;
}
.note__more:active { color: var(--green-900); }

/* A round's by-par rows are judged against the golfer's own normal for that par,
   which the lifetime block on the rounds screen has no equivalent of: there, the
   averages are the normal. Same markup, one extra tint. */
.bypar__row--good { background: var(--data-green-50); }
.bypar__row--good .bypar__rel { color: var(--data-green); }
.bypar__row--poor { background: var(--data-red-50); }
.bypar__row--poor .bypar__rel { color: var(--data-red); }
.bypar__row--ok .bypar__rel { color: var(--muted); }

/* Two-way switch over a block of figures. Sits above what it changes, so it reads
   as a lens on the numbers rather than navigation. */
.segmented {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: #EEF0F2; border-radius: 12px; padding: 4px; margin-bottom: 14px;
}
.segmented--three { grid-template-columns: repeat(3, 1fr); }
.segmented__btn {
  border: 0; background: none; border-radius: 9px; padding: 8px 6px;
  font-size: 13px; font-weight: 600; color: var(--muted);
}
.segmented__btn.is-on {
  background: #fff; color: var(--ink);
  box-shadow: 0 1px 3px rgba(20,24,28,.12);
}

/* A row that goes somewhere. Not a .card, because a card is something to read and
   this is something to press. */
.linkcard {
  width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  border: 1px solid var(--line); background: #fff; border-radius: var(--radius);
  padding: 14px 16px; margin-top: 4px;
}
.linkcard:active { background: #FAFAF8; }
.linkcard__text { display: grid; gap: 2px; min-width: 0; flex: 1; }
.linkcard__title { font-weight: 700; font-size: 15px; }
.linkcard__sub { font-size: 13px; color: var(--muted); line-height: 1.35; }
.linkcard__chevron { font-size: 22px; color: var(--muted); line-height: 1; flex: none; }
/* A small standing badge on a row: which routine the card prints, and anything
   else later that is true of one row in a list and has to be said, not inferred. */
.pill {
  flex: none; border-radius: 999px; padding: 3px 9px;
  font-size: 11px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
}
.pill--on { background: var(--green-700); color: #fff; }
/* A tee's colour, as a colour. Ringed rather than bare, because white and yellow
   tees are the two most common and both vanish on this background. */
.teedot {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--line); box-shadow: inset 0 0 0 1px rgba(20,24,28,.28);
}

/* Performance: the same blocks as a round, over many rounds. */
.statgrid--two { grid-template-columns: 1fr 1fr; }
.perf__count { margin: -6px 2px 16px; }

/* ============================================================
   Pre-shot routine
   ============================================================ */

/* --- The wizard --- */
.wizard { padding: 4px 2px 24px; }
.wizard__bar { height: 3px; border-radius: 999px; background: #EDEFF1; overflow: hidden; margin-bottom: 14px; }
.wizard__fill { display: block; height: 100%; background: var(--green-700); transition: width .25s ease; }
.wizard__count { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.wizard__q { font-family: var(--serif); font-size: 24px; font-weight: 800; letter-spacing: -0.01em; margin: 8px 0 4px; }
.wizard__sub { color: var(--muted); margin: 0 0 20px; line-height: 1.45; }

.options { display: grid; gap: 8px; }
.option {
  width: 100%; text-align: left; border: 1px solid var(--line); background: #fff;
  border-radius: 14px; padding: 15px 16px; font-size: 15px; font-weight: 600; color: var(--ink);
}
.option:active { background: #FAFAF8; }
.option.is-on { border-color: var(--green-700); box-shadow: inset 0 0 0 1px var(--green-700); }

.preshot__reminder { min-height: 96px; margin-bottom: 14px; resize: vertical; }

/* --- Albert working --- */
.building { display: grid; justify-items: center; text-align: center; gap: 8px; padding: 64px 24px; }
.building__avatar {
  display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%;
  background: var(--green-700); color: var(--cream); font-size: 28px; margin-bottom: 8px;
  animation: building-pulse 1.6s ease-in-out infinite;
}
@keyframes building-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.building__text { font-size: 17px; font-weight: 700; margin: 0; }
.building__sub { color: var(--muted); margin: 0; font-size: 14px; line-height: 1.45; }

/* --- The routine as a card you read --- */
.trigger {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  background: rgba(201,183,156,.22); border-radius: var(--radius);
  padding: 12px 16px; margin-bottom: 16px;
}
.trigger__label { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #7a6647; }
.trigger__phrase { font-family: var(--serif); font-size: 19px; font-weight: 800; }

.routine { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 2px; }
.routine__step {
  display: grid; grid-template-columns: 28px 1fr; gap: 12px; align-items: start;
  background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px;
}
.routine__num {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--green-700); color: #fff; font-size: 13px; font-weight: 800;
}
/* The routine's name, with the way to change it beside it rather than under it:
   under it, a rename link reads as an action on the whole screen. */
.routine__name { display: flex; align-items: baseline; gap: 10px; }
.routine__name .section__title { min-width: 0; }
.routine__rename {
  flex: none; background: none; border: 0; padding: 0;
  color: var(--green-700); font-size: 14px; font-weight: 600;
}
.routine__text { font-size: 15px; line-height: 1.5; padding-top: 3px; }
.routine__run { width: 100%; }
.routine__actions {
  display: flex; flex-direction: column; align-items: center; gap: 12px; margin: 14px 2px 20px;
}
/* Destructive actions, everywhere in the app: an outlined pill on white rather
   than a red word in a row of green ones. Red text alone reads as a link that has
   been styled oddly; an outline says this one is a button that does something to
   your data. Outlined rather than filled, because it is still the quiet option on
   the screen and should not compete with the primary button above it. */
.link--danger {
  display: block; width: fit-content; margin-inline: auto;
  background: #fff; color: var(--data-red);
  border: 1.5px solid var(--data-red); border-radius: 999px;
  padding: 9px 20px; font-size: 14px; font-weight: 700;
}
.link--danger:active { background: color-mix(in srgb, var(--data-red) 8%, #fff); }

/* --- Train: a practice plan, read standing on a range --- */
.tr__week { margin-bottom: 6px; }
.tr__session { padding: 13px 14px; }
.tr__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.tr__title { margin: 0; font-size: 15px; font-weight: 800; }
.tr__mins {
  flex: none; font-size: 11px; font-weight: 800; color: var(--green-700);
  font-variant-numeric: tabular-nums;
}
.tr__drills { margin: 9px 0 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.tr__drill { padding-top: 9px; border-top: 1px solid var(--line); }
.tr__drill:first-child { padding-top: 0; border-top: 0; }
.tr__drillTop { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.tr__drillName { font-size: 13px; font-weight: 700; }
.tr__drillMins {
  flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.tr__drillHow { margin: 2px 0 0; font-size: 13px; line-height: 1.45; color: var(--ink); }

/* --- Run mode: one step, arm's length, no timer --- */
.run {
  display: grid; align-content: center; justify-items: center; gap: 28px;
  min-height: 52vh; text-align: center; padding: 24px 8px;
  background: var(--green-900); border-radius: var(--radius); color: var(--cream);
}
.run__stage { display: grid; justify-items: center; gap: 14px; }
.run__num { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; opacity: .6; }
.run__text { font-family: var(--serif); font-size: 27px; font-weight: 800; line-height: 1.3; margin: 0; max-width: 18ch; }
.run__done { display: grid; justify-items: center; gap: 14px; }
.run__phrase { font-family: var(--serif); font-size: 30px; font-weight: 800; margin: 0; color: var(--accent); }
.run__hit { font-size: 16px; opacity: .75; margin: 0; }
.run__done .btn--primary { background: var(--cream); color: var(--green-900); }
.run__dots { display: flex; gap: 7px; }
.run__dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(243,239,231,.3); }
.run__dot.is-on { background: var(--accent); }
.run__hint { margin: 12px 2px 20px; }

/* ============================================================
   Pre-round routine
   ============================================================ */

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 9px 15px; font-size: 14px; font-weight: 600; color: var(--ink);
}
.chip.is-on { background: var(--green-700); border-color: var(--green-700); color: #fff; }
.chips__next { width: 100%; margin-top: 20px; }

.warmup__total { display: flex; align-items: baseline; gap: 6px; margin-bottom: 12px; }
.warmup__mins { font-family: var(--serif); font-size: 34px; font-weight: 800; letter-spacing: -0.02em; }
.warmup__minsLabel { font-size: 13px; font-weight: 600; color: var(--muted); }

.warmup { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 2px; }
.warmup__block {
  display: grid; grid-template-columns: 58px 1fr; gap: 12px; align-items: start;
  background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px;
}
.warmup__time {
  font-size: 12px; font-weight: 800; color: var(--green-700);
  font-variant-numeric: tabular-nums; padding-top: 3px;
}
.warmup__body { min-width: 0; }
.warmup__title { font-size: 15px; font-weight: 700; margin: 0 0 3px; }
.warmup__what { font-size: 14px; line-height: 1.5; color: var(--muted); margin: 0; }

/* --- Run mode with a clock. Sits on the bag divider and gets glanced at. --- */
.timer {
  display: grid; justify-items: center; gap: 18px; text-align: center;
  background: var(--green-900); border-radius: var(--radius); color: var(--cream);
  padding: 22px 18px 24px; min-height: 52vh; align-content: center;
}
.timer__bar {
  width: 100%; height: 3px; border-radius: 999px;
  background: rgba(243,239,231,.2); overflow: hidden;
}
.timer__fill { display: block; height: 100%; background: var(--accent); transition: width 1s linear; }
.timer__clock {
  font-family: var(--serif); font-size: 46px; font-weight: 800;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1;
}
.timer__stage { display: grid; justify-items: center; gap: 8px; }
.timer__title { font-family: var(--serif); font-size: 24px; font-weight: 800; margin: 0; }
.timer__what { font-size: 15px; line-height: 1.5; opacity: .8; margin: 0; max-width: 30ch; }
.timer__controls { display: flex; gap: 8px; }
.timer__btn {
  border: 1px solid rgba(243,239,231,.35); background: none; color: var(--cream);
  border-radius: 999px; padding: 9px 20px; font-size: 14px; font-weight: 600; min-width: 96px;
}
.timer__btn--next { background: var(--cream); border-color: var(--cream); color: var(--green-900); }

/* ============================================================
   Course Planner
   ============================================================ */

.linkcard.is-disabled { opacity: .5; }
.option__name { display: block; }
.option__meta { display: block; font-size: 12px; font-weight: 600; color: var(--muted); margin-top: 2px; }
.wizard__count--gap { display: block; margin-top: 22px; }


/* ============================================================
   Gameplan: the card itself, and four ways into it
   ============================================================ */

.gp__hint { display: flex; align-items: center; gap: 8px; margin: 0 2px 10px; font-size: 12px; color: var(--muted); }
.gp__hintClose { border: 0; background: none; color: var(--muted); font-size: 15px; line-height: 1; padding: 0 2px; }

/* The stage owns the space the scaled sheet occupies. A transform does not affect
   layout, so the height comes from fitPaper as a variable. */
/* Clipped, so that a sheet which has not been fitted yet is cut off rather than
   lying across the buttons underneath it. The fit is the normal case; this is what
   the abnormal one should look like. */
.gp__stage {
  position: relative; height: var(--sheet-h, 400px); margin-bottom: 12px; overflow: hidden;
}
.gp__stage .paperwrap { position: relative; padding: 0; }

/* Four transparent buttons floating over the sheet, sized from what the sheet
   actually measures rather than 100%: the scale is capped at 1, so on a wide
   screen the sheet is narrower than its wrapper and a percentage overlay would
   sit off to one side of it. */
.gp__hits {
  position: absolute; top: 0; left: var(--sheet-x, 0px);
  width: var(--sheet-w, 100%); height: var(--sheet-h, 100%);
  display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
}
.gp__hit {
  appearance: none; -webkit-appearance: none; background: transparent; border: 0;
  padding: 6px; margin: 0; font: inherit; color: inherit; text-align: left;
  -webkit-tap-highlight-color: transparent;
  position: relative; display: grid; align-content: center; justify-items: stretch;
}
/* A tap on a transparent button is otherwise completely silent. */
.gp__hit:active::after {
  content: ''; position: absolute; inset: 5px;
  border: 2px solid var(--green-700); border-radius: 10px;
}
/* An empty quadrant keeps the ruled-paper look the old fake preview had. It sits
   on this layer, so the sheet that prints still carries its honest "not built yet"
   line, which is the right thing to take to the course as a to-do. */
.gp__hit.is-empty {
  background-image: repeating-linear-gradient(transparent 0 7px, rgba(20,24,28,.05) 7px 8px);
}
.gp__hit.is-empty::before {
  content: ''; position: absolute; inset: 7px;
  border: 1.5px dashed var(--line); border-radius: 10px;
}
/* One caption, the same in all four quadrants: a band across the middle, full
   width, opaque. Centred is where the eye lands, and a quadrant is a thumbnail
   rather than something you read, so there is nothing underneath worth protecting.
   Full width rather than shrink-wrapped, so the four read as one set instead of
   two: built quadrants had a strip and empty ones a floating box, which made the
   card look like it had two kinds of thing on it. */
.gp__cap {
  position: relative; display: grid; gap: 1px;
  width: 100%; min-width: 0; text-align: center;
  background: rgba(255,255,255,.96); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 9px 7px;
  box-shadow: 0 2px 10px rgba(20,24,28,.10);
}
/* The state line, with the tick small and in front of it. On the label line the
   tick was a badge on a heading, and at "Pre-round routine" length it pushed the
   second word onto a line of its own. Down here it marks the state, which is what
   it was reporting on all along. Grey for empty, green for built, the same pair
   the label uses. */
.gp__capState {
  display: flex; align-items: center; justify-content: center; gap: 5px; min-width: 0;
}
.gp__tick {
  flex: none; display: grid; place-items: center; width: 12px; height: 12px;
  border-radius: 50%; background: var(--muted); color: #fff; font-size: 8px; line-height: 1;
}
.gp__hit.is-ready .gp__tick { background: var(--green-700); }
/* A little smaller and a little tighter than the rest of the app's small caps:
   "PRE-ROUND ROUTINE" is seventeen characters and half a quadrant is 116px, so at
   the usual 10px and .04em it wrapped. French still wraps, on the hyphen, which is
   a clean enough break to live with. */
.gp__capLabel {
  min-width: 0; font-size: 9.5px; font-weight: 800; letter-spacing: .02em;
  line-height: 1.2; text-transform: uppercase; color: var(--muted);
}
.gp__hit.is-ready .gp__capLabel { color: var(--green-700); }
.gp__sub {
  min-width: 0; font-size: 11px; color: var(--ink); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.gp__actions { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.gp__print { flex: 1; }


/* ============================================================
   Course Planner: map underneath, everything else floating over
   ============================================================ */

/* The map fills everything between the brand bar and the tabs: no page padding,
   edge to edge, but the app is still visibly the app. A satellite view of one hole
   boxed inside 16px of margin is a picture of a golf hole rather than something
   you can work on; losing the header and the tabs is a different mistake. */
/* Full bleed. A hole is a photograph of a place you are about to walk, and it was
   being shown in the letterbox between the app bar and the tabs. Everything the
   screen needs floats on top of it, so nothing is lost by taking the whole
   viewport, and the back button in the corner is the way out. */
.pl {
  position: fixed; inset: 0; z-index: 4; overflow: hidden;
  background: var(--green-900);
}
/* The floating Albert would land on the controls, which are the part of the screen
   you are actually pressing. He is one tap away in the tab bar regardless. */
body.has-map .fab,
body.has-map .appbar,
body.has-map .tabbar { display: none; }
/* The outlet still scrolls behind a fixed child, so it is pinned while the map is
   up. Otherwise a flick on the bottom sheet drags the page underneath it. */
body.has-map { overflow: hidden; }

.pl__map { position: absolute; inset: 0; }
/* Leaflet writes its own z-index stack; keep it under the floating chrome. */
.pl__map .leaflet-pane, .pl__map .leaflet-control { z-index: 1; }

/* Two corners of chrome and nothing else on the grass. The old layout put a
   column of nine white boxes down the left, which is a third of the hole. */
.pl__back {
  position: absolute; z-index: 800; left: 12px; top: calc(12px + env(safe-area-inset-top));
  width: 44px; height: 44px; border-radius: 50%;
  border: 0; background: #fff; color: var(--ink);
  font-size: 24px; font-weight: 700; line-height: 1; box-shadow: 0 2px 12px rgba(0,0,0,.34);
}

/* One card. The distance left is the number the screen exists to produce, so it
   is the only thing set at display size. */
/* Everything that floats on the right, stacked, so nothing has to guess how tall
   the thing above it is. The yardage card grows a line when a club is aimed and
   another when there is trouble in the dispersion ring. */
.pl__right {
  position: absolute; z-index: 500; right: 12px; top: calc(12px + env(safe-area-inset-top));
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  max-width: calc(100% - 84px); pointer-events: none;
}
.pl__right > * { pointer-events: auto; }
.pl__hud {
  background: rgba(255,255,255,.94); border-radius: 16px;
  box-shadow: 0 2px 10px rgba(0,0,0,.28);
  padding: 9px 14px 8px; text-align: right; min-width: 92px;
}
.pl__hudMain { display: flex; align-items: baseline; justify-content: flex-end; gap: 2px; }
.pl__toGreen {
  font-family: var(--serif); font-size: 30px; font-weight: 800;
  letter-spacing: -0.03em; line-height: 1; color: var(--green-900);
  font-variant-numeric: tabular-nums;
}
.pl__hudUnit { font-size: 11px; font-weight: 700; color: var(--muted); }
.pl__hudLabel {
  display: block; font-size: 9px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-top: 1px;
}
.pl__shotLine {
  display: none; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line);
  font-size: 12px; font-weight: 800; color: var(--green-700); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pl__shotLine.is-on { display: block; }
/* Trouble inside the ring, in words. An amber circle on a satellite photograph is
   not something anyone reads as "the water is in play". */
.pl__spreadNote {
  display: none; margin-top: 4px; font-size: 11px; font-weight: 800;
  color: #B4741B; white-space: nowrap;
}
.pl__spreadNote.is-on { display: block; }
/* The metres on a dispersion ring. Small and light: it labels the circle, it is
   not a number you read the hole by. */
.pl__ring {
  display: inline-block; padding: 1px 6px; border-radius: 7px;
  background: rgba(10,14,12,.72); color: #fff;
  font-size: 11px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.pl__ring--warn { background: #B4741B; }

/* Controls live at the bottom, in reach of a thumb, and off the hole. */
/* The controls float clear of the edge rather than sitting on it.
   A white bar welded to the bottom read as a page underneath the map, which is the
   opposite of what this screen is: the map is the screen and everything else is
   furniture on top of it. Dark and translucent, the hole carries on behind it. */
.pl__bottom {
  position: absolute; z-index: 600;
  left: 12px; right: 12px; bottom: calc(14px + env(safe-area-inset-bottom));
  border-radius: 20px;
  background: rgba(18, 42, 33, .72);
  -webkit-backdrop-filter: blur(12px) saturate(120%);
  backdrop-filter: blur(12px) saturate(120%);
  box-shadow: 0 6px 22px rgba(0,0,0,.34);
}

/* The shots committed to on this hole, under the distance on the right. The map
   already draws them on the fairway, but a plan is also something you read: driver,
   seven iron, pitching wedge is the sentence you take to the tee. Hidden until
   there is one, so an unplanned hole is just the hole. */
.pl__shots {
  display: none; margin: 0; padding: 6px; list-style: none;
  width: 116px; border-radius: 14px;
  background: rgba(18, 42, 33, .72);
  -webkit-backdrop-filter: blur(12px) saturate(120%);
  backdrop-filter: blur(12px) saturate(120%);
  box-shadow: 0 4px 16px rgba(0,0,0,.32);
}
.pl__shots.is-on { display: grid; gap: 3px; }
.pl__shot {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 5px; border-radius: 9px; color: #fff;
}
.pl__shotNum {
  flex: none; display: grid; place-items: center; width: 15px; height: 15px;
  border-radius: 50%; background: rgba(255,255,255,.20);
  font-size: 9px; font-weight: 800;
}
.pl__shotClub {
  flex: 1; min-width: 0; font-size: 12px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pl__shotDist {
  flex: none; font-size: 12px; font-weight: 800;
  font-variant-numeric: tabular-nums; color: rgba(255,255,255,.86);
}

/* Whole hole, or in on the green. One control, on the right under the shots, so
   the two ways of looking at a hole are asked for rather than done to you. */
.pl__zoom {
  position: absolute; z-index: 600; right: 12px;
  bottom: calc(96px + env(safe-area-inset-bottom));
  width: 44px; height: 44px; border-radius: 50%; border: 0;
  background: rgba(18, 42, 33, .72);
  -webkit-backdrop-filter: blur(12px) saturate(120%);
  backdrop-filter: blur(12px) saturate(120%);
  color: #fff; font-size: 22px; line-height: 1;
  display: grid; place-items: center;
  box-shadow: 0 4px 16px rgba(0,0,0,.32);
}

/* The bag as a wheel down the left.
   Whatever settles on the centre line is the club in play, so choosing one is a
   flick rather than a hunt and a tap. The thumb is already on that side of the
   phone, the clubs are in bag order, and the movement matches the distance. It
   floats over the map, narrow enough to leave the fairway beside it. */
.pl__rail {
  position: absolute; z-index: 700; left: 8px;
  bottom: calc(84px + env(safe-area-inset-bottom));
  top: calc(74px + env(safe-area-inset-top));
  display: flex; flex-direction: column; gap: 6px;
  overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* Vertical drags belong to this scroller, not to the map underneath it. Without
     this, a finger on the wheel panned the hole sideways: Leaflet takes any touch
     it is given, and a column with nothing to scroll gives it everything. The
     measured padding above and below guarantees there is always something to
     scroll, and this guarantees the gesture arrives here. */
  touch-action: pan-y;
  /* Proximity, not mandatory: mandatory plus scroll-snap-stop meant one club per
     flick and a wheel that refused to be thrown. The padding that lets the two
     ends of the bag reach the centre is measured in JS, because a percentage
     padding resolves against width and this box is 58 pixels wide. */
  scroll-snap-type: y proximity;
  padding: 0 2px;
}
.pl__rail::-webkit-scrollbar { display: none; }
/* The line the wheel reads, faint, so it is clear what is being chosen. */
.pl__rail::before {
  content: ''; position: absolute; left: 2px; width: 58px; top: 50%;
  height: 46px; transform: translateY(-50%);
  border-radius: 13px; background: rgba(255,255,255,.16);
  pointer-events: none;
}
.pl__club {
  flex: none; width: 54px; display: grid; justify-items: center; gap: 0;
  background: rgba(255,255,255,.92); border: 1.5px solid transparent; border-radius: 12px;
  padding: 6px 4px; color: var(--ink); box-shadow: 0 1px 6px rgba(20,24,28,.18);
  scroll-snap-align: center;
  transition: transform .14s ease, background .14s ease;
}
.pl__club b { font-size: 13px; font-weight: 800; line-height: 1.15; }
.pl__club small { font-size: 10px; font-weight: 700; color: var(--muted); }
/* The club in play is the dark one. Against a wheel of pale discs it is the only
   thing that reads at a glance on a bright satellite photograph, where a green
   outline on white does not. */
.pl__club.is-on {
  border-color: var(--green-900); background: var(--green-900); color: #fff;
  transform: scale(1.09); box-shadow: 0 3px 14px rgba(0,0,0,.42);
}
.pl__club.is-on small { color: rgba(255,255,255,.82); }
/* Stock carries, not the golfer's own. Dashed, so the wheel is honest about it
   without a line of explanation nobody reads on a map. */
.pl__club.is-stock { border-style: dashed; border-color: rgba(20,24,28,.22); }
.pl__club.is-stock.is-on { border-style: solid; border-color: var(--green-900); }

.pl__hbar { display: flex; align-items: center; gap: 8px; padding: 9px 11px 10px; }
.pl__holenav { display: flex; align-items: center; gap: 8px; margin-right: auto; min-width: 0; }
/* Everything inside the bar is now light on dark, so the outlines carry the shape
   rather than a fill: a white circle here would read as a hole punched in the bar. */
.pl__nav {
  width: 32px; height: 32px; flex: none; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.34); background: rgba(255,255,255,.10);
  font-size: 17px; color: #fff; line-height: 1;
}
.pl__hmid { display: grid; gap: 0; min-width: 0; text-align: center; }
.pl__holeNum {
  font-family: var(--serif); font-size: 16px; font-weight: 800; line-height: 1.15; color: #fff;
}
.pl__holeMeta {
  color: rgba(255,255,255,.72); font-size: 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pl__icon {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.34); background: rgba(255,255,255,.10);
  font-size: 14px; color: #fff;
}
.pl__icon:disabled { opacity: .3; }
/* A hole with a note on it says so, since the note is not otherwise on screen. */
.pl__note.is-on { background: #fff; color: var(--green-900); border-color: #fff; }
.pl__lock {
  flex: none; background: var(--green-700); color: #fff; border: 0; border-radius: 999px;
  padding: 10px 16px; font-weight: 700; font-size: 13px; white-space: nowrap;
}
.pl__lock:disabled { background: rgba(255,255,255,.14); color: rgba(255,255,255,.45); }
/* The hole is planned. Lighter than the lock, because moving on is the obvious
   thing to do rather than a commitment being made. */
.pl__lock--done { background: #fff; color: var(--green-900); }

/* Map furniture. The pin is a teardrop so its point is the actual target, which a
   circle cannot express. */
.pl__pin {
  display: block; width: 26px; height: 26px; border-radius: 50% 50% 50% 0;
  background: #E8A33D; border: 3px solid #fff; transform: rotate(-45deg);
  box-shadow: 0 2px 8px rgba(0,0,0,.5);
}
/* A shot is a circle on the line with its distance in it, and the club under it.
   As a pill carrying "7 iron · 138 m" every label was a different width and the
   line read as a row of tags; as a disc they read as the shots they are, and the
   eye follows the hole rather than the text. */
.pl__seg {
  display: grid; place-items: center; width: 44px; height: 44px; margin: 0 auto;
  border-radius: 50%; background: #fff; color: var(--ink);
  font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 8px rgba(0,0,0,.38);
}
.pl__seg--live { background: var(--green-700); color: #fff; }
.pl__segClub {
  display: block; margin: 3px auto 0; width: max-content; max-width: 92px;
  border-radius: 999px; padding: 1px 7px;
  background: rgba(20,24,28,.62); color: #fff;
  font-size: 10px; font-weight: 700; white-space: nowrap;
}

/* ============================================================
   Intel card: one sheet, four quadrants, two folds
   ============================================================ */

.card-opts { display: grid; gap: 12px; margin-bottom: 14px; }
.card-opt { display: grid; gap: 6px; }
.card-optLabel { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.card-print { width: 100%; }
.card-hint { margin: 10px 2px 18px; }

/* On screen the sheet is a preview: shrunk to the width available, with the paper
   shadow that tells you it is a physical object. In print it is the page. */
/* On screen the sheet is a preview at true size, scaled down to fit. The wrapper
   is given the scaled height in JS, because a transform does not affect layout and
   the page would otherwise reserve a full 297mm of empty space below it. */
.paperwrap { padding-bottom: 24px; }
.paper {
  position: relative; background: #fff; color: #14181C;
  box-shadow: 0 6px 24px rgba(20,24,28,.16);
  display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
  transform-origin: top left;
  transform: translateX(var(--paper-x, 0px)) scale(var(--paper-sx, 1), var(--paper-sy, 1));
  font-family: var(--font);
}
.paper--a4 { width: 210mm; height: 297mm; }
.paper--letter { width: 216mm; height: 279mm; }

.paper__fold { position: absolute; background: repeating-linear-gradient(transparent 0 3mm, #C9CDD1 3mm 5mm); }
.paper__fold--v { left: 50%; top: 0; bottom: 0; width: .3mm; }
.paper__fold--h { top: 50%; left: 0; right: 0; height: .3mm;
  background: repeating-linear-gradient(90deg, transparent 0 3mm, #C9CDD1 3mm 5mm); }

.paper__q { padding: 8mm 7mm; overflow: hidden; }
.paper__q--tl { grid-area: 1 / 1; }
.paper__q--tr { grid-area: 1 / 2; }
.paper__q--bl { grid-area: 2 / 1; }
.paper__q--br { grid-area: 2 / 2; }

.panel { height: 100%; display: flex; flex-direction: column; }
.panel__head { display: flex; align-items: baseline; justify-content: space-between; gap: 4mm;
  border-bottom: .4mm solid #14181C; padding-bottom: 1.6mm; margin-bottom: 2.6mm; }
.panel__label { font-size: 9pt; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.panel__meta { font-size: 7pt; color: #5A6169; white-space: nowrap; }
.panel__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.8mm; }
.panel__row { display: grid; grid-template-columns: 7mm 1fr; gap: 2mm; font-size: 7.6pt; line-height: 1.32; }
.panel__mins, .panel__num { font-weight: 800; font-size: 7.6pt; }
.panel__mins::after { content: "'"; }
.panel__body b { font-weight: 800; }
.panel__foot, .panel__trigger { margin: auto 0 0; padding-top: 2.5mm; font-size: 8pt; font-style: italic; }
.panel__trigger { font-style: normal; font-weight: 800; font-size: 10pt; text-align: center; }
.panel__missing { font-size: 8pt; color: #8A9098; }
.panel__player { display: flex; justify-content: space-between; gap: 3mm; font-size: 7pt; color: #5A6169; margin-bottom: 2mm; }
.panel__date { flex: 1; border-bottom: .3mm solid #9AA0A6; max-width: 26mm; }

/* The scorecard. Printed columns on the left, written columns on the right, and
   the written cells get the room because they are what has to be read back. */
.sc { width: 100%; border-collapse: collapse; font-size: 7pt; }
.sc th {
  font-size: 5.6pt; font-weight: 800; text-transform: uppercase; letter-spacing: .02em;
  background: #E8EAEC; border: .25mm solid #6E757C; padding: .8mm 0; text-align: center;
}
.sc td { border: .25mm solid #9AA0A6; text-align: center; height: 4.9mm; padding: 0; }
.sc--h { width: 6%; font-weight: 800; }
.sc--p, .sc--i { width: 6.5%; color: #5A6169; }
.sc--d { width: 9%; color: #5A6169; }
.sc--w { width: 15%; background: #fff; }
.sc--dir { width: 17%; }
.sc--dir i { font-style: normal; display: inline-block; width: 30%; font-size: 5.4pt; color: #9AA0A6; }
.sc__sum td { background: #E8EAEC; font-weight: 800; }
.sc__sum .sc--w, .sc__sum .sc--dir { background: #fff; }

/* The hole plan: eighteen lines, each the clubs you decided on and your own note
   about the hole. Three columns rather than a run-on line, so a long note wraps
   inside its own column and the eighteen rows still line up, which is the one
   thing this quadrant has to do. */
.plan__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .7mm; }
.plan__row {
  display: grid; grid-template-columns: 5mm minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 1.6mm; font-size: 7.2pt;
  border-bottom: .2mm dotted #C9CDD1; padding-bottom: .7mm;
}
.plan__h { font-weight: 800; }
.plan__shots { color: #14181C; }
.plan__note { color: #4A5158; font-style: italic; }

@media print {
  /* Only the sheet exists. Everything else is the app around it. Named by what it
     is rather than by listing every block on the screen: the old list had to be
     edited every time the Gameplan screen grew a row, and forgetting meant a
     button printed on the card. */
  .appbar, .tabbar, .fab, .nudge, .backlink, .noprint { display: none !important; }

  /* Any padding left on the shell is added to the sheet's own height and pushes
     a second, empty page out of the printer. The chain from html down to the
     wrapper is flattened to nothing so the sheet is the only thing with size. */
  html, body, .shell, .outlet, .section, .gp__stage, .paperwrap {
    background: #fff !important; margin: 0 !important; padding: 0 !important;
    min-height: 0 !important; overflow: visible !important; display: block !important;
  }
  html, body { height: 100% !important; }
  .shell, .outlet, .section, .gp__stage, .paperwrap { height: auto !important; }

  /* The sheet fills whatever printable area it is given rather than asserting
     297mm. With `@page { margin: 0 }` honoured that is the whole page and the
     folds land on the paper's true halves. Where a browser insists on its own
     print margins, the card shrinks to fit instead of spilling, and the folds are
     still at the centre of what was printed. Nothing is ever cut off, which
     matters more than a millimetre. */
  .paper {
    transform: none !important; box-shadow: none; break-inside: avoid;
    width: 100% !important; height: 100% !important;
  }
}
/* No static @page here. It cannot read a custom property and cannot be scoped to
   a class, so declaring it once meant the paper picker changed the preview and
   never what came out of the printer. The Gameplan screen injects it instead. */


/* ============================================================
   Adding a round
   ============================================================ */

.addround {
  width: 100%; display: flex; align-items: center; gap: 10px;
  background: var(--green-700); color: #fff; border: 0; border-radius: 14px;
  padding: 13px 16px; margin-bottom: 10px; font-weight: 700; font-size: 15px;
}
.addround:active { background: var(--green-900); }
.addround__plus {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: rgba(255,255,255,.2); font-size: 16px; line-height: 1; flex: none;
}

.ways { display: grid; gap: 10px; }
.way {
  width: 100%; display: flex; align-items: center; gap: 14px; text-align: left;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 16px;
}
.way:active { background: #FAFAF8; }
.way__icon {
  display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px;
  background: #EAF3EE; color: var(--green-700); font-size: 21px; flex: none;
}
.way__text { display: grid; gap: 3px; flex: 1; min-width: 0; }
.way__title { font-weight: 700; font-size: 16px; }
.way__desc { font-size: 13px; color: var(--muted); line-height: 1.35; }
.way__chev { font-size: 22px; color: var(--muted); line-height: 1; flex: none; }

.entry__meta { display: grid; gap: 12px; margin-bottom: 20px; }

/* The card, in the same column order as the printed one, so a golfer copying from
   paper reads straight across rather than hunting for the right box. */
.entry__head, .entry__row {
  display: grid; grid-template-columns: 22px 1fr 1fr 1fr 34px 32px 32px; gap: 5px; align-items: center;
}
.entry__head {
  padding: 0 2px 6px; font-size: 10px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); text-align: center;
}
.entry__head span:first-child { text-align: left; }
.entry__row { padding: 3px 2px; }
/* A hairline where the turn is, because the two nines are the story. */
.entry__row.is-turn { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 9px; }
.entry__hole { font-size: 13px; font-weight: 800; color: var(--muted); }
.entry__num {
  width: 100%; min-width: 0; height: 38px; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; text-align: center; font-size: 16px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; -moz-appearance: textfield;
}
/* 16px keeps iOS from zooming the page when the field takes focus, and the spinner
   arrows are useless at this size. */
.entry__num::-webkit-outer-spin-button, .entry__num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.entry__num:focus { border-color: var(--green-700); outline: none; box-shadow: 0 0 0 3px rgba(47,125,90,.14); }
.entry__num--par { background: #F4F6F8; color: var(--muted); font-weight: 600; }
.entry__num.is-set { border-color: #C8D2CC; }

/* The green is a readout, not a control: same size and place as the ticks so the
   row still lines up, but flat, because there is nothing to press. */
.entry__green {
  height: 38px; display: grid; place-items: center; border-radius: 10px;
  border: 1px dashed var(--line); font-size: 14px; font-weight: 800; color: var(--muted);
}
.entry__green.is-yes { background: var(--data-green-50); border-color: var(--data-green); border-style: solid; color: var(--data-green); }
.entry__green.is-no { color: #B9C0C6; }

.entry__tick, .entry__drive {
  height: 38px; border: 1px solid var(--line); border-radius: 10px; background: #fff;
  font-size: 14px; font-weight: 800; color: var(--muted); padding: 0;
}
/* Down the middle is the good one, either side is not, and nothing recorded reads
   as nothing rather than as a miss. */
.entry__drive.is-mid { background: var(--data-green-50); border-color: var(--data-green); color: var(--data-green); }
.entry__drive.is-off { background: var(--data-amber-50); border-color: var(--data-amber); color: #7A4E13; }
.entry__tick.is-yes { background: var(--data-green-50); border-color: var(--data-green); color: var(--data-green); }
.entry__tick.is-no  { background: #F4F6F8; color: var(--muted); }

.entry__totals {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  background: var(--green-900); color: var(--cream); border-radius: var(--radius);
  padding: 14px 12px; margin: 16px 0 18px;
}
.entry__tot { display: grid; justify-items: center; gap: 1px; }
.entry__totValue { font-family: var(--serif); font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.entry__totRel { font-size: 11px; font-weight: 800; color: var(--accent); }
.entry__totLabel { font-size: 10px; opacity: .7; text-transform: uppercase; letter-spacing: .05em; }

.entry__save { width: 100%; }
.entry__hint { margin: 10px 2px 20px; text-align: center; }

/* Deleting a round: reachable, and never in the way. */
.round-danger { display: flex; justify-content: center; margin: 4px 0 24px; }

/* Sharing a round. The link is shown once it exists, because a golfer who granted
   it should be able to see what they granted. */
.share { display: grid; justify-items: center; gap: 6px; margin: 4px 0 6px; }
.share__btn { width: 100%; }
.share__state {
  margin: 0; font-size: 12px; color: var(--muted); word-break: break-all;
  text-align: center; font-variant-numeric: tabular-nums;
}
.share__off { font-size: 13px; }
/* Not .btn--ghost: that name was taken first, by the red one that logs you out. */
.btn--outline {
  background: #fff; color: var(--green-700); border: 1px solid var(--green-700);
}
.btn--outline:active { background: #EAF3EE; }

/* The plan picker, in the sheet the app already has for Albert. */
.gp__picker { height: auto; max-height: 70dvh; padding-bottom: calc(env(safe-area-inset-bottom) + 16px); }
.gp__pickerTitle { margin: 0 18px 10px; }
.gp__pickerList { padding: 0 16px; overflow-y: auto; }

/* A date is eight characters wide. Stretched across the screen it reads as an
   input waiting for a sentence. */
.field--date { max-width: 190px; }

/* A date read off the photograph, offered rather than applied. */
.entry__dateNote { margin: 6px 2px 0; font-size: 12px; color: var(--muted); }
