/* ---------- Design tokens ---------- */
:root{
  /* Fairway greens */
  --green-950:#062a1c;
  --green-900:#0b3d2b;
  /*
   * green-800 was #0f5132 (deep fairway green) prior to v=google-42.
   * User requested a global swap to #006747 for the three primary surfaces
   * that use this token: the site header, the "Get GWI" primary CTA, and
   * the "Today" (active) date chip. #006747 is a slightly cooler, more
   * jewel-toned green that matches the OG social share card palette better.
   * Every consumer of this token flips automatically (single source of truth).
   */
  --green-800:#006747;
  --green-700:#137047;
  --green-600:#2f8f5f;
  --green-500:#4bb37b;
  --green-100:#d7f0e1;
  --green-50:#eaf7ef;

  /* Sky */
  --sky-500:#3b82f6;
  --sky-400:#60a5fa;

  /* Neutrals — warm parchment */
  /*
   * Main page background — was warm sand #faf7f2 through v=google-42.
   * Swapped to #E6F0EC in v=google-44 (user request): a 10%-tint of the
   * header green #006747 mixed with white. Pale green-tinted off-white,
   * cooler and more "turf-adjacent" than the previous cream cast.
   * The two radial gradients on `body` still layer on top for depth.
   */
  --sand-50:#E6F0EC;
  --sand-100:#f2ede3;
  --sand-200:#e6dfd0;
  --ink-900:#111713;
  --ink-700:#2b3830;
  --ink-500:#5a6b62;
  --ink-400:#7b8b83;
  --line:#dcd6c8;

  /* Score palette */
  --s-prime:#16a34a;
  --s-great:#22c55e; /* Locked to the orb's "great" gradient mid-stop so
                       the orb, the day-strip selected pill, and the
                       "Great" tier chip all render as the SAME green. */
  --s-good:#c39a1e;
  --s-ok:#d97706;
  --s-bad:#c2410c;
  --s-nogo:#991b1b;

  --radius:16px;
  --radius-sm:10px;
  --shadow-sm:0 1px 2px rgba(6,42,28,.06), 0 2px 6px rgba(6,42,28,.05);
  --shadow-md:0 10px 30px -12px rgba(6,42,28,.25);
  --wrap-max:1120px;

  /* Single sans-serif family used for both display and body — we differentiate
     via weight (900/800 for display, 400–600 for body) and letter-spacing. */
  /* System font stack — native UI font on each OS. No web-font download, no
     layout shift, no third-party dependency. SVG logo carries brand. */
  --font-display:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-body:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family:var(--font-sans);
  color:var(--ink-900);
  background:
    radial-gradient(1200px 600px at 85% -10%, rgba(75,179,123,.18), transparent 60%),
    radial-gradient(900px 500px at -5% 10%, rgba(59,130,246,.10), transparent 60%),
    var(--sand-50);
  -webkit-font-smoothing:antialiased;
  line-height:1.55;
}
img,svg{display:block;max-width:100%}
a{color:var(--green-800);text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit;cursor:pointer}
h1,h2,h3{font-family:var(--font-display);font-weight:800;letter-spacing:-0.025em;line-height:1.1;color:var(--ink-900);margin:0}
h1{font-size:clamp(2rem,5vw,3.6rem);font-weight:900}
h2{font-size:clamp(1.5rem,3vw,2.2rem)}
h3{font-size:1.15rem}
.wrap{max-width:var(--wrap-max);margin:0 auto;padding:0 20px}
.muted{color:var(--ink-500);font-weight:500}

/* ---------- Header ---------- */
/* Palette-matched to the OG social share card (deep-green surface, white
   text, gold accent). Establishes the brand color language before any body
   content so the site reads consistently against Slack / iMessage previews. */
.site-header{position:sticky;top:0;z-index:20;background:#006747;border-bottom:1px solid rgba(255,255,255,.08)}
.header-inner{display:flex;align-items:center;justify-content:space-between;height:64px}
.brand{display:flex;align-items:center;gap:10px;color:#fff;text-decoration:none;font-family:var(--font-display);font-weight:800;font-size:1.15rem;letter-spacing:-0.025em;line-height:1.1}
.brand:hover{text-decoration:none}
/* Divider between "GWI" and "Golf Weather Index" — soft white so it reads on
   the deep-green surface but doesn't fight the wordmark for attention. */
.brand-divider{margin:0 .35em;color:#fff;font-weight:600;opacity:.55}
/* Logo mark uses baked-in warm-gold colors (Direction 5A dimple constellation).
   No color inheritance needed — the palette IS the identity. */
.logo{width:32px;height:32px;flex:none}
/* Gold accent on the word "Index" — matches the OG card's gold treatment on
   "golf" and reinforces the same three-color system (green / white / gold). */
/*
 * "Index" wordmark color — swapped from gold #f4b53f to a brighter school-bus
 * yellow #FFCE1B in v=google-43 (user request). Reads more energetic against
 * the deep-green #006747 header. Only affects the last word in the brand
 * lockup; the Open-app pill background and hover accents keep gold.
 */
.brand-accent{color:#FFCE1B}
.site-nav{display:flex;gap:20px;font-weight:500;align-items:center}
.site-nav a{color:#fff}
.site-nav a:hover{color:#f4b53f;text-decoration:none}
/* Homepage doesn't ship an "Open app" CTA (it IS the app) but the class
   exists for parity with static pages. Keep tokens defined so any future
   embed is consistent with the static-page treatment below. */
.site-nav .nav-links-cta,
.site-nav .cta{background:#f4b53f;color:#006747;padding:8px 14px;border-radius:8px;font-weight:700;letter-spacing:-0.01em}
.site-nav .nav-links-cta:hover,
.site-nav .cta:hover{background:#ffca5c;color:#082e1c;text-decoration:none}
/* Hamburger — hidden on desktop, shown on mobile via media query below */
.nav-toggle{position:absolute;left:-9999px;opacity:0}
.nav-burger{display:none;cursor:pointer;padding:8px;margin-left:auto;border-radius:8px;user-select:none;color:#fff}
.nav-burger:hover{background:rgba(255,255,255,.08)}
.nav-burger svg{display:block;width:26px;height:26px}
.nav-burger .icon-close{display:none}

/* ---------- Hero ---------- */
.hero{padding:56px 0 40px}
.hero h1{max-width:820px}
.lede{font-size:clamp(1.05rem,1.6vw,1.25rem);color:var(--ink-700);max-width:760px;margin:16px 0 28px}

/* Search */
.search{display:flex;gap:10px;flex-wrap:wrap;max-width:820px;position:relative;align-items:center}
.search-field{
  flex:1 1 320px;display:flex;align-items:center;gap:8px;
  background:#fff;border:1px solid var(--line);border-radius:999px;padding:6px 8px 6px 16px;
  position:relative;
  box-shadow:var(--shadow-sm);transition:border-color .15s, box-shadow .15s;
  min-width:0;
}
.search-field:focus-within{border-color:var(--green-600);box-shadow:0 0 0 4px rgba(75,179,123,.18)}
.search-field .icon{width:20px;height:20px;color:var(--ink-500);flex:0 0 auto}
#q{flex:1;border:0;outline:0;padding:12px 0;font-size:1rem;background:transparent;min-width:0}
.ghost{background:transparent;border:0;padding:8px;border-radius:999px;color:var(--ink-500);display:inline-flex}
.ghost:hover{background:var(--sand-100);color:var(--green-800)}
.ghost svg{width:20px;height:20px}

/* Date field */
.date-field{
  display:flex;align-items:center;gap:8px;
  background:#fff;border:1px solid var(--line);border-radius:999px;padding:6px 14px;
  box-shadow:var(--shadow-sm);transition:border-color .15s, box-shadow .15s;
  min-width:0;
}
.date-field:focus-within{border-color:var(--green-600);box-shadow:0 0 0 4px rgba(75,179,123,.18)}
.date-field .icon{width:18px;height:18px;color:var(--ink-500);flex:0 0 auto}
#date{border:0;outline:0;padding:12px 0;font-size:1rem;background:transparent;font-family:inherit;color:var(--ink-900);min-width:130px}
#date::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.6}
#date::-webkit-calendar-picker-indicator:hover{opacity:1}

/* Date chips */
.date-chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;max-width:820px}
.date-chip{
  background:#fff;border:1px solid var(--line);border-radius:999px;padding:8px 14px;font-size:.88rem;font-weight:600;color:var(--ink-700);
  cursor:pointer;transition:all .15s;
}
.date-chip:hover{border-color:var(--green-600);color:var(--green-800)}
.date-chip.active{background:var(--green-800);color:#fff;border-color:var(--green-800)}
.date-chip .chip-sub{opacity:.7;font-weight:500;margin-left:4px;font-size:.78rem}
.primary{
  background:var(--green-800);color:#fff;border:0;border-radius:999px;padding:14px 22px;font-weight:600;
  box-shadow:var(--shadow-sm);transition:transform .05s ease, background .15s ease;
}
/*
 * .primary:hover — slightly darker version of --green-800 (#006747).
 * Was --green-900 (#0b3d2b) which read as a completely different green when
 * the main button flipped to #006747. #00553b is a hand-tuned darker shade
 * on the same hue so the hover reads as a natural press state.
 */
.primary:hover{background:#00553b}
.primary:active{transform:translateY(1px)}
.status{margin-top:12px;color:var(--ink-500);min-height:1.4em}
.status.error{color:#b91c1c}
.status.error strong{display:block;font-weight:600;margin-bottom:4px}
.status.error .status-details{margin:6px 0;color:#7f1d1d;font-weight:400}
.status.error .status-details summary{cursor:pointer;color:#b91c1c;text-decoration:underline;text-underline-offset:2px;font-weight:500;display:inline-block;padding:2px 0}
.status.error .status-details summary:hover{color:#7f1d1d}
.status.error .status-details[open] summary{margin-bottom:6px}
.status.error .status-details > *:not(summary){display:block;font-size:.94em;line-height:1.5;color:#5b1a1a}
.status.error .status-fallback{display:block;margin-top:6px;color:var(--ink-500);font-weight:400}

.suggestions{
  position:absolute;top:calc(100% + 8px);left:0;right:0;background:#fff;border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--shadow-md);overflow:hidden;overflow-y:auto;z-index:50;
  max-height:min(60vh, 460px);
}
.suggestions button{
  display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:transparent;border:0;padding:12px 16px;font-size:.98rem;font-family:inherit;color:inherit;cursor:pointer;
}
.suggestions button:hover,.suggestions button:focus{background:var(--sand-100)}
.suggestions .sug-icon{
  flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;
  border-radius:8px;background:var(--green-100,#e0efe6);font-size:1.1rem;
}
.suggestions .sug-icon-pin{background:var(--sand-100);}
.suggestions .sug-body{display:flex;flex-direction:column;line-height:1.25;min-width:0;flex:1}
.suggestions .sug-body strong{font-weight:700;color:var(--ink-900);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.suggestions .sug-sub{color:var(--ink-500);font-size:.82rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.suggestions .sug-dist{
  flex-shrink:0;font-size:.75rem;font-weight:700;color:var(--green-800);
  background:#e8f3ec;border:1px solid var(--green-600);border-radius:999px;
  padding:3px 9px;letter-spacing:.02em;
}
.suggestions .sug-dist.far{
  color:var(--ink-500);background:var(--sand-100);border-color:var(--line);font-weight:600;
}

/* Bottom-of-results "Nearby courses" list — shown after a geolocation-based search */
.nearby-bottom{margin-top:32px;min-width:0}
/*
  Grid tracks use minmax(0, 1fr) instead of 1fr so children with unbreakable
  meta content (rating chip + distance chip, both flex 0 0 auto) cannot force
  their track to grow past the container. Without this, the intrinsic min-width
  of a card is honored ahead of the fractional share, and 3 columns of ~380px
  overflow the 1080px grid container at viewports below ~1300px.
*/
.nearby-bottom-list{
  display:grid;
  grid-template-columns:minmax(0, 1fr);
  gap:10px;
  margin-top:12px;
  min-width:0;
}
@media(min-width:640px){.nearby-bottom-list{grid-template-columns:minmax(0, 1fr) minmax(0, 1fr)}}
@media(min-width:960px){.nearby-bottom-list{grid-template-columns:repeat(3, minmax(0, 1fr))}}
.nearby-bottom-list .nb-course{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:14px 16px;text-align:left;font:inherit;color:inherit;
  cursor:pointer;transition:border-color .15s, box-shadow .15s, transform .05s;
}
.nearby-bottom-list .nb-course:hover{border-color:var(--green-600);box-shadow:var(--shadow-sm)}
.nearby-bottom-list .nb-course:active{transform:scale(.995)}
/* Each card is a flex row: [name (grows, truncates)] [meta (fixed content)].
   min-width:0 on the card itself is critical — without it, the flex child's
   min-content width leaks upward into the grid track. */
.nearby-bottom-list .nb-course{min-width:0}
.nearby-bottom-list .nb-name{font-weight:700;color:var(--ink-900);flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nearby-bottom-list .nb-meta{display:flex;align-items:center;gap:8px;flex:0 0 auto;min-width:0}
.nearby-bottom-list .nb-rating{
  color:#8a5c00;font-size:.78rem;font-weight:700;white-space:nowrap;
  display:inline-flex;align-items:baseline;gap:2px;
}
.nearby-bottom-list .nb-rating[data-loading]{min-width:0;color:transparent}
.nearby-bottom-list .nb-rating-count{color:var(--ink-500);font-weight:500}
.nearby-bottom-list .nb-dist{
  color:var(--ink-500);background:var(--sand-100);border:1px solid var(--line);
  border-radius:999px;padding:3px 10px;font-size:.78rem;font-weight:600;
  white-space:nowrap;flex:0 0 auto;
}
.nearby-bottom-list .nb-loading,
.nearby-bottom-list .nb-empty{
  grid-column:1/-1;display:flex;align-items:center;justify-content:center;gap:12px;
  padding:20px;color:var(--ink-500);font-size:.92rem;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  flex-wrap:wrap;text-align:center;
}
.nearby-bottom-list .nb-retry{
  background:var(--green-800);color:#fff;border:0;border-radius:999px;
  padding:6px 14px;font-size:.85rem;font-weight:600;cursor:pointer;
  transition:background .15s;
}
.nearby-bottom-list .nb-retry:hover{background:var(--green-600)}

/* -----------------------------------------------------
   Course info panel (Google Places details for picked course)
----------------------------------------------------- */
.course-info{
  /* Section heading ("Book a tee time") sits above with its own margin;
     this panel is the section body so it just needs a small breathing gap. */
  margin:0 0 8px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:14px 18px;
  display:flex;flex-direction:column;gap:8px;
}
.course-info .ci-header{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 4px;
  font-size:.95rem;
}
.course-info .ci-rating{color:#8a5c00;font-weight:700}
.course-info .ci-rating strong{font-size:1.05rem;letter-spacing:.01em;margin:0 2px}
.course-info .ci-rating .ci-muted{color:var(--ink-500);font-weight:500}
.course-info .ci-price{color:var(--ink-700);font-weight:700;letter-spacing:.02em}
.course-info .ci-open{
  color:#0f5132;background:#e6f4ea;border:1px solid #cfe7d5;
  border-radius:999px;padding:2px 10px;font-size:.78rem;font-weight:700;letter-spacing:.02em;
}
.course-info .ci-closed{
  color:#7a1f1f;background:#fdecec;border:1px solid #f4c8c8;
  border-radius:999px;padding:2px 10px;font-size:.78rem;font-weight:700;letter-spacing:.02em;
}
.course-info .ci-dot{color:var(--ink-400);margin:0 4px;font-weight:400}
.course-info .ci-hours{color:var(--ink-700);font-size:.9rem}
.course-info .ci-summary{color:var(--ink-700);font-size:.9rem;line-height:1.45}
.course-info .ci-actions{
  display:flex;flex-wrap:wrap;gap:8px;margin-top:4px;
}
.course-info .ci-action{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--sand-100);border:1px solid var(--line);border-radius:999px;
  padding:6px 12px;color:var(--ink-900);font-size:.85rem;font-weight:600;
  text-decoration:none;transition:border-color .15s,background .15s,color .15s;
  max-width:100%;
}
.course-info .ci-action:hover{border-color:var(--green-600);background:#fff;color:var(--green-800)}
.course-info .ci-action svg{flex:0 0 auto;color:var(--green-800)}
.course-info .ci-action span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}

/* Skeleton while Place Details is loading */
.course-info .ci-skeleton{display:flex;flex-direction:column;gap:10px}
.course-info .ci-skel-line{height:14px;border-radius:6px;background:linear-gradient(90deg,#efece6 25%,#f6f4ef 37%,#efece6 63%);background-size:400% 100%;animation:ci-shimmer 1.4s ease-in-out infinite}
.course-info .ci-skel-w40{width:40%}
.course-info .ci-skel-actions{display:flex;gap:8px}
.course-info .ci-skel-pill{display:inline-block;width:90px;height:26px;border-radius:999px;background:linear-gradient(90deg,#efece6 25%,#f6f4ef 37%,#efece6 63%);background-size:400% 100%;animation:ci-shimmer 1.4s ease-in-out infinite}
@keyframes ci-shimmer{0%{background-position:100% 50%}100%{background-position:0 50%}}

/* "Load 10 more" button spans the full grid width, matches card styling */
.nearby-bottom-list .nb-load-more{
  grid-column:1/-1;
  background:#fff;color:var(--green-800);
  border:1px solid var(--line);border-radius:14px;
  padding:14px 20px;font-size:.95rem;font-weight:700;cursor:pointer;
  transition:background .15s,border-color .15s,transform .05s;
  margin-top:2px;
  font-family:inherit;
}
.nearby-bottom-list .nb-load-more:hover{
  background:var(--green-50,#eef7f0);
  border-color:var(--green-800);
}
.nearby-bottom-list .nb-load-more:active{transform:translateY(1px)}
.nearby-bottom-list .nb-spinner{
  width:14px;height:14px;border-radius:50%;
  border:2px solid var(--line);border-top-color:var(--green-600);
  animation:nb-spin .8s linear infinite;flex:0 0 auto;
}
@keyframes nb-spin{to{transform:rotate(360deg)}}

/* Nearby courses chip row — contain layout so async population doesn't shift the page */
.nearby-courses{
  overflow-anchor:none;contain:layout;
  margin-top:14px;padding:14px 16px 12px;border:1.5px dashed var(--green-600);
  border-radius:var(--radius-sm);background:linear-gradient(180deg, #f4faf6, #fff);
}
.nearby-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px}
.nearby-title{font-family:var(--font-display);font-weight:800;color:var(--green-800);font-size:.98rem}
.nearby-list{display:flex;flex-wrap:wrap;gap:8px}
.course-chip{
  display:inline-flex;align-items:center;gap:8px;background:#fff;border:1.5px solid var(--line);
  border-radius:999px;padding:7px 12px 7px 14px;cursor:pointer;font-family:inherit;color:var(--ink-900);
  font-size:.9rem;transition:border-color .15s, background .15s, transform .1s;box-shadow:var(--shadow-sm);
}
.course-chip:hover{border-color:var(--green-800);background:#f4faf6;transform:translateY(-1px)}
.course-chip-name{font-weight:600}
.course-chip-dist{color:var(--ink-500);font-size:.8rem;background:var(--sand-100);padding:2px 8px;border-radius:999px}

/* ---------- Empty state ---------- */
/* Empty-state (Recent / Favorites / illustrated onboarding) sits directly
   under the hero form on the pre-search view. Top padding was 32px — tightened
   to 12px so the RECENT chips read above the mobile fold. Bottom padding
   stays generous so the illustrated block doesn't crowd the footer. */
.empty-state{padding:12px 0 80px}
.empty-card{
  background:#fff;border:1.5px solid var(--line);border-radius:var(--radius);
  padding:36px 28px;box-shadow:var(--shadow-md);
  text-align:center;max-width:560px;margin:0 auto;
}
.empty-icon{
  font-size:2.6rem;line-height:1;margin-bottom:14px;
  display:inline-flex;align-items:center;justify-content:center;
  width:72px;height:72px;border-radius:50%;
  background:linear-gradient(180deg,#e8f3ec,#f4faf6);
  border:1.5px solid var(--green-600);
}
.empty-title{
  font-family:var(--font-display);font-weight:900;font-size:1.6rem;
  color:var(--green-800);margin:6px 0 10px;letter-spacing:-.01em;
}
.empty-sub{color:var(--ink-700);font-size:1rem;line-height:1.55;margin:0 auto 22px;max-width:440px}
.empty-hints{
  list-style:none;padding:0;margin:0;text-align:left;
  display:flex;flex-direction:column;gap:10px;max-width:420px;margin:0 auto;
}
.empty-hints li{
  display:flex;align-items:flex-start;gap:12px;
  background:var(--sand-100);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;font-size:.94rem;color:var(--ink-700);
}
.empty-hints li em{color:var(--ink-900);font-style:normal;font-weight:600;background:#fff;padding:1px 6px;border-radius:6px;border:1px solid var(--line)}
.eh-bullet{
  flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;border-radius:8px;background:#fff;border:1px solid var(--line);font-size:1rem;
}
@media(max-width:640px){
  .empty-card{padding:26px 20px}
  .empty-title{font-size:1.35rem}
  .empty-icon{width:60px;height:60px;font-size:2.1rem}
}

/* Nearby-courses block inside empty state */
.empty-nearby{
  margin:0 auto 22px;text-align:left;
  padding:14px 16px 14px;border:1.5px dashed var(--green-600);
  border-radius:14px;background:linear-gradient(180deg, #f4faf6, #fff);
  animation:fadein .35s ease;
}
@keyframes fadein{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.en-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px;gap:8px;flex-wrap:wrap}
.en-title{font-family:var(--font-display);font-weight:800;color:var(--green-800);font-size:.98rem}
.en-list{display:flex;flex-wrap:wrap;gap:8px}
.en-list .course-chip.use-loc{background:var(--green-800);border-color:var(--green-800);color:#fff}
.en-list .course-chip.use-loc:hover{background:#0a3d24;border-color:#0a3d24}

/* Show-all / show-fewer toggle inside chip lists */
.en-toggle{
  display:inline-flex;align-items:center;gap:6px;
  background:transparent;border:1.5px dashed var(--green-800);
  color:var(--green-800);border-radius:999px;
  padding:8px 14px;font-family:var(--font-body);
  font-weight:700;font-size:.86rem;cursor:pointer;
  transition:all .15s ease;
}
.en-toggle:hover{background:var(--green-800);color:#fff;border-style:solid}
.en-toggle-more{
  background:var(--sand-100);color:var(--green-800);
  padding:2px 8px;border-radius:999px;font-size:.75rem;font-weight:700;
}
.en-toggle:hover .en-toggle-more{background:#fff;color:var(--green-800)}

/* Soft loading hint while we resolve permission + fetch nearby */
.empty-geo-status{
  margin:0 auto 18px;font-size:.88rem;color:var(--ink-500);
  display:inline-flex;align-items:center;gap:8px;
}
/* HTML [hidden] attribute must beat the class's display:inline-flex — without
   this, hideEmptyGeoStatus() would set hidden=true but the spinner would still
   show because class specificity > user-agent [hidden] rule. */
.empty-geo-status[hidden]{display:none !important;}
.empty-geo-status.loading::before{
  content:'';display:inline-block;width:12px;height:12px;border-radius:50%;
  border:2px solid var(--green-600);border-top-color:transparent;
  animation:spin .8s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- Results ---------- */
.results{padding:8px 0 60px}
/* Offset scroll anchoring for the sticky header so the location name isn't hidden. */
/* Enough top offset to clear BOTH sticky bars: site header (64px) +
   day-strip (~60px desktop, ~56px mobile) + a little pad. */
.results-head{scroll-margin-top:140px}
@media(max-width:640px){.results-head{scroll-margin-top:132px}}
.results-head{
  display:grid;grid-template-columns:1fr;gap:20px;
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:24px;
  box-shadow:var(--shadow-md);
}
@media(min-width:780px){.results-head{grid-template-columns:1fr auto;align-items:center}}
.place-name{font-family:var(--font-display);font-weight:900;font-size:clamp(1.5rem,3vw,2rem)}
.place-meta{color:var(--ink-500);margin:6px 0 0}
/* Not-today emphasis on the golf-course details line. When the user is
   viewing a future-day forecast (e.g. after the 2h-before-sunset cutoff has
   passed today), the date renders bold and gets a colored "Next available
   round" prefix so there's no chance of mistaking it for today's forecast. */
.place-meta .meta-next-label{color:var(--brand-accent, #006747);font-weight:600}
.place-meta .meta-date{color:var(--ink-900, #111);font-weight:700}

/* Share button — sits under place meta on mobile, inline-right on desktop */
.results-head-title{display:flex;flex-direction:column;gap:6px}
.share-btn{
  align-self:flex-start;
  margin-top:10px;
  display:inline-flex;align-items:center;gap:8px;
  background:#fff;color:var(--green-800);
  border:1px solid var(--line);border-radius:999px;
  padding:8px 14px;font-size:.9rem;font-weight:700;cursor:pointer;
  transition:background .15s,border-color .15s,transform .05s;
  font-family:inherit;
}
.share-btn:hover{background:var(--green-50,#eef7f0);border-color:var(--green-800)}
.share-btn:active{transform:translateY(1px)}
.share-btn svg{flex:0 0 auto}

/* Star / Save-to-favorites button — sits inline with Share */
.star-btn{
  align-self:flex-start;
  margin-top:10px;
  margin-right:8px;
  display:inline-flex;align-items:center;gap:8px;
  background:#fff;color:var(--green-800);
  border:1px solid var(--line);border-radius:999px;
  padding:8px 14px;font-size:.9rem;font-weight:700;cursor:pointer;
  transition:background .15s,border-color .15s,transform .05s,color .15s;
  font-family:inherit;
}
.star-btn:hover{background:var(--green-50,#eef7f0);border-color:var(--green-800)}
.star-btn:active{transform:translateY(1px)}
.star-btn svg{flex:0 0 auto;transition:fill .15s,stroke .15s}
.star-btn.is-on{
  background:#fff8e1;
  border-color:#f5c518;
  color:#8a6d00;
}
.star-btn.is-on svg{fill:#f5c518;stroke:#e0a800}

/* Wrapper that puts Star + Share side by side under the place meta */
.results-actions{
  display:flex;flex-wrap:wrap;gap:8px;
  margin-top:10px;
}
.results-actions .star-btn,
.results-actions .share-btn{margin-top:0}

/* -----------------------------------------------------
   Header favorites star + slide-in drawer
   Star icon lives in .header-inner between the brand and the nav-toggle.
   Drawer slides in from the right on desktop AND mobile so it feels like a
   proper panel rather than a full-screen takeover.
------------------------------------------------------ */
/* Shared visual base for header icon buttons (search + favorites). Both are
   40x40 transparent buttons over the green header with a subtle hover fill. */
.header-icon-btn{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;
  background:transparent;color:#fff;
  border:0;border-radius:10px;
  margin-right:4px;
  cursor:pointer;
  transition:background .15s,color .15s,transform .05s;
  font-family:inherit;
  flex:0 0 auto;
}
.header-icon-btn:hover{background:rgba(255,255,255,.10)}
.header-icon-btn:active{transform:translateY(1px)}
.header-icon-btn:focus-visible{outline:2px solid #f5c518;outline-offset:2px}
.header-icon-btn svg{transition:fill .15s,stroke .15s}

/* First icon in the row (search) owns the "push cluster to right edge" via
   margin-left:auto so search + star + burger sit together on the right. */
.header-search-btn{margin-left:auto}

/* Favorites star fills yellow when count > 0. */
.header-fav-btn.has-favs svg{fill:#f5c518;stroke:#f5c518}
/* iOS notification-badge style: bright system red, white numeral, no dark
   stroke so the badge sits cleanly on the star's top-right without covering
   the icon itself. Sits above the top edge like Apple's Mail/Phone badges. */
.header-fav-badge{
  position:absolute;top:-2px;right:-2px;
  min-width:16px;height:16px;padding:0 4px;
  display:inline-flex;align-items:center;justify-content:center;
  background:#FF3B30;color:#fff;
  border-radius:999px;
  font-size:10.5px;font-weight:700;line-height:1;
  letter-spacing:0;
  pointer-events:none;
}
/* The HTML `hidden` attribute normally applies display:none, but any CSS
   `display` rule (like our inline-flex above) overrides it in Safari. Force
   it back so an empty (0-count) badge never covers the star. */
.header-fav-badge[hidden]{display:none !important}

/* With the header-fav-btn now owning the "push-right" via margin-left:auto,
   the burger no longer needs its own. Removing it prevents the two elements
   from fighting for space in the header flex row. */
.nav-burger{margin-left:0}

/* Overlay + drawer container. Overlay dims the page; drawer is a right-aligned
   panel that animates in. Both start hidden and become active via .is-open. */
.fav-drawer-overlay{
  position:fixed;inset:0;
  background:rgba(15,31,22,.45);
  opacity:0;pointer-events:none;
  transition:opacity .18s ease-out;
  z-index:998;
}
.fav-drawer-overlay.is-open{opacity:1;pointer-events:auto}

.fav-drawer{
  position:fixed;top:0;right:0;bottom:0;
  width:min(420px, 90vw);
  background:#fff;
  box-shadow:-16px 0 40px rgba(0,0,0,.18);
  transform:translateX(100%);
  transition:transform .22s ease-out;
  z-index:999;
  display:flex;flex-direction:column;
  overflow:hidden;
  color:var(--ink-900,#0f1f16);
}
.fav-drawer.is-open{transform:translateX(0)}

.fav-drawer-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:20px 20px 12px;
  border-bottom:1px solid var(--line,#e6ece8);
  flex:0 0 auto;
}
.fav-drawer-title{
  margin:0;
  font-size:1.35rem;font-weight:800;
  color:var(--green-900,#0e3823);
  letter-spacing:-.01em;
}
.fav-drawer-close{
  display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;
  background:transparent;color:var(--ink-700,#3a4a41);
  border:0;border-radius:8px;cursor:pointer;
  transition:background .15s,color .15s;
}
.fav-drawer-close:hover{background:#f2f5f3;color:var(--ink-900,#0f1f16)}

.fav-drawer-body{
  flex:1 1 auto;
  overflow-y:auto;
  padding:16px 12px 24px;
  -webkit-overflow-scrolling:touch;
}

.fav-section-label{
  padding:6px 10px 8px;
  font-size:.8rem;font-weight:700;
  color:var(--ink-soft,#6b7a72);
  text-transform:uppercase;letter-spacing:.06em;
}

.fav-list{display:flex;flex-direction:column;gap:2px}

.fav-row{
  display:flex;align-items:stretch;
  border-radius:10px;
  transition:background .12s;
}
.fav-row:hover{background:#f6f9f7}

.fav-row-link{
  flex:1 1 auto;
  display:flex;align-items:center;gap:12px;
  padding:12px 10px;
  background:transparent;color:inherit;
  border:0;border-radius:10px;
  text-align:left;cursor:pointer;
  font-family:inherit;font-size:1rem;
  min-width:0;
}
.fav-row-link:focus-visible{outline:2px solid var(--green-700,#1a5a3a);outline-offset:-2px}
.fav-row-icon{
  flex:0 0 auto;
  font-size:1.4rem;
  line-height:1;
}
.fav-row-body{
  display:flex;flex-direction:column;min-width:0;flex:1 1 auto;
}
.fav-row-name{
  font-weight:700;
  color:var(--green-900,#0e3823);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.fav-row-meta{
  font-size:.85rem;
  color:var(--ink-soft,#6b7a72);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.fav-row-remove{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;
  background:transparent;color:var(--ink-soft,#6b7a72);
  border:0;border-radius:8px;cursor:pointer;
  transition:background .12s,color .12s;
}
.fav-row-remove:hover{background:#fbeae7;color:#b3261e}
.fav-row-remove:focus-visible{outline:2px solid #b3261e;outline-offset:-2px}

.fav-empty{
  padding:40px 20px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:10px;
}
.fav-empty-icon{
  color:#f5c518;
  background:#fff8e1;
  width:64px;height:64px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
}
.fav-empty-title{
  margin:0;font-size:1.1rem;font-weight:800;
  color:var(--green-900,#0e3823);
}
.fav-empty-body{
  margin:0;max-width:280px;
  color:var(--ink-soft,#6b7a72);font-size:.95rem;line-height:1.5;
}
.fav-empty-body strong{color:var(--green-900,#0e3823);font-weight:700}

/* When the drawer is open, prevent background scroll on mobile. */
body.fav-drawer-open{overflow:hidden}

/* Reduced-motion users get an instant open/close, no slide. */
@media (prefers-reduced-motion: reduce){
  .fav-drawer,.fav-drawer-overlay{transition:none}
}

/* ------------------------------------------------------
   Header search sheet (top-slide)
   Tapping the header magnifier drops a sheet down from under the header
   containing the exact home-page search form (moved into #search-sheet-slot
   on open, restored to .hero on close). Different pattern from favorites
   drawer (right-slide) to keep the two triggers visually distinct.
------------------------------------------------------ */
.search-sheet-overlay{
  position:fixed;inset:0;
  background:rgba(15,31,22,.45);
  opacity:0;pointer-events:none;
  transition:opacity .18s ease-out;
  z-index:997; /* just below fav-drawer stack so they never fight */
}
.search-sheet-overlay.is-open{opacity:1;pointer-events:auto}

.search-sheet{
  position:fixed;left:0;right:0;top:0;
  background:#fff;
  transform:translateY(-100%);
  transition:transform .22s ease-out;
  z-index:998;
  box-shadow:0 8px 24px rgba(0,0,0,.15);
  max-height:min(90vh,720px);
  overflow-y:auto;
  border-bottom-left-radius:14px;
  border-bottom-right-radius:14px;
}
.search-sheet.is-open{transform:translateY(0)}

.search-sheet-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;
  padding:14px 18px 10px;
  border-bottom:1px solid rgba(15,31,22,.08);
}
.search-sheet-title{
  font-family:inherit;
  font-size:15px;font-weight:800;
  color:var(--green-900,#0e3823);
  letter-spacing:.02em;text-transform:uppercase;
  margin:0;
}
.search-sheet-close{
  width:36px;height:36px;
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;color:var(--green-900,#0e3823);
  border:0;border-radius:10px;
  cursor:pointer;font:inherit;
  transition:background .15s;
}
.search-sheet-close:hover{background:rgba(15,31,22,.06)}
.search-sheet-close:focus-visible{outline:2px solid #0e3823;outline-offset:2px}

.search-sheet-body{padding:16px 18px 18px}
/* The moved-in form should look identical to how it looks in the hero. It
   already has its own layout via .search / .search-field / .date-field, so
   we don't need to restyle it — just make sure the width fills the sheet. */
.search-sheet-body .search{width:100%;max-width:none;margin:0}

/* Small tap-to-close hint under the form (mirrors the sports-site pattern
   where the whole sheet is dismissable). Purely visual. */
.search-sheet-hint{
  font-size:12.5px;color:#5a6b60;
  margin:12px 0 0;
  text-align:center;
}

body.search-sheet-open{overflow:hidden}

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

/* Toast for copy-to-clipboard fallback */
.share-toast{
  position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(20px);
  background:var(--ink-900,#0f1f16);color:#fff;
  padding:12px 20px;border-radius:999px;font-size:.9rem;font-weight:600;
  box-shadow:0 10px 24px rgba(0,0,0,.18);
  opacity:0;pointer-events:none;
  transition:opacity .18s,transform .18s;
  z-index:9999;
}
.share-toast.is-visible{opacity:1;transform:translateX(-50%) translateY(0)}

/* ============================================================
   Score badge — Mock D hybrid layout

   Desktop (>= 720px):  Hero globe + secondary orb + verdict, side-by-side
   Mobile  (<  720px):  Segmented toggle + single hero globe + verdict, stacked
   ============================================================ */

.score-badge{display:flex;flex-direction:column;gap:16px;min-width:0}

/* Layout container */
.score-layout{display:flex;gap:32px;align-items:center}
.score-hero{display:flex;flex-direction:column;align-items:center;gap:12px;flex:0 0 auto}
.score-side{display:flex;flex-direction:column;gap:22px;flex:1;min-width:0}
.score-side-row{display:flex;align-items:center;gap:16px}

/* Hero caption below big globe */
.score-caption{font-size:.78rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-500);font-weight:600;text-align:center}
.score-caption .muted{text-transform:none;letter-spacing:0;font-weight:500;color:var(--ink-500)}
/* Do NOT force line-break inside .muted here — keeps "Peak window · 7 AM" on one line */

/* Secondary column text block */
.score-side-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.score-side-label{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-500);font-weight:700}
.score-side-val{font-family:var(--font-display);font-weight:800;font-size:1.05rem;color:var(--ink-900);letter-spacing:-0.01em;line-height:1.2}
.score-side-hint{font-size:.85rem;color:var(--ink-500);line-height:1.4;margin-top:2px;max-width:34ch}

/* Verdict sits below the secondary orb on desktop — normal styles apply */

/* Mobile-only segmented toggle. Default hidden; shown via media query. */
.score-toggle-wrap{display:none;justify-content:center;margin-bottom:4px}
.score-toggle{
  display:inline-flex;
  background:var(--sand-100, #f3f0e6);
  border:1px solid var(--line, #e5e2d6);
  border-radius:999px;
  padding:4px;
}
.score-toggle button{
  background:transparent;
  border:0;
  padding:8px 18px;
  font-family:inherit;
  font-size:.85rem;
  font-weight:700;
  color:var(--ink-500);
  border-radius:999px;
  cursor:pointer;
  letter-spacing:.01em;
  transition:background .18s ease, color .18s ease, box-shadow .18s ease;
}
.score-toggle button.active{
  background:#fff;
  color:var(--s-prime, #0f5132);
  box-shadow:0 1px 3px rgba(0,0,0,0.08), 0 0 0 1px rgba(15,81,50,0.1);
}
.score-toggle button .muted{color:inherit;opacity:.7;font-weight:600;margin-left:2px}

/* Mobile-only verdict block (below hero). Default hidden; shown on mobile. */
.score-verdict-mobile{display:none;text-align:center;max-width:38ch;margin:0 auto}
.score-verdict-mobile .verdict-sub{margin:6px auto 0}

/* Score-badge specific breakpoint: swap to mobile layout below 720px.
   This is INDEPENDENT of the app's global .site-nav/.hero breakpoint (520px)
   because the score's side-by-side layout gets cramped below ~720px, while
   the rest of the app can still render happily at that width. */
@media (max-width: 719px){
  .score-badge{align-items:stretch}
  .score-toggle-wrap{display:flex}
  .score-layout{flex-direction:column;gap:16px;align-items:center}
  .score-hero{width:100%}
  .score-hero .score-ring{width:220px;height:220px}
  .score-hero .score-ring .score-num{font-size:4.6rem}
  .score-caption{font-size:.85rem;letter-spacing:.1em}
  .score-side{display:none}
  .score-verdict-mobile{display:block}
}

/* Solid globe score badge — inspired by the OG share card.
   Structure per block:
     .score-ring (positioning wrapper — dictates size)
       svg (stroke ring = arc showing % full of the score)
       .score-num (huge white numeral centered inside the globe)
   The globe itself is a radial-gradient background on .score-ring::before,
   colored by the .ring-{prime|great|good|ok|bad|nogo} class we already toggle. */
/* Globe recipe — solid orb with glossy highlight, huge white numeral,
   translucent progress arc. Applied to both hero (large) and secondary
   (small) variants; size is set by variant-specific selectors below. */
.score-ring{
  position:relative;
  width:200px;height:200px;      /* Desktop hero default */
  flex:0 0 auto;
  border-radius:50%;
  /* Neutral placeholder background before a score loads */
  background:radial-gradient(circle at 30% 28%, #86efac 0%, #16a34a 55%, #14532d 100%);
  box-shadow:
    0 18px 40px -12px rgba(15,81,50,0.45),
    0 4px 12px -4px rgba(15,81,50,0.3),
    inset 0 3px 12px rgba(255,255,255,0.22),
    inset 0 -4px 14px rgba(0,0,0,0.18);
  transition:background .3s ease, box-shadow .3s ease;
}
/* Glossy specular highlight on the top-left — cheap but sells the "3D orb" feel */
.score-ring::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:50%;
  background:radial-gradient(circle at 32% 25%, rgba(255,255,255,0.35) 0%, rgba(255,255,255,0) 45%);
  pointer-events:none;
}
/* Progress arc lives on top of the globe as an SVG ring.
   We keep the existing SVG markup (viewBox 0 0 120, r=52, stroke-width=10)
   and just restyle strokes: track becomes a translucent white ring, foreground
   becomes a bright white arc that shows how full the score is. */
.score-ring svg{
  position:absolute;
  inset:0;
  width:100%;height:100%;
  transform:rotate(-90deg);
  pointer-events:none;
  /* Slight nudge so the ring sits just inside the globe edge, not on top */
  padding:6px;
  box-sizing:border-box;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,0.25));
}
.ring-bg{fill:none;stroke:rgba(255,255,255,0.18);stroke-width:6}
.ring-fg{
  fill:none;
  stroke:rgba(255,255,255,0.95);
  stroke-width:6;
  stroke-linecap:round;
  transition:stroke-dashoffset .8s cubic-bezier(.2,.8,.2,1), stroke .3s;
}
/* Numeral sits dead-center, big and white — matches OG card treatment */
/* Hero numeral — huge, white, dead-center */
.score-num{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  flex-direction:column;
  font-family:var(--font-display);
  font-weight:900;
  font-size:4.1rem;               /* Desktop hero default */
  line-height:1;
  color:#ffffff;
  letter-spacing:-0.04em;
  text-shadow:0 2px 10px rgba(0,0,0,0.28);
  padding-top:2px;
  transition:font-size .3s ease;
}
.score-num small{
  font-size:.24em;
  color:rgba(255,255,255,0.78);
  font-weight:700;
  letter-spacing:.06em;
  margin-top:6px;
  text-shadow:none;
}

/* Small variant (secondary daily-average orb on desktop) */
.score-ring.score-ring-sm{width:84px;height:84px}
.score-ring.score-ring-sm svg{padding:5px;filter:drop-shadow(0 1px 2px rgba(0,0,0,0.22))}
.score-ring.score-ring-sm .ring-bg{stroke-width:5}
.score-ring.score-ring-sm .ring-fg{stroke-width:5}
.score-ring.score-ring-sm .score-num{font-size:1.85rem;text-shadow:0 1px 4px rgba(0,0,0,0.28)}
.score-ring.score-ring-sm .score-num small{font-size:.28em;margin-top:2px}
/* Zero-state ("–") stays white but softer so it clearly reads as "waiting for data" */
.score-num:has(> span:empty), .score-num > span:empty::before{
  /* fallback for browsers without :has — the text "–" is set in HTML anyway */
}
.verdict-label{font-family:var(--font-display);font-weight:900;font-size:1.5rem;line-height:1.1}
.verdict-sub{color:var(--ink-500);margin-top:4px;max-width:32ch}

/* "How this will play" one-line tip.
   Sits between the "Conditions at peak window" chip (h3.section-title) and the
   factors grid. Small caps label + a clickable link that deep-scrolls to the
   matching FAQ. Uses accent color so it registers as interactive without
   competing with the score orbs above. */
.peak-tip{
  margin-top:6px;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding:10px 14px;
  background:linear-gradient(180deg, var(--sand-50, #fbfaf5) 0%, #fff 100%);
  border:1px solid var(--line);
  border-left:3px solid var(--accent-500, #0f5132);
  border-radius:var(--radius-sm);
}
.peak-tip-label{
  font-size:.72rem;text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink-500);font-weight:700;
  flex:0 0 auto;
}
.peak-tip-text{
  color:var(--ink-900);
  font-weight:500;
  text-decoration:none;
  transition:color .15s ease;
  flex:1 1 auto;
  min-width:0;
  line-height:1.4;
}
/* Trailing chevron cues that the tip is clickable and reveals more (FAQ). */
.peak-tip-text::after{
  content:" \2192";
  color:var(--accent-500, #0f5132);
  font-weight:700;
  white-space:nowrap;
  margin-left:2px;
  transition:transform .15s ease, margin-left .15s ease;
  display:inline-block;
}
.peak-tip-text:hover,
.peak-tip-text:focus-visible{
  color:var(--accent-500, #0f5132);
}
.peak-tip-text:hover::after,
.peak-tip-text:focus-visible::after{
  margin-left:6px;
}
.peak-tip-text:focus-visible{outline:2px solid var(--accent-500, #0f5132);outline-offset:3px;border-radius:2px}

/* Second chip: "Yardage today" ball-carry advisory. Sits directly below the
   "How this will play" chip. Uses an amber left-border to visually distinguish
   carry-yardage advice (data-driven, always-on when meaningful) from the
   dominant-factor playing tip (situational). Amber picks up the sun/heat
   semantics of temperature the same way the sand-50 tile background does. */
.peak-tip.peak-tip-carry{
  margin-top:6px;
  border-left:3px solid #c07f00;
}
.peak-tip.peak-tip-carry .peak-tip-text::after{color:#c07f00}
.peak-tip.peak-tip-carry .peak-tip-text:hover,
.peak-tip.peak-tip-carry .peak-tip-text:focus-visible{color:#c07f00}
.peak-tip.peak-tip-carry .peak-tip-text:focus-visible{outline-color:#c07f00}

/* When a user deep-links to a FAQ via #faq-* the anchor sits near the top of
   the viewport. Give the target a scroll-margin so the fixed nothing-visible
   overlaps the summary, and briefly highlight it so the user sees where their
   click landed. */
.faq details{scroll-margin-top:80px}
/* Anchor targets — offset for sticky header so they don't get covered on tap */
#how, #faq {scroll-margin-top: 90px}
@media(max-width:520px){#how, #faq {scroll-margin-top: 76px}}
.faq details:target > summary{
  background:var(--sand-100, #f2efe6);
  border-radius:6px;
  transition:background .3s ease;
}
@media (max-width:520px){
  .peak-tip{flex-direction:column;gap:4px;align-items:flex-start}
}

/* Factors grid */
.factors{
  margin-top:12px;display:grid;gap:12px;
  grid-template-columns:repeat(auto-fill, minmax(160px, 1fr));
}
.factor{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px 14px;
  display:flex;flex-direction:column;gap:6px;position:relative;overflow:hidden;
}
.factor .f-label{font-size:.78rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-500);font-weight:600;display:flex;align-items:center;gap:6px}
.factor .f-val{font-family:var(--font-display);font-weight:700;font-size:1.4rem;line-height:1}
.factor .f-sub{color:var(--ink-500);font-size:.85rem}
.factor .f-bar{height:6px;background:var(--sand-100);border-radius:4px;overflow:hidden;margin-top:2px}
.factor .f-bar > span{display:block;height:100%;border-radius:4px;background:var(--green-600);width:0;transition:width .8s ease}
.wind-compass{width:42px;height:42px;position:absolute;top:8px;right:8px;color:var(--green-800)}
.wind-compass .arrow{transition:transform .6s ease}

/* Section titles */
.section-title{margin:36px 0 12px;font-family:var(--font-display);font-weight:900;font-size:1.4rem}

/* Best windows */
.best-windows{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(220px,1fr))}
.window-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-sm);padding:14px 16px;display:flex;align-items:center;gap:14px;box-shadow:var(--shadow-sm)}
.window-rank{
  width:34px;height:34px;border-radius:50%;background:var(--green-800);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-family:var(--font-display);
  flex:0 0 auto;
}
.window-time{font-weight:700}
.window-sub{color:var(--ink-500);font-size:.88rem}
.window-score{margin-left:auto;font-family:var(--font-display);font-weight:900;font-size:1.4rem}

/* Week (7-day at-a-glance) */
.week-scroller{overflow-x:auto;padding:6px 0 14px;margin:0 -20px;padding-left:20px;padding-right:20px}
.week{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(160px, 1fr);gap:12px;min-width:min-content}
@media(min-width:900px){.week{grid-template-columns:repeat(7, minmax(0,1fr));grid-auto-flow:row}}
.day-card{
  position:relative;background:#fff;border:1.5px solid var(--line);border-radius:var(--radius-sm);
  padding:14px 14px 12px;text-align:left;cursor:pointer;transition:transform .1s ease, border-color .15s, box-shadow .15s;
  display:flex;flex-direction:column;gap:10px;box-shadow:var(--shadow-sm);
  font-family:inherit;color:inherit;
}
.day-card:hover{border-color:var(--green-600);transform:translateY(-1px);box-shadow:var(--shadow-md)}
.day-card.selected{border-color:var(--green-800);box-shadow:0 0 0 3px rgba(15,81,50,.15), var(--shadow-md);background:linear-gradient(180deg, #fff, #f4faf6)}
.day-card.disabled{opacity:.55;background:#f4f1ea}
.day-card.disabled:hover{transform:none}
.best-badge{
  position:absolute;top:-8px;right:10px;background:var(--green-800);color:#fff;
  font-size:.68rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  padding:3px 8px;border-radius:999px;box-shadow:var(--shadow-sm);
}
.day-head{display:flex;align-items:baseline;gap:8px}
.day-dow{font-family:var(--font-display);font-weight:900;font-size:1.05rem;color:var(--ink-900)}
.day-date{font-size:.82rem;color:var(--ink-500);font-weight:500}
.day-scores{display:flex;gap:16px;align-items:flex-end}
.day-score-block{display:flex;flex-direction:column;gap:2px}
.day-score-num{font-family:var(--font-display);font-weight:900;font-size:2rem;line-height:1}
.day-score-num.sm{font-size:1.35rem;opacity:.85}
.day-card.disabled .day-score-num{color:var(--ink-400)!important}
.day-score-cap{font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-500);font-weight:600}
.day-stats{display:grid;grid-template-columns:1fr 1fr;gap:4px 10px;font-size:.82rem;color:var(--ink-700);border-top:1px dashed var(--line);padding-top:8px;margin-top:2px}
.day-stat{display:flex;align-items:center;gap:5px}
.day-stat-icon{font-size:.9em}

/* Hourly */
.hourly-scroller{overflow-x:auto;padding:6px 0 14px;margin:0 -20px;padding-left:20px;padding-right:20px}
.hourly{display:flex;gap:8px;min-width:min-content}
.hour{
  flex:0 0 auto;width:78px;background:#fff;border:1px solid var(--line);border-radius:12px;
  padding:10px 8px;text-align:center;display:flex;flex-direction:column;gap:4px;position:relative;
}
.hour.now{border-color:var(--green-600);box-shadow:0 0 0 3px rgba(75,179,123,.2)}
.hour.peak{background:linear-gradient(180deg, #fff, #eaf7ef);border-color:var(--green-500)}
.hour.dark{background:#f4f1ea;opacity:.55}
.hour.dark .h-score{color:var(--ink-500)!important}
.h-badge{color:var(--green-800);margin-left:4px;font-size:.85rem}
.h-badge.dark{color:var(--ink-500)}
.empty-windows{
  background:#fff;border:1px dashed var(--line);border-radius:var(--radius-sm);
  padding:16px 18px;display:flex;flex-direction:column;gap:4px;
}
.empty-windows strong{font-family:var(--font-display);font-size:1.05rem}
/*
  "Try [Day]" smart-jump link — injected inline into the empty-windows copy
  and the closed-window Conditions caption. Red matches the Caddie's Read
  accent and the brand red swatch, signaling an interactive urgent element
  (window closed — jump forward) without competing with the primary green
  CTA palette. Underline is always visible so the anchor reads as a link
  even inside muted body copy.
*/
a.try-next-day{
  color:#b71c1c;               /* Deep red — AA contrast on cream/white surfaces (6.6:1) */
  font-weight:700;
  text-decoration:underline;
  text-underline-offset:2px;
  text-decoration-thickness:1.5px;
  cursor:pointer;
}
a.try-next-day:hover,
a.try-next-day:focus-visible{
  color:#7a1414;               /* Darker red on hover — 10.8:1 on white */
  text-decoration-thickness:2px;
}
a.try-next-day:focus-visible{
  outline:2px solid #f28b82;
  outline-offset:2px;
  border-radius:2px;
}
.hour .h-time{font-size:.78rem;color:var(--ink-500);font-weight:600}
.hour .h-score{font-family:var(--font-display);font-weight:900;font-size:1.3rem;line-height:1}
.hour .h-temp{font-size:.85rem;color:var(--ink-700)}
.hour .h-wind{font-size:.72rem;color:var(--ink-500)}
.hour .h-dot{width:100%;height:4px;border-radius:3px;background:var(--sand-200);overflow:hidden;margin-top:4px}
.hour .h-dot > span{display:block;height:100%;background:var(--green-600)}

/* Score colors (used inline via JS setting a class) */
/* Numeric color inside the globe stays white (better contrast on the solid fill)
   than the previous per-tier ink colors. We keep the classes as no-ops in case
   they're used elsewhere in the tree (day tiles, mini-badges). */
/* Inside a globe (.score-ring), the big numeral is always white regardless of
   which tier class .setSingleRing() puts on it. This overrides the generic
   .score-{tier} text colors used elsewhere. */
.score-num.score-prime, .score-num.score-great, .score-num.score-good,
.score-num.score-ok,    .score-num.score-bad,    .score-num.score-nogo,
.score-ring .score-num, .score-ring .score-num > span{ color:#ffffff !important; }
.score-ring .score-num small{ color:rgba(255,255,255,0.78) !important; }

/* Elsewhere in the app (day cards, hourly list, etc.) still uses these text
   colors — leave them intact. */
.score-prime{color:var(--s-prime)}
.score-great{color:var(--s-great)}
.score-good{color:var(--s-good)}
.score-ok{color:var(--s-ok)}
.score-bad{color:var(--s-bad)}
.score-nogo{color:var(--s-nogo)}

/* Globe background per score tier — matches the .ring-* class the app already
   applies to the foreground stroke element. We select the parent .score-ring
   via :has() (modern browsers) and re-color the whole orb.
   Colors mirror the --s-* tokens but as gradients with a light center. */
.score-ring:has(.ring-prime){
  background:radial-gradient(circle at 30% 28%, #86efac 0%, #16a34a 55%, #052e16 100%);
  box-shadow:0 18px 40px -12px rgba(15,122,60,0.5), 0 4px 12px -4px rgba(15,122,60,0.35), inset 0 3px 12px rgba(255,255,255,0.22), inset 0 -4px 14px rgba(0,0,0,0.22);
}
.score-ring:has(.ring-great){
  background:radial-gradient(circle at 30% 28%, #a7f3d0 0%, #22c55e 55%, #14532d 100%);
  box-shadow:0 18px 40px -12px rgba(58,155,74,0.5), 0 4px 12px -4px rgba(58,155,74,0.35), inset 0 3px 12px rgba(255,255,255,0.22), inset 0 -4px 14px rgba(0,0,0,0.22);
}
.score-ring:has(.ring-good){
  background:radial-gradient(circle at 30% 28%, #fde68a 0%, #eab308 55%, #713f12 100%);
  box-shadow:0 18px 40px -12px rgba(195,154,30,0.5), 0 4px 12px -4px rgba(195,154,30,0.35), inset 0 3px 12px rgba(255,255,255,0.24), inset 0 -4px 14px rgba(0,0,0,0.22);
}
.score-ring:has(.ring-ok){
  background:radial-gradient(circle at 30% 28%, #fed7aa 0%, #f97316 55%, #7c2d12 100%);
  box-shadow:0 18px 40px -12px rgba(217,119,6,0.5), 0 4px 12px -4px rgba(217,119,6,0.35), inset 0 3px 12px rgba(255,255,255,0.24), inset 0 -4px 14px rgba(0,0,0,0.22);
}
.score-ring:has(.ring-bad){
  background:radial-gradient(circle at 30% 28%, #fecaca 0%, #dc2626 55%, #7f1d1d 100%);
  box-shadow:0 18px 40px -12px rgba(194,65,12,0.5), 0 4px 12px -4px rgba(194,65,12,0.35), inset 0 3px 12px rgba(255,255,255,0.24), inset 0 -4px 14px rgba(0,0,0,0.22);
}
.score-ring:has(.ring-nogo){
  background:radial-gradient(circle at 30% 28%, #fca5a5 0%, #b91c1c 55%, #450a0a 100%);
  box-shadow:0 18px 40px -12px rgba(153,27,27,0.55), 0 4px 12px -4px rgba(153,27,27,0.4), inset 0 3px 12px rgba(255,255,255,0.22), inset 0 -4px 14px rgba(0,0,0,0.25);
}
/* Ring foreground stays white regardless of tier — the tier communicates via
   the globe color, so we override the previous per-tier stroke colors. */
.ring-prime,.ring-great,.ring-good,.ring-ok,.ring-bad,.ring-nogo{stroke:rgba(255,255,255,0.95)!important}
.bg-prime{background:var(--s-prime)!important}
.bg-great{background:var(--s-great)!important}
.bg-good{background:var(--s-good)!important}
.bg-ok{background:var(--s-ok)!important}
.bg-bad{background:var(--s-bad)!important}
.bg-nogo{background:var(--s-nogo)!important}

/* ---------- How it works ---------- */
.how{padding:60px 0;background:linear-gradient(180deg, transparent, #fff)}
.how-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));margin-top:28px}
.how-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-sm);padding:20px}
.how-icon{font-size:1.6rem;margin-bottom:8px}
.how-card h3{font-family:var(--font-display);font-size:1.1rem;margin-bottom:4px}
.how-card p{color:var(--ink-500);margin:4px 0 0;font-size:.94rem}

.scale{margin-top:36px;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:24px}
.scale h3{font-family:var(--font-display);font-size:1.2rem;margin-bottom:14px}
.scale-row{display:flex;align-items:center;gap:12px;padding:8px 0;border-bottom:1px dashed var(--line)}
.scale-row:last-child{border-bottom:0}
.chip{
  display:inline-block;padding:4px 10px;border-radius:999px;font-weight:700;font-size:.85rem;color:#fff;min-width:80px;text-align:center;
}
.s-prime{background:var(--s-prime)}
.s-great{background:var(--s-great)}
.s-good{background:var(--s-good)}
.s-ok{background:var(--s-ok)}
.s-bad{background:var(--s-bad)}
.s-nogo{background:var(--s-nogo)}

/* ---------- FAQ ---------- */
.faq{padding:60px 0;background:#fff;border-top:1px solid var(--line)}
.faq h2{margin-bottom:16px}
.faq details{border-top:1px solid var(--line);padding:16px 0}
.faq details:last-of-type{border-bottom:1px solid var(--line)}
.faq summary{cursor:pointer;font-weight:700;font-family:var(--font-display);font-size:1.05rem;list-style:none;display:flex;justify-content:space-between;align-items:center}
.faq summary::-webkit-details-marker{display:none}
/*
 * FAQ toggle marker — was a text "+" that rotated 45° to form an × when open.
 * Swapped to an SVG chevron in v=google-45 (user request):
 *   collapsed → chevron-down  |  open → chevron-up  (via CSS rotate).
 * SVG is embedded via a background-image data URI so it inherits the same
 * green as before (#006747 hard-coded because CSS variables aren't allowed
 * inside url()). Sizing (14px) mirrors the old glyph's visual weight.
 */
.faq summary::after{
  content:"";
  display:inline-block;
  width:14px;
  height:14px;
  flex:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23006747' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat:no-repeat;
  background-position:center;
  background-size:contain;
  transition:transform .2s ease;
}
.faq details[open] summary::after{transform:rotate(180deg)}
.faq p{color:var(--ink-700);margin:8px 0 0}
.faq p small{color:var(--ink-600);font-size:.86rem;font-style:italic}
.faq-table-wrap{margin:12px 0 4px;overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--line);border-radius:8px;background:#fff}
.faq-table{width:100%;border-collapse:collapse;font-family:var(--font-sans);font-size:.94rem;color:var(--ink-800)}
.faq-table thead th{background:var(--paper-200);color:var(--ink-900);text-align:left;font-weight:700;padding:10px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
.faq-table tbody td{padding:10px 14px;border-bottom:1px solid var(--line-100, #eee)}
.faq-table tbody tr:last-child td{border-bottom:none}
.faq-table tbody tr:nth-child(even){background:#faf8f4}
.faq-table tbody td:nth-child(2){font-variant-numeric:tabular-nums;color:var(--ink-900);font-weight:600}
.faq-table tbody td:nth-child(3){color:var(--ink-700)}
/* Wind table has TWO numeric-primary columns — make col 3 match col 2's weight
   and numeric alignment when we opt-in via the wide variant. */
.faq-table--wind tbody td:nth-child(2),
.faq-table--wind tbody td:nth-child(3){
  font-variant-numeric:tabular-nums;color:var(--ink-900);font-weight:600;
}
/* Inline "(one club more)" hint sits below the yardage on the wind table and
   is muted so the yardage number reads first. Uses inline-block + top margin so
   it wraps cleanly on narrow screens instead of squishing next to the yardage. */
.faq-table-note{
  display:inline-block;
  margin-top:2px;
  color:var(--ink-600);
  font-weight:400;
  font-size:.86rem;
  font-variant-numeric:normal;
}
@media (max-width:640px){
  .faq-table{font-size:.88rem}
  .faq-table thead th,.faq-table tbody td{padding:8px 10px}
  .faq-table-note{display:block;margin-top:2px}
}

/* ---------- Footer ---------- */
/*
 * Site footer background — was warm sand var(--sand-100) #f2ede3.
 * Swapped to #D3E4DA in v=google-46 (user request "match light green"):
 * a ~15% tint of the header green #006747 mixed with white, one step
 * deeper than the body's #E6F0EC so the footer still reads as a distinct
 * shelf under content, just like the old warm-sand shelf did.
 */
.site-footer{padding:28px 0 40px;color:var(--ink-500);border-top:1px solid var(--line);background:#D3E4DA}
.site-footer p{margin:2px 0}
.site-footer a{color:var(--green-800)}
.footer-directory{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px;font-size:14px}
.footer-directory a{color:var(--green-800);text-decoration:none;font-weight:600}
.footer-directory a:hover{text-decoration:underline}
.footer-directory span{color:var(--ink-300)}

/* ---------- Skeleton ---------- */
.skeleton{position:relative;overflow:hidden;background:var(--sand-200);border-radius:6px;color:transparent}
.skeleton::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.6),transparent);animation:shimmer 1.4s infinite}
@keyframes shimmer{from{transform:translateX(-100%)}to{transform:translateX(100%)}}

/* ---------- Nearby loading skeletons ---------- */
.nb-loading-live{
  grid-column:1 / -1;
  color:var(--ink-500);
  font-size:.9rem;
  padding:0 2px 6px;
}
.nb-skeleton{
  display:flex;align-items:center;justify-content:space-between;
  padding:14px 14px;
  background:#fff;
  border:1px solid var(--sand-300, #e6e2d5);
  border-radius:14px;
  min-height:52px;
}
.nb-skel-name{
  display:block;height:14px;width:60%;
  background:linear-gradient(90deg, #eef1ec 0%, #f8faf6 50%, #eef1ec 100%);
  background-size:200% 100%;
  border-radius:6px;
  animation:nbSkelShimmer 1.4s infinite linear;
}
.nb-skel-dist{
  display:block;height:14px;width:44px;
  background:linear-gradient(90deg, #eef1ec 0%, #f8faf6 50%, #eef1ec 100%);
  background-size:200% 100%;
  border-radius:20px;
  animation:nbSkelShimmer 1.4s infinite linear;
}
@keyframes nbSkelShimmer{
  from{background-position:200% 0}
  to{background-position:-200% 0}
}
@media (prefers-reduced-motion: reduce){
  .nb-skel-name, .nb-skel-dist{animation:none;background:#eef1ec}
}

/* ---------- Try Another Course module ---------- */
.try-another{margin-top:40px}
.ta-card{
  background:linear-gradient(180deg, var(--green-50) 0%, #ffffff 100%);
  border:1px solid var(--green-100);
  border-radius:20px;
  padding:24px;
  box-shadow:var(--shadow-sm);
}
.ta-head{margin-bottom:16px}
.ta-title{
  margin:0;
  font-size:1.25rem;
  font-weight:800;
  color:var(--ink-900);
  letter-spacing:-.01em;
}
.ta-sub{margin:4px 0 0;color:var(--ink-500);font-size:.95rem}
.ta-actions{
  display:grid;
  grid-template-columns:1fr;
  gap:10px;
}
@media(min-width:640px){.ta-actions{grid-template-columns:1fr 1fr 1fr}}
.ta-btn{
  display:flex;
  align-items:center;
  gap:14px;
  width:100%;
  padding:14px 16px;
  background:#ffffff;
  border:1px solid var(--green-100);
  border-radius:14px;
  cursor:pointer;
  text-align:left;
  transition:border-color .15s, box-shadow .15s, transform .05s;
  color:var(--ink-900);
  font:inherit;
}
.ta-btn:hover{border-color:var(--green-600);box-shadow:var(--shadow-sm)}
.ta-btn:active{transform:scale(.995)}
.ta-btn:focus-visible{outline:2px solid var(--green-600);outline-offset:2px}
.ta-btn svg{
  width:22px;height:22px;
  color:var(--green-700);
  flex:0 0 auto;
}
.ta-btn-label{display:flex;flex-direction:column;gap:2px;min-width:0}
.ta-btn-title{font-weight:700;color:var(--ink-900);line-height:1.2}
.ta-btn-sub{font-size:.82rem;color:var(--ink-500);line-height:1.2}

/* ---------- Small screens ---------- */
@media(max-width:520px){
  /* Solid deep-green on mobile too so the OG-card palette carries through
     to the collapsed hamburger state without any translucent cream bleed. */
  .site-header{background:#006747}
  /* Single-line header on mobile. flex-wrap:nowrap keeps the burger from
     dropping to line 2 once the theme toggle joins the icon row. The brand
     becomes the flex-shrink target so it truncates first if anything ever
     overflows again — icons stay full size. */
  .header-inner{position:relative;flex-wrap:nowrap;height:64px;min-height:64px;padding-top:0;padding-bottom:0;gap:2px}
  /* Hide the "GWI |" prefix on mobile so "Golf Weather Index" alone fits
     comfortably alongside search + star + moon + burger. Desktop still
     shows the full "GWI | Golf Weather Index" lockup. */
  .brand-prefix{display:none}
  .brand{font-size:1rem;gap:8px;min-width:0;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;letter-spacing:-0.03em}
  .brand-divider{margin:0 .22em}
  .header-icon-btn{width:38px;height:38px;margin-right:0;flex:0 0 auto}
  .nav-burger{display:flex;align-items:center;flex:0 0 auto;margin-left:2px}
  /* Expanded mobile drawer keeps the green surface + white links so the
     open menu reads as an extension of the header, not a separate panel.
     Absolutely positioned below the header row so the header stays a fixed
     single line even when the drawer is open. */
  .site-nav{display:none;position:absolute;top:100%;left:0;right:0;flex-direction:column;gap:0;margin-top:0;padding:8px 20px 12px;border-top:1px solid rgba(255,255,255,.12);background:#006747;box-shadow:0 8px 16px rgba(0,0,0,.15)}
  .site-nav a{padding:14px 4px;border-bottom:1px solid rgba(255,255,255,.08);font-size:1rem;color:#fff}
  .site-nav a:last-child{border-bottom:none}
  .nav-toggle:checked ~ .site-nav{display:flex}
  .nav-toggle:checked ~ .nav-burger .icon-open{display:none}
  .nav-toggle:checked ~ .nav-burger .icon-close{display:block}
  /* Score-badge mobile layout is handled by its own 720px breakpoint above,
     which fires before this 520px breakpoint. Nothing extra needed here. */
  /* Tighten hero spacing on mobile so the primary CTA and RECENT row appear
     above the fold. Was 32/24 with .lede margin 16/28 + .empty-state
     padding-top 32 — combined ~100px of vertical padding between the header
     and the first useful content. Now ~50px total, no visible crowding. */
  .hero{padding:20px 0 12px}
  .lede{margin:10px 0 18px}
  .date-field{flex:1 1 100%}
  #date{width:100%}
  .ta-card{padding:18px}
  /* Mobile-only tighter empty-state top padding (already 12px in the base
     rule; explicit here so future desktop-only bumps don't regress mobile). */
  .empty-state{padding-top:6px}
}

/* ---------- iPhone SE / narrow phones (≤ 380px) ---------- */
/* At iPhone-SE-class widths the four header icons + wordmark start
   competing for horizontal space and the wordmark clips (QA v73 caught
   "Golf Weather Ind" at 375px). Squeeze the icon column ~4px each,
   trim wrap padding, and drop the logo/type a hair so "Golf Weather Index"
   always fits on one line. Larger phones (≥ 390px) keep roomier icons. */
@media(max-width:380px){
  .wrap{padding-left:14px;padding-right:14px}
  .header-inner{gap:0}
  .header-icon-btn{width:34px;height:34px}
  .header-icon-btn svg{width:20px;height:20px}
  .nav-burger{padding:6px}
  .nav-burger svg{width:22px;height:22px}
  .brand{font-size:.95rem;gap:6px}
  .brand .logo{width:28px !important;height:28px !important}
}

/* ---------- Legacy narrow phones (≤ 335px, e.g. iPhone SE 1st gen / iPhone 5) ---------- */
/* At 320px there's not enough room for the full wordmark AND four icons
   without the search icon painting over "Index". Shrink the wordmark to
   ~13px and remove the star (rarely used vs. search + moon + burger). */
@media(max-width:335px){
  .brand{font-size:.82rem;gap:4px}
  .brand .logo{width:24px !important;height:24px !important}
  .header-icon-btn{width:32px;height:32px}
  .header-icon-btn svg{width:18px;height:18px}
  .header-fav-btn{display:none}
}

/* ---------- Saved locations (Favorites + Recent) ---------- */
.empty-saved-host{margin-bottom:22px}
.ta-saved-host{margin:14px 0 6px}
.saved-row{margin-bottom:14px}
.saved-row:last-child{margin-bottom:0}
.saved-row-title{
  font-size:.78rem;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink-500);
  margin-bottom:8px;
}
.saved-row-chips{
  display:flex;flex-wrap:wrap;gap:8px;
}
.saved-chip{
  display:inline-flex;align-items:center;gap:10px;
  background:#fff;
  border:1px solid var(--line);
  border-radius:999px;
  padding:8px 14px 8px 10px;
  font-family:inherit;font-size:.9rem;font-weight:600;
  color:var(--ink-900);
  cursor:pointer;
  transition:background .15s,border-color .15s,transform .05s;
  max-width:100%;
  text-align:left;
}
.saved-chip:hover{background:var(--green-50,#eef7f0);border-color:var(--green-800)}
.saved-chip:active{transform:translateY(1px)}
.saved-chip.is-fav{border-color:#f5c518;background:#fffdf5}
.saved-chip.is-fav:hover{background:#fff8e1;border-color:#e0a800}
.sc-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;flex:0 0 auto;
  font-size:.95rem;line-height:1;
}
.sc-body{display:inline-flex;flex-direction:column;line-height:1.15;min-width:0}
.sc-name{
  font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:210px;
}
.sc-meta{
  font-size:.72rem;font-weight:500;color:var(--ink-500);
  letter-spacing:.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:210px;
}

@media (max-width:520px){
  .sc-name, .sc-meta{max-width:160px}
}

/* ─────────────────────────────────────────────────────────────
   Back-to-search FAB (mobile-only)
   ─────────────────────────────────────────────────────────────
   Fixed to lower-right, appears once user scrolls past the search
   box. Uses env(safe-area-inset-*) so it clears the iOS home-bar
   and doesn't overlap the notch. Hidden by default (JS sets the
   [hidden] attribute) and hidden entirely on tablet/desktop where
   the search box is always one short scroll away.
*/
/* Matches the styling of the back-to-top button used across the directory
   pages so the whole site behaves consistently. Visible on all viewports.
   Uses inline-flex + opacity toggling driven by the .is-visible class.
   Keeps the safe-area insets so it clears the iOS home indicator. */
.back-to-top{
  position:fixed;
  right:calc(env(safe-area-inset-right, 0px) + 20px);
  bottom:calc(env(safe-area-inset-bottom, 0px) + 20px);
  z-index:50;

  width:48px;
  height:48px;
  border-radius:50%;
  border:none;
  padding:0;

  background:var(--accent-500, #0f5132);
  color:var(--cream, #faf3e2);
  box-shadow:0 4px 14px rgba(0,0,0,.18);

  display:inline-flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  font-family:inherit;

  opacity:0;
  transform:translateY(12px);
  pointer-events:none;
  transition:opacity .22s ease, transform .22s ease, background .18s ease;

  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}
.back-to-top.is-visible{
  opacity:1;
  transform:translateY(0);
  pointer-events:auto;
}
.back-to-top:hover{
  background:var(--green-mid, #0a3d24);
}
.back-to-top:focus-visible{
  outline:2px solid var(--gold, #f4b53f);
  outline-offset:3px;
}
.back-to-top svg{
  width:22px;
  height:22px;
  display:block;
  pointer-events:none;
}
.back-to-top[hidden]{display:none !important}

@media (max-width:600px){
  .back-to-top{
    right:calc(env(safe-area-inset-right, 0px) + 14px);
    bottom:calc(env(safe-area-inset-bottom, 0px) + 14px);
    width:44px;
    height:44px;
  }
  .back-to-top svg{width:20px;height:20px}
}

@media (prefers-reduced-motion:reduce){
  .back-to-top{
    transition:opacity .12s ease;
    transform:none;
  }
  .back-to-top.is-visible{transform:none}
}

/* =============================================================================
   DARK THEME (v=google-71)

   Activated by <html data-theme="dark"> which is set inline in <head> before
   this stylesheet loads (see the no-flash script in index.html). The dark
   palette is a charcoal-forward reinterpretation of the light theme:

     - Charcoal background (#0d1117) instead of pale-green sand
     - Dark cards (#161b22) with muted borders so surfaces layer subtly
     - Text lightens to #e6edf3 / #9da7b3, matching GitHub / Linear tone
     - Green accents keep their brand hue but shift +brightness for contrast
     - Score-ring green/yellow/red palette is UNCHANGED (semantic meaning)

   Implementation strategy: override the design tokens under [data-theme="dark"]
   first (that fixes ~70% of surfaces automatically), then patch the ~30 spots
   in the stylesheet that hardcode `#fff`, `rgba(255,255,255,x)`, or other
   light-mode literals. Grouped by UI region so future edits are easy to trace.
============================================================================= */

/* Icon toggle: moon shows when light is active (i.e. click to go dark),
   sun shows when dark is active (i.e. click to go light). */
.header-theme-btn .icon-sun{display:none}
[data-theme="dark"] .header-theme-btn .icon-moon{display:none}
[data-theme="dark"] .header-theme-btn .icon-sun{display:block}

[data-theme="dark"]{
  /* Neutrals — charcoal + text ramp */
  --sand-50:#0d1117;        /* page bg */
  --sand-100:#1c232c;       /* pill / chip bg */
  --sand-200:#242c36;       /* hover fills */
  --ink-900:#e6edf3;        /* primary text */
  --ink-700:#c9d1d9;        /* secondary text */
  --ink-500:#8b949e;        /* tertiary / muted */
  --ink-400:#6e7681;        /* dim */
  --line:#30363d;           /* borders / dividers */

  /* Green — same hue, slight lift for dark-bg contrast */
  --green-800:#3fb27f;      /* CTAs, active states */
  --green-700:#4bb37b;
  --green-600:#4bb37b;
  --green-500:#5cc38a;
  --green-100:#1e3a2b;      /* subtle green tint bg */
  --green-50:#152a20;

  /* Shadows: darker underlays instead of soft green so they read on charcoal */
  --shadow-sm:0 1px 2px rgba(0,0,0,.30), 0 2px 6px rgba(0,0,0,.25);
  --shadow-md:0 12px 30px -12px rgba(0,0,0,.55);

  color-scheme:dark;
}

/* Body: swap radial gradients to muted charcoal wash. Keep the two-blob
   layered look for depth so dark mode doesn't feel like a flat solid color. */
[data-theme="dark"] body{
  background:
    radial-gradient(1200px 600px at 85% -10%, rgba(63,178,127,.10), transparent 60%),
    radial-gradient(900px 500px at -5% 10%, rgba(59,130,246,.06), transparent 60%),
    var(--sand-50);
}

/* Card surfaces — anything that hardcoded #fff becomes charcoal card #161b22.
   Grouped selectors keep the diff readable; each targets a specific surface. */
[data-theme="dark"] .search-field,
[data-theme="dark"] .date-field,
[data-theme="dark"] .suggestions,
[data-theme="dark"] .course-info,
[data-theme="dark"] .empty-card,
[data-theme="dark"] .course-chip,
[data-theme="dark"] .nearby-bottom-list .nb-course,
[data-theme="dark"] .nearby-bottom-list .nb-empty,
[data-theme="dark"] .nearby-bottom-list .nb-load-more{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}

/* Inputs: keep transparent (they sit inside .search-field / .date-field which
   are now dark), but recolor the placeholder + value + icons. */
[data-theme="dark"] #q,
[data-theme="dark"] #date{color:var(--ink-900)}
[data-theme="dark"] #q::placeholder{color:var(--ink-500)}

/* Suggestions dropdown hover state */
[data-theme="dark"] .suggestions button:hover,
[data-theme="dark"] .suggestions button:focus{background:var(--sand-200)}
[data-theme="dark"] .suggestions .sug-body strong{color:var(--ink-900)}
[data-theme="dark"] .suggestions .sug-sub{color:var(--ink-500)}
[data-theme="dark"] .suggestions .sug-icon{background:var(--green-100)}
[data-theme="dark"] .suggestions .sug-icon-pin{background:var(--sand-200)}

/* Date chips (Today / +1 / +2 ...) */
[data-theme="dark"] .date-chip{
  background:transparent;
  border-color:var(--line);
  color:var(--ink-700);
}
[data-theme="dark"] .date-chip:hover{
  border-color:var(--green-600);
  color:var(--green-500);
}
[data-theme="dark"] .date-chip.active{
  background:var(--green-800);
  color:#0d1117;
  border-color:var(--green-800);
}

/* Primary CTA (green pill) — the auto-inherit from --green-800 works, but
   the hover state was hardcoded so pin it here. */
[data-theme="dark"] .primary:hover{background:var(--green-700)}

/* Nearby courses band — dashed border still reads on dark, but the linear
   gradient needs to swap so it doesn't look like a milky bar. */
[data-theme="dark"] .nearby-courses{
  background:linear-gradient(180deg, #10161d, #161b22);
  border-color:var(--green-600);
}
[data-theme="dark"] .nearby-title{color:var(--green-500)}
[data-theme="dark"] .course-chip:hover{
  background:#1c2531;
  border-color:var(--green-600);
}
[data-theme="dark"] .course-chip-dist{
  background:var(--sand-200);
  color:var(--ink-500);
}

/* Course-info panel — action pills, hours, ratings */
[data-theme="dark"] .course-info .ci-action{
  background:var(--sand-100);
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .course-info .ci-action:hover{
  background:#1c2531;
  border-color:var(--green-600);
  color:var(--green-500);
}
[data-theme="dark"] .course-info .ci-action svg{color:var(--green-500)}
[data-theme="dark"] .course-info .ci-rating{color:#f5c518}
[data-theme="dark"] .course-info .ci-price{color:var(--ink-700)}
[data-theme="dark"] .course-info .ci-open{
  color:#7ee0a6;background:rgba(63,178,127,.12);border-color:rgba(63,178,127,.35);
}
[data-theme="dark"] .course-info .ci-closed{
  color:#ff9d9d;background:rgba(239,68,68,.10);border-color:rgba(239,68,68,.35);
}

/* Course-info skeleton loaders — swap the light shimmer gradient to dark. */
[data-theme="dark"] .course-info .ci-skel-line,
[data-theme="dark"] .course-info .ci-skel-pill{
  background:linear-gradient(90deg,#1a2029 25%,#242c36 37%,#1a2029 63%);
  background-size:400% 100%;
}

/* Nearby-bottom-list — course rating rows, distance pills, hover states */
[data-theme="dark"] .nearby-bottom-list .nb-course:hover{
  border-color:var(--green-600);
  box-shadow:var(--shadow-sm);
  background:#1c2531;
}
[data-theme="dark"] .nearby-bottom-list .nb-name{color:var(--ink-900)}
[data-theme="dark"] .nearby-bottom-list .nb-rating{color:#f5c518}
[data-theme="dark"] .nearby-bottom-list .nb-rating-count{color:var(--ink-500)}
[data-theme="dark"] .nearby-bottom-list .nb-dist{
  background:var(--sand-100);
  border-color:var(--line);
  color:var(--ink-500);
}
[data-theme="dark"] .nearby-bottom-list .nb-load-more{
  background:#161b22;
  color:var(--green-500);
  border-color:var(--line);
}
[data-theme="dark"] .nearby-bottom-list .nb-load-more:hover{
  background:#1c2531;
  border-color:var(--green-600);
}

/* Empty state (pre-search) — hero card + illustrated icon well */
[data-theme="dark"] .empty-card{
  background:#161b22;
  border-color:var(--line);
  box-shadow:var(--shadow-md);
}
[data-theme="dark"] .empty-icon{
  background:linear-gradient(180deg,#1e3a2b,#152a20);
  border-color:var(--green-600);
}
[data-theme="dark"] .empty-title{color:var(--green-500)}

/* Ghost button (X-clear inside search field) */
[data-theme="dark"] .ghost{color:var(--ink-500)}
[data-theme="dark"] .ghost:hover{
  background:var(--sand-200);
  color:var(--green-500);
}

/* Muted / lede text */
[data-theme="dark"] .muted,
[data-theme="dark"] .lede{color:var(--ink-700)}

/* Anchor links */
[data-theme="dark"] a{color:var(--green-500)}
/* Brand wordmark override: the generic dark-mode link color above turns the
   "Golf Weather" text muted green. Force it back to white so the header
   lockup (white + gold) reads the same in both themes. "Index" keeps its
   yellow accent via .brand-accent. */
[data-theme="dark"] .brand,
[data-theme="dark"] .brand:hover,
[data-theme="dark"] .brand-text{ color:#ffffff; }

/* Hour strip — the horizontal card row under the score. Hardcoded whites live
   here; swap card bg, borders, and text ramp. Score fill (green bar) stays. */
[data-theme="dark"] .hour-card,
[data-theme="dark"] .hour-row .hour{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .hour-row .hour.active,
[data-theme="dark"] .hour-row .hour[aria-selected="true"]{
  background:rgba(63,178,127,.18);
  border-color:var(--green-600);
}

/* Score card wrapping the ring — dark card so the ring floats cleanly */
[data-theme="dark"] .score-card,
[data-theme="dark"] .score-block,
[data-theme="dark"] .score-summary,
[data-theme="dark"] .day-average,
[data-theme="dark"] .peak-window,
[data-theme="dark"] .conditions,
[data-theme="dark"] .caddie-read,
[data-theme="dark"] .forecast-grid,
[data-theme="dark"] .card,
[data-theme="dark"] .panel{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}

/* Any element that had inline `background:#fff` via legacy class (defensive
   catch-all — surfaces we may have missed above still get dark cards). */
[data-theme="dark"] [style*="background:#fff"],
[data-theme="dark"] [style*="background: #fff"],
[data-theme="dark"] [style*="background-color:#fff"],
[data-theme="dark"] [style*="background-color: #fff"]{
  background:#161b22 !important;
}

/* Search sheet (top-slide dialog opened by the header magnifier) */
[data-theme="dark"] #search-sheet{
  background:#0d1117;
  color:var(--ink-900);
  border-bottom:1px solid var(--line);
}
[data-theme="dark"] #search-sheet-overlay{background:rgba(0,0,0,.65)}
[data-theme="dark"] .search-sheet-title{color:var(--ink-900)}
[data-theme="dark"] .search-sheet-close{color:var(--ink-500)}
[data-theme="dark"] .search-sheet-close:hover{color:var(--ink-900);background:var(--sand-200)}

/* Favorites drawer (side sheet opened by the header star) */
[data-theme="dark"] .fav-drawer,
[data-theme="dark"] #fav-drawer{
  background:#0d1117;
  color:var(--ink-900);
  border-left:1px solid var(--line);
}
[data-theme="dark"] .fav-drawer-title{color:var(--ink-900)}
[data-theme="dark"] .fav-row{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .fav-row:hover{background:#1c2531;border-color:var(--green-600)}
[data-theme="dark"] .fav-row-loc{color:var(--ink-500)}
[data-theme="dark"] .fav-empty{color:var(--ink-500)}

/* Caddie's Read box — the highlighted "Caddie's Read" section under the ring */
[data-theme="dark"] .caddie-read{
  background:#161b22;
  border-left-color:var(--green-500);
}
[data-theme="dark"] .caddie-read .caddie-label{color:var(--green-500)}

/* Tooltips, popovers, misc chrome */
[data-theme="dark"] .tooltip,
[data-theme="dark"] .popover{
  background:#1c2531;
  color:var(--ink-900);
  border-color:var(--line);
  box-shadow:var(--shadow-md);
}

/* Back-to-top FAB */
[data-theme="dark"] .back-to-top{
  background:#161b22;
  color:var(--green-500);
  border:1px solid var(--line);
  box-shadow:var(--shadow-md);
}
[data-theme="dark"] .back-to-top:hover{background:#1c2531}

/* Status messages */
[data-theme="dark"] .status{color:var(--ink-500)}
[data-theme="dark"] .status.error{color:#ff9d9d}
[data-theme="dark"] .status.error .status-details summary{color:#ff9d9d}
[data-theme="dark"] .status.error .status-details > *:not(summary){color:#f5b8b8}

/* Header stays the deep green in both themes (brand consistency) — no override
   needed. The white icons on green already read fine in dark mode. */

/* =============================================================================
   DARK THEME — round 2 (v=google-72)
   QA pass caught: .how / .how-card, .scale + .scale-row, .faq + .faq-table,
   .empty-hints example pills, .site-footer. All hardcode `#fff` and were
   missed by the first-round overrides. Grouped by section so future edits
   are trivial to trace.
============================================================================= */

/* "How the Golf Weather Index works" — the 8 factor cards */
[data-theme="dark"] .how{
  background:linear-gradient(180deg, transparent, #10161d);
}
[data-theme="dark"] .how-card{
  background:#161b22;
  border-color:var(--line);
}
[data-theme="dark"] .how-card h3{color:var(--ink-900)}
[data-theme="dark"] .how-card p{color:var(--ink-500)}

/* "The GWI scale" — score legend card */
[data-theme="dark"] .scale{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .scale h3{color:var(--ink-900)}
[data-theme="dark"] .scale-row{
  border-bottom-color:rgba(255,255,255,.06);
  color:var(--ink-700);
}
/* Score chips (85–100 / 70–84 / etc.) — their color-coded backgrounds carry
   semantic meaning so we KEEP them. Just make sure text stays readable. */
[data-theme="dark"] .chip{color:#fff}

/* FAQ section */
[data-theme="dark"] .faq{
  background:#0d1117;
  border-top-color:var(--line);
}
[data-theme="dark"] .faq h2{color:var(--ink-900)}
[data-theme="dark"] .faq details{
  border-top-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .faq details:last-of-type{border-bottom-color:var(--line)}
[data-theme="dark"] .faq summary{color:var(--ink-900)}
[data-theme="dark"] .faq p{color:var(--ink-700)}
[data-theme="dark"] .faq p small{color:var(--ink-500)}

/* FAQ tables (carry vs. temp, wind vs. club selection) */
[data-theme="dark"] .faq-table-wrap{
  background:#161b22;
  border-color:var(--line);
}
[data-theme="dark"] .faq-table{color:var(--ink-900)}
[data-theme="dark"] .faq-table thead th{
  background:#1c2531;
  color:var(--ink-900);
  border-bottom-color:var(--line);
}
[data-theme="dark"] .faq-table tbody td{border-bottom-color:var(--line)}
[data-theme="dark"] .faq-table tbody tr:nth-child(even){background:#1a2029}
[data-theme="dark"] .faq-table tbody td:nth-child(2){color:var(--ink-900)}
[data-theme="dark"] .faq-table tbody td:nth-child(3){color:var(--ink-700)}
[data-theme="dark"] .faq-table-note{color:var(--ink-500)}

/* Empty-state example pills — "Oakland Hills" / "Pebble Beach" / "Scottsdale" */
[data-theme="dark"] .empty-hints li em{
  background:var(--sand-200);
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .empty-sub{color:var(--ink-700)}

/* Site footer */
[data-theme="dark"] .site-footer{
  background:#10161d;
  color:var(--ink-500);
  border-top-color:var(--line);
}
[data-theme="dark"] .site-footer a{color:var(--green-500)}

/* Details/summary marker (the caret at the end of each FAQ summary) — the ::after
   generated content picks up currentColor, so tinting the summary is enough. */

/* =============================================================================
   DARK THEME — round 3 (v=google-76)
   Results-view compliance pass. User reported light-on-light contrast on the
   score card ("Livonia, Michigan"), condition factor cards (TEMP 75°F, WIND
   13 mph, etc.), and Best-windows list — all hardcode `background:#fff` so
   the theme variables never touched them. Fixed together here so WCAG AA
   contrast holds across every panel that appears after a search.
============================================================================= */

/* Big score card container (place name + date + share + score badge) */
[data-theme="dark"] .results-head{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
  box-shadow:0 4px 20px rgba(0,0,0,.4);
}
[data-theme="dark"] .place-name{color:var(--ink-900)}
[data-theme="dark"] .place-meta{color:var(--ink-500)}
[data-theme="dark"] .place-meta .meta-date{color:var(--ink-900)}
[data-theme="dark"] .place-meta .meta-next-label{color:var(--green-500)}

/* Share button — was white pill with green text; keep visible on dark card */
[data-theme="dark"] .share-btn{
  background:#1c2531;
  color:var(--green-500);
  border-color:var(--line);
}
[data-theme="dark"] .share-btn:hover{
  background:#242c36;
  border-color:var(--green-500);
}

/* Favorite button — same treatment (rendered inside the score card) */
[data-theme="dark"] #fav-toggle,
[data-theme="dark"] .fav-toggle{
  background:#1c2531;
  color:var(--green-500);
  border-color:var(--line);
}
[data-theme="dark"] #fav-toggle:hover,
[data-theme="dark"] .fav-toggle:hover{
  background:#242c36;
  border-color:var(--green-500);
}
[data-theme="dark"] #fav-toggle.is-fav,
[data-theme="dark"] .fav-toggle.is-fav{color:#f5c518}

/* Score-toggle segmented control (Peak / Daily average) */
[data-theme="dark"] .score-toggle{
  background:#0d1117;
  border:1px solid var(--line);
}
[data-theme="dark"] .score-toggle button{color:var(--ink-500)}
[data-theme="dark"] .score-toggle button.active{
  background:#242c36;
  color:var(--ink-900);
}
[data-theme="dark"] .score-caption,
[data-theme="dark"] .score-caption .muted,
[data-theme="dark"] .score-side-label{color:var(--ink-500)}

/* Verdict phrases below the score ring ("Great day for a round" etc.) */
[data-theme="dark"] .verdict-label,
[data-theme="dark"] .score-side-val{color:var(--green-500)}
[data-theme="dark"] .verdict-sub,
[data-theme="dark"] .score-side-hint{color:var(--ink-500)}

/* Section titles ("Conditions at peak window", "Best windows to tee off", …) */
[data-theme="dark"] .section-title{color:var(--ink-900)}
[data-theme="dark"] .section-title .muted{color:var(--ink-500)}

/* Factor cards — the 8 condition tiles (TEMP, WIND, PRECIP, DEW POINT, …) */
[data-theme="dark"] .factor{
  background:#161b22;
  border-color:var(--line);
}
[data-theme="dark"] .factor .f-label{color:var(--ink-500)}
[data-theme="dark"] .factor .f-val{color:var(--ink-900)}
[data-theme="dark"] .factor .f-sub{color:var(--ink-500)}
[data-theme="dark"] .factor .f-bar{background:#0d1117}
[data-theme="dark"] .wind-compass{color:var(--green-500)}

/* Best windows to tee off — the ranked cards under the score */
[data-theme="dark"] .window-card{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .empty-windows{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-700);
}

/* 7-day cards */
[data-theme="dark"] .day-card{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .day-card:hover{border-color:var(--green-500)}

/* Hourly scroller cells */
[data-theme="dark"] .hour{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .hour.now{
  border-color:var(--green-500);
  box-shadow:0 0 0 3px rgba(63,178,127,.22);
}
[data-theme="dark"] .hour.peak{
  background:linear-gradient(180deg, #161b22, #1c2f24);
  border-color:var(--green-500);
}
[data-theme="dark"] .hour.dark{background:#10161d;opacity:.55}
[data-theme="dark"] .hour .h-time{color:var(--ink-500)}
[data-theme="dark"] .hour .h-temp{color:var(--ink-700)}
[data-theme="dark"] .h-badge{color:var(--green-500)}
[data-theme="dark"] .h-badge.dark{color:var(--ink-500)}

/* Peak-tip yellow highlight — invert cream→dark warm tone */
[data-theme="dark"] .peak-tip{
  background:#2a2416;
  border-color:#3a3116;
  color:var(--ink-900);
}
[data-theme="dark"] .peak-tip-label{color:#f5c518}
[data-theme="dark"] .peak-tip-text{color:var(--ink-900)}

/* Nearby / typeahead skeleton loaders + example course buttons */
[data-theme="dark"] .nb-skeleton{
  background:#161b22;
  border-color:var(--line);
}
[data-theme="dark"] .ta-btn{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .ta-btn:hover{border-color:var(--green-500)}

/* Saved-chip (Favorites + Recents pill row above the search) */
[data-theme="dark"] .saved-chip{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .saved-chip:hover{background:#1c2531;border-color:var(--green-500)}
[data-theme="dark"] .saved-chip.is-fav{background:#2a2416;border-color:#3a3116}
[data-theme="dark"] .saved-chip.is-fav:hover{background:#332a17;border-color:#f5c518}
[data-theme="dark"] .saved-row-title{color:var(--ink-500)}

/* Course-info panel + its action buttons (Book a tee time) */
[data-theme="dark"] .course-info{
  background:#161b22;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .course-info .ci-action{
  background:#1c2531;
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .course-info .ci-action:hover{
  background:#242c36;
  border-color:var(--green-500);
  color:var(--green-500);
}

/* Round 3.1: patch the two remaining surfaces flagged by QA */

/* "Not the right course?" callout card (.ta-card) — was a light-green→white
   gradient that painted a white halo in dark mode. Swap for a subtle
   dark-green→charcoal gradient so it still reads as a soft accent panel. */
[data-theme="dark"] .ta-card{
  background:linear-gradient(180deg, #142a20 0%, #161b22 100%);
  border-color:var(--line);
  color:var(--ink-900);
}
[data-theme="dark"] .ta-title{color:var(--ink-900)}
[data-theme="dark"] .ta-sub{color:var(--ink-500)}

/* Favorite button — the outline star pill was still solid white in dark
   mode. Match .share-btn treatment (dark pill + green text). Its "is-fav"
   state (starred) keeps the yellow accent. */
[data-theme="dark"] #fav-toggle:not(.is-fav),
[data-theme="dark"] .fav-toggle:not(.is-fav){
  background:#1c2531;
  color:var(--green-500);
  border-color:var(--line);
}

/* Round 3.2: Favorites drawer empty state — dark mode
   The .fav-empty-title used --green-900 (#0e3823, near-black green) which
   became invisible on the dark drawer. The .fav-empty-icon had a cream
   #fff8e1 circle which flared against the dark background. */
[data-theme="dark"] .fav-empty-icon{
  background:#2a2416;
  color:#f5c518;
}
[data-theme="dark"] .fav-empty-title{color:var(--green-500)}
[data-theme="dark"] .fav-empty-body{color:var(--ink-500)}
[data-theme="dark"] .fav-empty-body strong{color:var(--green-500)}

/* Round 3.3: Favorites drawer entry rows — dark mode
   Course names used --green-900 (near-black) and became unreadable on the
   dark drawer. Meta line and remove-X also needed tuning. */
[data-theme="dark"] .fav-section-label{color:var(--ink-500)}
[data-theme="dark"] .fav-row-name{color:var(--green-500)}
[data-theme="dark"] .fav-row-meta{color:var(--ink-500)}
[data-theme="dark"] .fav-row-remove{color:var(--ink-500)}
[data-theme="dark"] .fav-row-remove:hover{background:#3a1a17;color:#ff9d9d}
[data-theme="dark"] .fav-row:hover{background:#1c2531}

/* -----------------------------------------------------------------
   Forecast confidence chip (v=google-82)
   Shown inside the score-hero column when the multi-model blend
   (GFS + ECMWF + best_match) disagrees enough at the peak hour to
   matter. Hidden otherwise so easy-agreement days stay uncluttered.
   ------------------------------------------------------------------ */
.forecast-confidence{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:6px 10px;
  margin-top:10px;
  padding:8px 12px;
  border-radius:10px;
  font-size:12px;
  line-height:1.35;
  max-width:100%;
}
.forecast-confidence .fc-dot{
  flex:0 0 auto;
  width:8px;height:8px;
  border-radius:50%;
  align-self:center;
}
.forecast-confidence .fc-text{ font-weight:600; }
.forecast-confidence .fc-models{
  width:100%;
  font-size:11px;
  opacity:.75;
  font-weight:400;
}
/* Amber warn — some disagreement */
.forecast-confidence.fc-warn{
  background:#fff7e6;
  color:#7a4a00;
  border:1px solid #f5c98a;
}
.forecast-confidence.fc-warn .fc-dot{ background:#e0a441; }
/* Red alert — big disagreement across both axes */
.forecast-confidence.fc-alert{
  background:#fdecea;
  color:#7a1a13;
  border:1px solid #f0aca4;
}
.forecast-confidence.fc-alert .fc-dot{ background:#c0362c; }

[data-theme="dark"] .forecast-confidence.fc-warn{
  background:#2a2416;
  color:#f5c98a;
  border-color:#3d3620;
}
[data-theme="dark"] .forecast-confidence.fc-alert{
  background:#2a1616;
  color:#f0aca4;
  border-color:#3d2020;
}

/* -----------------------------------------------------------------
   Sticky 7-day date strip (v=google-83)
   Behavior:
     - Sits at natural position inside #results, `position: sticky; top: 0`.
     - Invisible (transparent bg, no shadow) until IntersectionObserver
       sentinel above it leaves the viewport → .is-stuck class added.
     - Horizontally scrollable on narrow screens, snap-aligned.
     - Selected pill = filled green; today = green outline when not
       selected; ★ marks the best-scoring day of the week; a colored dot
       under each date mirrors the peak-score band.
   ------------------------------------------------------------------ */
.day-strip-wrap{
  /* Sit BELOW the sticky site header (64px tall, z-index 20) so the two
     never overlap. z-index 19 keeps the strip beneath the header shadow
     but above ordinary page content. Fully opaque when stuck; a solid
     background prevents any ghosting of underlying content. */
  position: sticky;
  top: 64px;
  z-index: 19;
  background: transparent;
  transition: background-color .18s ease, box-shadow .18s ease, border-color .18s ease;
  border-bottom: 1px solid transparent;
}
.day-strip-wrap.is-stuck{
  background: #f2f7f4; /* solid app surface tint — no transparency */
  box-shadow: 0 4px 16px rgba(0,0,0,0.08);
  border-bottom-color: rgba(0,0,0,0.08);
}
.day-strip-wrap .wrap{ padding-top: 8px; padding-bottom: 8px; }
.day-strip{
  display: flex;
  gap: 6px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 2px 0;
}
.day-strip::-webkit-scrollbar{ display: none; }
.ds-pill{
  position: relative;
  flex: 1 1 0;
  min-width: 60px;
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 6px 10px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  color: var(--ink-700, #1f2937);
  font: inherit;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease, transform .12s ease;
  -webkit-tap-highlight-color: transparent;
}
.ds-pill:hover{ background: rgba(0,0,0,0.04); }
.ds-pill:active{ transform: scale(0.97); }
.ds-pill .ds-dow{
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-500, #6b7280);
  line-height: 1;
}
.ds-pill .ds-day{
  font-size: 18px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--ink-900, #111827);
}
/* Peak GWI score for that day, rendered as “NN/100” under the day digit.
   The “/100” suffix makes the number self-explanatory (it's a rating, not
   temperature). White text with a soft dark shadow so it stays AA on any
   tier-color pill background. */
.ds-pill .ds-score{
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  margin-top: 3px;
  letter-spacing: 0.02em;
  color: #ffffff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
}
.ds-pill .ds-score .ds-score-max{
  font-size: 9px;
  font-weight: 700;
  opacity: 0.80;
  margin-left: 1px;
}

/* Per-tier pill background — the whole week reads as a red→green severity
   bar. Same saturated palette as the score-legend chips and orb, so tier
   colors stay locked across every component that shows a GWI score. */
.ds-pill.ds-tier-prime{ background: #16a34a; border-color: #16a34a; }
.ds-pill.ds-tier-great{ background: #22c55e; border-color: #22c55e; }
.ds-pill.ds-tier-good{  background: #eab308; border-color: #eab308; }
.ds-pill.ds-tier-ok{    background: #f97316; border-color: #f97316; }
.ds-pill.ds-tier-bad{   background: #dc2626; border-color: #dc2626; }
/* Disabled / no-forecast day — muted slate so it recedes vs playable days. */
.ds-pill.ds-tier-nogo{  background: #64748b; border-color: #64748b; }

/* All pill text renders WHITE on the tier-colored background, with a
   subtle shadow for AA on lighter tiers (gold especially). Overrides the
   earlier ink-color defaults on .ds-dow and .ds-day. */
.ds-pill .ds-dow{ color: #ffffff; opacity: 0.92; text-shadow: 0 1px 1px rgba(0,0,0,0.25); }
.ds-pill .ds-day{ color: #ffffff; text-shadow: 0 1px 1px rgba(0,0,0,0.30); }

/* Selected day — white 2px stroke acts as the “you are here” marker.
   The pill keeps its tier-color fill so “which day” and “how good” stay
   independent visual signals. Full opacity even when disabled. */
.ds-pill.ds-selected{
  border: 2px solid #ffffff;
  transform: translateY(-1px);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.35),
    0 3px 10px rgba(0, 0, 0, 0.18);
  opacity: 1 !important;
}

/* Disabled day (fully past / no playable hours) — muted, still tappable. */
.ds-pill.ds-disabled{ opacity: 0.55; }

/* Best-day badge — bright ★ badge in the top-right of the pill.
   Previously positioned at top:-6px which was being clipped by the
   parent .day-strip's overflow-y:hidden (needed for horizontal scroll).
   Sits INSIDE the pill's top-right corner now, larger and with a soft
   glow so it reads as a deliberate best-day marker at a glance. */
.ds-pill .ds-best{
  position: absolute;
  top: 3px;
  right: 4px;
  font-size: 14px;
  line-height: 1;
  color: #f59e0b; /* amber-500 — reads warm gold on any pill fill */
  text-shadow:
    0 0 3px rgba(245, 158, 11, 0.55),
    0 1px 2px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  z-index: 2;
}
/* On the selected (green) pill, brighten the star to pure yellow so it
   pops off the green fill without competing with the white "MON 31". */
.ds-pill.ds-selected .ds-best{
  color: #fde047; /* yellow-300 */
  text-shadow:
    0 0 4px rgba(253, 224, 71, 0.75),
    0 1px 2px rgba(0, 0, 0, 0.35);
}
/* Dark mode: same warm-gold amber; the glow does the heavy lifting on
   charcoal so no extra tuning needed. */
[data-theme="dark"] .ds-pill .ds-best{
  color: #fbbf24; /* amber-400, one step brighter for dark backgrounds */
  text-shadow:
    0 0 4px rgba(251, 191, 36, 0.65),
    0 1px 2px rgba(0, 0, 0, 0.55);
}

/* Dark mode */
/* Dark-mode: solid dark surface, no transparency. */
[data-theme="dark"] .day-strip-wrap.is-stuck{
  background: #1f2937 !important;
  box-shadow: 0 4px 16px rgba(0,0,0,0.35) !important;
  border-bottom-color: rgba(255,255,255,0.08) !important;
}
[data-theme="dark"] .day-strip-wrap.is-stuck-legacy{
  background: rgba(20, 26, 34, 0.94);
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  border-bottom-color: rgba(255,255,255,0.06);
}
/* Dark mode day pills — identical to light mode. The saturated tier
   backgrounds and white text work uniformly in both themes, so we keep
   the palette locked to eliminate dark-mode drift. Only the hover state
   changes to a lighter overlay for touch feedback. */
[data-theme="dark"] .ds-pill:hover{ background: rgba(255,255,255,0.06); }

/* Mobile: tighter spacing, allow horizontal scroll. */
@media (max-width: 560px){
  .day-strip{ gap: 4px; }
  .ds-pill{ min-width: 56px; padding: 8px 4px 10px; }
  .ds-pill .ds-day{ font-size: 17px; }
}

/* ------------------------------------------------------------------
   Last-updated indicator (v=google-88)
   Small line beneath the place-meta showing "Last updated Xm ago"
   with a manual refresh button. Auto-refreshes every 20 minutes.
   ------------------------------------------------------------------ */
.place-updated{
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0 0;
  font-size: 12px;
  color: #6b7280;
  font-weight: 500;
}
.place-updated[hidden]{ display: none !important; }
.place-updated .lu-dot{
  width: 6px; height: 6px; border-radius: 50%;
  background: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
  flex: 0 0 auto;
}
.place-updated.is-stale .lu-dot{
  background: #f59e0b;
  box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.15);
}
.place-updated.is-refreshing .lu-dot{
  background: #3b82f6;
  animation: lu-pulse 1s ease-in-out infinite;
}
@keyframes lu-pulse{
  0%,100%{ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15); opacity: 1; }
  50%    { box-shadow: 0 0 0 6px rgba(59, 130, 246, 0.05); opacity: 0.7; }
}
.place-updated .lu-label{ line-height: 1.2; }
.lu-refresh-btn{
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  padding: 0; margin-left: 2px;
  background: transparent; border: 1px solid transparent;
  border-radius: 50%; color: #6b7280;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease, transform .3s ease;
}
.lu-refresh-btn:hover{ background: rgba(0, 103, 71, 0.08); color: #006747; border-color: rgba(0, 103, 71, 0.15); }
.lu-refresh-btn:active{ transform: scale(0.92); }
.lu-refresh-btn:focus-visible{ outline: 2px solid #f5c518; outline-offset: 2px; }
.place-updated.is-refreshing .lu-refresh-btn svg{ animation: lu-spin 0.9s linear infinite; }
@keyframes lu-spin{ to { transform: rotate(360deg); } }

/* Dark mode */
[data-theme="dark"] .place-updated{ color: #9ca3af; }
[data-theme="dark"] .lu-refresh-btn{ color: #9ca3af; }
[data-theme="dark"] .lu-refresh-btn:hover{
  background: rgba(74, 222, 128, 0.10);
  color: #4ade80;
  border-color: rgba(74, 222, 128, 0.20);
}

/* ==================================================================
   Score-tier legend (v=google-89)

   Compact 6-segment scale sitting directly under the score orb + caption.
   All six tiers show at once so the user can see the whole GWI scale
   at a glance; the tier matching the current hero score is filled with
   its tier color, and the other five are dimmed to a muted outline.

   Runs on both mobile (segments narrow, ranges only shown on wider
   viewports) and desktop.
   ================================================================== */
.score-legend{
  width: 100%;
  max-width: 520px;
  margin: 14px auto 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.score-legend[hidden]{ display: none !important; }
.sl-track{
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
  /* Room above the row for the pointer that sits on top of the active
     pill (see .sl-seg.is-active::before). Without this, the caret is
     clipped by whatever sits above. */
  padding-top: 18px;
}
/* Base segment.
   Same saturated palette in light AND dark mode so the legend reads
   identically across themes — the red→green severity gradient is the
   point of this component. Inactive pills get a gray outline so the
   ACTIVE pill's white stroke pops as the current-tier marker. */
.sl-seg{
  appearance: none;
  -webkit-appearance: none;
  border-radius: 8px;
  padding: 6px 4px 7px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: default;
  transition: transform .18s ease, background .18s ease, border-color .18s ease, box-shadow .18s ease, opacity .18s ease;
  min-height: 42px;
  text-align: center;
  font-family: inherit;
  /* Per-tier CSS var overridden below to use the ORB's bright mid-stops so
     the legend colors match what's inside the score circle. 65% color-mix
     with a deep neutral gives a saturated but slightly toned-down fill. */
  background: color-mix(in srgb, var(--sl-tier-color) 65%, #0f172a 35%);
  border: 2px solid rgba(148, 163, 184, 0.45); /* slate-400 @ 45% */
}
.sl-seg .sl-range{
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  /* White label with a soft dark shadow so it stays AA on every tier color,
     especially the lighter golds. Matches the dark-mode treatment so the
     component looks the same across themes. */
  color: #ffffff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
  line-height: 1;
}
.sl-seg .sl-name{
  font-size: 10px;
  font-weight: 700;
  color: #ffffff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* Per-tier color assignment. --sl-tier-color drives BOTH the toned fill
   (inactive) and the full fill (active). Values below are the BRIGHT
   orb mid-stops so the legend matches the score-circle color the user
   sees inside the orb — identical in light and dark mode. */
.sl-seg[data-tier="nogo"] { --sl-tier-color: #b91c1c; }
.sl-seg[data-tier="bad"]  { --sl-tier-color: #dc2626; }
.sl-seg[data-tier="ok"]   { --sl-tier-color: #f97316; }
.sl-seg[data-tier="good"] { --sl-tier-color: #eab308; }
.sl-seg[data-tier="great"]{ --sl-tier-color: #22c55e; }
.sl-seg[data-tier="prime"]{ --sl-tier-color: #16a34a; }

/* Active tier — fully saturated fill with a bright WHITE 2px stroke, lift +
   colored glow. The gray-vs-white outline is what makes the active tier
   unambiguously stand out from its 5 muted siblings. */
.sl-seg{ position: relative; }
.sl-seg.is-active{
  background: var(--sl-tier-color);
  border-color: #ffffff;
  transform: translateY(-1px);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--sl-tier-color) 60%, transparent),
    0 3px 12px color-mix(in srgb, var(--sl-tier-color) 55%, transparent);
}
/* Downward caret centered over the ACTIVE tier — a "you are here" pointer
   that follows whichever pill is highlighted. Pure CSS triangle so it
   scales cleanly. Black in light mode, white in dark mode (rule below). */
.sl-seg.is-active::before{
  content: "";
  position: absolute;
  left: 50%;
  top: -15px; /* sits in the .sl-track padding-top above */
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 12px solid #111827; /* light-mode arrow: near-black */
  pointer-events: none;
}
.sl-seg.is-active .sl-range,
.sl-seg.is-active .sl-name{ color: #fff; }

/* Under-legend caption: "Peak 76 · Great" / "Daily average 63 · Playable" */
.sl-note{
  margin: 0;
  text-align: center;
  font-size: 12px;
  color: #6b7280;
  line-height: 1.3;
}
.sl-note #sl-current{ font-weight: 600; color: #1f2937; }

/* Compact viewports — hide the numeric range so the tier name still fits
   in the narrow segment. Ranges stay on wider mobile + desktop. */
@media (max-width: 400px){
  .sl-seg .sl-range{ display: none; }
  .sl-seg .sl-name{ font-size: 11px; }
  .sl-seg{ padding: 8px 4px 9px; min-height: 40px; }
}

/* Dark mode: same colors, same treatment. The base rules above already
   ship the saturated palette; dark mode just tweaks the note text,
   keeps the active-pill white text working, and flips the caret to white
   so it reads on the dark card. */
[data-theme="dark"] .sl-note{ color: #9ca3af; }
[data-theme="dark"] .sl-note #sl-current{ color: #f3f4f6; }
[data-theme="dark"] .sl-seg.is-active .sl-range,
[data-theme="dark"] .sl-seg.is-active .sl-name{ color: #fff; }
[data-theme="dark"] .sl-seg.is-active::before{ border-top-color: #ffffff; }
